Subject: Re: build aborts in regress/lib/libpthread/sem
To: None <port-dreamcast@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-dreamcast
Date: 02/23/2003 12:03:36
In article <yf93cmfzvl3.fsf@mc.pp.se>
marcus@mc.pp.se wrote:
> But which bus_space functions have conditional returns? Is this
> really an issue?
No, it is not used at the moment. I'd be a bit paranoid :-)
> I'm fine with the DECL+LOCK+UNLOCK proposal too.
Ok, then how about the attached patch (with some cosmetic changes)?
I'm not sure if unrolling multi/region ops is really worth, though.
(it's optional in this patch for now)
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp
Index: g2bus_bus_mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/g2/g2bus_bus_mem.c,v
retrieving revision 1.6
diff -u -r1.6 g2bus_bus_mem.c
--- g2bus_bus_mem.c 2002/12/27 11:34:05 1.6
+++ g2bus_bus_mem.c 2003/02/23 02:30:39
@@ -147,30 +147,35 @@
* The following paired macros will take the necessary precautions.
*/
-#define G2_LOCK \
+#define G2LOCK_DECL \
+ int __s
+
+#define G2_LOCK() \
do { \
- _cpu_exception_suspend(); \
+ __s = _cpu_intr_suspend(); \
/* suspend any G2 DMA here... */ \
- while((*(volatile unsigned int *)0xa05f688c) & 32); \
- } while(/*CONSTCOND*/0)
+ while((*(volatile u_int32_t *)0xa05f688c) & 0x20); \
+ } while (/*CONSTCOND*/0)
-#define G2_UNLOCK \
+#define G2_UNLOCK() \
do { \
/* resume any G2 DMA here... */ \
- _cpu_exception_resume(0); \
- } while(/*CONSTCOND*/0)
+ _cpu_intr_resume(__s); \
+ } while (/*CONSTCOND*/0)
+/* #define G2BUSMEM_UNROLL_ITERATIONS */
u_int8_t
g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int8_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int8_t *)(sh + off);
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -178,13 +183,14 @@
u_int16_t
g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int16_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int16_t *)(sh + off);
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -192,13 +198,14 @@
u_int32_t
g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int32_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int32_t *)(sh + off);
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -207,64 +214,115 @@
g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
u_int8_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int8_t *)(sh + off) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
u_int16_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int16_t *)(sh + off) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
u_int32_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int32_t *)(sh + off) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_bus_mem_read_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile const u_int8_t *baddr = (u_int8_t *)(sh + off);
- G2_LOCK;
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 16; len -= 16) {
+ G2_LOCK();
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ *addr++ = *baddr++;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
+ G2_LOCK();
+
while (len--)
*addr++ = *baddr++;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_bus_mem_write_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
const u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile u_int8_t *baddr = (u_int8_t *)(sh + off);
+
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 16; len -= 16) {
+ G2_LOCK();
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ *baddr++ = *addr++;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
- G2_LOCK;
+ G2_LOCK();
while (len--)
*baddr++ = *addr++;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
@@ -291,13 +349,14 @@
u_int8_t
g2bus_sparse_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int8_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int8_t *)(sh + (off * 4));
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -305,13 +364,14 @@
u_int16_t
g2bus_sparse_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int16_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int16_t *)(sh + (off * 4));
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -319,13 +379,14 @@
u_int32_t
g2bus_sparse_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
{
+ G2LOCK_DECL;
u_int32_t rv;
- G2_LOCK;
+ G2_LOCK();
rv = *(__volatile u_int32_t *)(sh + (off * 4));
- G2_UNLOCK;
+ G2_UNLOCK();
return (rv);
}
@@ -334,94 +395,193 @@
g2bus_sparse_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
u_int8_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int8_t *)(sh + (off * 4)) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
u_int16_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int16_t *)(sh + (off * 4)) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
u_int32_t val)
{
+ G2LOCK_DECL;
- G2_LOCK;
+ G2_LOCK();
*(__volatile u_int32_t *)(sh + (off * 4)) = val;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_read_region_1(void *v, bus_space_handle_t sh,
bus_size_t off, u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile const u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
- G2_LOCK;
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 8; len -= 8) {
+ G2_LOCK();
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ *addr++ = *baddr;
+ baddr += 4;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
+
+ G2_LOCK();
while (len--) {
*addr++ = *baddr;
baddr += 4;
}
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_write_region_1(void *v, bus_space_handle_t sh,
bus_size_t off, const u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
- G2_LOCK;
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 8; len -= 8) {
+ G2_LOCK();
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ *baddr = *addr++;
+ baddr += 4;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
+
+ G2_LOCK();
while (len--) {
*baddr = *addr++;
baddr += 4;
}
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_read_multi_1(void *v, bus_space_handle_t sh,
bus_size_t off, u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile const u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
+
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 16; len -= 16) {
+ G2_LOCK();
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ *addr++ = *baddr;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
- G2_LOCK;
+ G2_LOCK();
while (len--)
*addr++ = *baddr;
- G2_UNLOCK;
+ G2_UNLOCK();
}
void
g2bus_sparse_bus_mem_write_multi_1(void *v, bus_space_handle_t sh,
bus_size_t off, const u_int8_t *addr, bus_size_t len)
{
+ G2LOCK_DECL;
__volatile u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
+
+#ifdef G2BUSMEM_UNROLL_ITERATIONS
+ for (; len >= 16; len -= 16) {
+ G2_LOCK();
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ *baddr = *addr++;
+ G2_UNLOCK();
+ }
+#endif /* G2BUSMEM_UNROLL_ITERATIONS */
- G2_LOCK;
+ G2_LOCK();
while (len--)
*baddr = *addr++;
- G2_UNLOCK;
+ G2_UNLOCK();
}