⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 startup.s

📁 WinCE5.0部分核心源码
💻 S
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//      TITLE("Kernel Initialization")
//------------------------------------------------------------------------------
//
//
// Module Name:
//
//    startup.s
//
// Abstract:
//
//    This module implements the code necessary to initialize the Kernel to
// run on an R4000 series processor.
//
//
// Environment:
//
//    Kernel mode only.
//
//------------------------------------------------------------------------------

#include "ksmips.h"
#include "nkintr.h"
#include "kpage.h"
#include "mem_mips.h"

#define jalfix(func)    \
        jal func;   \
        nop;

#if 0   // PERP
#define LIGHTS(t0, t1, value)   \
        lui     t0, 0xaa00; \
        li      t1, value;  \
        sw      t1, 0x1010(t0);
#endif

#if 0
#define LIGHTS(t0, t1, value)   \
        lui     t0, 0xb040; \
        lh  t1, 2(t0);  \
        and t1, 0xff;   \
        or  t1, value<<8;   \
        sh      t1, 2(t0);
#endif

#ifndef LIGHTS
#define LIGHTS(t0, t1, value)
#endif

//------------------------------------------------------------------------------
// KPAGE : allocate RAM space for the KDATA section (mapped to high address)
//------------------------------------------------------------------------------
        .data   .KDATA
        .globl  KPAGE_VIRT            
KPAGE_VIRT: .space KPAGE_LENGTH
    
    
        .text

//
// the following 4 variables can be updated by OEM using FIXUPVAR in config.bib
// to tell us what the CPU type is and we'll by-pass CPU type detection if the 
// value changed. 
//      fNKMIPS16Sup - set to 1 if the CPU support MIPS16 instructions, 0 if not
//      fNKTinyPageSup - set to 1 if the CPU support tiny pages (e.g. R41XX processors), 0 if not
//      fNKHasFPU - set to 1 if the FPU exist, 0 if not
//      fNKExHandlerNeedNops - set to 1 if need to insert 2-nop at the beginning of exception handler
//
// we'll try our best to detect the CPU types if the values are left unchanged (-1).
//
// NOTE: you MUST change all 4 if you need to change any of them.
//
        .globl  fNKMIPS16Sup
        .globl  fNKTinyPageSup
        .globl  fNKHasFPU
        .globl  fNKExHandlerNeedNops

fNKMIPS16Sup:           .word -1
fNKTinyPageSup:         .word -1
fNKHasFPU:              .word -1
fNKExHandlerNeedNops:   .word -1

// legacy MIPSII
#define PRID_R41XX      0x0C00                  // bit 8-15 of prid == 0xC
#define R41XX_M16SUP    0x00100000              // bit 20 of config on R41XX indicate MIPS16 support

// MIPS32/MIPS64
#define CFG1_MIPS16     0x4                     // bit 2 of config1 indicate MIPS16 support
#define CFG1_FPU        0x1                     // bit 0 of config1 indicate FPU

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LEAF_ENTRY(KernelStart)
        .set noreorder

        mtc0    zero, cause             // Clear interrupts
        mtc0    zero, entryhi           // Clear asid
        mtc0    zero, context           // clear the context register
        mtc0    zero, entrylo0          
        mtc0    zero, entrylo1          
        mtc0    zero, pagemask          
        mtc0    zero, count             // clear count (time since restart)

        move    k0, zero
        move    k1, zero

        lw      s0, fNKMIPS16Sup
        lw      s1, fNKTinyPageSup
        lw      s2, fNKHasFPU
        lw      s6, fNKExHandlerNeedNops

        li      t0, -1
        bne     t0, s0, 3f              // don't bother detect if value changed
        nop

        // try to figure out the information from config+procid registers
        move    s0, zero                // default no MIPS16 support
        move    s1, zero                // default not tiny page support
        move    s2, zero                // default no FPU
        move    s6, zero                // default don't need to add no-op for exception handler

        mfc0    t0, config              // (t0) = config register
        nop                             // 1 cycle hazard??

        bltz    t0, 2f                  // bit 31 config indicate if config1 register exist
        nop
        
        // bit 31 is 0, legacy MIPSII CPUs
        mfc0    t2, prid                // t2 = prid
        nop                             // 1 cycle hazard??
        
        andi    t2, t2, 0xff00          // bit [8-15] is the processor family
        li      t1, PRID_R41XX          // (t1) = prid of R41XX family (0xc00)
        
        bne     t2, t1, 3f              // use default if not R41XX
        nop

        // R41XX (t0) == config register
        li      s1, 1                   // support tiny page
        move    s6, s1                  // need to insert no-op for exception handler
        li      t1, R41XX_M16SUP        // MIPS16 support is bit 20 of config register on R41XX
        j       3f
        and     s0, t0, t1              // (delay slot) s0 == support MIPS16

