From de064ac74b8ed1b26441562fbd9e3975a7a9dc67 Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Fri, 11 Apr 2014 10:20:46 +0100 Subject: [PATCH] Moved rdisk.c into kernel. Renamed startup.S to _startup.S --- sys/{pic32 => kernel}/rdisk.c | 0 sys/pic32/_startup.S | 406 +++++++++++++++++++++++++++++++++- sys/pic32/startup.S | 405 --------------------------------- 3 files changed, 405 insertions(+), 406 deletions(-) rename sys/{pic32 => kernel}/rdisk.c (100%) mode change 120000 => 100644 sys/pic32/_startup.S delete mode 100644 sys/pic32/startup.S diff --git a/sys/pic32/rdisk.c b/sys/kernel/rdisk.c similarity index 100% rename from sys/pic32/rdisk.c rename to sys/kernel/rdisk.c diff --git a/sys/pic32/_startup.S b/sys/pic32/_startup.S deleted file mode 120000 index cac3df3..0000000 --- a/sys/pic32/_startup.S +++ /dev/null @@ -1 +0,0 @@ -startup.S \ No newline at end of file diff --git a/sys/pic32/_startup.S b/sys/pic32/_startup.S new file mode 100644 index 0000000..dddbdee --- /dev/null +++ b/sys/pic32/_startup.S @@ -0,0 +1,405 @@ +# +# Startup code for Microchip PIC32 microcontrollers. +# Using HID bootloader. +# +# Copyright (C) 2010 Serge Vakulenko, +# +# Permission to use, copy, modify, and distribute this software +# and its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that the copyright notice and this +# permission notice and warranty disclaimer appear in supporting +# documentation, and that the name of the author not be used in +# advertising or publicity pertaining to distribution of the +# software without specific, written prior permission. +# +# The author disclaim all warranties with regard to this +# software, including all implied warranties of merchantability +# and fitness. In no event shall the author be liable for any +# special, indirect or consequential damages or any damages +# whatsoever resulting from loss of use, data or profits, whether +# in an action of contract, negligence or other tortious action, +# arising out of or in connection with the use or performance of +# this software. +# +#include "machine/io.h" + +#define UBASE 0x7f008000 /* User space base address */ + + .set noreorder + .set mips32r2 + .set nomips16 + + .extern u + .extern u_end + .extern u0 + .extern main + .extern exception + +#--------------------------------------- +# Reset vector: main entry point +# + .section .startup,"ax",@progbits + .org 0 + .type _reset_vector_, @function +_reset_vector_: .globl _reset_vector_ + + .set noat + move $1, $zero # Clear all regs + move $2, $zero + move $3, $zero + move $4, $zero + move $5, $zero + move $6, $zero + move $7, $zero + move $8, $zero + move $9, $zero + move $10, $zero + move $11, $zero + move $12, $zero + move $13, $zero + move $14, $zero + move $15, $zero + move $16, $zero + move $17, $zero + move $18, $zero + move $19, $zero + move $20, $zero + move $21, $zero + move $22, $zero + move $23, $zero + move $24, $zero + move $25, $zero + move $26, $zero + move $27, $zero + move $28, $zero + move $29, $zero + move $30, $zero + move $31, $zero + mtlo $zero + mthi $zero + .set at + + la $sp, u_end - 16 # Stack at end of U area + la $a0, main + jalr $a0 # Jump to main() + lui $gp, 0x8000 # Set global pointer (delay slot) + + la $k0, UBASE + mtc0 $k0, $C0_EPC # Entry to user code. + + mfc0 $k0, $C0_STATUS + ori $k0, $k0, ST_UM | ST_EXL | ST_IE # Set user mode and enable interrupts + mtc0 $k0, $C0_STATUS # Put SR back + ehb + eret # PC <= EPC; EXL <= 0 + nop # just to be safe + + +#--------------------------------------- +# Secondary entry point for RetroBSD bootloader. +# + .section .exception,"ax",@progbits +_exception_base_: .globl _exception_base_ + + .org 0 + .type _entry_vector_, @function +_entry_vector_: .globl _entry_vector_ + la $k0, _reset_vector_ + jr $k0 + nop + +#--------------------------------------- +# Exception vector: handle interrupts and exceptions +# + .org 0x200 + .type _exception_vector_, @function +_exception_vector_: .globl _exception_vector_ + + mfc0 $k0, $C0_STATUS + andi $k1, $k0, ST_UM # Check user mode + beqz $k1, kernel_exception + move $k1, $sp + + # + # Exception in user mode: switch stack. + # +user_exception: + la $sp, u_end # Stack at end of U area +kernel_exception: + addi $sp, -16-FRAME_WORDS*4 # Allocate space for registers +save_regs: + sw $k0, (16+FRAME_STATUS*4) ($sp) + sw $k1, (16+FRAME_SP*4) ($sp) + + .set noat + sw $1, (16+FRAME_R1*4) ($sp) # Save general registers + sw $2, (16+FRAME_R2*4) ($sp) + sw $3, (16+FRAME_R3*4) ($sp) + sw $4, (16+FRAME_R4*4) ($sp) + sw $5, (16+FRAME_R5*4) ($sp) + sw $6, (16+FRAME_R6*4) ($sp) + sw $7, (16+FRAME_R7*4) ($sp) + sw $8, (16+FRAME_R8*4) ($sp) + sw $9, (16+FRAME_R9*4) ($sp) + sw $10, (16+FRAME_R10*4) ($sp) + sw $11, (16+FRAME_R11*4) ($sp) + sw $12, (16+FRAME_R12*4) ($sp) + sw $13, (16+FRAME_R13*4) ($sp) + sw $14, (16+FRAME_R14*4) ($sp) + sw $15, (16+FRAME_R15*4) ($sp) + sw $16, (16+FRAME_R16*4) ($sp) + sw $17, (16+FRAME_R17*4) ($sp) + sw $18, (16+FRAME_R18*4) ($sp) + sw $19, (16+FRAME_R19*4) ($sp) + sw $20, (16+FRAME_R20*4) ($sp) + sw $21, (16+FRAME_R21*4) ($sp) + sw $22, (16+FRAME_R22*4) ($sp) + sw $23, (16+FRAME_R23*4) ($sp) + sw $24, (16+FRAME_R24*4) ($sp) + sw $25, (16+FRAME_R25*4) ($sp) + # Skip $26 - K0 + # Skip $27 - K1 + sw $28, (16+FRAME_GP*4) ($sp) + # Skip $29 - SP + sw $30, (16+FRAME_FP*4) ($sp) + sw $31, (16+FRAME_RA*4) ($sp) + .set at + + mfhi $k0 # Save special registers + sw $k0, (16+FRAME_HI*4) ($sp) + + mflo $k0 + sw $k0, (16+FRAME_LO*4) ($sp) + + mfc0 $k0, $C0_EPC + sw $k0, (16+FRAME_PC*4) ($sp) + + move $a0, $sp + addi $a0, 16 # Arg 0: saved regs. + jal exception # Call C code. + lui $gp, 0x8000 # Set global pointer (delay slot) + + # + # Restore CPU state and return from interrupt. + # +restore_regs: + lw $a0, (16+FRAME_LO*4) ($sp) # Load HI, LO registers + mtlo $a0 + lw $a0, (16+FRAME_HI*4) ($sp) + mthi $a0 + + .set noat + lw $1, (16+FRAME_R1*4) ($sp) # Load general registers + lw $2, (16+FRAME_R2*4) ($sp) + lw $3, (16+FRAME_R3*4) ($sp) + lw $4, (16+FRAME_R4*4) ($sp) + lw $5, (16+FRAME_R5*4) ($sp) + lw $6, (16+FRAME_R6*4) ($sp) + lw $7, (16+FRAME_R7*4) ($sp) + lw $8, (16+FRAME_R8*4) ($sp) + lw $9, (16+FRAME_R9*4) ($sp) + lw $10, (16+FRAME_R10*4) ($sp) + lw $11, (16+FRAME_R11*4) ($sp) + lw $12, (16+FRAME_R12*4) ($sp) + lw $13, (16+FRAME_R13*4) ($sp) + lw $14, (16+FRAME_R14*4) ($sp) + lw $15, (16+FRAME_R15*4) ($sp) + lw $16, (16+FRAME_R16*4) ($sp) + lw $17, (16+FRAME_R17*4) ($sp) + lw $18, (16+FRAME_R18*4) ($sp) + lw $19, (16+FRAME_R19*4) ($sp) + lw $20, (16+FRAME_R20*4) ($sp) + lw $21, (16+FRAME_R21*4) ($sp) + lw $22, (16+FRAME_R22*4) ($sp) + lw $23, (16+FRAME_R23*4) ($sp) + lw $24, (16+FRAME_R24*4) ($sp) + lw $25, (16+FRAME_R25*4) ($sp) + # Skip $26 - K0 + # Skip $27 - K1 + lw $28, (16+FRAME_GP*4) ($sp) + # Skip $29 - SP + lw $30, (16+FRAME_FP*4) ($sp) + .set at + + # Do not use k0/k1 here, as interrupts are still enabled + lw $31, (16+FRAME_STATUS*4) ($sp) # K0 = saved status + ori $31, ST_EXL # Set EXL + mtc0 $31, $C0_STATUS # put SR back: disable interrupts + ehb + + lw $k0, (16+FRAME_PC*4) ($sp) # K0 = EPC + mtc0 $k0, $C0_EPC # put PC in EPC + ext $k1, $31, 27, 1 # get RP bit: single-step request + + lw $31, (16+FRAME_RA*4) ($sp) + lw $sp, (16+FRAME_SP*4) ($sp) # Restore stack + + # Return from exception + bnez $k1, debug_request # single-step request + ehb + eret # PC <= EPC; EXL <= 0 +debug_request: + sdbbp # enter debug mode + +#--------------------------------------- +# Debug exception processing. +# + .org 0x480 + .type _debug_vector_, @function +_debug_vector_: .globl _debug_vector_ + + mfc0 $k0, $C0_DEPC + la $k1, debug_request + bne $k0, $k1, single_step_done + nop + + # single step request + mfc0 $k0, $C0_DEBUG + ori $k0, DB_SST # set SST bit + mtc0 $k0, $C0_DEBUG + + mfc0 $k1, $C0_EPC + mtc0 $k1, $C0_DEPC # DEPC <= EPC + mfc0 $k0, $C0_STATUS + xori $k0, ST_EXL # Clear EXL + mtc0 $k0, $C0_STATUS + ehb + deret # PC <= DEPC; DM <= 0 + +single_step_done: + mtc0 $k0, $C0_EPC # EPC <= DEPC + + la $k1, _exception_vector_ + mtc0 $k1, $C0_DEPC # DEPC <= exception handler + + mfc0 $k0, $C0_DEBUG + sw $k0, c0_debug # save Debug register + ori $k0, DB_SST + xori $k0, DB_SST # clear SST bit + mtc0 $k0, $C0_DEBUG + + mfc0 $k1, $C0_STATUS + ori $k1, ST_EXL # Set EXL + mtc0 $k1, $C0_STATUS + ehb + deret # PC <= DEPC; DM <= 0 + +#--------------------------------------- +# Icode is copied out to process 1 to exec /sbin/init. +# If the exec fails, process 1 exits. +# + .globl icode, icodeend + .type icode, @function + .type icodeend, @function +icode: + la $a0, UBASE + move $a1, $a0 + addi $a0, etcinit - icode + addi $a1, argv - icode + syscall 11 # SYS_execv + move $a0, $v0 + syscall 1 # SYS_exit +etcinit: + .ascii "/sbin/init\0" +initflags: + .ascii "-\0" # ASCII initflags +argv: + .word etcinit + 6 - icode + UBASE # address of "init\0" + .word initflags - icode + UBASE # init options + .word 0 + +icodeend: nop + +#--------------------------------------- +# int setjmp (label_t *env); +# +# Setjmp(env) will save the process' current register variables, stack +# and program counter context and return a zero. +# + .type setjmp, @function +setjmp: .globl setjmp + sw $s0, (0 * 4) ($a0) # save register variables s0-s8 + sw $s1, (1 * 4) ($a0) + sw $s2, (2 * 4) ($a0) + sw $s3, (3 * 4) ($a0) + sw $s4, (4 * 4) ($a0) + sw $s5, (5 * 4) ($a0) + sw $s6, (6 * 4) ($a0) + sw $s7, (7 * 4) ($a0) + sw $s8, (8 * 4) ($a0) # frame pointer + sw $ra, (9 * 4) ($a0) # return address + sw $gp, (10 * 4) ($a0) # global data pointer + sw $sp, (11 * 4) ($a0) # stack pointer + j $ra + move $v0, $zero # return a zero for the setjmp call + +#--------------------------------------- +# void longjmp (memaddr uaddr, label_t *env); +# +# Longjmp(uaddr, env) will generate a "return(1)" from the last +# call to setjmp(env) by mapping in the user structure pointed to by uaddr, +# restoring the context saved by setjmp in env and returning a "1". +# Note that registers are recovered statically from the env buffer. +# Stack is not used. +# +# This longjmp differs from the longjmp found in the standard library - +# it's actually closer to the resume routine of the 4.3BSD kernel. +# + .type longjmp, @function +longjmp: .globl longjmp + + di # can't let anything in till we get a valid stack... + + la $v0, u # pointer to &u + beq $v0, $a0, 2f # if uaddr == &u... + nop # ...no need to remap U area + + la $a3, u_end # pointer to &u + USIZE + la $a0, u0 # pointer to &u0 + + lw $v1, 0($v0) # u.u_procp + sw $a0, 60($v1) # u.u_procp->p_addr = &u0 + + # exchange contents of u and u0 + move $v1, $v0 +1: + lw $t1, 0($v1) + lw $t0, 0($a0) + sw $t0, 0($v1) + sw $t1, 0($a0) + lw $t1, 4($v1) + lw $t0, 4($a0) + sw $t0, 4($v1) + sw $t1, 4($a0) + lw $t1, 8($v1) + lw $t0, 8($a0) + sw $t0, 8($v1) + sw $t1, 8($a0) + lw $t1, 12($v1) + lw $t0, 12($a0) + sw $t0, 12($v1) + sw $t1, 12($a0) + addiu $v1, $v1, 16 + bne $a3, $v1, 1b + addiu $a0, $a0, 16 + + lw $v1, 0($v0) # u.u_procp + sw $v0, 60($v1) # u.u_procp->p_addr = &u +2: + lw $s0, (0 * 4) ($a1) # restore register variables s0-s8 + lw $s1, (1 * 4) ($a1) + lw $s2, (2 * 4) ($a1) + lw $s3, (3 * 4) ($a1) + lw $s4, (4 * 4) ($a1) + lw $s5, (5 * 4) ($a1) + lw $s6, (6 * 4) ($a1) + lw $s7, (7 * 4) ($a1) + lw $s8, (8 * 4) ($a1) # frame pointer + lw $ra, (9 * 4) ($a1) # return address + lw $gp, (10 * 4) ($a1) # global data pointer + lw $sp, (11 * 4) ($a1) # stack pointer + + ei # release interrupts + j $ra # transfer back to setjmp() + li $v0, 1 # return value of 1 diff --git a/sys/pic32/startup.S b/sys/pic32/startup.S deleted file mode 100644 index dddbdee..0000000 --- a/sys/pic32/startup.S +++ /dev/null @@ -1,405 +0,0 @@ -# -# Startup code for Microchip PIC32 microcontrollers. -# Using HID bootloader. -# -# Copyright (C) 2010 Serge Vakulenko, -# -# Permission to use, copy, modify, and distribute this software -# and its documentation for any purpose and without fee is hereby -# granted, provided that the above copyright notice appear in all -# copies and that both that the copyright notice and this -# permission notice and warranty disclaimer appear in supporting -# documentation, and that the name of the author not be used in -# advertising or publicity pertaining to distribution of the -# software without specific, written prior permission. -# -# The author disclaim all warranties with regard to this -# software, including all implied warranties of merchantability -# and fitness. In no event shall the author be liable for any -# special, indirect or consequential damages or any damages -# whatsoever resulting from loss of use, data or profits, whether -# in an action of contract, negligence or other tortious action, -# arising out of or in connection with the use or performance of -# this software. -# -#include "machine/io.h" - -#define UBASE 0x7f008000 /* User space base address */ - - .set noreorder - .set mips32r2 - .set nomips16 - - .extern u - .extern u_end - .extern u0 - .extern main - .extern exception - -#--------------------------------------- -# Reset vector: main entry point -# - .section .startup,"ax",@progbits - .org 0 - .type _reset_vector_, @function -_reset_vector_: .globl _reset_vector_ - - .set noat - move $1, $zero # Clear all regs - move $2, $zero - move $3, $zero - move $4, $zero - move $5, $zero - move $6, $zero - move $7, $zero - move $8, $zero - move $9, $zero - move $10, $zero - move $11, $zero - move $12, $zero - move $13, $zero - move $14, $zero - move $15, $zero - move $16, $zero - move $17, $zero - move $18, $zero - move $19, $zero - move $20, $zero - move $21, $zero - move $22, $zero - move $23, $zero - move $24, $zero - move $25, $zero - move $26, $zero - move $27, $zero - move $28, $zero - move $29, $zero - move $30, $zero - move $31, $zero - mtlo $zero - mthi $zero - .set at - - la $sp, u_end - 16 # Stack at end of U area - la $a0, main - jalr $a0 # Jump to main() - lui $gp, 0x8000 # Set global pointer (delay slot) - - la $k0, UBASE - mtc0 $k0, $C0_EPC # Entry to user code. - - mfc0 $k0, $C0_STATUS - ori $k0, $k0, ST_UM | ST_EXL | ST_IE # Set user mode and enable interrupts - mtc0 $k0, $C0_STATUS # Put SR back - ehb - eret # PC <= EPC; EXL <= 0 - nop # just to be safe - - -#--------------------------------------- -# Secondary entry point for RetroBSD bootloader. -# - .section .exception,"ax",@progbits -_exception_base_: .globl _exception_base_ - - .org 0 - .type _entry_vector_, @function -_entry_vector_: .globl _entry_vector_ - la $k0, _reset_vector_ - jr $k0 - nop - -#--------------------------------------- -# Exception vector: handle interrupts and exceptions -# - .org 0x200 - .type _exception_vector_, @function -_exception_vector_: .globl _exception_vector_ - - mfc0 $k0, $C0_STATUS - andi $k1, $k0, ST_UM # Check user mode - beqz $k1, kernel_exception - move $k1, $sp - - # - # Exception in user mode: switch stack. - # -user_exception: - la $sp, u_end # Stack at end of U area -kernel_exception: - addi $sp, -16-FRAME_WORDS*4 # Allocate space for registers -save_regs: - sw $k0, (16+FRAME_STATUS*4) ($sp) - sw $k1, (16+FRAME_SP*4) ($sp) - - .set noat - sw $1, (16+FRAME_R1*4) ($sp) # Save general registers - sw $2, (16+FRAME_R2*4) ($sp) - sw $3, (16+FRAME_R3*4) ($sp) - sw $4, (16+FRAME_R4*4) ($sp) - sw $5, (16+FRAME_R5*4) ($sp) - sw $6, (16+FRAME_R6*4) ($sp) - sw $7, (16+FRAME_R7*4) ($sp) - sw $8, (16+FRAME_R8*4) ($sp) - sw $9, (16+FRAME_R9*4) ($sp) - sw $10, (16+FRAME_R10*4) ($sp) - sw $11, (16+FRAME_R11*4) ($sp) - sw $12, (16+FRAME_R12*4) ($sp) - sw $13, (16+FRAME_R13*4) ($sp) - sw $14, (16+FRAME_R14*4) ($sp) - sw $15, (16+FRAME_R15*4) ($sp) - sw $16, (16+FRAME_R16*4) ($sp) - sw $17, (16+FRAME_R17*4) ($sp) - sw $18, (16+FRAME_R18*4) ($sp) - sw $19, (16+FRAME_R19*4) ($sp) - sw $20, (16+FRAME_R20*4) ($sp) - sw $21, (16+FRAME_R21*4) ($sp) - sw $22, (16+FRAME_R22*4) ($sp) - sw $23, (16+FRAME_R23*4) ($sp) - sw $24, (16+FRAME_R24*4) ($sp) - sw $25, (16+FRAME_R25*4) ($sp) - # Skip $26 - K0 - # Skip $27 - K1 - sw $28, (16+FRAME_GP*4) ($sp) - # Skip $29 - SP - sw $30, (16+FRAME_FP*4) ($sp) - sw $31, (16+FRAME_RA*4) ($sp) - .set at - - mfhi $k0 # Save special registers - sw $k0, (16+FRAME_HI*4) ($sp) - - mflo $k0 - sw $k0, (16+FRAME_LO*4) ($sp) - - mfc0 $k0, $C0_EPC - sw $k0, (16+FRAME_PC*4) ($sp) - - move $a0, $sp - addi $a0, 16 # Arg 0: saved regs. - jal exception # Call C code. - lui $gp, 0x8000 # Set global pointer (delay slot) - - # - # Restore CPU state and return from interrupt. - # -restore_regs: - lw $a0, (16+FRAME_LO*4) ($sp) # Load HI, LO registers - mtlo $a0 - lw $a0, (16+FRAME_HI*4) ($sp) - mthi $a0 - - .set noat - lw $1, (16+FRAME_R1*4) ($sp) # Load general registers - lw $2, (16+FRAME_R2*4) ($sp) - lw $3, (16+FRAME_R3*4) ($sp) - lw $4, (16+FRAME_R4*4) ($sp) - lw $5, (16+FRAME_R5*4) ($sp) - lw $6, (16+FRAME_R6*4) ($sp) - lw $7, (16+FRAME_R7*4) ($sp) - lw $8, (16+FRAME_R8*4) ($sp) - lw $9, (16+FRAME_R9*4) ($sp) - lw $10, (16+FRAME_R10*4) ($sp) - lw $11, (16+FRAME_R11*4) ($sp) - lw $12, (16+FRAME_R12*4) ($sp) - lw $13, (16+FRAME_R13*4) ($sp) - lw $14, (16+FRAME_R14*4) ($sp) - lw $15, (16+FRAME_R15*4) ($sp) - lw $16, (16+FRAME_R16*4) ($sp) - lw $17, (16+FRAME_R17*4) ($sp) - lw $18, (16+FRAME_R18*4) ($sp) - lw $19, (16+FRAME_R19*4) ($sp) - lw $20, (16+FRAME_R20*4) ($sp) - lw $21, (16+FRAME_R21*4) ($sp) - lw $22, (16+FRAME_R22*4) ($sp) - lw $23, (16+FRAME_R23*4) ($sp) - lw $24, (16+FRAME_R24*4) ($sp) - lw $25, (16+FRAME_R25*4) ($sp) - # Skip $26 - K0 - # Skip $27 - K1 - lw $28, (16+FRAME_GP*4) ($sp) - # Skip $29 - SP - lw $30, (16+FRAME_FP*4) ($sp) - .set at - - # Do not use k0/k1 here, as interrupts are still enabled - lw $31, (16+FRAME_STATUS*4) ($sp) # K0 = saved status - ori $31, ST_EXL # Set EXL - mtc0 $31, $C0_STATUS # put SR back: disable interrupts - ehb - - lw $k0, (16+FRAME_PC*4) ($sp) # K0 = EPC - mtc0 $k0, $C0_EPC # put PC in EPC - ext $k1, $31, 27, 1 # get RP bit: single-step request - - lw $31, (16+FRAME_RA*4) ($sp) - lw $sp, (16+FRAME_SP*4) ($sp) # Restore stack - - # Return from exception - bnez $k1, debug_request # single-step request - ehb - eret # PC <= EPC; EXL <= 0 -debug_request: - sdbbp # enter debug mode - -#--------------------------------------- -# Debug exception processing. -# - .org 0x480 - .type _debug_vector_, @function -_debug_vector_: .globl _debug_vector_ - - mfc0 $k0, $C0_DEPC - la $k1, debug_request - bne $k0, $k1, single_step_done - nop - - # single step request - mfc0 $k0, $C0_DEBUG - ori $k0, DB_SST # set SST bit - mtc0 $k0, $C0_DEBUG - - mfc0 $k1, $C0_EPC - mtc0 $k1, $C0_DEPC # DEPC <= EPC - mfc0 $k0, $C0_STATUS - xori $k0, ST_EXL # Clear EXL - mtc0 $k0, $C0_STATUS - ehb - deret # PC <= DEPC; DM <= 0 - -single_step_done: - mtc0 $k0, $C0_EPC # EPC <= DEPC - - la $k1, _exception_vector_ - mtc0 $k1, $C0_DEPC # DEPC <= exception handler - - mfc0 $k0, $C0_DEBUG - sw $k0, c0_debug # save Debug register - ori $k0, DB_SST - xori $k0, DB_SST # clear SST bit - mtc0 $k0, $C0_DEBUG - - mfc0 $k1, $C0_STATUS - ori $k1, ST_EXL # Set EXL - mtc0 $k1, $C0_STATUS - ehb - deret # PC <= DEPC; DM <= 0 - -#--------------------------------------- -# Icode is copied out to process 1 to exec /sbin/init. -# If the exec fails, process 1 exits. -# - .globl icode, icodeend - .type icode, @function - .type icodeend, @function -icode: - la $a0, UBASE - move $a1, $a0 - addi $a0, etcinit - icode - addi $a1, argv - icode - syscall 11 # SYS_execv - move $a0, $v0 - syscall 1 # SYS_exit -etcinit: - .ascii "/sbin/init\0" -initflags: - .ascii "-\0" # ASCII initflags -argv: - .word etcinit + 6 - icode + UBASE # address of "init\0" - .word initflags - icode + UBASE # init options - .word 0 - -icodeend: nop - -#--------------------------------------- -# int setjmp (label_t *env); -# -# Setjmp(env) will save the process' current register variables, stack -# and program counter context and return a zero. -# - .type setjmp, @function -setjmp: .globl setjmp - sw $s0, (0 * 4) ($a0) # save register variables s0-s8 - sw $s1, (1 * 4) ($a0) - sw $s2, (2 * 4) ($a0) - sw $s3, (3 * 4) ($a0) - sw $s4, (4 * 4) ($a0) - sw $s5, (5 * 4) ($a0) - sw $s6, (6 * 4) ($a0) - sw $s7, (7 * 4) ($a0) - sw $s8, (8 * 4) ($a0) # frame pointer - sw $ra, (9 * 4) ($a0) # return address - sw $gp, (10 * 4) ($a0) # global data pointer - sw $sp, (11 * 4) ($a0) # stack pointer - j $ra - move $v0, $zero # return a zero for the setjmp call - -#--------------------------------------- -# void longjmp (memaddr uaddr, label_t *env); -# -# Longjmp(uaddr, env) will generate a "return(1)" from the last -# call to setjmp(env) by mapping in the user structure pointed to by uaddr, -# restoring the context saved by setjmp in env and returning a "1". -# Note that registers are recovered statically from the env buffer. -# Stack is not used. -# -# This longjmp differs from the longjmp found in the standard library - -# it's actually closer to the resume routine of the 4.3BSD kernel. -# - .type longjmp, @function -longjmp: .globl longjmp - - di # can't let anything in till we get a valid stack... - - la $v0, u # pointer to &u - beq $v0, $a0, 2f # if uaddr == &u... - nop # ...no need to remap U area - - la $a3, u_end # pointer to &u + USIZE - la $a0, u0 # pointer to &u0 - - lw $v1, 0($v0) # u.u_procp - sw $a0, 60($v1) # u.u_procp->p_addr = &u0 - - # exchange contents of u and u0 - move $v1, $v0 -1: - lw $t1, 0($v1) - lw $t0, 0($a0) - sw $t0, 0($v1) - sw $t1, 0($a0) - lw $t1, 4($v1) - lw $t0, 4($a0) - sw $t0, 4($v1) - sw $t1, 4($a0) - lw $t1, 8($v1) - lw $t0, 8($a0) - sw $t0, 8($v1) - sw $t1, 8($a0) - lw $t1, 12($v1) - lw $t0, 12($a0) - sw $t0, 12($v1) - sw $t1, 12($a0) - addiu $v1, $v1, 16 - bne $a3, $v1, 1b - addiu $a0, $a0, 16 - - lw $v1, 0($v0) # u.u_procp - sw $v0, 60($v1) # u.u_procp->p_addr = &u -2: - lw $s0, (0 * 4) ($a1) # restore register variables s0-s8 - lw $s1, (1 * 4) ($a1) - lw $s2, (2 * 4) ($a1) - lw $s3, (3 * 4) ($a1) - lw $s4, (4 * 4) ($a1) - lw $s5, (5 * 4) ($a1) - lw $s6, (6 * 4) ($a1) - lw $s7, (7 * 4) ($a1) - lw $s8, (8 * 4) ($a1) # frame pointer - lw $ra, (9 * 4) ($a1) # return address - lw $gp, (10 * 4) ($a1) # global data pointer - lw $sp, (11 * 4) ($a1) # stack pointer - - ei # release interrupts - j $ra # transfer back to setjmp() - li $v0, 1 # return value of 1