1 /* interrupts-asm.S -- interrupt handling for OpenRISC 1000.
3 * Copyright (c) 2011, 2012, 2014 Authors
5 * Contributor Julius Baxter <juliusbaxter@gmail.com>
6 * Contributor Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
7 * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de>
9 * The authors hereby grant permission to use, copy, modify, distribute,
10 * and license this software and its documentation for any purpose, provided
11 * that existing copyright notices are retained in all copies and that this
12 * notice is included verbatim in any distributions. No written agreement,
13 * license, or royalty fee is required for any of the authorized uses.
14 * Modifications to this software may be copyrighted by their authors
15 * and need not follow the licensing terms described here, provided that
16 * the new terms are clearly indicated on the first page of each file where
20 /* -------------------------------------------------------------------------- */
21 /*!Generic interrupt handler function for or1k
23 /* -------------------------------------------------------------------------- */
25 #include "include/or1k-asm.h"
26 #include "include/or1k-sprs.h"
28 .extern _or1k_interrupt_handler_table
29 .extern _or1k_interrupt_handler_data_ptr_table
31 /* -------------------------------------------------------------------------- */
32 /*!Function to call appropriate interrupt handler
34 /* -------------------------------------------------------------------------- */
37 .global _or1k_interrupt_handler
38 .type _or1k_interrupt_handler,@function
40 _or1k_interrupt_handler:
41 /* Make room on stack, save link address register */
46 l.mfspr r20,r0,OR1K_SPR_PIC_PICSR_ADDR
48 /* Load handler table base address */
49 // Needs to be callee-saved register
50 l.movhi r16,hi(_or1k_interrupt_handler_table)
51 l.ori r16,r16,lo(_or1k_interrupt_handler_table)
52 /* Load data pointer table base address */
53 // Needs to be callee-saved register
54 l.movhi r18,hi(_or1k_interrupt_handler_data_ptr_table)
55 l.ori r18,r18,lo(_or1k_interrupt_handler_data_ptr_table)
56 #ifdef __OR1K_MULTICORE__
57 /* Read the addresses of the arrays of cores */
58 /* r7 = (*or1k_interrupt_handler_table) */
60 /* r12 = (*or1k_interrupt_handler_data_ptr_table) */
62 /* Generate offset in arrays */
64 l.mfspr r14,r0,OR1K_SPR_SYS_COREID_ADDR
65 /* r14 = coreid*32*4 = off */
67 /* r7 = (*or1k_exception_handler_table)[coreid] */
69 /* r12 = (*or1k_exception_handler_table)[coreid] */
74 /* Find first set bit in PICSR */
79 OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L2))
80 /* What is IRQ function table offset? */
83 /* Add this to table bases */
87 /* Fetch handler function address */
90 /* Double check it's valid, compare against INTERRUPT_HANDLER_NOT_SET */
92 /* Skip if no handler: TODO: Indicate interrupt fired but no handler*/
93 OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L1))
95 /* Call handler, load data pointer */
97 OR1K_INST(l.lwz r3,0(r13)),
102 /* Clear bit from PICSR, return to start of checking loop */
106 OR1K_INST(l.xor r20,r20,r6),
111 /* Finish up - write PICSR back, restore r9*/
113 l.mtspr r0,r20,OR1K_SPR_PIC_PICSR_ADDR
115 OR1K_INST(l.addi r1,r1,4),
119 /* -------------------------------------------------------------------------- */
120 /*!Function to enable an interrupt handler in the PICMR
122 /* -------------------------------------------------------------------------- */
123 .global or1k_interrupt_enable
124 .type or1k_interrupt_enable,@function
126 /* r3 should have IRQ line for peripheral */
127 or1k_interrupt_enable:
132 l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR
134 l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR
137 OR1K_INST(l.addi r1,r1,4),
141 /* -------------------------------------------------------------------------- */
142 /*!Function to disable an interrupt handler in the PICMR
144 /* -------------------------------------------------------------------------- */
145 .global or1k_interrupt_disable
146 .type or1k_interrupt_disable,@function
148 /* r3 should have IRQ line for peripheral */
149 or1k_interrupt_disable:
155 l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR
157 l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR
160 OR1K_INST(l.addi r1,r1,4),