142 lines
4.5 KiB
C
142 lines
4.5 KiB
C
|
/***************************************************************************
|
||
|
* __________ __ ___.
|
||
|
* 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;
|
||
|
}
|