Improve ARM_TP_ADDRESS and RAS area.

De-hardcode usage of ARM_TP_ADDRESS and RAS local storage, and move this
special purpose page to a more convenient place i.e. after the vectors high
page, more towards the end of address space. Previous location (0xe000_0000)
caused grief if KVA was to go beyond the default limit.

Note that ARM world rebuilding is required after this change since the
location of ARM_TP_ADDRESS is shared between kernel and userland.

Submitted by:	Grzegorz Bernacki (gjb AT semihalf dot com)
Reviewed by:	imp
Approved by:	cognet (mentor)
This commit is contained in:
Rafal Jaworowski 2008-02-05 10:22:33 +00:00
parent bcb20d7b06
commit e081d0ac19
5 changed files with 51 additions and 62 deletions

@ -102,6 +102,8 @@ ASSYM(P_PID, offsetof(struct proc, p_pid));
ASSYM(P_FLAG, offsetof(struct proc, p_flag));
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
ASSYM(ARM_RAS_START, ARM_RAS_START);
ASSYM(ARM_RAS_END, ARM_RAS_END);
ASSYM(PAGE_SIZE, PAGE_SIZE);
ASSYM(PDESIZE, PDESIZE);
ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);

@ -205,7 +205,7 @@ ENTRY(cpu_throw)
/* Set the new tp */
ldr r6, [r5, #(TD_MD + MD_TP)]
mov r5, #ARM_TP_ADDRESS
ldr r5, =ARM_TP_ADDRESS
strt r6, [r5]
/* Hook in a new pcb */
@ -263,7 +263,7 @@ ENTRY(cpu_switch)
* them for the new process.
*/
/* Store the old tp */
mov r3, #ARM_TP_ADDRESS
ldr r3, =ARM_TP_ADDRESS
ldrt r9, [r3]
str r9, [r0, #(TD_MD + MD_TP)]

@ -68,10 +68,10 @@
mov r0, r0; /* NOP for previous instruction */ \
mrs r0, spsr_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!; \
mov r0, #0xe0000004; \
ldr r0, =ARM_RAS_START; \
mov r1, #0; \
str r1, [r0]; \
mov r0, #0xe0000008; \
ldr r0, =ARM_RAS_END; \
mov r1, #0xffffffff; \
str r1, [r0];
@ -119,11 +119,11 @@
add r0, sp, #(4*13); /* Adjust the stack pointer */ \
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
mov r0, r0; /* NOP for previous instruction */ \
ldr r5, =0xe0000004; /* Check if there's any RAS */ \
ldr r5, =ARM_RAS_START; /* Check if there's any RAS */ \
ldr r3, [r5]; \
cmp r3, #0; /* Is the update needed ? */ \
ldrgt lr, [r0, #16]; \
ldrgt r1, =0xe0000008; \
ldrgt r1, =ARM_RAS_END; \
ldrgt r4, [r1]; /* Get the end of the RAS */ \
movgt r2, #0; /* Reset the magic addresses */ \
strgt r2, [r5]; \

@ -39,12 +39,14 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
#ifndef _LOCORE
#include <sys/types.h>
#ifndef _KERNEL
#include <machine/sysarch.h>
#endif
#ifndef I32_bit
#define I32_bit (1 << 7) /* IRQ disable */
#endif
@ -71,9 +73,6 @@
: "cc" ); \
} while(0)
#define ARM_RAS_START 0xe0000004
#define ARM_RAS_END 0xe0000008
static __inline uint32_t
__swp(uint32_t val, volatile uint32_t *ptr)
{
@ -145,28 +144,24 @@ atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
static __inline u_int32_t
atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
{
register int done, ras_start;
register int done, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"cmp %1, %3\n"
"streq %4, [%2]\n"
"2:\n"
"mov %1, #0\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %1, #0xffffffff\n"
"mov %0, #0xe0000008\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"moveq %1, #1\n"
"movne %1, #0\n"
: "=r" (ras_start), "=r" (done)
: "+r" (ras_start), "=r" (done)
,"+r" (p), "+r" (cmpval), "+r" (newval) : : "memory");
return (done);
}
@ -174,106 +169,90 @@ atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_in
static __inline void
atomic_add_32(volatile u_int32_t *p, u_int32_t val)
{
int ras_start, start;
int start, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"add %1, %1, %3\n"
"str %1, [%2]\n"
"2:\n"
"mov %0, #0xe0000004\n"
"mov %1, #0\n"
"str %1, [%0]\n"
"mov %1, #0xffffffff\n"
"mov %0, #0xe0000008\n"
"str %1, [%0]\n"
: "=r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
"str %1, [%0, #4]\n"
: "+r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
: : "memory");
}
static __inline void
atomic_subtract_32(volatile u_int32_t *p, u_int32_t val)
{
int ras_start, start;
int start, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"sub %1, %1, %3\n"
"str %1, [%2]\n"
"2:\n"
"mov %0, #0xe0000004\n"
"mov %1, #0\n"
"str %1, [%0]\n"
"mov %1, #0xffffffff\n"
"mov %0, #0xe0000008\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
: "=r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
: "+r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
: : "memory");
}
static __inline void
atomic_set_32(volatile uint32_t *address, uint32_t setmask)
{
int ras_start, start;
int start, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"orr %1, %1, %3\n"
"str %1, [%2]\n"
"2:\n"
"mov %0, #0xe0000004\n"
"mov %1, #0\n"
"str %1, [%0]\n"
"mov %1, #0xffffffff\n"
"mov %0, #0xe0000008\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
: "=r" (ras_start), "=r" (start), "+r" (address), "+r" (setmask)
: "+r" (ras_start), "=r" (start), "+r" (address), "+r" (setmask)
: : "memory");
}
static __inline void
atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
{
int ras_start, start;
int start, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"bic %1, %1, %3\n"
"str %1, [%2]\n"
"2:\n"
"mov %0, #0xe0000004\n"
"mov %1, #0\n"
"str %1, [%0]\n"
"mov %1, #0xffffffff\n"
"mov %0, #0xe0000008\n"
"str %1, [%0]\n"
: "=r" (ras_start), "=r" (start), "+r" (address), "+r" (clearmask)
"str %1, [%0, #4]\n"
: "+r" (ras_start), "=r" (start), "+r" (address), "+r" (clearmask)
: : "memory");
}
@ -281,26 +260,22 @@ atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
static __inline uint32_t
atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
{
uint32_t ras_start, start;
uint32_t start, ras_start = ARM_RAS_START;
__asm __volatile("1:\n"
"adr %1, 1b\n"
"mov %0, #0xe0000004\n"
"str %1, [%0]\n"
"mov %0, #0xe0000008\n"
"adr %1, 2f\n"
"str %1, [%0]\n"
"str %1, [%0, #4]\n"
"ldr %1, [%2]\n"
"add %0, %1, %3\n"
"add %1, %1, %3\n"
"str %0, [%2]\n"
"2:\n"
"mov %0, #0xe0000004\n"
"mov %3, #0\n"
"str %3, [%0]\n"
"mov %0, #0xe0000008\n"
"mov %3, #0xffffffff\n"
"str %3, [%0]\n"
: "=r" (ras_start), "=r" (start), "+r" (p), "+r" (v)
"str %3, [%0, #4]\n"
: "+r" (ras_start), "=r" (start), "+r" (p), "+r" (v)
: : "memory");
return (start);
}

@ -37,6 +37,18 @@
#ifndef _ARM_SYSARCH_H_
#define _ARM_SYSARCH_H_
#include <machine/armreg.h>
/*
* The ARM_TP_ADDRESS points to a special purpose page, which is used as local
* store for the ARM per-thread data and Restartable Atomic Sequences support.
* Put it just above the "high" vectors' page.
*/
#define ARM_TP_ADDRESS (ARM_VECTORS_HIGH + 0x1000)
#define ARM_RAS_START (ARM_TP_ADDRESS + 4)
#define ARM_RAS_END (ARM_TP_ADDRESS + 8)
#ifndef LOCORE
#include <sys/cdefs.h>
/*
@ -53,8 +65,6 @@
#define ARM_SET_TP 2
#define ARM_GET_TP 3
#define ARM_TP_ADDRESS 0xe0000000 /* Magic */
struct arm_sync_icache_args {
uintptr_t addr; /* Virtual start address */
size_t len; /* Region size */
@ -68,4 +78,6 @@ int sysarch(int, void *);
__END_DECLS
#endif
#endif /* LOCORE */
#endif /* !_ARM_SYSARCH_H_ */