isr.s
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 384 行
S
384 行
// TITLE("ALTOONA ISR")
//++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// Copyright (c) 1995-1998 Microsoft Corporation
//
// Module Name:
//
// isr.s
//
// Abstract:
//
// This module implements the code necessary to process interrupts
//
// Author:
//
// Jun Liu (25-June-1998)
//
// Notes:
//
//
//--
#define ASSEMBLY_LANGUAGE
#include <kxmips.h>
#include <nkintr.h>
#include <oalintr.h>
#include <alt_def.h>
#include <altoona.h>
#include <vrc5074.h>
#define PIC0_VBASE 0x40 // PIC0 vector base
#define PIC1_VBASE 0x48 // PIC1 vector base
#define PIC_NS_EOI 0x20 // IRQ EOI constant
#define PIC0_PORT (PHYS_ADDR_IO_SPACE_BASE+IOBASE_PIC1)
#define PIC0_MASK (PHYS_ADDR_IO_SPACE_BASE+IOBASE_PIC1+1)
#define PIC1_PORT (PHYS_ADDR_IO_SPACE_BASE+IOBASE_PIC2)
#define PIC1_MASK (PHYS_ADDR_IO_SPACE_BASE+IOBASE_PIC2+1)
#define INTCTRL (VRC5074_BASE+0x0088)
#define INTSTAT0 (VRC5074_BASE+0x0090)
#define INTSTAT1 (VRC5074_BASE+0x0098)
#define PCIINIT1 (VRC5074_BASE+0x00f8)
//
// a0 contains LED value
//
LEAF_ENTRY(ShowLED)
.set noreorder
li a3, LED_BASE + KSEG1_BASE
sb a0, 0(a3)
Forever:
nop
j Forever
nop
.end ShowLED
///////////////////////////////////////////////////////////////////////////
//
// ALTOONA interrupt service routine.
//
// Registers: v0, AT, a0-a3 available for use.
//
// Entry (a0) = (hw interrupt #)
// (a1) = ptr to apvIntrData array
// Exit (v0) = interrupt dispostion information
// Uses v0, a0-a3, AT
//
//
///////////////////////////////////////////////////////////////////////////
LEAF_ENTRY(AltoonaISR)
.set noreorder
.set noat
ALTERNATE_ENTRY(Intr0ISR)
li a0, INTSTAT0 | KSEG1_BASE // Get INTSTAT0 address
b IDispatcher
lw a0, 0(a0) // Read INSTAT0 low
ALTERNATE_ENTRY(Intr1ISR)
li a0, INTSTAT0 | KSEG1_BASE // Get INTSTAT0 address
lw a0, 0(a0) // Read INSTAT0 low
b IDispatcher
srl a0, a0, 16 // Place status at lowest 16 bit
ALTERNATE_ENTRY(Intr2ISR)
li a0, INTSTAT0 | KSEG1_BASE // Get INTSTAT0 address
b IDispatcher
lw a0, 4(a0) // Read INSTAT0 high
ALTERNATE_ENTRY(Intr3ISR)
li a0, INTSTAT0 | KSEG1_BASE // Get INTSTAT0 address
lw a0, 4(a0) // Read INSTAT0 high
b IDispatcher
srl a0, a0, 16 // Place status at lowest 16 bit
ALTERNATE_ENTRY(Intr4ISR)
li a0, INTSTAT1 | KSEG1_BASE // Get INTSTAT1 address
lw a0, 0(a0) // Read INSTAT1 low
/////////////////////////////////////////////////////////////////////////////////
// System level interrupt dispatcher
//
// (a0) = low 16 bit contains the interrupt status bit
//
IDispatcher:
li a1, 0xffff
and a1, a0, a1 // Mask upper bits
addi AT,a1,-1
not AT,AT
and a1,a1,AT // Isolate lowest set bit
//
// (a1) = Interrupt bit to process
//
li a3, INTCTRL | KSEG1_BASE // Get interrupt control reg address
sltiu AT,a1,0x100
bne AT,zero,bit0_8
move a2,zero
srl a1,a1,8
add a2,a2,8
add a3, a3, 4 // Point a3 to INTCTRL high
bit0_8: // Bit is now in the low 8 bits
sltiu AT,a1,0x10
bne AT,zero,bit0_4
nop
srl a1,a1,4
addu a2,a2,4
bit0_4: // Bit is now in the low 4 bits
sltiu AT,a1,0x4
bne AT,zero,bit0_2
nop
srl a1,a1,2
addu a2,a2,2
bit0_2: // Bit is now in the low 2 bits
sltiu AT,a1,0x2
bne AT,zero,xbit
nop
addu a2,a2,1
xbit:
//
// (a2) = Master interrupt number
// (a3) = Corresponding INTCTRL register
//
la a0, IMAP_Aln2Sys // Get 1st master interrupt ID map
addu a0, a0, a2 // Point to the right ID
li a1, 0xff
lbu v0, MASTERINTR_VECTOR(a0) // Get interrupt ID
and v0, a1, v0
//
// See if the interrupt belongs to special interrupt group
// (v0) = Interrupt ID
//
//
li a1, SYSINTR_ISA_GROUP
beq v0, a1, ISAInterrupts
nop
//
// Mask interrupt
//
li a0, 0x8 // Initial mask pattern
sll a2, a2, 2 // Interrupt number times 4
sllv a0, a0, a2 // Compute the mask bit
lw a1, 0(a3) // Get current control register
not a0, a0 // Setup clear mask
and a0, a1, a0 // Mask the interrupt bit
sw a0, 0(a3) // Update the control register
jr ra
sync
///////////////////////////////////////////////////////////////////////////
//
// ISA Interrupts
//
ISAInterrupts:
li a0, PCIINIT1 | KSEG1_BASE // Get address of the PCIINIT1 reg
lw a2, 0(a0) // Save current PCIINIT1 low
lw a3, 4(a0) // Save current PCIINIT1 high
li a1, PCIINIT_TYPE_INTACK | PCIINIT_ACCESS_32
sw zero, 4(a0)
sw a1, 0(a0) // Setup PCI access window for int ACK
li v0, PCI_INTACK_BASE | KSEG1_BASE
lbu a1, 0(v0) // Read interrupt vector... (a1) = ISR Interrupt Vector
sw a2, 0(a0) // Restore old PCIINIT1 low
//
// (a1) = ISR interrupt vector
//
addiu a2, a1, -PIC1_VBASE
bgez a2, PIC1Intr
sw a3, 4(a0) // Restore old PCIINIT1 high
PIC0Intr:
addiu a1, a2, PIC1_VBASE-PIC0_VBASE // Compute IRQ number
la a0, IRQJumpTable0 // Get jump table base
sll a1, a1, 4 // Setup jump offset
addu a0, a1, a0 // Compute the jump address
li v0, PIC0_MASK | KSEG1_BASE // Get PIC0 mask address
la a2, IMAP_Aln2Sys
jr a0 // Jump to IRQ handler
lbu a3, 0(v0) // Rettrieve current mask
IRQJumpTable0:
ori a3, a3, 0x01 // Setup new mask
addi a2, a2, 0 // IRQ0
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x02 // Setup new mask
addi a2, a2, 1 // IRQ1
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x04 // Setup new mask
addi a2, a2, 2 // IRQ2
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x08 // Setup new mask
addi a2, a2, 3 // IRQ3
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x10 // Setup new mask
addi a2, a2, 4 // IRQ4
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x20 // Setup new mask
addi a2, a2, 5 // IRQ5
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x40 // Setup new mask
addi a2, a2, 6 // IRQ6
b EndOfPIC0
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x80 // Setup new mask
addi a2, a2, 7 // IRQ7
b EndOfPIC0
sb a3, 0(v0) // Update new mask
EndOfPIC0:
li a0, PIC_NS_EOI // Get EOI constants
li a1, PIC0_PORT | KSEG1_BASE
lbu v0, ISAINTR_VECTOR(a2) // Get return interrupt ID
sb a0, 0(a1) // EOI the controller
jr ra
sync
PIC1Intr:
la a0, IRQJumpTable1 // Get jump table base
sll a1, a2, 4 // Setup jump offset
addu a0, a1, a0 // Compute the jump address
li v0, PIC1_MASK | KSEG1_BASE // Get PIC0 mask address
la a2, IMAP_Aln2Sys
jr a0 // Jump to IRQ handler
lbu a3, 0(v0) // Rettrieve current mask
IRQJumpTable1:
ori a3, a3, 0x01 // Setup new mask
addi a2, a2, 0 // IRQ8
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x02 // Setup new mask
addi a2, a2, 1 // IRQ9
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x04 // Setup new mask
addi a2, a2, 2 // IRQ10
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x08 // Setup new mask
addi a2, a2, 3 // IRQ11
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x10 // Setup new mask
addi a2, a2, 4 // IRQ12
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x20 // Setup new mask
addi a2, a2, 5 // IRQ13
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x40 // Setup new mask
addi a2, a2, 6 // IRQ14
b EndOfPIC1
sb a3, 0(v0) // Update new mask
ori a3, a3, 0x80 // Setup new mask
addi a2, a2, 7 // IRQ15
b EndOfPIC1
sb a3, 0(v0) // Update new mask
EndOfPIC1:
li a0, PIC_NS_EOI // Get EOI constants
li a1, PIC1_PORT | KSEG1_BASE
li v0,ISAINTR_VECTOR + 8
lbu v0, (ISAINTR_VECTOR+8)(a2) // Get return interrupt ID
sb a0, 0(a1) // EOI to PIC1
li a2, PIC0_PORT | KSEG1_BASE
sb a0, 0(a2) // EOI to PIC0
jr ra
sync
.set at
.set reorder
.end AltoonaISR
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?