/* * Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU) * OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: * http://license.coscl.org.cn/MulanPSL * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. */ #include #include #include "exception.h" #include "esr.h" .extern syscall_table .extern hook_syscall .extern lock_kernel .extern unlock_kernel .macro exception_entry label /* Each entry should be 0x80 aligned */ .align 7 b \label .endm .macro handle_entry el, type exception_enter mov x0, #\type mrs x1, esr_el1 mrs x2, elr_el1 bl handle_entry_c exception_return .endm /* See more details about the bias in registers.h */ .macro exception_enter sub sp, sp, #ARCH_EXEC_CONT_SIZE stp x0, x1, [sp, #16 * 0] stp x2, x3, [sp, #16 * 1] stp x4, x5, [sp, #16 * 2] stp x6, x7, [sp, #16 * 3] stp x8, x9, [sp, #16 * 4] stp x10, x11, [sp, #16 * 5] stp x12, x13, [sp, #16 * 6] stp x14, x15, [sp, #16 * 7] stp x16, x17, [sp, #16 * 8] stp x18, x19, [sp, #16 * 9] stp x20, x21, [sp, #16 * 10] stp x22, x23, [sp, #16 * 11] stp x24, x25, [sp, #16 * 12] stp x26, x27, [sp, #16 * 13] stp x28, x29, [sp, #16 * 14] mrs x10, sp_el0 mrs x11, elr_el1 mrs x12, spsr_el1 stp x30, x10, [sp, #16 * 15] stp x11, x12, [sp, #16 * 16] .endm .macro exception_exit ldp x11, x12, [sp, #16 * 16] ldp x30, x10, [sp, #16 * 15] msr sp_el0, x10 msr elr_el1, x11 msr spsr_el1, x12 ldp x0, x1, [sp, #16 * 0] ldp x2, x3, [sp, #16 * 1] ldp x4, x5, [sp, #16 * 2] ldp x6, x7, [sp, #16 * 3] ldp x8, x9, [sp, #16 * 4] ldp x10, x11, [sp, #16 * 5] ldp x12, x13, [sp, #16 * 6] ldp x14, x15, [sp, #16 * 7] ldp x16, x17, [sp, #16 * 8] ldp x18, x19, [sp, #16 * 9] ldp x20, x21, [sp, #16 * 10] ldp x22, x23, [sp, #16 * 11] ldp x24, x25, [sp, #16 * 12] ldp x26, x27, [sp, #16 * 13] ldp x28, x29, [sp, #16 * 14] add sp, sp, #ARCH_EXEC_CONT_SIZE eret .endm /** * Lab4 * unlock the big kernel lock before returning to the user mode */ .macro exception_return bl unlock_kernel exception_exit .endm /* * Vecotr table offsets from vector table base address from ARMv8 Manual * Address | Exception Type | Description * ============================================================================ * VBAR_Eln+0x000 | Synchronous | SPSel=0 * +0x080 | IRQ/vIRQ | Current EL * +0x100 | FIQ/vFIQ | with Stack Pointer * +0x180 | SError/vSError | shared with EL0 * ============================================================================ * VBAR_Eln+0x200 | Synchronous | SPSel=1 * +0x280 | IRQ/vIRQ | Current EL * +0x300 | FIQ/vFIQ | with dedicated * +0x380 | SError/vSError | Stack Pointer * ============================================================================ * VBAR_Eln+0x400 | Synchronous | * +0x480 | IRQ/vIRQ | Lower EL * +0x500 | FIQ/vFIQ | using AArch64 * +0x580 | SError/vSError | * ============================================================================ * VBAR_Eln+0x600 | Synchronous | * +0x680 | IRQ/vIRQ | Lower EL * +0x700 | FIQ/vFIQ | using AArch32 * +0x780 | SError/vSError | * ============================================================================ */ /* * Lab3: Your code here * Use exception_entry to fill the exception vector table to redirect * every entry to cooresponeding entry. * NOTE: el1t means SP_EL0 is used as stack before exception and el1h * means SP_EL1 is used */ .align 11 EXPORT(el1_vector) // ELx SP_EL0 exception_entry sync_el1t exception_entry irq_el1t exception_entry fiq_el1t exception_entry error_el1t // ELx SP_ELx exception_entry sync_el1h exception_entry irq_el1h exception_entry fiq_el1h exception_entry error_el1h // EL0 AArch64 exception_entry sync_el0_64 exception_entry irq_el0_64 exception_entry fiq_el0_64 exception_entry error_el0_64 // EL0 AArch32 exception_entry sync_el0_32 exception_entry irq_el0_32 exception_entry fiq_el0_32 exception_entry error_el0_32 sync_el1t: handle_entry 1, SYNC_EL1t irq_el1t: handle_entry 1, IRQ_EL1t fiq_el1t: handle_entry 1, FIQ_EL1t error_el1t: handle_entry 1, ERROR_EL1t sync_el1h: handle_entry 1, SYNC_EL1h fiq_el1h: handle_entry 1, FIQ_EL1h error_el1h: handle_entry 1, ERROR_EL1h sync_el0_64: /* Since we cannot touch x0-x7, we need some extra work here */ exception_enter mrs x25, esr_el1 lsr x24, x25, #ESR_EL1_EC_SHIFT cmp x24, #ESR_EL1_EC_SVC_64 b.eq el0_syscall /* Not supported exception */ mov x0, SYNC_EL0_64 mrs x1, esr_el1 mrs x2, elr_el1 bl handle_entry_c exception_return el0_syscall: /* Lab4 * Acquire the big kernel lock for syscall */ // 保存现场 sub sp, sp, #16 * 8 stp x0, x1, [sp, #16 * 0] stp x2, x3, [sp, #16 * 1] stp x4, x5, [sp, #16 * 2] stp x6, x7, [sp, #16 * 3] stp x8, x9, [sp, #16 * 4] stp x10, x11, [sp, #16 * 5] stp x12, x13, [sp, #16 * 6] stp x14, x15, [sp, #16 * 7] bl lock_kernel ldp x0, x1, [sp, #16 * 0] ldp x2, x3, [sp, #16 * 1] ldp x4, x5, [sp, #16 * 2] ldp x6, x7, [sp, #16 * 3] ldp x8, x9, [sp, #16 * 4] ldp x10, x11, [sp, #16 * 5] ldp x12, x13, [sp, #16 * 6] ldp x14, x15, [sp, #16 * 7] add sp, sp, #16 * 8 // 系统调用号左移 2 位作为系统调用表偏移 adr x27, syscall_table // syscall table in x27 uxtw x16, w8 // syscall number in x16 ldr x16, [x27, x16, lsl #3] // find the syscall entry blr x16 /* Ret from syscall */ // bl disable_irq str x0, [sp] /* set the return value of the syscall */ exception_return irq_el1h: exception_enter mov x0, IRQ_EL1h bl handle_irq /* should nerver reach here */ b . irq_el0_64: exception_enter mov x0, IRQ_EL0_64 bl handle_irq /* should nerver reach here */ b . fiq_el0_64: handle_entry 0, FIQ_EL0_64 error_el0_64: handle_entry 0, ERROR_EL0_64 sync_el0_32: handle_entry 0, SYNC_EL0_32 irq_el0_32: handle_entry 0, IRQ_EL0_32 fiq_el0_32: handle_entry 0, FIQ_EL0_32 error_el0_32: handle_entry 0, ERROR_EL0_32 /* void eret_to_thread(u64 sp) */ BEGIN_FUNC(eret_to_thread) mov sp, x0 exception_return END_FUNC(eret_to_thread)