diff options
Diffstat (limited to 'libgloss/or1k/interrupts-asm.S')
-rw-r--r-- | libgloss/or1k/interrupts-asm.S | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/libgloss/or1k/interrupts-asm.S b/libgloss/or1k/interrupts-asm.S deleted file mode 100644 index 560035285..000000000 --- a/libgloss/or1k/interrupts-asm.S +++ /dev/null @@ -1,166 +0,0 @@ -/* interrupts-asm.S -- interrupt handling for OpenRISC 1000. - * - * Copyright (c) 2011, 2012, 2014 Authors - * - * Contributor Julius Baxter <juliusbaxter@gmail.com> - * Contributor Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> - * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de> - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -/* -------------------------------------------------------------------------- */ -/*!Generic interrupt handler function for or1k - */ -/* -------------------------------------------------------------------------- */ - -#include "include/or1k-asm.h" -#include "include/or1k-sprs.h" - - .extern _or1k_interrupt_handler_table - .extern _or1k_interrupt_handler_data_ptr_table - -/* -------------------------------------------------------------------------- */ -/*!Function to call appropriate interrupt handler - */ -/* -------------------------------------------------------------------------- */ - - .section .text - .global _or1k_interrupt_handler - .type _or1k_interrupt_handler,@function - -_or1k_interrupt_handler: - /* Make room on stack, save link register */ - l.addi r1,r1,-12 - l.sw 0(r1),r9 - - /* Read PICSR */ - l.mfspr r3,r0,OR1K_SPR_PIC_PICSR_ADDR - - /* Load handler table base address */ - l.movhi r7,hi(_or1k_interrupt_handler_table) - l.ori r7,r7,lo(_or1k_interrupt_handler_table) - /* Load data pointer table base address */ - l.movhi r12,hi(_or1k_interrupt_handler_data_ptr_table) - l.ori r12,r12,lo(_or1k_interrupt_handler_data_ptr_table) -#ifdef __OR1K_MULTICORE__ - /* Read the addresses of the arrays of cores */ - /* r7 = (*or1k_interrupt_handler_table) */ - l.lwz r7,0(r7) - /* r12 = (*or1k_interrupt_handler_data_ptr_table) */ - l.lwz r12,0(r12) - /* Generate offset in arrays */ - /* r14 = coreid */ - l.mfspr r14,r0,OR1K_SPR_SYS_COREID_ADDR - /* r14 = coreid*32*4 = off */ - l.slli r14,r14,7 - /* r7 = (*or1k_exception_handler_table)[coreid] */ - l.add r7,r7,r14 - /* r12 = (*or1k_exception_handler_table)[coreid] */ - l.add r12,r12,r14 -#endif - -.L0: - /* Find first set bit in PICSR */ - l.ff1 r4,r3 - /* Any bits set? */ - l.sfne r4,r0 - /* If none, finish */ - OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L2)) - /* What is IRQ function table offset? */ - l.addi r5,r4,-1 - l.slli r6,r5,2 - /* Add this to table bases */ - l.add r14,r6,r7 - l.add r13,r6,r12 - - /* Fetch handler function address */ - l.lwz r14,0(r14) - - /* Double check it's valid, compare against INTERRUPT_HANDLER_NOT_SET */ - l.sfne r14,r0 - /* Skip if no handler: TODO: Indicate interrupt fired but no handler*/ - OR1K_DELAYED_NOP(OR1K_INST(l.bnf .L1)) - - /* Pull out data pointer from table, save r3, we'll write over it */ - l.sw 4(r1),r3 - l.lwz r3,0(r13) - /* Call handler, save r5 in delay slot */ - OR1K_DELAYED( - OR1K_INST(l.sw 8(r1),r5), - OR1K_INST(l.jalr r14) - ) - - /* Reload r3,r5 */ - l.lwz r3,4(r1) - l.lwz r5,8(r1) -.L1: - /* Clear bit from PICSR, return to start of checking loop */ - l.ori r6,r0,1 - l.sll r6,r6,r5 - OR1K_DELAYED( - OR1K_INST(l.xor r3,r3,r6), - OR1K_INST(l.j .L0) - ) - -.L2: - /* Finish up - write PICSR back, restore r9*/ - l.lwz r9,0(r1) - l.mtspr r0,r3,OR1K_SPR_PIC_PICSR_ADDR - OR1K_DELAYED( - OR1K_INST(l.addi r1,r1,12), - OR1K_INST(l.jr r9) - ) - -/* -------------------------------------------------------------------------- */ -/*!Function to enable an interrupt handler in the PICMR - */ -/* -------------------------------------------------------------------------- */ - .global or1k_interrupt_enable - .type or1k_interrupt_enable,@function - - /* r3 should have IRQ line for peripheral */ -or1k_interrupt_enable: - l.addi r1,r1,-4 - l.sw 0(r1),r4 - l.ori r4,r0,0x1 - l.sll r4,r4,r3 - l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR - l.or r3,r3,r4 - l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR - l.lwz r4,0(r1) - OR1K_DELAYED( - OR1K_INST(l.addi r1,r1,4), - OR1K_INST(l.jr r9) - ) - -/* -------------------------------------------------------------------------- */ -/*!Function to disable an interrupt handler in the PICMR - */ -/* -------------------------------------------------------------------------- */ - .global or1k_interrupt_disable - .type or1k_interrupt_disable,@function - - /* r3 should have IRQ line for peripheral */ -or1k_interrupt_disable: - l.addi r1,r1,-4 - l.sw 0(r1),r4 - l.ori r4,r0,0x1 - l.sll r4,r4,r3 - l.xori r4,r4,0xffff - l.mfspr r3,r0,OR1K_SPR_PIC_PICMR_ADDR - l.and r3,r3,r4 - l.mtspr r0,r3,OR1K_SPR_PIC_PICMR_ADDR - l.lwz r4,0(r1) - OR1K_DELAYED( - OR1K_INST(l.addi r1,r1,4), - OR1K_INST(l.jr r9) - ) |