Hi,

since ARMv6 the coprocessor provides special registers to store software
defined values.  Those registers are:

  * TPIDRURW -> kernel RW, user RW
  * TPIDRURO -> kernel RW, user RO
  * TPIDRPRW -> kernel RW

TPIDRPRW is typically used to store the pointer to the curcpu struct,
while TPIDRURO is used to point to the TCB.

The following diff implements using TPIDRPRW to store and retrieve the
curcpu struct pointer.  This will especially be helpful in future MP
efforts.  I have guarded it for ARMv7 only, as that's the only hardware
I have that supports it and I was able to test on.

I have removed a few #ifdef MULTIPROCESSOR as they wouldn't be needed
with curcpu stored in that register and there'll probably never be
support for MP on non-ARMv7 machines.

If TCB_GET()'s only user is libpthread, then it could make sense to
store the TCB pointer in TPIDRURO.  If it's possible that it's also
used in ports, then the arm packages won't be compatible to
armish/zaurus anymore.  But the TCB stuff is not part of this diff.

Patrick

diff --git sys/arch/arm/arm/bcopyinout.S sys/arch/arm/arm/bcopyinout.S
index 4d423e5..be9bb47 100644
--- sys/arch/arm/arm/bcopyinout.S
+++ sys/arch/arm/arm/bcopyinout.S
@@ -82,18 +82,14 @@ ENTRY(copyin)
        moveq   pc, lr
 
        SAVE_REGS
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r2, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r4, .Lcpu_info
-       ldr     r4, [r4, r0, lsl #2]
-       ldr     r4, [r4, #CI_CURPCB]
-       ldmfd   sp!, {r0-r2, r14}
+
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r4, c13, c0, 4
 #else
        ldr     r4, .Lcpu_info_primary
-       ldr     r4, [r4, #CI_CURPCB]
 #endif
+       ldr     r4, [r4, #CI_CURPCB]
 
        ldr     r5, [r4, #PCB_ONFAULT]
        adr     r3, .Lcopyfault
@@ -305,18 +301,14 @@ ENTRY(copyout)
        moveq   pc, lr
 
        SAVE_REGS
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r2, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r4, .Lcpu_info
-       ldr     r4, [r4, r0, lsl #2]
-       ldr     r4, [r4, #CI_CURPCB]
-       ldmfd   sp!, {r0-r2, r14}
+
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r4, c13, c0, 4
 #else
        ldr     r4, .Lcpu_info_primary
-       ldr     r4, [r4, #CI_CURPCB]
 #endif
+       ldr     r4, [r4, #CI_CURPCB]
 
        ldr     r5, [r4, #PCB_ONFAULT]
        adr     r3, .Lcopyfault
@@ -518,18 +510,14 @@ ENTRY(kcopy)
        moveq   pc, lr
 
        SAVE_REGS
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r2, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r4, .Lcpu_info
-       ldr     r4, [r4, r0, lsl #2]
-       ldr     r4, [r4, #CI_CURPCB]
-       ldmfd   sp!, {r0-r2, r14}
+
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r4, c13, c0, 4
 #else
        ldr     r4, .Lcpu_info_primary
-       ldr     r4, [r4, #CI_CURPCB]
 #endif
+       ldr     r4, [r4, #CI_CURPCB]
 
        ldr     r5, [r4, #PCB_ONFAULT]
        adr     r3, .Lcopyfault
@@ -711,18 +699,13 @@ ENTRY(kcopy)
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_1)
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r1, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r2, .Lcpu_info
-       ldr     r2, [r2, r0, lsl #2]
-       ldr     r2, [r2, #CI_CURPCB]
-       ldmfd   sp!, {r0-r1, r14}
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r2, c13, c0, 4
 #else
        ldr     r2, .Lcpu_info_primary
-       ldr     r2, [r2, #CI_CURPCB]
 #endif
+       ldr     r2, [r2, #CI_CURPCB]
        ldr     ip, [r2, #PCB_ONFAULT]
        adr     r3, 1f
        str     r3, [r2, #PCB_ONFAULT]
@@ -745,18 +728,13 @@ ENTRY(badaddr_read_1)
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_2)
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r1, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r2, .Lcpu_info
-       ldr     r2, [r2, r0, lsl #2]
-       ldr     r2, [r2, #CI_CURPCB]
-       ldmfd   sp!, {r0-r1, r14}
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r2, c13, c0, 4
 #else
        ldr     r2, .Lcpu_info_primary
-       ldr     r2, [r2, #CI_CURPCB]
 #endif
+       ldr     r2, [r2, #CI_CURPCB]
        ldr     ip, [r2, #PCB_ONFAULT]
        adr     r3, 1f
        str     r3, [r2, #PCB_ONFAULT]
@@ -779,18 +757,13 @@ ENTRY(badaddr_read_2)
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_4)
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r1, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r2, .Lcpu_info
-       ldr     r2, [r2, r0, lsl #2]
-       ldr     r2, [r2, #CI_CURPCB]
-       ldmfd   sp!, {r0-r1, r14}
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r2, c13, c0, 4
 #else
        ldr     r2, .Lcpu_info_primary
-       ldr     r2, [r2, #CI_CURPCB]
 #endif
+       ldr     r2, [r2, #CI_CURPCB]
        ldr     ip, [r2, #PCB_ONFAULT]
        adr     r3, 1f
        str     r3, [r2, #PCB_ONFAULT]
diff --git sys/arch/arm/arm/copystr.S sys/arch/arm/arm/copystr.S
index 3723f18..3941553 100644
--- sys/arch/arm/arm/copystr.S
+++ sys/arch/arm/arm/copystr.S
@@ -104,18 +104,13 @@ ENTRY(copyinstr)
        moveq   r0, #ENAMETOOLONG
        beq     2f
 
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r3, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r4, .Lcpu_info
-       ldr     r4, [r4, r0, lsl #2]
-       ldr     r4, [r4, #CI_CURPCB]
-       ldmfd   sp!, {r0-r3, r14}
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r4, c13, c0, 4
 #else
        ldr     r4, .Lcpu_info_primary
-       ldr     r4, [r4, #CI_CURPCB]
 #endif
+       ldr     r4, [r4, #CI_CURPCB]
 
 #ifdef DEBUG
        teq     r4, #0x00000000
@@ -161,18 +156,13 @@ ENTRY(copyoutstr)
        moveq   r0, #ENAMETOOLONG
        beq     2f
 
-#ifdef MULTIPROCESSOR
-       /* XXX Probably not appropriate for non-Hydra SMPs */
-       stmfd   sp!, {r0-r3, r14}
-       bl      _C_LABEL(cpu_number)
-       ldr     r4, .Lcpu_info
-       ldr     r4, [r4, r0, lsl #2]
-       ldr     r4, [r4, #CI_CURPCB]
-       ldmfd   sp!, {r0-r3, r14}
+#ifdef CPU_ARMv7
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r4, c13, c0, 4
 #else
        ldr     r4, .Lcpu_info_primary
-       ldr     r4, [r4, #CI_CURPCB]
 #endif
+       ldr     r4, [r4, #CI_CURPCB]
 
 #ifdef DEBUG
        teq     r4, #0x00000000
diff --git sys/arch/arm/arm/cpuswitch7.S sys/arch/arm/arm/cpuswitch7.S
index 126b41a..f6f78a6 100644
--- sys/arch/arm/arm/cpuswitch7.S
+++ sys/arch/arm/arm/cpuswitch7.S
@@ -105,13 +105,6 @@
 
        .text
 
-.Lcpu_info_primary:
-       .word   _C_LABEL(cpu_info_primary)
-.Lcurproc:
-       .word   _C_LABEL(cpu_info_primary) + CI_CURPROC
-.Lcurpcb:
-       .word   _C_LABEL(cpu_info_primary) + CI_CURPCB
-
 .Lcpufuncs:
        .word   _C_LABEL(cpufuncs)
 
@@ -166,10 +159,10 @@ ENTRY(cpu_idle_leave)
 ENTRY(cpu_switchto)
        stmfd   sp!, {r4-r7, lr}
 
+       /* Get curcpu from TPIDRPRW. */
+       mrc     p15, 0, r3, c13, c0, 4
 #ifdef MULTIPROCESSOR
-       /* XXX use curcpu() */
-       ldr     r2, .Lcpu_info_primary
-       str     r2, [r1, #(P_CPU)]
+       str     r3, [r1, #(P_CPU)]
 #else
        /* p->p_cpu initialized in fork1() for single-processor */
 #endif
@@ -179,14 +172,12 @@ ENTRY(cpu_switchto)
        strb    r2, [r1, #(P_STAT)]
 
        /* We have a new curproc now so make a note it */
-       ldr     r7, .Lcurproc
-       str     r1, [r7]
+       str     r1, [r3, #(CI_CURPROC)]
 
        /* Hook in a new pcb */
-       ldr     r7, .Lcurpcb
-       ldr     r6, [r7]                        /* Remember the old PCB */
+       ldr     r6, [r3, #(CI_CURPCB)]          /* Remember the old PCB */
        ldr     r2, [r1, #(P_ADDR)]
-       str     r2, [r7]
+       str     r2, [r3, #(CI_CURPCB)]
 
        /*
         * If the old proc on entry to cpu_switch was zero then the
diff --git sys/arch/arm/arm/irq_dispatch.S sys/arch/arm/arm/irq_dispatch.S
index c84b131..8c2736e 100644
--- sys/arch/arm/arm/irq_dispatch.S
+++ sys/arch/arm/arm/irq_dispatch.S
@@ -105,7 +105,11 @@ ASENTRY_NP(irq_entry)
         *      r5      address of the curcpu struct
         *      r6      old value of curcpu()->ci_idepth
         */
+#ifdef CPU_ARMv7
+       mrc     p15, 0, r5, c13, c0, 4  /* Get curcpu from TPIDRPRW. */
+#else
        ldr     r5, .Lcpu_info_primary
+#endif
        mov     r0, sp                  /* arg for dispatcher */
        ldr     r6, [r5, #CI_IDEPTH]
        add     r1, r6, #1
diff --git sys/arch/arm/arm/locore.S sys/arch/arm/arm/locore.S
index 6fb7b62..e45011e 100644
--- sys/arch/arm/arm/locore.S
+++ sys/arch/arm/arm/locore.S
@@ -56,7 +56,12 @@ ASENTRY_NP(start)
        mov     r5, r1
        mov     r6, r2
        adr     r1, .Lstart
-       ldmia   r1, {r1, r2, sp}        /* Set initial stack and */
+       ldmia   r1, {r1, r2, r8, sp}    /* Set initial stack and */
+
+#ifdef CPU_ARMv7
+       mcr     p15, 0, r8, c13, c0, 4  /* put curcpu into the TPIDRPRW */
+#endif
+
        sub     r2, r2, r1              /* get zero init data */
        mov     r3, #0
 
@@ -87,6 +92,7 @@ ASENTRY_NP(start)
 .Lstart:
        .word   _edata
        .word   _end
+       .word   _C_LABEL(cpu_info_primary)
        .word   svcstk + INIT_ARM_STACK_SIZE
 
 .Lmainreturned:
diff --git sys/arch/arm/include/cpu.h sys/arch/arm/include/cpu.h
index 2587991..563a101 100644
--- sys/arch/arm/include/cpu.h
+++ sys/arch/arm/include/cpu.h
@@ -208,8 +208,19 @@ struct cpu_info {
 extern struct cpu_info cpu_info_primary;
 extern struct cpu_info *cpu_info_list;
 
-#ifndef MULTIPROCESSOR
+#ifdef CPU_ARMv7
+static inline struct cpu_info *
+curcpu(void)
+{
+       struct cpu_info *__ci;
+       __asm volatile("mrc     p15, 0, %0, c13, c0, 4" : "=r" (__ci));
+       return (__ci);
+}
+#else
 #define        curcpu()        (&cpu_info_primary)
+#endif
+
+#ifndef MULTIPROCESSOR
 #define cpu_number()   0
 #define CPU_IS_PRIMARY(ci)     1
 #define CPU_INFO_ITERATOR      int

Reply via email to