123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /*
- * interrupt vector setup
- *
- * Copyright (c) 2009 Openmoko Inc.
- *
- * Authors Daniel Mack <daniel@caiaq.de>
- * Christopher Hall <hsw@openmoko.com>
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <wikilib.h>
- #include <input.h>
- #include <regs.h>
- #include <interrupt.h>
- #include <misc.h>
- #include <button.h>
- #include <ctp.h>
- #include "traps.h"
- #include "serial.h"
- #define CLEAR_IRQ(reg,val) \
- do { \
- (reg) = (val); \
- } while (0)
- static void undef_irq_handler(void) __attribute__((interrupt_handler));
- static void illegal_instruction(void) __attribute__((interrupt_handler));
- static void illegal_irq_handler(void) __attribute__((interrupt_handler));
- static void serial0_err_irq(void) __attribute__((interrupt_handler));
- static void serial0_in_irq(void) __attribute__((interrupt_handler));
- static void serial0_out_irq(void) __attribute__((interrupt_handler));
- static void serial1_out_irq(void) __attribute__((interrupt_handler));
- static void unaligned_data_access(void) __attribute__((interrupt_handler));
- void panic(const char *s, const uint32_t *stack)
- {
- uint32_t *sp = (uint32_t *)((uint32_t)stack & ~3);
- print_char('\n');
- print(s);
- print("\nSP = ");
- print_u32((uint32_t)stack);
- print_char('\n');
- {
- register unsigned int i = 0;
- register unsigned int j = 0;
- register unsigned int p = 0;
- for (i = 0; i <= 15; ++i) {
- print("R");
- print_dec32(i);
- if ( i < 10) {
- print_char(' ');
- }
- print(" = ");
- print_u32(sp[p]);
- print(" [");
- print_dec32(sp[p++]);
- print("]\n");
- }
- print("PS");
- print(" = ");
- print_u32(sp[p++]);
- print_char('\n');
- print("IP");
- print(" = ");
- i = sp[p++];
- print_u32(i);
- print(" [-1..]: ");
- for (j = 0; j < 8; j += 2) {
- print_char(' ');
- print_byte(((uint8_t *)i)[j - 2]);
- print_byte(((uint8_t *)i)[j - 1]);
- }
- print_char('\n');
- for (i = 0; i < 8; ++i) {
- print("sp[");
- print_dec32(p);
- print("] = ");
- for (j = 0; j < 4; ++j) {
- print_u32(sp[p++]);
- print_char(' ');
- }
- print_char('\n');
- }
- }
- hex_dump(stack, 256);
- for (;;) {
- }
- }
- #define PANIC(str) \
- do { \
- asm volatile( \
- "\tpushn\t%%r15\n" \
- "\txld.w\t%%r6, %0\n" \
- "\tld.w\t%%r7, %%sp\n" \
- "\txcall\tpanic\n" \
- : \
- : "i"((str)) \
- ); \
- } while (0)
- static void undef_irq_handler(void)
- {
- PANIC("Undefined interrupt");
- }
- static void nmi_handler(void)
- {
- PANIC("Non-maskable interrupt");
- }
- static void illegal_irq_handler(void)
- {
- PANIC("Illegal interrupt");
- }
- static void illegal_instruction(void)
- {
- PANIC("Illegal instruction");
- }
- static void unaligned_data_access(void)
- {
- PANIC("Unaligned data access");
- }
- static void serial0_err_irq(void)
- {
- CLEAR_IRQ(REG_INT_FSIF01, 1 << 0);
- }
- static void serial0_in_irq(void)
- {
- serial_filled_0();
- CLEAR_IRQ(REG_INT_FSIF01, 1 << 1);
- }
- static void serial0_out_irq(void)
- {
- serial_drained_0();
- }
- static void serial1_out_irq(void)
- {
- CLEAR_IRQ(REG_INT_FSIF01, 1 << 5);
- }
- #define N_TRAPS 108
- typedef void (*irq_callback)(void);
- irq_callback trap_table[N_TRAPS] = {
- undef_irq_handler, // 0 Reset
- undef_irq_handler, // 1 *reserved*
- undef_irq_handler, // 2 ext exception
- illegal_instruction, // 3 Undefined instruction exception
- undef_irq_handler, // 4 *reserved*
- undef_irq_handler, // 5 *reserved*
- unaligned_data_access, // 6 Address misaligned exception
- nmi_handler, // 7 NMI
- undef_irq_handler, // 8 *reserved*
- undef_irq_handler, // 9 *reserved*
- undef_irq_handler, // 10 *reserved*
- illegal_irq_handler, // 11 Illegal interrupt exception
- undef_irq_handler, // 12 Software exception 0
- undef_irq_handler, // 13 Software exception 1
- undef_irq_handler, // 14 Software exception 2
- undef_irq_handler, // 15 Software exception 3
- undef_irq_handler, // 16 Port input interrupt 0
- undef_irq_handler, // 17 Port input interrupt 1
- undef_irq_handler, // 18 Port input interrupt 2
- Button_PowerInterrupt, // 19 Port input interrupt 3
- Button_KeyInterrupt, // 20 Key input interrupt 0
- Button_KeyInterrupt, // 21 Key input interrupt 1
- undef_irq_handler, // 22 High-speed DMA Ch.0
- undef_irq_handler, // 23 High-speed DMA Ch.1
- undef_irq_handler, // 24 High-speed DMA Ch.2
- undef_irq_handler, // 25 High-speed DMA Ch.3
- undef_irq_handler, // 26 Intelligent DMA
- undef_irq_handler, // 27 *reserved*
- undef_irq_handler, // 28 *reserved*
- undef_irq_handler, // 29 *reserved*
- undef_irq_handler, // 30 16-bit timer 0 - compare-match B
- undef_irq_handler, // 31 16-bit timer 0 - compare-match A
- undef_irq_handler, // 32 *reserved*
- undef_irq_handler, // 33 *reserved*
- undef_irq_handler, // 34 16-bit timer 1 - compare-match B
- undef_irq_handler, // 35 16-bit timer 1 - compare-match A
- undef_irq_handler, // 36 *reserved*
- undef_irq_handler, // 37 *reserved*
- undef_irq_handler, // 38 16-bit timer 2 - compare-match B
- undef_irq_handler, // 39 16-bit timer 2 - compare-match A
- undef_irq_handler, // 40 *reserved*
- undef_irq_handler, // 41 *reserved*
- undef_irq_handler, // 42 16-bit timer 3 - compare-match B
- undef_irq_handler, // 43 16-bit timer 3 - compare-match A
- undef_irq_handler, // 44 *reserved*
- undef_irq_handler, // 45 *reserved*
- undef_irq_handler, // 46 16-bit timer 4 - compare-match B
- undef_irq_handler, // 47 16-bit timer 4 - compare-match A
- undef_irq_handler, // 48 *reserved*
- undef_irq_handler, // 49 *reserved*
- undef_irq_handler, // 50 16-bit timer 5 - compare-match B
- undef_irq_handler, // 51 16-bit timer 5 - compare-match A
- undef_irq_handler, // 52 *reserved*
- undef_irq_handler, // 53 *reserved*
- undef_irq_handler, // 54 *reserved*
- undef_irq_handler, // 55 *reserved*
- serial0_err_irq, // 56 Serial interface Ch.0 - Receive error
- serial0_in_irq, // 57 Serial interface Ch.0 - Receive buffer full
- serial0_out_irq, // 58 Serial interface Ch.0 - Transmit buffer empty
- undef_irq_handler, // 59 *reserved*
- CTP_interrupt, // 60 Serial interface Ch.1 - Receive error
- CTP_interrupt, // 61 Serial interface Ch.1 - Receive buffer full
- serial1_out_irq, // 62 Serial interface Ch.1 - Transmit buffer empty
- undef_irq_handler, // 63 A/D converter - Result out of range
- undef_irq_handler, // 64 A/D converter - End of conversion
- undef_irq_handler, // 65 RTC
- undef_irq_handler, // 66 *reserved*
- undef_irq_handler, // 67 *reserved*
- undef_irq_handler, // 68 Port input interrupt 4
- undef_irq_handler, // 69 Port input interrupt 5
- undef_irq_handler, // 70 Port input interrupt 6
- undef_irq_handler, // 71 Port input interrupt 7
- undef_irq_handler, // 72 *reserved*
- undef_irq_handler, // 73 LCDC
- undef_irq_handler, // 74 *reserved*
- undef_irq_handler, // 75 *reserved*
- undef_irq_handler, // 76 Serial interface Ch.2 - Receive error
- undef_irq_handler, // 77 Serial interface Ch.2 - Receive buffer full
- undef_irq_handler, // 78 Serial interface Ch.2 - Transmit buffer empty
- undef_irq_handler, // 79 *reserved*
- undef_irq_handler, // 80 *reserved*
- undef_irq_handler, // 81 SPI - Receive DMA request
- undef_irq_handler, // 82 SPI - Transmit DMA request
- undef_irq_handler, // 83 *reserved*
- undef_irq_handler, // 84 Port input interrupt 8 / SPI - SPI interrupt
- undef_irq_handler, // 85 Port input interrupt 9 / USB PDREQ - USB DMA request
- undef_irq_handler, // 86 Port input interrupt 10 / USB - USBinterrupt
- undef_irq_handler, // 87 Port input interrupt 11 / DCSIO - DCSIO interrupt
- undef_irq_handler, // 88 Port input interrupt 12
- undef_irq_handler, // 89 Port input interrupt 13
- undef_irq_handler, // 90 Port input interrupt 14
- undef_irq_handler, // 91 Port input interrupt 15
- undef_irq_handler, // 92 *reserved*
- undef_irq_handler, // 93 *reserved*
- undef_irq_handler, // 94 I2S interface - I2S FIFO empty
- undef_irq_handler, // 95 *reserved*
- undef_irq_handler, // 96 *reserved*
- undef_irq_handler, // 97 *reserved*
- undef_irq_handler, // 98 *reserved*
- undef_irq_handler, // 99 *reserved*
- undef_irq_handler, // 100 *reserved*
- undef_irq_handler, // 101 *reserved*
- undef_irq_handler, // 102 *reserved*
- undef_irq_handler, // 103 *reserved*
- undef_irq_handler, // 104 *reserved*
- undef_irq_handler, // 105 *reserved*
- undef_irq_handler, // 106 *reserved*
- undef_irq_handler, // 107 *reserved*
- };
- void traps_init(void)
- {
- (void)Interrupt_disable();
- /* WAKEUP=1 */
- REG_CMU_PROTECT = CMU_PROTECT_OFF;
- REG_CMU_OPT |= 0x1;
- REG_CMU_PROTECT = CMU_PROTECT_ON;
- /* relocate the trap table */
- asm("ld.w %%ttbr, %0" :: "r"(0x84000));
- Interrupt_enable(true);
- void traps_check(void);
- print("traps_init\n");
- traps_check();
- }
- void traps_check(void)
- {
- register uint32_t *tt, nh;
- asm volatile (
- "xld.w %0, trap_table\n"
- "xld.w %1, nmi_handler\n"
- : "=r"(tt), "=r"(nh)
- :
- );
- if (tt[7] != nh) {
- print("trap_table is corrupt\n");
- print_u32(tt[7]);
- print(" should be ");
- print_u32(nh);
- print("\n");
- }
- }
|