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:
parent
bcb20d7b06
commit
e081d0ac19
sys/arm
@ -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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user