1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * IRQ polling File: sb1250_ircpoll.S 5 * 6 * This module contains code to poll the interrupt controller 7 * and invoke the servicing of pending, unmasked interrupts. 8 * 9 ********************************************************************* 10 * 11 * Copyright 2000,2001,2002,2003 12 * Broadcom Corporation. All rights reserved. 13 * 14 * This software is furnished under license and may be used and 15 * copied only in accordance with the following terms and 16 * conditions. Subject to these conditions, you may download, 17 * copy, install, use, modify and distribute modified or unmodified 18 * copies of this software in source and/or binary form. No title 19 * or ownership is transferred hereby. 20 * 21 * 1) Any source code used, modified or distributed must reproduce 22 * and retain this copyright notice and list of conditions 23 * as they appear in the source file. 24 * 25 * 2) No right is granted to use any trade name, trademark, or 26 * logo of Broadcom Corporation. The "Broadcom Corporation" 27 * name may not be used to endorse or promote products derived 28 * from this software without the prior written permission of 29 * Broadcom Corporation. 30 * 31 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 32 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 33 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 34 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 35 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 36 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 39 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 40 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 41 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 42 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 43 * THE POSSIBILITY OF SUCH DAMAGE. 44 ********************************************************************* */ 45 46#include "sbmips.h" 47#include "cpu_config.h" 48#include "mipsmacros.h" 49#include "sb1250_regs.h" 50#include "sb1250_int.h" 51 52/* 53 * External interrupt conventions: 54 * i5 (IP7) is reserved for sources within the CPU 55 * i0 (IP2) is used for polling and always masked 56 * i1 (IP3) is used for armed interrupts that are registered (not yet) 57 * i2-i4 are available for specific devices. 58 */ 59 60/* EOIs are issued when LDT interrupts are programmed as levels. */ 61 62#define A_LDT_EOI PHYS_TO_XKPHYS_UNCACHED(0x00D8000000) 63#define D_EOI_MDT (0x7 << 2) 64 65 .text 66 67/* ********************************************************************* 68 * CFE_IRQ_POLL 69 * 70 * Scan the interrupt_source_status and interrupt_ldt registers. 71 * For those not masked by the interrupt_mask register, invoke 72 * <cpu>_dispatch_irq with the interrupt number as argument. 73 * 74 * For LDT-signaled interrupts, also clear the pending vector. 75 * 76 * For asynchronous dispatch, called with interrupts disabled. 77 * 78 * Input parameters: 79 * nothing 80 * 81 * Return value: 82 * nothing 83 ********************************************************************* */ 84 85 .set push 86 .set noreorder 87 .set noat 88 .set mips64 89 90 .extern sb1250_dispatch_irq /* NB: accessed via gp */ 91 92#if 1 93 /* This version accomodates level-triggered LDT interrupts by 94 issuing EOI's on return from each handler. In pass 1 chips, 95 EOIs are not issued correctly and will not clear a 96 level-triggered interrupt. Thus only edge-triggered mode 97 should be used in pass 1. This code depends on the fact that 98 an EOI will cause a level-sensitive interrupt to resend the 99 interrupt message if that interrupt is still pending. It is 100 not safe for edge-triggered interrupts. See below for a 101 version that avoids EOIs. */ 102 103 /* Note that and'ing the interrupt_mask and interrupt_status 104 effectively merges processing of all IP levels. Reading 105 interrupt status[n] will be a better strategy when we know n. 106 We still need to determine which bits are sourced by LDT and 107 potentially require EOIs. */ 108 109LEAF(cfe_irq_poll) 110 111 daddiu sp, -72 /* saved register space */ 112 sd s0, 32(sp) 113 sd s1, 40(sp) 114 sd s2, 48(sp) 115 sd s3, 56(sp) 116 sd ra, 64(sp) 117 118 mfc0 a0, C0_CAUSE 119 andi a0, a0, M_CAUSE_IP2 120 beqz a0, 5f 121 122 la v0, K1BASE + A_IMR_CPU0_BASE 123 ld a1, R_IMR_INTERRUPT_MASK(v0) 124 ld s0, R_IMR_INTERRUPT_SOURCE_STATUS(v0) 125 ld s2, R_IMR_LDT_INTERRUPT(v0) 126 nor a1, a1, zero /* Negate mask to turn it into an and mask */ 127 or s0, s0, s2 /* Unified pending bits */ 128 and s0, s0, a1 /* Bit vector of unmasked pending IRQs */ 129 beqz s0, 5f /* No interrupts. Return */ 130 and s2, s2, a1 /* ... and unmasked LDT IRQs */ 131 132 /* The bit scan loop */ 133 dclz s1, s0 /* Find index of the next interrupt */ 1343: 135 li s3, 1 136 dsubu s1, zero, s1 137 daddiu s1, s1, 63 138 dsllv s3, s3, s1 139 xor s0, s0, s3 /* clear current bit */ 140 la t9, sb1250_dispatch_irq 141 jalr ra, t9 /* NB: SVR4 PIC requires t9 */ 142 move a0, s1 /* a0 is interrupt number */ 143 144 and a0, s2, s3 145 beqz a0, 4f /* not LDT */ 146 dsll s1, s1, 16 147 148 /* Clear the latched bit and send EOI if a pending LDT interrupt */ 149 la v0, K1BASE + A_IMR_CPU0_BASE 150 sd s3, R_IMR_LDT_INTERRUPT_CLR(v0) 151 dla v0, A_LDT_EOI 152 or v0, v0, s1 153 sync 154 155 mfc0 s3, C0_SR 156 ori AT, s3, M_SR_KX 157 mtc0 AT, C0_SR 158 HAZARD 159 160 sw zero, D_EOI_MDT(v0) 161 162 mtc0 s3, C0_SR 163 HAZARD 164 1654: 166 bnez s0, 3b /* More interrupts to service? */ 167 dclz s1, s0 /* unroll for branch delay slot */ 1685: 169 ld ra, 64(sp) /* restore registers */ 170 ld s3, 56(sp) 171 ld s2, 48(sp) 172 ld s1, 40(sp) 173 ld s0, 32(sp) 174 175 jr ra 176 daddiu sp, 72 /* saved register space */ 177 178END(cfe_irq_poll) 179 180#else 181 /* The version for only edge-triggered LDT interrupts. */ 182 183 /* This version also shows one way of saving 64-bit registers 184 in systems that don't necessarily preserve the high 32 bits 185 across subroutine calls. That is not an issue for CFE with 186 current compilation options but is required for, e.g., 32-bit 187 Linux and NetBSD systems. */ 188 189LEAF(cfe_irq_poll) 190 191 daddiu sp, -56 /* saved register space */ 192 sd s0, 32(sp) 193 sd s1, 40(sp) 194 sd ra, 48(sp) 195 196 mfc0 a0, C0_CAUSE 197 andi a0, a0, M_CAUSE_IP2 198 beqz a0, 4f 199 200 la v0, K1BASE + A_IMR_CPU0_BASE 201 ld a1, R_IMR_INTERRUPT_MASK(v0) 202 ld s0, R_IMR_INTERRUPT_SOURCE_STATUS(v0) 203 ld s1, R_IMR_LDT_INTERRUPT(v0) 204 nor a1, a1, zero /* Negate mask to turn it into an and mask */ 205 or s0, s0, s1 /* Unified pending bits */ 206 and s0, s0, a1 /* Bit vector of unmasked pending IRQs */ 207 and s1, s1, a1 /* ... and unmasked LDT IRQs */ 208 beqz s0, 4f /* No interrupts. Return */ 209 nop 210 211 /* Clear the accumulated LDT (edge-triggered) interrupts */ 212 sd s1, R_IMR_LDT_INTERRUPT_CLR(v0) 213 214 /* The bit scan loop */ 215 dclz s1, s0 /* Find index of the next interrupt */ 2163: 217 li a1, 1 218 dsubu a0, zero, s1 219 daddiu a0, a0, 63 220 dsllv a1, a1, a0 221 xor s0, s0, a1 /* clear current bit */ 222 la t9, sb1250_dispatch_irq 223 jalr ra, t9 /* NB: SVR4 PIC requires t9 */ 224 dsrl32 s1, s0, 0 /* Save upper 32 bits of unified vector */ 225 226 dsll32 s0, s0, 0 /* clear upper bits of s0 */ 227 dsll32 s1, s1, 0 /* get saved back in the right place */ 228 dsrl32 s0, s0, 0 /* realign s0 */ 229 or s0, s0, s1 /* restore the saved bits */ 230 bnez s0, 3b /* More interrupts to service? */ 231 dclz s1, s0 /* unroll for branch delay slot */ 2324: 233 ld ra, 48(sp) /* restore registers */ 234 ld s1, 40(sp) 235 ld s0, 32(sp) 236 237 jr ra 238 daddiu sp, 56 /* saved register space */ 239 240END(cfe_irq_poll) 241 242#endif 243 244 .set pop 245 246 247/* ********************************************************************* 248 * sb1250_irq_arm() 249 * 250 * Set up CP0 Status and Cause per conventions above (not really -- yet) 251 * 252 * This function should be called with interrupts disabled. 253 * 254 * Input parameters: 255 * nothing 256 * 257 * Return value: 258 * nothing 259 ********************************************************************* */ 260 261 .set push 262 .set noreorder 263 .set mips64 264 265LEAF(sb1250_irq_arm) 266 267 mfc0 t0,C0_CAUSE 268 or t0,t0,M_CAUSE_IV 269 mtc0 t0,C0_CAUSE 270 271 mfc0 t0,C0_SR 272 li t1,M_SR_IMMASK /* Mask all interrupt levels */ 273 nor t1,t1,zero 274 and t0,t0,t1 275 or t0,t0,M_SR_IE /* but set IE */ 276 mtc0 t0,C0_SR 277 278 HAZARD 279 280 jr ra 281 nop 282 283END(sb1250_irq_arm) 284 285 .set pop 286 287 288 289/* ********************************************************************* 290 * cfe_irq_disable() 291 * 292 * Disable interrupts 293 * XXX: This is not really atomic. 294 * 295 * Input parameters: 296 * none 297 * 298 * Return value: 299 * current SR interrupt mask 300 ********************************************************************* */ 301 302 .set push 303 .set noreorder 304 .set mips64 305 306LEAF(cfe_irq_disable) 307 308 mfc0 t0,C0_SR 309 li t1,M_SR_IMMASK|M_SR_IE 310 li t2,~(M_SR_IMMASK|M_SR_IE) 311 and v0,t0,t1 /* current mask bits */ 312 and t0,t0,t2 313 mtc0 t0,C0_SR /* all enables cleared */ 314 315 HAZARD 316 317 jr ra 318 nop 319 320END(cfe_irq_disable) 321 322 .set pop 323 324 325/* ********************************************************************* 326 * cfe_irq_enable(mask) 327 * 328 * Restore enabled interrupts 329 * XXX: This is not really atomic. 330 * 331 * Input parameters: 332 * interrupt mask (from irq_disable) 333 * 334 * Return value: 335 * nothing 336 ********************************************************************* */ 337 338 .set push 339 .set noreorder 340 .set mips64 341 342LEAF(cfe_irq_enable) 343 344 mfc0 t0,C0_SR 345 li t1,M_SR_IMMASK|M_SR_IE 346 li t2,~(M_SR_IMMASK|M_SR_IE) 347 and a0,a0,t1 348 and t0,t0,t2 349 or t0,t0,a0 350 mtc0 t0,C0_SR 351 352 HAZARD 353 354 jr ra 355 nop 356 357END(cfe_irq_enable) 358 359 .set pop 360 361 362/* ********************************************************************* 363 * sb1250_update_sr(clear,set) 364 * 365 * Upate Status.IM according to masks 366 * 367 * Caller should disable interrupts if the effect is to be atomic. 368 * 369 * Input parameters: 370 * a0 SR bits to be cleared 371 * a1 SR bits to be set 372 * 373 * Return value: 374 * none 375 ********************************************************************* */ 376 377 .set push 378 .set noreorder 379 .set mips64 380 381LEAF(sb1250_update_sr) 382 383 nor a0,a0,zero 384 mfc0 t0,C0_SR 385 and t0,t0,a0 /* current mask bits */ 386 or t0,t0,a1 387 mtc0 t0,C0_SR /* all enables cleared */ 388 389 HAZARD 390 391 jr ra 392 nop 393 394END(sb1250_update_sr) 395 396 .set pop 397