Module Name: src
Committed By: christos
Date: Tue Jul 26 03:09:55 UTC 2016
Modified Files:
src/sys/arch/alpha/tc: tc_bus_mem.c
Log Message:
>From Felix Deichmann:
While writing "slhci at tc" support, I noticed TC bus_space functions
for alpha don't work as they should (tc_bus_mem.c). Consideration of
dense vs. sparse space seems problematic, especially for widths < 4.
I found information mainly in
[1] https://web-docs.gsi.de/~kraemer/COLLECTION/DEC/d3syspmb.pdf
[2]
http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623255
and a dirty (but tested) hack based on this is attached as an example.
It would be great if someone could have a look and do a cleaner version
preferably.
Especially the end of ([2] section 12.2.2) provides a summary of which
"instruction" to use for which data width in which space, and possible
side effects (unintentional double reads/writes) in dense space...
To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/alpha/tc/tc_bus_mem.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/alpha/tc/tc_bus_mem.c
diff -u src/sys/arch/alpha/tc/tc_bus_mem.c:1.35 src/sys/arch/alpha/tc/tc_bus_mem.c:1.36
--- src/sys/arch/alpha/tc/tc_bus_mem.c:1.35 Mon Nov 4 11:55:31 2013
+++ src/sys/arch/alpha/tc/tc_bus_mem.c Mon Jul 25 23:09:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: tc_bus_mem.c,v 1.35 2013/11/04 16:55:31 christos Exp $ */
+/* $NetBSD: tc_bus_mem.c,v 1.36 2016/07/26 03:09:55 christos Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -33,7 +33,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: tc_bus_mem.c,v 1.35 2013/11/04 16:55:31 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tc_bus_mem.c,v 1.36 2016/07/26 03:09:55 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -364,32 +364,49 @@ tc_mem_barrier(void *v, bus_space_handle
alpha_wmb();
}
+/*
+ * https://web-docs.gsi.de/~kraemer/COLLECTION/DEC/d3syspmb.pdf
+ * http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623255
+ */
+#define TC_SPARSE_PTR(memh, off) \
+ ((void *)((memh)+ ((off & ((bus_size_t)-1 << 2)) << 1)))
+
static inline uint8_t
tc_mem_read_1(void *v, bus_space_handle_t memh, bus_size_t off)
{
- volatile uint8_t *p;
alpha_mb(); /* XXX XXX XXX */
- if ((memh & TC_SPACE_SPARSE) != 0)
- panic("tc_mem_read_1 not implemented for sparse space");
+ if ((memh & TC_SPACE_SPARSE) != 0) {
+ volatile uint32_t *p;
- p = (uint8_t *)(memh + off);
- return (*p);
+ p = TC_SPARSE_PTR(memh, off);
+ return ((*p >> ((off & 3) * 8)) & 0xff);
+ } else {
+ volatile uint8_t *p;
+
+ p = (uint8_t *)(memh + off);
+ return (*p);
+ }
}
static inline uint16_t
tc_mem_read_2(void *v, bus_space_handle_t memh, bus_size_t off)
{
- volatile uint16_t *p;
alpha_mb(); /* XXX XXX XXX */
- if ((memh & TC_SPACE_SPARSE) != 0)
- panic("tc_mem_read_2 not implemented for sparse space");
+ if ((memh & TC_SPACE_SPARSE) != 0) {
+ volatile uint32_t *p;
- p = (uint16_t *)(memh + off);
- return (*p);
+ p = TC_SPARSE_PTR(memh, off);
+ return ((*p >> ((off & 2) * 8)) & 0xffff);
+ } else {
+ volatile uint16_t *p;
+
+ p = (uint16_t *)(memh + off);
+ return (*p);
+ }
}
static inline uint32_t
@@ -467,17 +484,13 @@ tc_mem_write_1(void *v, bus_space_handle
if ((memh & TC_SPACE_SPARSE) != 0) {
volatile uint64_t *p;
- off &= 0x3;
-
- p = (uint64_t *)(memh + (off << 1));
+ uint64_t mask = UINT64_C(0x1) << (32 + (off & 3));
- *p = val;
- } else {
- volatile uint8_t *p;
+ p = TC_SPARSE_PTR(memh, off);
+ *p = mask | ((uint64_t)val << ((off & 3) * 8));
+ } else
+ panic("tc_mem_write_1 not implemented for dense space");
- p = (uint8_t *)(memh + off);
- *p = val;
- }
alpha_mb(); /* XXX XXX XXX */
}
@@ -487,18 +500,13 @@ tc_mem_write_2(void *v, bus_space_handle
if ((memh & TC_SPACE_SPARSE) != 0) {
volatile uint64_t *p;
+ uint64_t mask = UINT64_C(0x3) << (32 + (off & 2));
- off &= 0x3;
+ p = TC_SPARSE_PTR(memh, off);
+ *p = mask | ((uint64_t)val << ((off & 2) * 8));
+ } else
+ panic("tc_mem_write_2 not implemented for dense space");
- p = (uint64_t *)(memh + (off << 1));
-
- *p = val;
- } else {
- volatile uint16_t *p;
-
- p = (uint16_t *)(memh + off);
- *p = val;
- }
alpha_mb(); /* XXX XXX XXX */
}
@@ -513,6 +521,7 @@ tc_mem_write_4(void *v, bus_space_handle
else
p = (uint32_t *)(memh + off);
*p = val;
+
alpha_mb(); /* XXX XXX XXX */
}
@@ -526,6 +535,7 @@ tc_mem_write_8(void *v, bus_space_handle
p = (uint64_t *)(memh + off);
*p = val;
+
alpha_mb(); /* XXX XXX XXX */
}