#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)
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
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
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 */
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++ */
#include <machine/setjmp.h>
+#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
#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; \
#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_ */