Bump, now that the tree is unlocked again.
Patrick
On Sat, Feb 20, 2016 at 10:49:36PM +0100, Patrick Wildt wrote:
> 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
>