📄 cpu_asm.s
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * cpu_asm.S (memory) * * SH7751R-dependent functions */#define _in_asm_source_#include <machine.h>#include <tk/asm.h>#include <sys/sysinfo.h>#include <sys/memdef.h>#include "cpu_asm.h"/* * Call system program * ER CallSysProgInit( INT ac, UB *av[], FP entry ) */ .text .balign 2 .globl Csym(CallSysProgInit) .type Csym(CallSysProgInit), @functionCsym(CallSysProgInit): mov.l r8, @-SP // Save register mov.l r9, @-SP mov.l r10, @-SP mov.l r11, @-SP mov.l r12, @-SP mov.l r13, @-SP mov.l r14, @-SP sts.l pr, @-SP sts.l fpscr, @-SP // Save FPU register sts.l fpul, @-SP mov.l S_INIT_FPSCR, r8 lds r8, fpscr frchg // FPSCR.FR=1 SZ=0 fmov.s fr15, @-SP fmov.s fr14, @-SP fmov.s fr13, @-SP fmov.s fr12, @-SP fmov.s fr11, @-SP fmov.s fr10, @-SP fmov.s fr9, @-SP fmov.s fr8, @-SP fmov.s fr7, @-SP fmov.s fr6, @-SP fmov.s fr5, @-SP fmov.s fr4, @-SP fmov.s fr3, @-SP fmov.s fr2, @-SP fmov.s fr1, @-SP fmov.s fr0, @-SP frchg // FPSCR.FR=0 SZ=0 fmov.s fr15, @-SP fmov.s fr14, @-SP fmov.s fr13, @-SP fmov.s fr12, @-SP jsr @r6 // call entry(ac, av) nop mov #0, r8 // Restore FPU register lds r8, fpscr // FPSCR.FR=0 SZ=0 fmov.s @SP+, fr12 fmov.s @SP+, fr13 fmov.s @SP+, fr14 fmov.s @SP+, fr15 frchg // FPSCR.FR=1 SZ=0 fmov.s @SP+, fr0 fmov.s @SP+, fr1 fmov.s @SP+, fr2 fmov.s @SP+, fr3 fmov.s @SP+, fr4 fmov.s @SP+, fr5 fmov.s @SP+, fr6 fmov.s @SP+, fr7 fmov.s @SP+, fr8 fmov.s @SP+, fr9 fmov.s @SP+, fr10 fmov.s @SP+, fr11 fmov.s @SP+, fr12 fmov.s @SP+, fr13 fmov.s @SP+, fr14 fmov.s @SP+, fr15 lds.l @SP+, fpul lds.l @SP+, fpscr lds.l @SP+, pr // Restore register mov.l @SP+, r14 mov.l @SP+, r13 mov.l @SP+, r12 mov.l @SP+, r11 mov.l @SP+, r10 mov.l @SP+, r9 rts mov.l @SP+, r8 .balign 4 S_INIT_FPSCR: .long 0x000c0000/* ------------------------------------------------------------------------ *//* * Dedicated stack for page fault handler * Used as virtual memory within page fault handler * System stack cannot be used. */#define PAGEFAULTHDR_STACKSZ (3 * 1024)#define PAGEFAULTHDR_STACKTOP (pagefaulthdr_stack + PAGEFAULTHDR_STACKSZ) .lcomm pagefaulthdr_stack, PAGEFAULTHDR_STACKSZ/* * Page fault handler entry * TA_ASM-format handler */ .text .balign 2 .globl Csym(asmPageFaultHdr) .type Csym(asmPageFaultHdr), @functionCsym(asmPageFaultHdr): /* SR.BL=1, SR.RB=1, SR.I=15 */ mov.l r0, @-ISP // R0_BANK1 (Vector index + factor) Save mov.l r4, @-ISP // R4_BANK1 Save mov.l SP, @-ISP // For page fault handler only mov.l P_STACKTOP, r0 // Use stack. mov.l P_STACKLIMIT, r4 cmp/hi r4, SP bf l_chgstk cmp/hs SP, r0 bt l_nochgstk l_chgstk: mov r0, SP l_nochgstk: stc.l r4_bank, @-SP // Save register stc.l r5_bank, @-SP stc.l r6_bank, @-SP mov.l P_EXPEVT, r7 // Obtain exception information. mov.l P_TEA, r0 mov.l @r7, r4 // Save EXPEVT in r4_bank1. mov.l P_MMUCR, r7 ldc r4, r4_bank // r4_bank0 = EXPEVT ldc.l @r0+, r5_bank // r5_bank0 = TEA ldc.l @r7+, r6_bank // r6_bank0 = MMUCR mov.l P_SR_NOBLOCK, r7 // Reset exception block. ldc r7, sr // Switch register banks. /* SR.BL=0, SR.RB=0, SR.I=15 */ mov.l r0, @-SP // Save register mov.l r1, @-SP mov.l r2, @-SP mov.l r3, @-SP mov.l r7, @-SP sts.l mach, @-SP sts.l macl, @-SP sts.l pr, @-SP mov.l P_HDRENT, r0 jsr @r0 // call PageFaultHdr(EXPEVT,TEA,MMUCR) nop ldc r0, r0_bank // Save return value in r0_bank1. lds.l @SP+, pr // Restore register lds.l @SP+, macl lds.l @SP+, mach mov.l @SP+, r7 mov.l @SP+, r3 mov.l @SP+, r2 mov.l @SP+, r1 mov.l @SP+, r0 mov.l @SP+, r6 mov.l @SP+, r5 mov.l P_SR_NOBL_RB, r4 // Switch register banks. ldc r4, sr /* SR.BL=0, SR.RB=1, SR.I=15 */ ldc.l @SP+, r4_bank // R4_BANK0 Restore mov.l @ISP+, SP // Turn back stack tst r0, r0 bf l_enter_bms mov.l @ISP+, r4 // R4_BANK1 Restore mov.l @ISP+, r0 // R0_BANK1 Restore trapa #TRAP_RETINT // ret_int() l_enter_bms: mov.l P_SR_BLOCK, r0 // Exception block ldc r0, sr /* SR.BL=1, SR.RB=1, SR.I=15 */ mov.l P_DEFHDR, r7 mov.l P_EXPEVT, r0 mov.l @r7, r7 mov.l r4, @r0 // Restore exception code in EXPEVT. mov.l @ISP+, r4 // R4_BANK1 Restore jmp @r7 // To BMS default handler. mov.l @ISP+, r0 // R0_BANK1 Restore/* * Provisional page fault handler entry * Used provisionally until T-Kernel starts. * Switched to a regular page fault handler after T-Kernel startup. */ .text .balign 2 .globl Csym(asmTmpPageFaultHdr) .type Csym(asmTmpPageFaultHdr), @functionCsym(asmTmpPageFaultHdr): /* SR.BL=1, SR.RB=1, SR.I=15 */ stc.l r4_bank, @-ISP // Save register stc.l r5_bank, @-ISP stc.l r6_bank, @-ISP mov.l SP, @-ISP // For page fault handler only mov.l P_STACKTOP, SP // Use stack. mov.l P_EXPEVT, r7 // Obtain exception information. mov.l P_TEA, r0 ldc.l @r7+, r4_bank // r4_bank0 = EXPEVT mov.l P_MMUCR, r7 ldc.l @r0+, r5_bank // r5_bank0 = TEA ldc.l @r7+, r6_bank // r6_bank0 = MMUCR mov.l P_SR_NOBLOCK, r7 // Reset exception block. ldc r7, sr // Switch register banks. /* SR.BL=0, SR.RB=0, SR.I=15 */ mov.l r0, @-SP // Restore register mov.l r1, @-SP mov.l r2, @-SP mov.l r3, @-SP mov.l r7, @-SP sts.l mach, @-SP sts.l macl, @-SP sts.l pr, @-SP mov.l P_TMPHDR, r0 jsr @r0 // call TmpPageFaultHdr(EXPEVT,TEA,MMUCR) nop lds.l @SP+, pr // Restore register lds.l @SP+, macl lds.l @SP+, mach mov.l @SP+, r7 mov.l @SP+, r3 mov.l @SP+, r2 mov.l @SP+, r1 mov.l @SP+, r0 mov.l P_SR_BLOCK, r4 // Exception block ldc r4, sr // Switch register banks. /* SR.BL=1, SR.RB=1, SR.I=15 */ mov.l @ISP+, SP // Turn back stack ldc.l @ISP+, r6_bank // Restore register ldc.l @ISP+, r5_bank ldc.l @ISP+, r4_bank INT_RETURN asmTmpPageFaultHdr /* Entry address of BMS default handler */ .comm Csym(DefaultHandlerEntry), 4, 4 .balign 4 P_STACKTOP: .long PAGEFAULTHDR_STACKTOP P_STACKLIMIT: .long pagefaulthdr_stack P_EXPEVT: .long EXPEVT P_TEA: .long TEA P_MMUCR: .long MMUCR P_DEFHDR: .long Csym(DefaultHandlerEntry) P_HDRENT: .long Csym(PageFaultHdr) P_TMPHDR: .long Csym(TmpPageFaultHdr) P_SR_NOBLOCK: .long SR_MD | SR_FD | SR_I(15) P_SR_NOBL_RB: .long SR_MD | SR_FD | SR_I(15) | SR_RB P_SR_BLOCK: .long SR_MD | SR_FD | SR_I(15) | SR_RB | SR_BL/* * TLB miss exception handler * All processing has to be performed without changing the exception block (SR.BL=1). */ .text .balign 2 .globl Csym(asmTLBMissHdr) .type Csym(asmTLBMissHdr), @functionCsym(asmTLBMissHdr): /* SR.BL=1, SR.RB=1 */ mov.l r0, @-ISP // Save work register. mov.l r8, @-ISP mov.l r9, @-ISP mov.l T_PTEH, r7 mov #-22, r0 mov.l @r7, r8 mov #10, r7 mov r8, r9 shld r0, r8 // r8 = Page directory index shld r7, r9 shld r0, r9 // r9 = Page table index mov #NUM_PDIR_ENTRIES, r0 mov.l T_TTB, r7 cmp/ge r0, r8 bf l_localspace mov.l T_SATB, r7 l_localspace: mov.l @r7, r0 // r0 = Page directory movt r7 // r7 = 1:Shared space 0:Unique space tst r0, r0 // If TTB or SATB is NULL, the address is invalid. bt l_notpresent shll2 r8 mov.l @(r0, r8), r0 mov.l T_PBIT, r8 tst r8, r0 // Check the existence of page table. bt l_notpresent mov.l T_PFAMSK, r8 and r8, r0 // r0 = Page table shll2 r9 add r0, r9 mov.l @r9, r0 // r0 = PTE mov.l T_PBIT, r8 tst r8, r0 // Check the existence of page. bt l_notpresent or #PT_Accessed, r0 mov.l r0, @r9 // Update access bit. l_loadtlb: mov.l T_TLBMSK, r8 and r8, r0 // Omit bits used by OS. shll r7 // Set shared bits. add #TLB_PageSize4K, r7 // Set page size 4KB (fixed) or r7, r0 // r0 = TLB loading value mov.l T_PTEL, r7 mov.l r0, @r7 ldtlb // Load into TLB. mov.l @ISP+, r9 // Restore work register. mov.l @ISP+, r8 mov.l @ISP+, r0 rte nop l_notpresent: mov.l @ISP+, r9 // Restore work register. mov.l @ISP+, r8 mov.l @ISP+, r0 INT_ENTER asmTLBMissHdr mov.l T_EXPEVT, r0 // Obtain exception code. mov.l @r0, r0 mov #-5, r7 shad r7, r0 shll2 r0 // Vector table index mov.l T_VECTBL, r7 // Obtain handler address. mov.l @(r0, r7), r7 tst r7, r7 // NULL means undefined. bf l_jmpexc mov.l T_DEFAULT, r7 // Default handler mov.l @r7, r7 l_jmpexc: jmp @r7 // Jump to exception handler nop // r0 = Vector index + factor (0) .balign 4 T_SATB: .long Csym(SATB) T_TTB: .long TTB T_PTEH: .long PTEH T_PTEL: .long PTEL T_PBIT: .long PT_Present T_PFAMSK: .long PT_Address T_TLBMSK: .long TLB_MASK T_EXPEVT: .long EXPEVT T_VECTBL: .long VECTBL T_DEFAULT: .long DEFAULTHDR/* * TLB exception handler for re-startup processing * TLB invalid exception (read) * TLB miss exception */ .text .balign 2 .globl Csym(warmBootTLBInvRHdr) .globl Csym(warmBootTLBMissHdr) .type Csym(warmBootTLBInvRHdr), @function .type Csym(warmBootTLBMissHdr), @functionCsym(warmBootTLBInvRHdr): mov.l @ISP+, r0 // R0 Restore ldc.l @ISP+, spc // SPC Restore ldc.l @ISP+, ssr // SSR Restore mov.l @ISP+, MDR // MDR RestoreCsym(warmBootTLBMissHdr): /* SR.BL=1, SR.RB=1 */ mov.l r0, @-ISP // Save register mov.l r8, @-ISP mov.l r9, @-ISP mov.l W_PTEH, r7 mov #-22, r0 mov.l @r7, r8 mov #10, r7 mov r8, r9 shld r0, r8 // r8 = Page directory index shld r7, r9 shld r0, r9 // r9 = Page table index mov.l W_TTB, r7 mov.l @r7, r0 // r0 = Page directory shll2 r8 mov.l @(r0, r8), r0 mov.l W_PFAMSK, r8 and r8, r0 // r0 = Page table shll2 r9 mov.l W_TLBMSK, r7 mov.l @(r0, r9), r0 // r0 = PTE and r7, r0 // Omit bits used by OS. or #TLB_PageSize4K|TLB_Share, r0 // Set shared page size. mov.l W_PTEL, r7 mov.l r0, @r7 ldtlb // Load into TLB. mov.l @ISP+, r9 mov.l @ISP+, r8 mov.l @ISP+, r0 rte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -