source: trunk/libs/newlib/src/libgloss/or1k/interrupts-asm.S @ 514

Last change on this file since 514 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.1 KB
Line 
1/* interrupts-asm.S -- interrupt handling for OpenRISC 1000.
2 *
3 * Copyright (c) 2011, 2012, 2014 Authors
4 *
5 * Contributor Julius Baxter <juliusbaxter@gmail.com>
6 * Contributor Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
7 * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de>
8 *
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
17 * they apply.
18 */
19
20/* -------------------------------------------------------------------------- */
21/*!Generic interrupt handler function for or1k
22                                                                              */
23/* -------------------------------------------------------------------------- */
24
25#include "include/or1k-asm.h"
26#include "include/or1k-sprs.h"
27
28        .extern _or1k_interrupt_handler_table
29        .extern _or1k_interrupt_handler_data_ptr_table
30
31/* -------------------------------------------------------------------------- */
32/*!Function to call appropriate interrupt handler
33                                                                              */
34/* -------------------------------------------------------------------------- */
35
36        .section .text
37        .global _or1k_interrupt_handler
38        .type   _or1k_interrupt_handler,@function
39
40_or1k_interrupt_handler:
41        /* Make room on stack, save link address register */
42        l.addi  r1,r1,-4
43        l.sw    0(r1),r9
44
45        /* Read PICSR */
46        l.mfspr r20,r0,OR1K_SPR_PIC_PICSR_ADDR
47
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)  */
59        l.lwz   r16,0(r16)
60        /* r12 = (*or1k_interrupt_handler_data_ptr_table)  */
61        l.lwz   r18,0(r18)
62        /* Generate offset in arrays */
63        /* r14 = coreid */
64        l.mfspr r14,r0,OR1K_SPR_SYS_COREID_ADDR
65        /* r14 = coreid*32*4 = off */
66        l.slli  r14,r14,7
67        /* r7 = (*or1k_exception_handler_table)[coreid] */
68        l.add   r16,r16,r14
69        /* r12 = (*or1k_exception_handler_table)[coreid] */
70        l.add   r18,r18,r14
71#endif
72
73.L0:
74        /* Find first set bit in PICSR */
75        l.ff1   r4,r20
76        /* Any bits set? */
77        l.sfne  r4,r0
78        /* If none, finish */
79        OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L2))
80        /* What is IRQ function table offset? */
81        l.addi  r22,r4,-1
82        l.slli  r6,r22,2
83        /* Add this to table bases */
84        l.add   r14,r6,r16
85        l.add   r13,r6,r18
86
87        /* Fetch handler function address */
88        l.lwz   r14,0(r14)
89
90        /* Double check it's valid, compare against INTERRUPT_HANDLER_NOT_SET */
91        l.sfne  r14,r0
92        /* Skip if no handler: TODO: Indicate interrupt fired but no handler*/
93        OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L1))
94
95        /* Call handler, load data pointer */
96        OR1K_DELAYED(
97                OR1K_INST(l.lwz  r3,0(r13)),
98                OR1K_INST(l.jalr r14)
99        )
100
101.L1:
102        /* Clear bit from PICSR, return to start of checking loop */
103        l.ori   r6,r0,1
104        l.sll   r6,r6,r22
105        OR1K_DELAYED(
106                OR1K_INST(l.xor r20,r20,r6),
107                OR1K_INST(l.j   .L0)
108        )
109
110.L2:
111        /* Finish up - write PICSR back, restore r9*/
112        l.lwz   r9,0(r1)
113        l.mtspr r0,r20,OR1K_SPR_PIC_PICSR_ADDR
114        OR1K_DELAYED(
115                OR1K_INST(l.addi r1,r1,4),
116                OR1K_INST(l.jr   r9)
117        )
118
119/* -------------------------------------------------------------------------- */
120/*!Function to enable an interrupt handler in the PICMR
121                                                                              */
122/* -------------------------------------------------------------------------- */
123        .global or1k_interrupt_enable
124        .type   or1k_interrupt_enable,@function
125
126        /* r3 should have IRQ line for peripheral */
127or1k_interrupt_enable:
128        l.addi  r1,r1,-4
129        l.sw    0(r1),r4
130        l.ori   r4,r0,0x1
131        l.sll   r4,r4,r3
132        l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR
133        l.or    r3,r3,r4
134        l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR
135        l.lwz   r4,0(r1)
136        OR1K_DELAYED(
137                OR1K_INST(l.addi        r1,r1,4),
138                OR1K_INST(l.jr  r9)
139        )
140
141/* -------------------------------------------------------------------------- */
142/*!Function to disable an interrupt handler in the PICMR
143                                                                              */
144/* -------------------------------------------------------------------------- */
145        .global or1k_interrupt_disable
146        .type   or1k_interrupt_disable,@function
147
148        /* r3 should have IRQ line for peripheral */
149or1k_interrupt_disable:
150        l.addi  r1,r1,-4
151        l.sw    0(r1),r4
152        l.ori   r4,r0,0x1
153        l.sll   r4,r4,r3
154        l.xori  r4,r4,0xffff
155        l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR
156        l.and   r3,r3,r4
157        l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR
158        l.lwz   r4,0(r1)
159        OR1K_DELAYED(
160                OR1K_INST(l.addi r1,r1,4),
161                OR1K_INST(l.jr   r9)
162        )
Note: See TracBrowser for help on using the repository browser.