From 6fe86a5be0a776a996857d316863ad453bb16964 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 4 Feb 2015 16:44:08 +0000 Subject: [PATCH] Add support for the fu* functions to fail --- sys/arm64/arm64/copyinout.S | 20 +++++------- sys/arm64/arm64/support.c | 35 --------------------- sys/arm64/arm64/support_asm.S | 58 +++++++++++++++++++++++++++++++++++ sys/arm64/include/asm.h | 14 +++++++++ 4 files changed, 79 insertions(+), 48 deletions(-) diff --git a/sys/arm64/arm64/copyinout.S b/sys/arm64/arm64/copyinout.S index ef311788a653..56512ecdf13f 100644 --- a/sys/arm64/arm64/copyinout.S +++ b/sys/arm64/arm64/copyinout.S @@ -35,17 +35,11 @@ __FBSDID("$FreeBSD$"); #include "assym.s" -.macro set_fault_handler handler, tmp - ldr \tmp, [x18, #PC_CURTHREAD] /* Load curthread */ - ldr \tmp, [\tmp, #TD_PCB] /* Load the pcb */ - str \handler, [\tmp, #PCB_ONFAULT] /* Set the handler */ -.endm - /* * Fault handler for the copy{in,out} functions below. */ ENTRY(copyio_fault) - set_fault_handler xzr, x1 /* Clear the handler */ + SET_FAULT_HANDLER(xzr, x1) /* Clear the handler */ mov x0, #EFAULT ret END(copyio_fault) @@ -59,14 +53,14 @@ ENTRY(copyout) cbz x2, 2f /* If len == 0 then skip loop */ adr x6, copyio_fault /* Get the handler address */ - set_fault_handler x6, x7 /* Set the handler */ + SET_FAULT_HANDLER(x6, x7) /* Set the handler */ 1: ldrb w4, [x0], #1 /* Load from kaddr */ strb w4, [x1], #1 /* Store in uaddr */ sub x2, x2, #1 /* len-- */ cbnz x2, 1b - set_fault_handler xzr, x7 /* Clear the handler */ + SET_FAULT_HANDLER(xzr, x7) /* Clear the handler */ 2: mov x0, xzr /* return 0 */ ret @@ -81,14 +75,14 @@ ENTRY(copyin) cbz x2, 2f /* If len == 0 then skip loop */ adr x6, copyio_fault /* Get the handler address */ - set_fault_handler x6, x7 /* Set the handler */ + SET_FAULT_HANDLER(x6, x7) /* Set the handler */ 1: ldrb w4, [x0], #1 /* Load from uaddr */ strb w4, [x1], #1 /* Store in kaddr */ sub x2, x2, #1 /* len-- */ cbnz x2, 1b - set_fault_handler xzr, x7 /* Clear the handler */ + SET_FAULT_HANDLER(xzr, x7) /* Clear the handler */ 2: mov x0, xzr /* return 0 */ ret @@ -104,7 +98,7 @@ ENTRY(copyinstr) cbz x2, 3f /* If len == 0 then skip loop */ adr x6, copyio_fault /* Get the handler address */ - set_fault_handler x6, x7 /* Set the handler */ + SET_FAULT_HANDLER(x6, x7) /* Set the handler */ 1: ldrb w4, [x0], #1 /* Load from uaddr */ strb w4, [x1], #1 /* Store in kaddr */ @@ -113,7 +107,7 @@ ENTRY(copyinstr) add x5, x5, #1 /* count++ */ cbnz x2, 1b -2: set_fault_handler xzr, x7 /* Clear the handler */ +2: SET_FAULT_HANDLER(xzr, x7) /* Clear the handler */ 3: cbz x3, 4f /* Check if done != NULL */ add x5, x5, #1 /* count++ */ diff --git a/sys/arm64/arm64/support.c b/sys/arm64/arm64/support.c index 15694b1be768..411d95a34600 100644 --- a/sys/arm64/arm64/support.c +++ b/sys/arm64/arm64/support.c @@ -32,41 +32,6 @@ __FBSDID("$FreeBSD$"); #include #include -int -fubyte(volatile const void *base) -{ - - return *(volatile uint8_t *)base; -} - -long -fuword(volatile const void *base) -{ - - return *(volatile long *)base; -} - -int -fuword16(volatile const void *base) -{ - - panic("fuword16"); -} - -int32_t -fuword32(volatile const void *base) -{ - - panic("fuword32"); -} - -int64_t -fuword64(volatile const void *base) -{ - - panic("fuword64"); -} - int fuswintr(void *base) { diff --git a/sys/arm64/arm64/support_asm.S b/sys/arm64/arm64/support_asm.S index f88079300e50..441c387c4643 100644 --- a/sys/arm64/arm64/support_asm.S +++ b/sys/arm64/arm64/support_asm.S @@ -34,6 +34,64 @@ __FBSDID("$FreeBSD$"); #include +#include "assym.s" + +/* + * One of the fu* or su* functions failed, return -1. + */ +ENTRY(fsu_fault) + SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */ + mov x0, #-1 + ret +END(fsu_fault) + +/* + * int fubyte(volatile const void *) + */ +ENTRY(fubyte) + adr x6, fsu_fault /* Load the fault handler */ + SET_FAULT_HANDLER(x6, x1) /* And set it */ + ldrb w0, [x0] /* Try loading the data */ + SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ + ret /* Return */ +END(fubyte) + +/* + * int fuword(volatile const void *) + */ +ENTRY(fuword16) + adr x6, fsu_fault /* Load the fault handler */ + SET_FAULT_HANDLER(x6, x1) /* And set it */ + ldrh w0, [x0] /* Try loading the data */ + SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ + ret /* Return */ +END(fuword16) + +/* + * int32_t fuword32(volatile const void *) + */ +ENTRY(fuword32) + adr x6, fsu_fault /* Load the fault handler */ + SET_FAULT_HANDLER(x6, x1) /* And set it */ + ldr w0, [x0] /* Try loading the data */ + SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ + ret /* Return */ +END(fuword32) + +/* + * long fuword(volatile const void *) + * int64_t fuword64(volatile const void *) + */ +ENTRY(fuword) +EENTRY(fuword64) + adr x6, fsu_fault /* Load the fault handler */ + SET_FAULT_HANDLER(x6, x1) /* And set it */ + ldr x0, [x0] /* Try loading the data */ + SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ + ret /* Return */ +EEND(fuword64) +END(fuword) + ENTRY(setjmp) /* Store the stack pointer */ mov x8, sp diff --git a/sys/arm64/include/asm.h b/sys/arm64/include/asm.h index b47dc456324b..7449d43f817c 100644 --- a/sys/arm64/include/asm.h +++ b/sys/arm64/include/asm.h @@ -39,7 +39,10 @@ #define ENTRY(sym) \ .text; .globl sym; .align 2; sym: +#define EENTRY(sym) \ + .globl sym; sym: #define END(sym) .size sym, . - sym +#define EEND(sym) #define WEAK_REFERENCE(sym, alias) \ .weak alias; \ @@ -53,4 +56,15 @@ #define PIC_SYM(x,y) x #endif +/* + * Sets the trap fault handler. The exception handler will return to the + * address in the handler register on a data abort or the xzr register to + * clear the handler. The tmp parameter should be a register able to hold + * the temporary data. + */ +#define SET_FAULT_HANDLER(handler, tmp) \ + ldr tmp, [x18, #PC_CURTHREAD]; /* Load curthread */ \ + ldr tmp, [tmp, #TD_PCB]; /* Load the pcb */ \ + str handler, [tmp, #PCB_ONFAULT] /* Set the handler */ + #endif /* _MACHINE_ASM_H_ */ -- 2.39.5