2:
        // MIPS32/MIPS64
        //mfc0    t0, config, 1         // read config1 register
        .word	0x40088001              // encoding for MIPS32 instruction "mfc0 t0, config, 1"
        
        andi    s0, t0, CFG1_MIPS16     // (s0) = support MIPS16?
        andi    s2, t0, CFG1_FPU        // (s2) = has FPU?

3:
        //
        //      (s0) - non-zero if support MIPS16
        //      (s1) - non-zero if support tiny page (R41XX)
        //      (s2) - non-zero if support FPU  (might not be needed since we can detect FPU by try-except
        //      (s6) - non-zero if need to insert no-op at the beginning of exception handler
        //

        // CPU with tiny page support need a different pagemask
        beqz    s1, 4f
        li      s3, PFN_SHIFT_MIPS32    // (delay slot) (s3) = default PFN_SHIFT

        // tiny page support
        li      t0, 0x1800              // page mask for 4K pagesize on R4100
        li      s3, PFN_SHIFT_R41XX     // PFN_SHIFT is different with tiny page support
        mtc0    t0, pagemask

4:
        // (s3) = PFN_SHIFT
        li      s4, PAGE_SIZE           // (s4) = PAGE_SIZE
        srlv    s4, s4, s3              // (s4) = (PAGE_SIZE >> PFN_SHIFT) == PFN_INCR

        la      t3, KPAGE_VIRT
        li      t1, 0xA0000000
        or      t3, t3, t1
        
        li      t1, PFN_MASK
        and     t4, t3, t1              // (t4) = (KPAGE_VIRT | 0xa0000000) & PFN_MASK
        srlv    t4, t4, s3              // (t4) >>= PFN_SHIFT
        // t3 = virtual uncached KPAGE base
        // t4 = PFN of KPAGE_BASE
        
        //
        // Zero out kernel data page.
        //
        move    t0, t3
        li      t1, KPAGE_LENGTH
8:      sw      zero, (t0)
        subu    t1, 4
        bgtz    t1, 8b
        addiu   t0, 4

        LIGHTS(t0,t1, 0xCC)
        //
        // Initialize SectionTable in KPage
        //
        addi    t0, t3, (SectionTable-KData)
        li      t1, SECTION_MASK+1
        la      t2, NullSection
9:      sw      t2, (t0)
        subu    t1, 1
        bgtz    t1, 9b
        addiu   t0, 4
        //
        // Initialize the interrupt dispatch tables
        //
        addi    t0, t3, (FalseInt-KData)
        la      t1, FalseInterrupt
        sw      t1, (t0)
        la      t1, DisabledInterruptHandler
        sw      t1, 4(t0)
        sw      t1, 8(t0)
        sw      t1, 12(t0)
        sw      t1, 16(t0)
        sw      t1, 20(t0)
        sw      t1, 24(t0)
    
        //
        // Load temp stack pointer & global pointer.
        //
        addi    sp, t3, (KStack-KData)
        li      gp, 0
        li      t1, 0x80000000
        sw      t1, HandleBase-KData(t3)
        la      t1, APICallReturn
        sw      t1, PtrAPIRet-KData(t3)
        
        LIGHTS(t0,t1, 0xF0)

        //  Initialize address translation hardware.
        li      v0, 0x80000000          // Unmapped address
        lw      v1, OEMTLBSize          // (v1) = index & loop counter
10:     mtc0    zero, entrylo0          // Clear entrylo0 - Invalid entry
        mtc0    zero, entrylo1          // Clear entrylo1 - Invalid entry
        mtc0    v0, entryhi             // Clear entryhi - Ivalid address
        mtc0    v1, index               // Set index
        add     v0, 0x2000
        ssnop                           // super scalar core requires 4 integer instructions
        ssnop                           // to guarantee a 2 cycle hazard
        ssnop
        tlbwi                           // Write entry (indexed)
        addiu   v1, v1, -1              // Decrement index, loop counter
        bgez    v1, 10b                 // If not done (<0) do next one
        nop
        //
        // Initialize wired TLB entries as follows:
        //  0: virtual 0x00005000 to the kernel's data page (read-only)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -