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

📄 shexcept.src

📁 WinCE5.0部分核心源码
💻 SRC
📖 第 1 页 / 共 5 页
字号:
;
; 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.
;
        .HEADING "SH3 Interrupt and Exception Processing"
;++
;
;
; Module Name:
;
;    shexcept.src
;
; Abstract:
;
;    This module implements the code necessary to field and process SH3
;    interrupt and exception conditions.
;
;    WARNING: This module executes in KSEG0 and, in general, cannot
;       tolerate a TLB Miss. Registers k0 and k1 are used during initial
;       interrupt and exception processing, and therefore, extreme care must
;       be exercised when modifying this module.
;
; Revision History:
;
;--

        .list OFF
        .include "ksshx.h"
        .list ON

VALIDATE_CACHE: .equ 0                  ; set to force cache validation.
INTRLOCK_LEDS: .equ 0

PERFORMCALLBACK:        .equ   -113
RAISEEXCEPTION:         .equ   -114
CALLEE_SAVED_REGS:      .equ    32      ; (7 registers)  {r8-r14}, add 1 to make 8 byte alignment)

; must match the value in kernel.h
SECURESTK_RESERVE:      .equ    48      ; SIZE_PRETLS + 16
MAX_PSL_ARGS:           .equ    56

SECURE_SECTION:         .equ    h'61

SHARED_SLOT_BASE:       .equ    h'7c000000      ; shared section
SLOT_MASK:              .equ    h'fe000000      ; mask of the top 7 bits
READONLY_MASK           .equ    h'ffffffdf      ; == ~0x20 (mask to clear write bit)

; must match the value in celog.h
CELOGSTATUS_ENABLED_GENERAL   .equ    h'20000000



