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> 36fc2a8776SEd Maste#include "assym.inc" 3728029b68SRuslan Bukin 3828029b68SRuslan Bukin#include <machine/trap.h> 3928029b68SRuslan Bukin#include <machine/riscvreg.h> 4028029b68SRuslan Bukin 41da8944d9SJessica Clarke.macro save_registers mode 424d50647dSRuslan Bukin addi sp, sp, -(TF_SIZE) 4328029b68SRuslan Bukin 4428029b68SRuslan Bukin sd ra, (TF_RA)(sp) 453c6fb586SChristos Margiolis sd tp, (TF_TP)(sp) 463b35d2a8SJohn Baldwin sd gp, (TF_GP)(sp) 4728029b68SRuslan Bukin 48da8944d9SJessica Clarke.if \mode == 0 /* We came from userspace. */ 496ae48dd8SMitchell Horne.option push 506ae48dd8SMitchell Horne.option norelax 516ae48dd8SMitchell Horne /* Load the kernel's global pointer */ 526ae48dd8SMitchell Horne la gp, __global_pointer$ 536ae48dd8SMitchell Horne.option pop 546ae48dd8SMitchell Horne 556ae48dd8SMitchell Horne /* Load our pcpu */ 566ae48dd8SMitchell Horne ld tp, (TF_SIZE)(sp) 574d50647dSRuslan Bukin.endif 584d50647dSRuslan Bukin 5928029b68SRuslan Bukin sd t0, (TF_T + 0 * 8)(sp) 6028029b68SRuslan Bukin sd t1, (TF_T + 1 * 8)(sp) 6128029b68SRuslan Bukin sd t2, (TF_T + 2 * 8)(sp) 6228029b68SRuslan Bukin sd t3, (TF_T + 3 * 8)(sp) 6328029b68SRuslan Bukin sd t4, (TF_T + 4 * 8)(sp) 6428029b68SRuslan Bukin sd t5, (TF_T + 5 * 8)(sp) 6528029b68SRuslan Bukin sd t6, (TF_T + 6 * 8)(sp) 6628029b68SRuslan Bukin 6728029b68SRuslan Bukin sd s0, (TF_S + 0 * 8)(sp) 6828029b68SRuslan Bukin sd s1, (TF_S + 1 * 8)(sp) 6928029b68SRuslan Bukin sd s2, (TF_S + 2 * 8)(sp) 7028029b68SRuslan Bukin sd s3, (TF_S + 3 * 8)(sp) 7128029b68SRuslan Bukin sd s4, (TF_S + 4 * 8)(sp) 7228029b68SRuslan Bukin sd s5, (TF_S + 5 * 8)(sp) 7328029b68SRuslan Bukin sd s6, (TF_S + 6 * 8)(sp) 7428029b68SRuslan Bukin sd s7, (TF_S + 7 * 8)(sp) 7528029b68SRuslan Bukin sd s8, (TF_S + 8 * 8)(sp) 7628029b68SRuslan Bukin sd s9, (TF_S + 9 * 8)(sp) 7728029b68SRuslan Bukin sd s10, (TF_S + 10 * 8)(sp) 7828029b68SRuslan Bukin sd s11, (TF_S + 11 * 8)(sp) 7928029b68SRuslan Bukin 8028029b68SRuslan Bukin sd a0, (TF_A + 0 * 8)(sp) 8128029b68SRuslan Bukin sd a1, (TF_A + 1 * 8)(sp) 8228029b68SRuslan Bukin sd a2, (TF_A + 2 * 8)(sp) 8328029b68SRuslan Bukin sd a3, (TF_A + 3 * 8)(sp) 8428029b68SRuslan Bukin sd a4, (TF_A + 4 * 8)(sp) 8528029b68SRuslan Bukin sd a5, (TF_A + 5 * 8)(sp) 8628029b68SRuslan Bukin sd a6, (TF_A + 6 * 8)(sp) 8728029b68SRuslan Bukin sd a7, (TF_A + 7 * 8)(sp) 8828029b68SRuslan Bukin 89da8944d9SJessica Clarke.if \mode == 1 9028029b68SRuslan Bukin /* Store kernel sp */ 91892933d0SRuslan Bukin li t1, TF_SIZE 92892933d0SRuslan Bukin add t0, sp, t1 93892933d0SRuslan Bukin sd t0, (TF_SP)(sp) 9428029b68SRuslan Bukin.else 9528029b68SRuslan Bukin /* Store user sp */ 9628029b68SRuslan Bukin csrr t0, sscratch 9728029b68SRuslan Bukin sd t0, (TF_SP)(sp) 9828029b68SRuslan Bukin.endif 9928029b68SRuslan Bukin li t0, 0 10028029b68SRuslan Bukin csrw sscratch, t0 10128029b68SRuslan Bukin csrr t0, sepc 10228029b68SRuslan Bukin sd t0, (TF_SEPC)(sp) 10328029b68SRuslan Bukin csrr t0, sstatus 10428029b68SRuslan Bukin sd t0, (TF_SSTATUS)(sp) 105753bcca4SJohn Baldwin.if \mode == 1 106753bcca4SJohn Baldwin /* Disable user address access for supervisor mode exceptions. */ 107753bcca4SJohn Baldwin li t0, SSTATUS_SUM 108753bcca4SJohn Baldwin csrc sstatus, t0 109753bcca4SJohn Baldwin.endif 11053941c0aSMark Johnston csrr t0, stval 11153941c0aSMark Johnston sd t0, (TF_STVAL)(sp) 11228029b68SRuslan Bukin csrr t0, scause 11328029b68SRuslan Bukin sd t0, (TF_SCAUSE)(sp) 11428029b68SRuslan Bukin.endm 11528029b68SRuslan Bukin 116da8944d9SJessica Clarke.macro load_registers mode 11728029b68SRuslan Bukin ld t0, (TF_SSTATUS)(sp) 118da8944d9SJessica Clarke.if \mode == 0 119157654d0SRuslan Bukin /* Ensure user interrupts will be enabled on eret */ 120157654d0SRuslan Bukin li t1, SSTATUS_SPIE 12198f50c44SRuslan Bukin or t0, t0, t1 12228029b68SRuslan Bukin.else 12328029b68SRuslan Bukin /* 12428029b68SRuslan Bukin * Disable interrupts for supervisor mode exceptions. 12528029b68SRuslan Bukin * For user mode exceptions we have already done this 12628029b68SRuslan Bukin * in do_ast. 12728029b68SRuslan Bukin */ 12898f50c44SRuslan Bukin li t1, ~SSTATUS_SIE 12928029b68SRuslan Bukin and t0, t0, t1 13028029b68SRuslan Bukin.endif 13128029b68SRuslan Bukin csrw sstatus, t0 13228029b68SRuslan Bukin 13328029b68SRuslan Bukin ld t0, (TF_SEPC)(sp) 13428029b68SRuslan Bukin csrw sepc, t0 13528029b68SRuslan Bukin 136da8944d9SJessica Clarke.if \mode == 0 1374d50647dSRuslan Bukin /* We go to userspace. Load user sp */ 13828029b68SRuslan Bukin ld t0, (TF_SP)(sp) 13928029b68SRuslan Bukin csrw sscratch, t0 1404d50647dSRuslan Bukin 1416ae48dd8SMitchell Horne /* Store our pcpu */ 1426ae48dd8SMitchell Horne sd tp, (TF_SIZE)(sp) 1436ae48dd8SMitchell Horne ld tp, (TF_TP)(sp) 1446ae48dd8SMitchell Horne 1456ae48dd8SMitchell Horne /* And restore the user's global pointer */ 1464d50647dSRuslan Bukin ld gp, (TF_GP)(sp) 14728029b68SRuslan Bukin.endif 14828029b68SRuslan Bukin 14928029b68SRuslan Bukin ld ra, (TF_RA)(sp) 15028029b68SRuslan Bukin 15128029b68SRuslan Bukin ld t0, (TF_T + 0 * 8)(sp) 15228029b68SRuslan Bukin ld t1, (TF_T + 1 * 8)(sp) 15328029b68SRuslan Bukin ld t2, (TF_T + 2 * 8)(sp) 15428029b68SRuslan Bukin ld t3, (TF_T + 3 * 8)(sp) 15528029b68SRuslan Bukin ld t4, (TF_T + 4 * 8)(sp) 15628029b68SRuslan Bukin ld t5, (TF_T + 5 * 8)(sp) 15728029b68SRuslan Bukin ld t6, (TF_T + 6 * 8)(sp) 15828029b68SRuslan Bukin 15928029b68SRuslan Bukin ld s0, (TF_S + 0 * 8)(sp) 16028029b68SRuslan Bukin ld s1, (TF_S + 1 * 8)(sp) 16128029b68SRuslan Bukin ld s2, (TF_S + 2 * 8)(sp) 16228029b68SRuslan Bukin ld s3, (TF_S + 3 * 8)(sp) 16328029b68SRuslan Bukin ld s4, (TF_S + 4 * 8)(sp) 16428029b68SRuslan Bukin ld s5, (TF_S + 5 * 8)(sp) 16528029b68SRuslan Bukin ld s6, (TF_S + 6 * 8)(sp) 16628029b68SRuslan Bukin ld s7, (TF_S + 7 * 8)(sp) 16728029b68SRuslan Bukin ld s8, (TF_S + 8 * 8)(sp) 16828029b68SRuslan Bukin ld s9, (TF_S + 9 * 8)(sp) 16928029b68SRuslan Bukin ld s10, (TF_S + 10 * 8)(sp) 17028029b68SRuslan Bukin ld s11, (TF_S + 11 * 8)(sp) 17128029b68SRuslan Bukin 17228029b68SRuslan Bukin ld a0, (TF_A + 0 * 8)(sp) 17328029b68SRuslan Bukin ld a1, (TF_A + 1 * 8)(sp) 17428029b68SRuslan Bukin ld a2, (TF_A + 2 * 8)(sp) 17528029b68SRuslan Bukin ld a3, (TF_A + 3 * 8)(sp) 17628029b68SRuslan Bukin ld a4, (TF_A + 4 * 8)(sp) 17728029b68SRuslan Bukin ld a5, (TF_A + 5 * 8)(sp) 17828029b68SRuslan Bukin ld a6, (TF_A + 6 * 8)(sp) 17928029b68SRuslan Bukin ld a7, (TF_A + 7 * 8)(sp) 18028029b68SRuslan Bukin 1814d50647dSRuslan Bukin addi sp, sp, (TF_SIZE) 18228029b68SRuslan Bukin.endm 18328029b68SRuslan Bukin 18428029b68SRuslan Bukin.macro do_ast 18528029b68SRuslan Bukin /* Disable interrupts */ 18628029b68SRuslan Bukin csrr a4, sstatus 18728029b68SRuslan Bukin1: 18898f50c44SRuslan Bukin csrci sstatus, (SSTATUS_SIE) 18928029b68SRuslan Bukin 1906ae48dd8SMitchell Horne ld a1, PC_CURTHREAD(tp) 191c6d31b83SKonstantin Belousov lw a2, TD_AST(a1) 19228029b68SRuslan Bukin 19328029b68SRuslan Bukin beqz a2, 2f 19428029b68SRuslan Bukin 19528029b68SRuslan Bukin /* Restore interrupts */ 19698f50c44SRuslan Bukin andi a4, a4, (SSTATUS_SIE) 19728029b68SRuslan Bukin csrs sstatus, a4 19828029b68SRuslan Bukin 19928029b68SRuslan Bukin /* Handle the ast */ 20028029b68SRuslan Bukin mv a0, sp 20128029b68SRuslan Bukin call _C_LABEL(ast) 20228029b68SRuslan Bukin 20328029b68SRuslan Bukin /* Re-check for new ast scheduled */ 20428029b68SRuslan Bukin j 1b 20528029b68SRuslan Bukin2: 20628029b68SRuslan Bukin.endm 20728029b68SRuslan Bukin 20898f50c44SRuslan BukinENTRY(cpu_exception_handler) 20998f50c44SRuslan Bukin csrrw sp, sscratch, sp 21098f50c44SRuslan Bukin beqz sp, 1f 21198f50c44SRuslan Bukin /* User mode detected */ 21298f50c44SRuslan Bukin j cpu_exception_handler_user 21398f50c44SRuslan Bukin1: 21498f50c44SRuslan Bukin /* Supervisor mode detected */ 21598f50c44SRuslan Bukin csrrw sp, sscratch, sp 21698f50c44SRuslan Bukin j cpu_exception_handler_supervisor 21798f50c44SRuslan BukinEND(cpu_exception_handler) 21898f50c44SRuslan Bukin 21928029b68SRuslan BukinENTRY(cpu_exception_handler_supervisor) 22028029b68SRuslan Bukin save_registers 1 22128029b68SRuslan Bukin mv a0, sp 22228029b68SRuslan Bukin call _C_LABEL(do_trap_supervisor) 22328029b68SRuslan Bukin load_registers 1 22498f50c44SRuslan Bukin sret 22528029b68SRuslan BukinEND(cpu_exception_handler_supervisor) 22628029b68SRuslan Bukin 22728029b68SRuslan BukinENTRY(cpu_exception_handler_user) 22828029b68SRuslan Bukin save_registers 0 22928029b68SRuslan Bukin mv a0, sp 23028029b68SRuslan Bukin call _C_LABEL(do_trap_user) 23128029b68SRuslan Bukin do_ast 23228029b68SRuslan Bukin load_registers 0 23328029b68SRuslan Bukin csrrw sp, sscratch, sp 23498f50c44SRuslan Bukin sret 23528029b68SRuslan BukinEND(cpu_exception_handler_user) 236