1/* $OpenBSD: cpuswitch.S,v 1.8 2023/10/24 13:20:10 claudio Exp $ */ 2 3/* 4 * Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com> 5 * Copyright (c) 2020 Brian Bamsch <bbamsch@google.com> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#include "machine/asm.h" 21#include "assym.h" 22 23/* 24 * cpu_switchto(struct proc *oldproc, struct proc *newproc) 25 * a0 'struct proc *' of the old context 26 * a1 'struct proc *' of the new context 27 */ 28ENTRY(cpu_switchto_asm) 29 // check if old context needs to be saved 30 beqz a0, 1f 31 32 // create switchframe 33 addi sp, sp, -SWITCHFRAME_SIZEOF 34 sd s0, (SF_S + 0 * 8)(sp) 35 sd s1, (SF_S + 1 * 8)(sp) 36 sd s2, (SF_S + 2 * 8)(sp) 37 sd s3, (SF_S + 3 * 8)(sp) 38 sd s4, (SF_S + 4 * 8)(sp) 39 sd s5, (SF_S + 5 * 8)(sp) 40 sd s6, (SF_S + 6 * 8)(sp) 41 sd s7, (SF_S + 7 * 8)(sp) 42 sd s8, (SF_S + 8 * 8)(sp) 43 sd s9, (SF_S + 9 * 8)(sp) 44 sd s10, (SF_S + 10 * 8)(sp) 45 sd s11, (SF_S + 11 * 8)(sp) 46 sd ra, SF_RA(sp) 47 48 // store switchframe 49 ld a5, CI_CURPCB(tp) 50 sd sp, PCB_SP(a5) 51 521: 53 RETGUARD_SYMBOL(cpu_switchto) 54 RETGUARD_LOAD_RANDOM(cpu_switchto, s0) 55 56 li a5, SONPROC 57 sb a5, P_STAT(a1) // Mark new on cpu 58 sd tp, P_CPU(a1) // Store curcpu 59 ld a5, P_ADDR(a1) // Load new pcb 60 sd a5, CI_CURPCB(tp) 61 sd a1, CI_CURPROC(tp) 62 63 // Unlike AArch64, RISC-V does not have a dedicated register in which 64 // we can also store pcb_tcb. Supervisor must access tcb indirectly. 65 66 ld s1, PCB_SP(a5) // load new stack pointer 67 mv a0, a1 68 la t0, pmap_set_satp 69 jalr t0 70 71 mv a7, s0 // move retguard random 72 mv sp, s1 // restore stack pointer 73 74 ld s0, (SF_S + 0 * 8)(sp) 75 ld s1, (SF_S + 1 * 8)(sp) 76 ld s2, (SF_S + 2 * 8)(sp) 77 ld s3, (SF_S + 3 * 8)(sp) 78 ld s4, (SF_S + 4 * 8)(sp) 79 ld s5, (SF_S + 5 * 8)(sp) 80 ld s6, (SF_S + 6 * 8)(sp) 81 ld s7, (SF_S + 7 * 8)(sp) 82 ld s8, (SF_S + 8 * 8)(sp) 83 ld s9, (SF_S + 9 * 8)(sp) 84 ld s10, (SF_S + 10 * 8)(sp) 85 ld s11, (SF_S + 11 * 8)(sp) 86 ld ra, SF_RA(sp) 87 88 RETGUARD_CALC_COOKIE(a7) 89 addi sp, sp, SWITCHFRAME_SIZEOF 90 RETGUARD_CHECK(cpu_switchto, a7) 91 ret 92END(cpu_switch_asm) 93 94ENTRY(proc_trampoline) 95 la t0, proc_trampoline_mi 96 jalr t0 97 mv a0, s2 98 jalr s1 99 la t0, syscall_return 100 jr t0 101END(cpu_switch) 102