root/arch/mips/kernel/magnum4000.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  * arch/mips/kernel/magnum4000.S
   3  *
   4  * Copyright (C) 1995 Waldorf Electronics
   5  * written by Ralf Baechle and Andreas Busse
   6  */
   7 #include <asm/asm.h>
   8 #include <asm/mipsregs.h>
   9 #include <asm/jazz.h>
  10 #include <asm/stackframe.h>
  11 
  12 /*
  13  * mips_magnum_4000_handle_int: Interrupt handler for Mips Magnum 4000 
  14  */
  15                 .set    noreorder
  16 
  17                 NESTED(mips_magnum_4000_handle_int, FR_SIZE, ra)
  18                 .set    noat
  19                 SAVE_ALL
  20                 CLI
  21                 .set    at
  22 
  23                 /*
  24                  * Get pending interrupts
  25                  */
  26                 mfc0    t0,CP0_CAUSE            # get pending interrupts
  27                 mfc0    t1,CP0_STATUS           # get enabled interrupts
  28                 and     t0,t1                   # isolate allowed ones
  29                 andi    t0,0xff00               # isolate pending bits
  30                 beqz    t0,spurious_interrupt
  31                 sll     t0,16                   # delay slot
  32 
  33                 /*
  34                  * Find irq with highest priority
  35                  * FIXME: This is slow
  36                  */
  37                 la      t1,ll_vectors
  38 1:              bltz    t0,2f                   # found pending irq
  39                 sll     t0,1
  40                 b       1b
  41                 subu    t1,PTRSIZE              # delay slot
  42 
  43                 /*
  44                  * Do the low-level stuff
  45                  */
  46 2:              lw      t0,(t1)
  47                 jr      t0
  48                 nop                             # delay slot
  49                 END(mips_magnum_4000_handle_int)
  50 
  51 /*
  52  * Used for keyboard driver's fake_keyboard_interrupt()
  53  */
  54 ll_sw0:         li      s1,~IE_SW0
  55                 mfc0    t0,CP0_CAUSE
  56                 and     t0,s1
  57                 mtc0    t0,CP0_CAUSE
  58         PRINT("sw0 received...\n")
  59                 li      t1,1
  60                 b       call_real
  61                 li      t3,PTRSIZE      # delay slot, re-map to irq level 1
  62 
  63 ll_sw1:         li      s1,~IE_SW1
  64                 PANIC("Unimplemented sw1 handler")
  65 
  66 ll_local_dma:   li      s1,~IE_IRQ0
  67                 PANIC("Unimplemented local_dma handler")
  68 
  69 ll_local_dev:   lbu     t0,JAZZ_IO_IRQ_SOURCE
  70 #if __mips == 3
  71                 dsll    t0,1
  72                 ld      t0,local_vector(t0)
  73 #else /* 32 bit */
  74                 lw      t0,local_vector(t0)
  75 #endif
  76                 jr      t0
  77                 nop
  78 
  79 
  80 loc_no_irq:     PANIC("Unimplemented loc_no_irq handler")
  81 loc_sound:      PANIC("Unimplemented loc_sound handler")
  82 loc_video:      PANIC("Unimplemented loc_video handler")
  83 loc_scsi:       PANIC("Unimplemented loc_scsi handler")
  84 
  85 /*
  86  * Keyboard interrupt handler
  87  */
  88 loc_keyboard:   li      s1,~JAZZ_IE_KEYBOARD
  89                 li      t1,JAZZ_KEYBOARD_IRQ
  90                 b       loc_call
  91                 li      t3,PTRSIZE*JAZZ_KEYBOARD_IRQ    # delay slot
  92 
  93 /*
  94  * Ethernet interrupt handler, remapped to level 2
  95  */
  96 loc_ethernet: /*        PRINT ("ethernet IRQ\n"); */
  97                 li      s1,~JAZZ_IE_ETHERNET
  98                 li      t1,JAZZ_ETHERNET_IRQ
  99                 b       loc_call
 100                 li      t3,PTRSIZE*JAZZ_ETHERNET_IRQ    # delay slot
 101 
 102 
 103 loc_mouse:      PANIC("Unimplemented loc_mouse handler")
 104 
 105 /*
 106  * Serial port 1 IRQ, remapped to level 3
 107  */
 108 loc_serial1:    li      s1,~JAZZ_IE_SERIAL1
 109                 li      t1,JAZZ_SERIAL1_IRQ
 110                 b       loc_call
 111                 li      t3,PTRSIZE*JAZZ_SERIAL1_IRQ     # delay slot
 112 
 113 /*
 114  * Serial port 2 IRQ, remapped to level 4
 115  */
 116 loc_serial2:    li      s1,~JAZZ_IE_SERIAL2
 117                 li      t1,JAZZ_SERIAL2_IRQ
 118                 b       loc_call
 119                 li      t3,PTRSIZE*JAZZ_SERIAL2_IRQ     # delay slot
 120 
 121 /*
 122  * Parallel port IRQ, remapped to level 5
 123  */
 124 loc_parallel:   li      s1,~JAZZ_IE_PARALLEL
 125                 li      t1,JAZZ_PARALLEL_IRQ
 126                 b       loc_call
 127                 li      t3,PTRSIZE*JAZZ_PARALLEL_IRQ    # delay slot
 128 
 129 /*
 130  * Floppy IRQ, remapped to level 6
 131  */
 132 loc_floppy:     li      s1,~JAZZ_IE_FLOPPY
 133                 li      t1,JAZZ_FLOPPY_IRQ
 134                 b       loc_call
 135                 li      t3,PTRSIZE*JAZZ_FLOPPY_IRQ      # delay slot
 136 
 137 /*
 138  * Now call the real handler
 139  */
 140 loc_call:       lui     s3,%hi(intr_count)
 141                 lw      t2,%lo(intr_count)(s3)
 142                 la      t0,IRQ_vectors                  # delay slot
 143                 addiu   t2,1
 144                 sw      t2,%lo(intr_count)(s3)
 145 
 146                 /*
 147                  * Temporarily disable interrupt source
 148                  */
 149                 lhu     t2,JAZZ_IO_IRQ_ENABLE
 150                 addu    t0,t3                           # make ptr to IRQ handler
 151                 lw      t0,(t0)
 152                 and     t2,s1                           # delay slot
 153                 sh      t2,JAZZ_IO_IRQ_ENABLE
 154                 jalr    t0                              # call IRQ handler
 155                 nor     s1,zero,s1                      # delay slot
 156 
 157                 /*
 158                  * Reenable interrupt
 159                  */
 160                 lhu     t2,JAZZ_IO_IRQ_ENABLE
 161                 lw      t1,%lo(intr_count)(s3)          # delay slot
 162                 or      t2,s1
 163                 sh      t2,JAZZ_IO_IRQ_ENABLE
 164 
 165                 subu    t1,1
 166                 jr      v0
 167                 sw      t1,%lo(intr_count)(s3)
 168 
 169 ll_eisa_irq:    li      s1,~IE_IRQ2
 170                 PANIC("Unimplemented eisa_irq handler")
 171 
 172 ll_eisa_nmi:    li      s1,~IE_IRQ3
 173                 PANIC("Unimplemented eisa_nmi handler")
 174 
 175 /*
 176  * Timer IRQ
 177  * We remap the timer irq to be more similar to a IBM compatible
 178  */
 179 ll_timer:       lw      t0,JAZZ_TIMER_REGISTER # timer irq cleared on read
 180                 li      s1,~IE_IRQ4
 181                 li      t1,0
 182                 b       call_real
 183                 li      t3,0            # delay slot, re-map to irq level 0
 184 
 185 /*
 186  * CPU count/compare IRQ (unused)
 187  */
 188 ll_count:       j       return
 189                 mtc0    zero,CP0_COMPARE
 190 
 191 /*
 192  * Now call the real handler
 193  */
 194 call_real:      lui     s3,%hi(intr_count)
 195                 lw      t2,%lo(intr_count)(s3)
 196                 la      t0,IRQ_vectors                  # delay slot
 197                 addiu   t2,1
 198                 sw      t2,%lo(intr_count)(s3)
 199 
 200                 /*
 201                  * temporarily disable interrupt
 202                  */
 203                 mfc0    t2,CP0_STATUS
 204                 and     t2,s1
 205 
 206                 addu    t0,t3
 207                 lw      t0,(t0)
 208                 mtc0    t2,CP0_STATUS           # delay slot
 209                 jalr    t0
 210                 nor     s1,zero,s1              # delay slot
 211 
 212                 /*
 213                  * reenable interrupt
 214                  */
 215                 mfc0    t2,CP0_STATUS
 216                 or      t2,s1
 217                 mtc0    t2,CP0_STATUS
 218 
 219                 lw      t2,%lo(intr_count)(s3)
 220                 subu    t2,1
 221 
 222                 jr      v0
 223                 sw      t2,%lo(intr_count)(s3)
 224 
 225 /*
 226  * Just for debugging...
 227  */
 228                 LEAF(drawline)
 229                 li      t1,0xffffffff
 230                 li      t2,0x100
 231 1:              sw      t1,(a0)
 232                 addiu   a0,a0,4
 233                 addiu   t2,t2,-1
 234                 bnez    t2,1b
 235                 nop
 236                 jr      ra
 237                 nop
 238                 END(drawline)
 239 
 240 
 241                 .data
 242                 PTR     ll_sw0                  # SW0
 243                 PTR     ll_sw1                  # SW1
 244                 PTR     ll_local_dma            # Local DMA
 245                 PTR     ll_local_dev            # Local devices
 246                 PTR     ll_eisa_irq             # EISA IRQ
 247                 PTR     ll_eisa_nmi             # EISA NMI
 248                 PTR     ll_timer                # Timer
 249 ll_vectors:     PTR     ll_count                # Count/Compare IRQ
 250 
 251 local_vector:   PTR     loc_no_irq
 252                 PTR     loc_parallel
 253                 PTR     loc_floppy
 254                 PTR     loc_sound
 255                 PTR     loc_video
 256                 PTR     loc_ethernet
 257                 PTR     loc_scsi
 258                 PTR     loc_keyboard
 259                 PTR     loc_mouse
 260                 PTR     loc_serial1
 261                 PTR     loc_serial2
 262 
 263                 .align  5
 264 LEAF(spurious_interrupt)
 265                 /*
 266                  * Nothing happened... (whistle)
 267                  */
 268                 lui     t1,%hi(spurious_count)
 269                 lw      t0,%lo(spurious_count)(t1)
 270                 la      v0,return
 271                 addiu   t0,1
 272                 jr      ra
 273                 sw      t0,%lo(spurious_count)(t1)
 274                 END(spurious_interrupt)
 275 

/* [previous][next][first][last][top][bottom][index][help] */