Port-mips archive

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

MIPS bus space



Hello,

I've been busy ripping out the home grown bus_space and bus_dma from
sgimips and replaced them with code from arch/mips/, now I'm at the
point that everything in my O2 works. It needs a few changes in mips/
though.

The following is for dealing with the O2's PCI host bridge which 32bit
endian-translates all accesses to PCI space, which can't be turned off
as far as I can tell. So all 8 and 16bit accesses need their addresses
translated. With this ahc at pci works.

Index: bus_space_alignstride_chipdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c,v
retrieving revision 1.19
diff -u -w -r1.19 bus_space_alignstride_chipdep.c
--- bus_space_alignstride_chipdep.c     27 Jan 2012 18:52:58 -0000      1.19
+++ bus_space_alignstride_chipdep.c     4 Feb 2015 11:57:41 -0000
@@ -194,17 +194,25 @@
 #define        CHIP_ALIGN_STRIDE       0
 #endif
 
+#ifdef CHIP_WRONG_ENDIAN
+#define        CHIP_OFF8(o)    ((o) ^ 3)
+#else
 #if CHIP_ALIGN_STRIDE > 0
 #define        CHIP_OFF8(o)    ((o) << (CHIP_ALIGN_STRIDE))
 #else
 #define        CHIP_OFF8(o)    (o)
 #endif
+#endif
 
+#ifdef CHIP_WRONG_ENDIAN
+#define        CHIP_OFF16(o)   ((o) ^ 2)
+#else
 #if CHIP_ALIGN_STRIDE > 1
 #define        CHIP_OFF16(o)   ((o) << (CHIP_ALIGN_STRIDE - 1))
 #else
 #define        CHIP_OFF16(o)   (o)
 #endif

The 2nd one is an actual bug in all _read and _write methods:
@@ -662,7 +670,8 @@
         int shift;
 
         h += CHIP_OFF8(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
         r = (uint8_t)(CHIP_SWAP_ACCESS(*ptr) >> shift);
 
The O2's ISA implementation is weird too, it's a bunch of 8bit
registers, accessed as 64bit quantities, spaced 256 bytes apart. So we
need CHIP_ALIGN_STRIDE = 8 and CHIP_ACCESS_SIZE = 8. The problem is
that currently, to extract - say - an 8bit quantity from - for example
- a 64bit word, the original, un-shifted offset is used. With registers
spaced apart that makes no sense and we should use the shifted value
instead.
With this the O2's serial ports work.

All other devices in the O2 just work without further hackery.

Comments?

have fun
Michael
Index: bus_space_alignstride_chipdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c,v
retrieving revision 1.19
diff -u -w -r1.19 bus_space_alignstride_chipdep.c
--- bus_space_alignstride_chipdep.c	27 Jan 2012 18:52:58 -0000	1.19
+++ bus_space_alignstride_chipdep.c	4 Feb 2015 11:57:41 -0000
@@ -194,17 +194,25 @@
 #define	CHIP_ALIGN_STRIDE	0
 #endif
 
+#ifdef CHIP_WRONG_ENDIAN
+#define	CHIP_OFF8(o)	((o) ^ 3)
+#else
 #if CHIP_ALIGN_STRIDE > 0
 #define	CHIP_OFF8(o)	((o) << (CHIP_ALIGN_STRIDE))
 #else
 #define	CHIP_OFF8(o)	(o)
 #endif
+#endif
 
+#ifdef CHIP_WRONG_ENDIAN
+#define	CHIP_OFF16(o)	((o) ^ 2)
+#else
 #if CHIP_ALIGN_STRIDE > 1
 #define	CHIP_OFF16(o)	((o) << (CHIP_ALIGN_STRIDE - 1))
 #else
 #define	CHIP_OFF16(o)	(o)
 #endif
+#endif
 
 #if CHIP_ALIGN_STRIDE > 2
 #define	CHIP_OFF32(o)	((o) << (CHIP_ALIGN_STRIDE - 2))
@@ -662,7 +670,8 @@
         int shift;
 
         h += CHIP_OFF8(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
         r = (uint8_t)(CHIP_SWAP_ACCESS(*ptr) >> shift);
 
@@ -682,7 +691,7 @@
 
 	KASSERT((off & 1) == 0);
         h += CHIP_OFF16(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	r = (uint16_t)CHIP_SWAP16(*ptr >> shift);
 
@@ -702,7 +711,7 @@
 
 	KASSERT((off & 3) == 0);
         h += CHIP_OFF32(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	r = (uint32_t)CHIP_SWAP32(*ptr >> shift);
 
@@ -718,7 +727,7 @@
 
 	KASSERT((off & 7) == 0);
         h += CHIP_OFF64(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	r =  CHIP_SWAP64(*ptr >> shift);
 
@@ -771,7 +780,7 @@
 	int shift;
 
 	h += CHIP_OFF8(off);
-	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+	shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
 	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	*ptr = CHIP_SWAP_ACCESS(((CHIP_TYPE)val) << shift);
 }
@@ -788,7 +797,7 @@
 
 	KASSERT((off & 1) == 0);
 	h += CHIP_OFF16(off);
-	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+	shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
 	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	if (CHIP_ACCESS_SIZE > 2)
 		*ptr = (CHIP_TYPE)(CHIP_SWAP16(val)) << shift;
@@ -808,7 +817,7 @@
 
 	KASSERT((off & 3) == 0);
         h += CHIP_OFF32(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
         if (CHIP_ACCESS_SIZE > 4)
 		*ptr = (CHIP_TYPE)(CHIP_SWAP32(val)) << shift;
@@ -824,7 +833,7 @@
 
 	KASSERT((off & 7) == 0);
         h += CHIP_OFF64(off);
-        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
+        shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8;
         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
 	*ptr = CHIP_SWAP64(val) << shift;
 }


Home | Main Index | Thread Index | Old Index