API_MAX: .equ   FIRST_METHOD - (h'3fff * 2)


        .import _DumpFrame
        .import _HandleException
        .import _KernelInit
        .import _NextThread
        .import _KCNextThread
        .import _RunList
        .import _SleepList
        .import _ObjectCall
        .import _ServerCallReturn
        .import _CallbackReturn
        .import _PerformCallBackExt
        .import _SH3Init
        .import _ExceptionDispatch
        .import OEMNMI
        .import _OEMIdle
        .import _SetBadHandleError
        .import _NKSection
        .import _NKCallIntChainWrapped
  .aif SH_CPU eq h'40
        .import _dwStoreQueueBase
        .import _SH4CacheLines
  .aelse
        .import _SH3CacheLines
  .aendi
  .aif NKPROF eq h'01
        .import _CeLogInterrupt
        .import _dwCeLogTLBMiss
  .aendi
        .import _CeLogThreadMigrate

        ;; for ISR hook
        .import _pfnOEMIntrOccurs

        .PAGE
        .section .data,data
        .align  4
        .export _InterruptTable
        .export ExceptionTable
ExceptionTable:
        .data.l _UnusedHandler          ; 0x000 power-on reset (intr resched)
        .data.l _UnusedHandler          ; 0x020 manual restart
        .data.l _UnusedHandler          ; 0x040 TLB miss load
        .data.l _UnusedHandler          ; 0x060 TLB miss store
        .data.l _UnusedHandler          ; 0x080 initial page write
        .data.l _UnusedHandler          ; 0x0A0 TLB protection violation (load)
        .data.l _UnusedHandler          ; 0x0c0 TLB protection violation (store)
        .data.l _UnusedHandler          ; 0x0e0 address error (load)
        .data.l _UnusedHandler          ; 0x100 address error (store)
        .data.l _UnusedHandler          ; 0x120 reserved
        .data.l _UnusedHandler          ; 0x140 reserved
        .data.l _UnusedHandler          ; 0x160 TRAPA instruction
        .data.l _UnusedHandler          ; 0x180 reserved instruction
        .data.l _UnusedHandler          ; 0x1A0 invalid delay slot instruction
        .data.l OEMNMI                          ; 0x1C0 NMI (general interrupt request)
        .data.l _UnusedHandler          ; 0x1E0 user breakpoint (HW breakpoints)
_InterruptTable:
        .arepeat 112                            ; 0x200-0xfe0 HW interrupts
        .data.l _UnusedHandler
        .aendr
  .aif SH_CPU eq h'40
_bEnableRAMMode:
        .res.l 1
;--------- Work around for SH4 sleep problem. ----------------------------------
fInIdle:
        .data.l 0
  .aendi
        
 .export _IntrPrio
	.data.b 0xf,0xf,0xf,0xf
_IntrPrio:
        .data.b 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 ; 0x200-0x3e0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0x400-0x5e0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0x600-0x7e0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0x800-0x9e0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0xa00-0xbe0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0xc00-0xde0
        .data.b 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1 ; 0xe00-0xfe0

        .section .KDATA,stack
        .export _KDBase
        .export _KStack
_KDBase: .res.b h'1000  ; reserve an extra page for the debugger
         .res.b h'7e0
_KStack: .res.l 8
        .export _KData
_KData: .res.b  cMsec
        .export _CurMSec
_CurMSec: .res.b h'400 - cMsec

        .section .text,code,align=16

KPAGE_PTEL: .equ _KData + h'14a ; user read-only, 1k, cachable, !dirty, shared, valid

   .aif SH_CPU eq h'40

PR_B1_BK: .equ h'70008000       ; privileged mode, bank 1, exceptions blocked
PR_B0_IE: .equ h'40008000       ; privileged mode, bank 0, un-blocked, intr unmasked
PR_B0_IM: .equ h'400080f0       ; privileged mode, bank 0, un-blocked, intr masked
PR_B0_BK: .equ h'50008000       ; privileged mode, bank 0, exceptions blocked

        .aelse

PR_B1_BK: .equ h'70000000       ; privileged mode, bank 1, exceptions blocked
PR_B0_IE: .equ h'40000000       ; privileged mode, bank 0, un-blocked, intr unmasked
PR_B0_IM: .equ h'400000f0       ; privileged mode, bank 0, un-blocked, intr masked
PR_B0_BK: .equ h'50000000       ; privileged mode, bank 0, exceptions blocked

        .aendi

        START_REGION    ExceptionBase   ; base to load into VBR

        LEAF_ENTRY _DebugBreak
        trapa   #1
        rts
        nop
        .endf

        LEAF_ENTRY _INTERRUPTS_ON
        mov     #h'ffffff0f, r1
        stc     SR, r0
        and     r1, r0
        ldc     r0, SR
        rts
        nop
        .endf

        LEAF_ENTRY _INTERRUPTS_OFF
        stc     SR, r0
        or      #h'f0, r0
        ldc     r0, SR
        rts
        nop
        .endf   

        .align  4
        .export _PtrCurMSec
_PtrCurMSec: .data.l _CurMSec


; SetCPUASID - set address space id
;
;   SetCPUASID updates the MMU control registers and kernel page info
; when a thread's current process or access key is changed.
;
;       Entry   (r4) = ptr to thread
;       Return  nothing
;       Uses    r0, r1, r2, r3, r7

        LEAF_ENTRY _SetCPUASID

        ;------ CeLogThreadMigrate ------
        ;
        ; NOTE : To make things relatively consistent, I'm going to make
        ; the registers R0-R3, R6 available for use. On entry to
        ; CELOG_ThreadMigrateSHx R0 will contain the handle of the process.
        ;
        ; I'm assuming that at this point the only registers that I need to
        ; preserve are R4 (ptr to thread) and PR (return address)
        ;

        mov     #_KData+CeLogStatus, r0 ; (r0) = &KInfoTable[KINX_CELOGSTATUS]
        mov     @r0, r0                 ; (r0) = KInfoTable[KINX_CELOGSTATUS]
        mov     #CELOGSTATUS_ENABLED_GENERAL, r1  ; (r1) = CELOGSTATUS_ENABLED_GENERAL
        and     r1, r0                  ; mask off KInfoTable entry with flag
        tst     r0, r0                  ; if !IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)
        bt/s    celog10                 ; then skip CeLog call
        nop

        mov.l   @(ThProc,r4), r0        ; (r0) = ptr to current process
        mov     @(PrcHandle,r0), r0     ; (r0) = handle of current process
        mov     #_KData+hCurProc, r1    ; (r1) = &hCurProc
        mov     @r1, r1                 ; (r1) = old process handle
        cmp/eq  r0, r1                  ; if new process == old process
        bt/s    celog10                 ; then skip CeLog call
        nop

        sts     pr, @-r15               ; Save current return address
        mov.l   r4, @-r15               ; Save register

        mov.l   @(ThProc,r4), r5        ; (r5) = ptr to current process
        mov     @(PrcHandle,r5), r4     ; (r4) = handle of current process

        mov     #_CeLogThreadMigrate, r2
        mov     #1, r5                  ; (r5) = 1
        jsr     @r2                     ; CELOG_ThreadMigrateSHx(hProc)
        add.l   #-16,  r15              ; (delay slot) room for 4 arguments, C calling convention

        add.l   #16,   r15              ; restore sp
        mov.l   @r15+, r4               ; Restore register
        lds     @r15+, pr               ; Restore return address

