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 + -
显示快捷键?