128029b68SRuslan Bukin/*- 2157654d0SRuslan Bukin * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com> 328029b68SRuslan Bukin * All rights reserved. 428029b68SRuslan Bukin * 528029b68SRuslan Bukin * Portions of this software were developed by SRI International and the 628029b68SRuslan Bukin * University of Cambridge Computer Laboratory under DARPA/AFRL contract 728029b68SRuslan Bukin * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. 828029b68SRuslan Bukin * 928029b68SRuslan Bukin * Portions of this software were developed by the University of Cambridge 1028029b68SRuslan Bukin * Computer Laboratory as part of the CTSRD Project, with support from the 1128029b68SRuslan Bukin * UK Higher Education Innovation Fund (HEIF). 1228029b68SRuslan Bukin * 1328029b68SRuslan Bukin * Redistribution and use in source and binary forms, with or without 1428029b68SRuslan Bukin * modification, are permitted provided that the following conditions 1528029b68SRuslan Bukin * are met: 1628029b68SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 1728029b68SRuslan Bukin * notice, this list of conditions and the following disclaimer. 1828029b68SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 1928029b68SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 2028029b68SRuslan Bukin * documentation and/or other materials provided with the distribution. 2128029b68SRuslan Bukin * 2228029b68SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2328029b68SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2428029b68SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2528029b68SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2628029b68SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2728029b68SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2828029b68SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2928029b68SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3028029b68SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3128029b68SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3228029b68SRuslan Bukin * SUCH DAMAGE. 3328029b68SRuslan Bukin */ 3428029b68SRuslan Bukin 3528029b68SRuslan Bukin#include <machine/asm.h> 3628029b68SRuslan Bukin__FBSDID("$FreeBSD$"); 3728029b68SRuslan Bukin 38fc2a8776SEd Maste#include "assym.inc" 3928029b68SRuslan Bukin 4028029b68SRuslan Bukin#include <machine/trap.h> 4128029b68SRuslan Bukin#include <machine/riscvreg.h> 4228029b68SRuslan Bukin 43da8944d9SJessica Clarke.macro save_registers mode 444d50647dSRuslan Bukin addi sp, sp, -(TF_SIZE) 4528029b68SRuslan Bukin 4628029b68SRuslan Bukin sd ra, (TF_RA)(sp) 4728029b68SRuslan Bukin 48da8944d9SJessica Clarke.if \mode == 0 /* We came from userspace. */ 494d50647dSRuslan Bukin sd gp, (TF_GP)(sp) 506ae48dd8SMitchell Horne.option push 516ae48dd8SMitchell Horne.option norelax 526ae48dd8SMitchell Horne /* Load the kernel's global pointer */ 536ae48dd8SMitchell Horne la gp, __global_pointer$ 546ae48dd8SMitchell Horne.option pop 556ae48dd8SMitchell Horne 566ae48dd8SMitchell Horne /* Load our pcpu */ 576ae48dd8SMitchell Horne sd tp, (TF_TP)(sp) 586ae48dd8SMitchell Horne ld tp, (TF_SIZE)(sp) 594d50647dSRuslan Bukin.endif 604d50647dSRuslan Bukin 6128029b68SRuslan Bukin sd t0, (TF_T + 0 * 8)(sp) 6228029b68SRuslan Bukin sd t1, (TF_T + 1 * 8)(sp) 6328029b68SRuslan Bukin sd t2, (TF_T + 2 * 8)(sp) 6428029b68SRuslan Bukin sd t3, (TF_T + 3 * 8)(sp) 6528029b68SRuslan Bukin sd t4, (TF_T + 4 * 8)(sp) 6628029b68SRuslan Bukin sd t5, (TF_T + 5 * 8)(sp) 6728029b68SRuslan Bukin sd t6, (TF_T + 6 * 8)(sp) 6828029b68SRuslan Bukin 6928029b68SRuslan Bukin sd s0, (TF_S + 0 * 8)(sp) 7028029b68SRuslan Bukin sd s1, (TF_S + 1 * 8)(sp) 7128029b68SRuslan Bukin sd s2, (TF_S + 2 * 8)(sp) 7228029b68SRuslan Bukin sd s3, (TF_S + 3 * 8)(sp) 7328029b68SRuslan Bukin sd s4, (TF_S + 4 * 8)(sp) 7428029b68SRuslan Bukin sd s5, (TF_S + 5 * 8)(sp) 7528029b68SRuslan Bukin sd s6, (TF_S + 6 * 8)(sp) 7628029b68SRuslan Bukin sd s7, (TF_S + 7 * 8)(sp) 7728029b68SRuslan Bukin sd s8, (TF_S + 8 * 8)(sp) 7828029b68SRuslan Bukin sd s9, (TF_S + 9 * 8)(sp) 7928029b68SRuslan Bukin sd s10, (TF_S + 10 * 8)(sp) 8028029b68SRuslan Bukin sd s11, (TF_S + 11 * 8)(sp) 8128029b68SRuslan Bukin 8228029b68SRuslan Bukin sd a0, (TF_A + 0 * 8)(sp) 8328029b68SRuslan Bukin sd a1, (TF_A + 1 * 8)(sp) 8428029b68SRuslan Bukin sd a2, (TF_A + 2 * 8)(sp) 8528029b68SRuslan Bukin sd a3, (TF_A + 3 * 8)(sp) 8628029b68SRuslan Bukin sd a4, (TF_A + 4 * 8)(sp) 8728029b68SRuslan Bukin sd a5, (TF_A + 5 * 8)(sp) 8828029b68SRuslan Bukin sd a6, (TF_A + 6 * 8)(sp) 8928029b68SRuslan Bukin sd a7, (TF_A + 7 * 8)(sp) 9028029b68SRuslan Bukin 91da8944d9SJessica Clarke.if \mode == 1 9228029b68SRuslan Bukin /* Store kernel sp */ 93892933d0SRuslan Bukin li t1, TF_SIZE 94892933d0SRuslan Bukin add t0, sp, t1 95892933d0SRuslan Bukin sd t0, (TF_SP)(sp) 9628029b68SRuslan Bukin.else 9728029b68SRuslan Bukin /* Store user sp */ 9828029b68SRuslan Bukin csrr t0, sscratch 9928029b68SRuslan Bukin sd t0, (TF_SP)(sp) 10028029b68SRuslan Bukin.endif 10128029b68SRuslan Bukin li t0, 0 10228029b68SRuslan Bukin csrw sscratch, t0 10328029b68SRuslan Bukin csrr t0, sepc 10428029b68SRuslan Bukin sd t0, (TF_SEPC)(sp) 10528029b68SRuslan Bukin csrr t0, sstatus 10628029b68SRuslan Bukin sd t0, (TF_SSTATUS)(sp) 107753bcca4SJohn Baldwin.if \mode == 1 108753bcca4SJohn Baldwin /* Disable user address access for supervisor mode exceptions. */ 109753bcca4SJohn Baldwin li t0, SSTATUS_SUM 110753bcca4SJohn Baldwin csrc sstatus, t0 111753bcca4SJohn Baldwin.endif 11253941c0aSMark Johnston csrr t0, stval 11353941c0aSMark Johnston sd t0, (TF_STVAL)(sp) 11428029b68SRuslan Bukin csrr t0, scause 11528029b68SRuslan Bukin sd t0, (TF_SCAUSE)(sp) 11628029b68SRuslan Bukin.endm 11728029b68SRuslan Bukin 118da8944d9SJessica Clarke.macro load_registers mode 11928029b68SRuslan Bukin ld t0, (TF_SSTATUS)(sp) 120da8944d9SJessica Clarke.if \mode == 0 121157654d0SRuslan Bukin /* Ensure user interrupts will be enabled on eret */ 122157654d0SRuslan Bukin li t1, SSTATUS_SPIE 12398f50c44SRuslan Bukin or t0, t0, t1 12428029b68SRuslan Bukin.else 12528029b68SRuslan Bukin /* 12628029b68SRuslan Bukin * Disable interrupts for supervisor mode exceptions. 12728029b68SRuslan Bukin * For user mode exceptions we have already done this 12828029b68SRuslan Bukin * in do_ast. 12928029b68SRuslan Bukin */ 13098f50c44SRuslan Bukin li t1, ~SSTATUS_SIE 13128029b68SRuslan Bukin and t0, t0, t1 13228029b68SRuslan Bukin.endif 13328029b68SRuslan Bukin csrw sstatus, t0 13428029b68SRuslan Bukin 13528029b68SRuslan Bukin ld t0, (TF_SEPC)(sp) 13628029b68SRuslan Bukin csrw sepc, t0 13728029b68SRuslan Bukin 138da8944d9SJessica Clarke.if \mode == 0 1394d50647dSRuslan Bukin /* We go to userspace. Load user sp */ 14028029b68SRuslan Bukin ld t0, (TF_SP)(sp) 14128029b68SRuslan Bukin csrw sscratch, t0 1424d50647dSRuslan Bukin 1436ae48dd8SMitchell Horne /* Store our pcpu */ 1446ae48dd8SMitchell Horne sd tp, (TF_SIZE)(sp) 1456ae48dd8SMitchell Horne ld tp, (TF_TP)(sp) 1466ae48dd8SMitchell Horne 1476ae48dd8SMitchell Horne /* And restore the user's global pointer */ 1484d50647dSRuslan Bukin ld gp, (TF_GP)(sp) 14928029b68SRuslan Bukin.endif 15028029b68SRuslan Bukin 15128029b68SRuslan Bukin ld ra, (TF_RA)(sp) 15228029b68SRuslan Bukin 15328029b68SRuslan Bukin ld t0, (TF_T + 0 * 8)(sp) 15428029b68SRuslan Bukin ld t1, (TF_T + 1 * 8)(sp) 15528029b68SRuslan Bukin ld t2, (TF_T + 2 * 8)(sp) 15628029b68SRuslan Bukin ld t3, (TF_T + 3 * 8)(sp) 15728029b68SRuslan Bukin ld t4, (TF_T + 4 * 8)(sp) 15828029b68SRuslan Bukin ld t5, (TF_T + 5 * 8)(sp) 15928029b68SRuslan Bukin ld t6, (TF_T + 6 * 8)(sp) 16028029b68SRuslan Bukin 16128029b68SRuslan Bukin ld s0, (TF_S + 0 * 8)(sp) 16228029b68SRuslan Bukin ld s1, (TF_S + 1 * 8)(sp) 16328029b68SRuslan Bukin ld s2, (TF_S + 2 * 8)(sp) 16428029b68SRuslan Bukin ld s3, (TF_S + 3 * 8)(sp) 16528029b68SRuslan Bukin ld s4, (TF_S + 4 * 8)(sp) 16628029b68SRuslan Bukin ld s5, (TF_S + 5 * 8)(sp) 16728029b68SRuslan Bukin ld s6, (TF_S + 6 * 8)(sp) 16828029b68SRuslan Bukin ld s7, (TF_S + 7 * 8)(sp) 16928029b68SRuslan Bukin ld s8, (TF_S + 8 * 8)(sp) 17028029b68SRuslan Bukin ld s9, (TF_S + 9 * 8)(sp) 17128029b68SRuslan Bukin ld s10, (TF_S + 10 * 8)(sp) 17228029b68SRuslan Bukin ld s11, (TF_S + 11 * 8)(sp) 17328029b68SRuslan Bukin 17428029b68SRuslan Bukin ld a0, (TF_A + 0 * 8)(sp) 17528029b68SRuslan Bukin ld a1, (TF_A + 1 * 8)(sp) 17628029b68SRuslan Bukin ld a2, (TF_A + 2 * 8)(sp) 17728029b68SRuslan Bukin ld a3, (TF_A + 3 * 8)(sp) 17828029b68SRuslan Bukin ld a4, (TF_A + 4 * 8)(sp) 17928029b68SRuslan Bukin ld a5, (TF_A + 5 * 8)(sp) 18028029b68SRuslan Bukin ld a6, (TF_A + 6 * 8)(sp) 18128029b68SRuslan Bukin ld a7, (TF_A + 7 * 8)(sp) 18228029b68SRuslan Bukin 1834d50647dSRuslan Bukin addi sp, sp, (TF_SIZE) 18428029b68SRuslan Bukin.endm 18528029b68SRuslan Bukin 18628029b68SRuslan Bukin.macro do_ast 18728029b68SRuslan Bukin /* Disable interrupts */ 18828029b68SRuslan Bukin csrr a4, sstatus 18928029b68SRuslan Bukin1: 19098f50c44SRuslan Bukin csrci sstatus, (SSTATUS_SIE) 19128029b68SRuslan Bukin 1926ae48dd8SMitchell Horne ld a1, PC_CURTHREAD(tp) 19328029b68SRuslan Bukin lw a2, TD_FLAGS(a1) 19428029b68SRuslan Bukin 19528029b68SRuslan Bukin li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED) 19628029b68SRuslan Bukin and a2, a2, a3 19728029b68SRuslan Bukin beqz a2, 2f 19828029b68SRuslan Bukin 19928029b68SRuslan Bukin /* Restore interrupts */ 20098f50c44SRuslan Bukin andi a4, a4, (SSTATUS_SIE) 20128029b68SRuslan Bukin csrs sstatus, a4 20228029b68SRuslan Bukin 20328029b68SRuslan Bukin /* Handle the ast */ 20428029b68SRuslan Bukin mv a0, sp 20528029b68SRuslan Bukin call _C_LABEL(ast) 20628029b68SRuslan Bukin 20728029b68SRuslan Bukin /* Re-check for new ast scheduled */ 20828029b68SRuslan Bukin j 1b 20928029b68SRuslan Bukin2: 21028029b68SRuslan Bukin.endm 21128029b68SRuslan Bukin 21298f50c44SRuslan BukinENTRY(cpu_exception_handler) 21398f50c44SRuslan Bukin csrrw sp, sscratch, sp 21498f50c44SRuslan Bukin beqz sp, 1f 21598f50c44SRuslan Bukin /* User mode detected */ 21698f50c44SRuslan Bukin j cpu_exception_handler_user 21798f50c44SRuslan Bukin1: 21898f50c44SRuslan Bukin /* Supervisor mode detected */ 21998f50c44SRuslan Bukin csrrw sp, sscratch, sp 22098f50c44SRuslan Bukin j cpu_exception_handler_supervisor 22198f50c44SRuslan BukinEND(cpu_exception_handler) 22298f50c44SRuslan Bukin 22328029b68SRuslan BukinENTRY(cpu_exception_handler_supervisor) 22428029b68SRuslan Bukin save_registers 1 22528029b68SRuslan Bukin mv a0, sp 22628029b68SRuslan Bukin call _C_LABEL(do_trap_supervisor) 22728029b68SRuslan Bukin load_registers 1 22898f50c44SRuslan Bukin sret 22928029b68SRuslan BukinEND(cpu_exception_handler_supervisor) 23028029b68SRuslan Bukin 23128029b68SRuslan BukinENTRY(cpu_exception_handler_user) 23228029b68SRuslan Bukin save_registers 0 23328029b68SRuslan Bukin mv a0, sp 23428029b68SRuslan Bukin call _C_LABEL(do_trap_user) 23528029b68SRuslan Bukin do_ast 23628029b68SRuslan Bukin load_registers 0 23728029b68SRuslan Bukin csrrw sp, sscratch, sp 23898f50c44SRuslan Bukin sret 23928029b68SRuslan BukinEND(cpu_exception_handler_user) 240