celog10:
        ;---- End CeLogThreadMigrate ----

        mov.l   @(ThProc,r4), r1        ; (r1) = ptr to current process
        mov     #_KData+hCurProc, r0    ; (r0) = &hCurProc
        mov     @(PrcHandle,r1), r7     ; (r7) = handle of current process
        mov     r7, @r0                 ; set current process handle
        add     #bResched-hCurProc, r0  ; (r0) = &bResched
        mov.l   r1, @(pCurPrc-bResched,r0)      ; set current process pointer      |
        mov.l   @(PrcVMBase,r1), r3     ; (r3) = memory section base address       |
        mov     #SH3CTL_BASE, r7        ;                                          |
        ERRNZ PrcID                     ;                                          |
        mov.b   @r1, r1                 ; (r1) = process ID                        |
        mov     #_NKSection, r2         ; (r2) = process section, default to NKSection
        
        tst     r1, r1                  ; is it NK?
        bt/s    ContinueSetASID         ; just use NKSection if it is 
        add     #aSections-bResched, r0 ; (r0) = ptr to SectionTable (delay slot)  |

        ; not NK, find the process VM section
        ; (r3) = pCurProc->dwVMBase
        mov     #2-VA_SECTION, r2       ; (r2) = right shift count
        shld    r2, r3                  ; (r3) = section index * 4                 |
        mov.l   @(r0,r3), r2            ; (r2) = process's memory section          |

ContinueSetASID:
        ;
        ;       (r1) = procid
        ;       (r2) = SectionTable of pCurProc (NKSection if it's NK)
        ;
        mov.l   r1, @(MMUPTEH,r7)       ; set ASID                                 |
        rts
        mov.l   r2, @r0                 ; swap in default process slot
        .endf

        LEAF_ENTRY _SetCPUGlobals
        mov #_KData+pCurThd, r0
        mov @r0, r0
        ldc     r0, r4_bank
        rts
        nop
        .endf

        .PAGE
        LEAF_ENTRY KernelStart
;* Inititalize Status register:
;       Kernel mode,
;       exceptions blocked,
;       register bank 1
        mov     #PR_B1_BK, r0
        ldc     r0, SR                  ; (SR) = kmode, blocked, bank1
        mov     #h'A0000000, r2         ; (r2) = un-cached, un-mapped region base
        mov     #_SH3Init, r1
        mov     #_KStack, r15
        or      r2, r15                 ; (r15) = un-cached stack
        or      r2, r1                  ; (r1) = un-cached destination

        mov     #SH_CPU, r4             ; (r4) = processor type
        jsr     @r1                     ; perform general SH3 initialization
        nop

; Switch stack to cached, un-mapped region.
        mov     #_KStack, r15           ; switch to normal kernel stack

; Load new status register with:
;       kernel mode,
;       excpetions enabled,
;       register bank 0,
;       interrupts un-masked.

        mov     #SH3CTL_BASE, r7        ; (r7_priv) = ptr to SH3 control registers
        mov     #ExceptionBase, r3      ; (r3) = kernel exception handlers
        ldc     r3, VBR                 ; switch to kernel's exception handlers
        mov     #PR_B0_IE, r1
        mov     #_KernelInit, r8
        ldc     r1, SR                  ; (SR) = privileged, bank 0, unblocked
        jsr     @r8
        nop
        bra     resched
        mov     #0, r14                 ; no current thread
        .endf

        .PAGE
        
;
; APICall is the starting of SHx general exception handlers.  It will
; never be invoked directly but indirectly.  All SHx general exceptions 
; except TLBMiss exceptions will be forwarded to the handler defined in 
; the address computed from the sum of VBR, which stores the exception 
; handler base address, and the offset 0x100.  This is exactly where 
; APICall starts as you see ".org	h'100" in the following lines:
;
        LEAF_ENTRY APICall
        
        .PAGE
        
; Bank 1 registers are pre-loaded with the following values:
;
;       (r4) - ptr to current thread
;       (r5) - ptr to context save area
;       (r7) - SH3CTL_BASE (used to access MMU & exception data)

        .org    h'100
; Please note that at this point, SPC will contain the saved PC so does SSR 
; to the saved SR.  Also SR.MD will be set to the previledge mode, SR.BL will 
; be set to disable interrupt, and SR.BR will be set to Bank 1 mode.  Thus 
; a handful of general registers, [r1..r7][_bank1], will be freely available 
; to exception handler right away while [r1..r7][_bank0|_user] will be kept 
; around but only access through LDC instruction. 
;
        mov     @(EXPEVT,r7), r0        ; (r0) = exception code

⌨️ 快捷键说明

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