summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorraj <raj@FreeBSD.org>2008-02-05 10:22:33 +0000
committerraj <raj@FreeBSD.org>2008-02-05 10:22:33 +0000
commita6d33e31649c175889ccaf55a0bf9374041e2667 (patch)
tree26cb5987a5c7544a3bc7975b6c1134fe1a52d180
parenta2636de674ca0feb2c4a25f90808e99029868d14 (diff)
downloadFreeBSD-src-a6d33e31649c175889ccaf55a0bf9374041e2667.zip
FreeBSD-src-a6d33e31649c175889ccaf55a0bf9374041e2667.tar.gz
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)
-rw-r--r--sys/arm/arm/genassym.c2
-rw-r--r--sys/arm/arm/swtch.S4
-rw-r--r--sys/arm/include/asmacros.h8
-rw-r--r--sys/arm/include/atomic.h83
-rw-r--r--sys/arm/include/sysarch.h16
5 files changed, 51 insertions, 62 deletions
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index 5583cab..b3ba25c 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -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);
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 5d59f99..77703a2 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -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)]
diff --git a/sys/arm/include/asmacros.h b/sys/arm/include/asmacros.h
index 91887ca..5b0f317 100644
--- a/sys/arm/include/asmacros.h
+++ b/sys/arm/include/asmacros.h
@@ -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]; \
diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h
index bed5a72..6a33699 100644
--- a/sys/arm/include/atomic.h
+++ b/sys/arm/include/atomic.h
@@ -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);
}
diff --git a/sys/arm/include/sysarch.h b/sys/arm/include/sysarch.h
index 4d6234b..5623fd7 100644
--- a/sys/arm/include/sysarch.h
+++ b/sys/arm/include/sysarch.h
@@ -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_ */
OpenPOWER on IntegriCloud