Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/tc From Felix Deichmann:



details:   https://anonhg.NetBSD.org/src/rev/200bb392325d
branches:  trunk
changeset: 346657:200bb392325d
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Jul 26 03:09:55 2016 +0000

description:
>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...

diffstat:

 sys/arch/alpha/tc/tc_bus_mem.c |  72 +++++++++++++++++++++++------------------
 1 files changed, 41 insertions(+), 31 deletions(-)

diffs (141 lines):

diff -r c7bdd77d40c0 -r 200bb392325d sys/arch/alpha/tc/tc_bus_mem.c
--- a/sys/arch/alpha/tc/tc_bus_mem.c    Tue Jul 26 01:49:48 2016 +0000
+++ b/sys/arch/alpha/tc/tc_bus_mem.c    Tue Jul 26 03:09:55 2016 +0000
@@ -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 @@
                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 @@
 
        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 @@
 
        if ((memh & TC_SPACE_SPARSE) != 0) {
                volatile uint64_t *p;
-
-               off &= 0x3;
-
-               p = (uint64_t *)(memh + (off << 1));
+               uint64_t mask = UINT64_C(0x3) << (32 + (off & 2));
 
-               *p = val;
-       } else {
-               volatile uint16_t *p;
+               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 = (uint16_t *)(memh + off);
-               *p = val;
-       }
        alpha_mb();             /* XXX XXX XXX */
 }
 
@@ -513,6 +521,7 @@
        else
                p = (uint32_t *)(memh + off);
        *p = val;
+
        alpha_mb();             /* XXX XXX XXX */
 }
 
@@ -526,6 +535,7 @@
 
        p = (uint64_t *)(memh + off);
        *p = val;
+
        alpha_mb();             /* XXX XXX XXX */
 }
 



Home | Main Index | Thread Index | Old Index