/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 by Rob Purchase * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "kernel.h" #include "system.h" #include "panic.h" #define default_interrupt(name) \ extern __attribute__((weak,alias("UIRQ"))) void name (void) void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked)); default_interrupt(INT_WATCHDOG); default_interrupt(INT_TIMER1); default_interrupt(INT_TIMER2); default_interrupt(INT_USB); default_interrupt(INT_DMAC); default_interrupt(INT_NAND); default_interrupt(INT_IDE); default_interrupt(INT_MCI0); default_interrupt(INT_MCI1); default_interrupt(INT_AUDIO); default_interrupt(INT_SSP); default_interrupt(INT_I2C_MS); default_interrupt(INT_I2C_AUDIO); default_interrupt(INT_I2SIN); default_interrupt(INT_I2SOUT); default_interrupt(INT_UART); default_interrupt(INT_GPIOD); default_interrupt(RESERVED1); /* Interrupt 17 : unused */ default_interrupt(INT_CGU); default_interrupt(INT_MEMORY_STICK); default_interrupt(INT_DBOP); default_interrupt(RESERVED2); /* Interrupt 21 : unused */ default_interrupt(RESERVED3); /* Interrupt 22 : unused */ default_interrupt(RESERVED4); /* Interrupt 23 : unused */ default_interrupt(RESERVED5); /* Interrupt 24 : unused */ default_interrupt(RESERVED6); /* Interrupt 25 : unused */ default_interrupt(RESERVED7); /* Interrupt 26 : unused */ default_interrupt(RESERVED8); /* Interrupt 27 : unused */ default_interrupt(RESERVED9); /* Interrupt 28 : unused */ default_interrupt(INT_GPIOA); default_interrupt(INT_GPIOB); default_interrupt(INT_GPIOC); static void (* const irqvector[])(void) = { INT_WATCHDOG, INT_TIMER1, INT_TIMER2, INT_USB, INT_DMAC, INT_NAND, INT_IDE, INT_MCI0, INT_MCI1, INT_AUDIO, INT_SSP, INT_I2C_MS, INT_I2C_AUDIO, INT_I2SIN, INT_I2SOUT, INT_UART, INT_GPIOD, RESERVED1 /* 17 */ ,INT_CGU, INT_MEMORY_STICK, INT_DBOP, RESERVED2 /* 21 */, RESERVED3 /* 22 */, RESERVED4 /* 23 */, RESERVED5 /* 24 */, RESERVED6 /* 25 */, RESERVED7 /* 26 */, RESERVED8 /* 27 */, RESERVED9 /* 28 */, INT_GPIOA, INT_GPIOB, INT_GPIOC }; static const char * const irqname[] = { "INT_WATCHDOG", "INT_TIMER1", "INT_TIMER2", "INT_USB", "INT_DMAC", "INT_NAND", "INT_IDE", "INT_MCI0", "INT_MCI1", "INT_AUDIO", "INT_SSP", "INT_I2C_MS", "INT_I2C_AUDIO", "INT_I2SIN", "INT_I2SOUT", "INT_UART", "INT_GPIOD", "RESERVED1", "INT_CGU", "INT_MEMORY_STICK", "INT_DBOP", "RESERVED2", "RESERVED3", "RESERVED4", "RESERVED5", "RESERVED6", "RESERVED7", "RESERVED8", "RESERVED9", "INT_GPIOA", "INT_GPIOB", "INT_GPIOC" }; static void UIRQ(void) { /* TODO unsigned int offset = INTOFFSET; panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); */ } void irq_handler(void) { /* * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c */ asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ "sub sp, sp, #8 \n"); /* Reserve stack */ /* TODO */ #if 0 int irq_no = INTOFFSET; /* Read clears the corresponding IRQ status */ #else int irq_no = 69; #endif if ((irq_no & (1<<31)) == 0) /* Ensure invalid flag is not set */ { irqvector[irq_no](); } asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ "subs pc, lr, #4 \n"); /* Return from IRQ */ } void fiq_handler(void) { asm volatile ( "subs pc, lr, #4 \r\n" ); } void system_init(void) { /* CGU_PERI |= CGU_GPIO_CLOCK_ENABLE; */ } void system_reboot(void) { } int system_memory_guard(int newmode) { (void)newmode; return 0; }