From f62388f82c1a3cbc5e47c8e002abb5a514e9251b Mon Sep 17 00:00:00 2001 From: Rob Purchase Date: Wed, 24 Jun 2009 07:37:11 +0000 Subject: [PATCH] TCC78x: Enable interrupts/threading in the bootloader (required now that the storage driver yields). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21486 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/telechips.c | 64 ++------------------ firmware/SOURCES | 2 +- firmware/target/arm/tcc780x/crt0.S | 43 +++++++------ firmware/target/arm/tcc780x/kernel-tcc780x.c | 24 +++++++- firmware/target/arm/tcc780x/system-tcc780x.c | 8 --- firmware/target/arm/tcc780x/timer-tcc780x.c | 23 ------- 6 files changed, 52 insertions(+), 112 deletions(-) diff --git a/bootloader/telechips.c b/bootloader/telechips.c index 1e54f5d37d..8babbf3b62 100644 --- a/bootloader/telechips.c +++ b/bootloader/telechips.c @@ -57,19 +57,18 @@ extern int line; #define MAX_LOAD_SIZE (8*1024*1024) /* Arbitrary, but plenty. */ /* The following function is just test/development code */ -#ifdef CPU_TCC77X void show_debug_screen(void) { int button; int power_count = 0; int count = 0; bool do_power_off = false; - - lcd_puts_scroll(0,0,"this is a very long line to test scrolling"); + + lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---"); while (!do_power_off) { line = 1; button = button_get(false); - + /* Power-off if POWER button has been held for a time This loop is currently running at about 100 iterations/second */ @@ -107,6 +106,7 @@ void show_debug_screen(void) #endif count++; printf("Count: %d",count); + lcd_update(); sleep(HZ/10); } @@ -122,57 +122,6 @@ void show_debug_screen(void) while (true); } -#else /* !CPU_TCC77X */ - -void show_debug_screen(void) -{ - int button; - int power_count = 0; - int count = 0; - bool do_power_off = false; -#ifdef HAVE_BUTTON_DATA - unsigned int data; -#endif - - while(!do_power_off) { - line = 0; - printf("Hello World!"); - -#ifdef HAVE_BUTTON_DATA - button = button_read_device(&data); -#else - button = button_read_device(); -#endif - - /* Power-off if POWER button has been held for a long time - This loop is currently running at about 100 iterations/second - */ - if (button & POWEROFF_BUTTON) { - power_count++; - if (power_count > 200) - do_power_off = true; - } else { - power_count = 0; - } - - printf("Btn: 0x%08x",button); - - count++; - printf("Count: %d",count); - } - - lcd_clear_display(); - line = 0; - printf("POWER-OFF"); - - /* Power-off */ - power_off(); - - printf("(NOT) POWERED OFF"); - while (true); -} -#endif - void* main(void) { #ifdef TCCBOOT @@ -182,11 +131,10 @@ void* main(void) system_init(); power_init(); -#ifndef COWON_D2 - /* The D2 doesn't enable threading or interrupts */ + kernel_init(); enable_irq(); -#endif + lcd_init(); adc_init(); diff --git a/firmware/SOURCES b/firmware/SOURCES index 0eff012660..6f23012b61 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1202,6 +1202,7 @@ drivers/pcf50606.c target/arm/lcd-as-memframe.S target/arm/tcc780x/adc-tcc780x.c target/arm/tcc780x/system-tcc780x.c +target/arm/tcc780x/kernel-tcc780x.c target/arm/tcc780x/cowond2/button-cowond2.c target/arm/tcc780x/cowond2/lcd-cowond2.c target/arm/tcc780x/cowond2/power-cowond2.c @@ -1209,7 +1210,6 @@ target/arm/tcc780x/cowond2/powermgmt-cowond2.c target/arm/tcc780x/cowond2/backlight-cowond2.c target/arm/usb-tcc.c #ifndef BOOTLOADER -target/arm/tcc780x/kernel-tcc780x.c target/arm/tcc780x/timer-tcc780x.c target/arm/wmcodec-telechips.c target/arm/tcc780x/debug-tcc780x.c diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S index 03f17957c5..f02a204d7e 100644 --- a/firmware/target/arm/tcc780x/crt0.S +++ b/firmware/target/arm/tcc780x/crt0.S @@ -94,9 +94,8 @@ start_loc: ldr pc, =copied_start /* jump to the relocated start_loc: */ copied_start: -#endif -#else - /* We don't use interrupts in the bootloader */ +#endif /* TCCBOOT */ +#endif /* BOOTLOADER */ /* Set up stack for IRQ mode */ mov r0,#0xd2 @@ -107,13 +106,15 @@ copied_start: mov r0,#0xd1 msr cpsr, r0 ldr sp, =fiq_stack - + +#ifndef BOOTLOADER /* Load the banked FIQ mode registers with useful values here. These values will be used in the FIQ handler in pcm-tcc780x.c */ .equ DADO_BASE, 0xF0059020 ldr r10, =DADO_BASE ldr r11, =dma_play_data +#endif /* Let abort and undefined modes use IRQ stack */ mov r0,#0xd7 @@ -122,7 +123,6 @@ copied_start: mov r0,#0xdb msr cpsr, r0 ldr sp, =irq_stack -#endif /* Switch to supervisor mode */ mov r0,#0xd3 @@ -176,18 +176,19 @@ copied_start: mcr p15, 0, r0, c7, c6, 0 /* Invalidate Dcache */ mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */ -#if !defined(BOOTLOADER) && !defined(STUB) - +#ifndef STUB + /* Copy exception handler code to address 0 */ - ldr r2, =_vectorsstart - ldr r3, =_vectorsend - ldr r4, =_vectorscopy + mov r2, #0x0 + ldr r3, =vectors_start + ldr r4, =vectors_end 1: - cmp r3, r2 - ldrhi r5, [r4], #4 + cmp r4, r3 + ldrhi r5, [r3], #4 strhi r5, [r2], #4 bhi 1b +#ifndef BOOTLOADER /* Copy the IRAM (SRAM) */ ldr r2, =_iramcopy ldr r3, =_iramstart @@ -226,7 +227,8 @@ copied_start: ldrhi r5, [r2], #4 strhi r5, [r3], #4 bhi 1b -#endif /* !BOOTLOADER,!STUB */ +#endif /* !BOOTLOADER */ +#endif /* !STUB */ /* Initialise bss section to zero */ ldr r2, =_edata @@ -250,10 +252,9 @@ copied_start: bl main /* main() should never return */ -#ifndef BOOTLOADER - /* Exception handlers. Will be copied to address 0 after memory remapping */ - .section .vectors,"aw" + +vectors_start: ldr pc, [pc, #24] ldr pc, [pc, #24] ldr pc, [pc, #24] @@ -274,6 +275,7 @@ vectors: .word reserved_handler .word irq_handler .word fiq_handler +vectors_end: .text @@ -304,13 +306,16 @@ data_abort_handler: mov r1, #2 b UIE +#ifdef BOOTLOADER +fiq_handler: + subs pc, lr, #4 +#endif + #if defined(STUB) UIE: b UIE #endif - /* We don't use interrupts in the bootloader */ - /* Align stacks to cache line boundary */ .balign 16 @@ -321,5 +326,3 @@ irq_stack: /* 256 words of FIQ stack */ .space 256*4 fiq_stack: - -#endif diff --git a/firmware/target/arm/tcc780x/kernel-tcc780x.c b/firmware/target/arm/tcc780x/kernel-tcc780x.c index dee5e040e2..76395d2b33 100644 --- a/firmware/target/arm/tcc780x/kernel-tcc780x.c +++ b/firmware/target/arm/tcc780x/kernel-tcc780x.c @@ -38,5 +38,25 @@ void tick_start(unsigned int interval_in_ms) TCFG(0) = TCFG_CLEAR | (0 << TCFG_SEL) | TCFG_IEN | TCFG_EN; } -/* NB: Since we are using a single timer IRQ, tick tasks are dispatched as - part of the central timer IRQ processing in timer-tcc780x.c */ + +/* Timer interrupt processing - all timers (inc. tick) share a single IRQ */ +void TIMER0(void) +{ + if (TIREQ & TIREQ_TF0) /* Timer0 reached ref value */ + { + /* Run through the list of tick tasks */ + call_tick_tasks(); + + /* reset Timer 0 IRQ & ref flags */ + TIREQ = TIREQ_TI0 | TIREQ_TF0; + } + + if (TIREQ & TIREQ_TF4) /* Timer4 reached ref value */ + { + /* dispatch user timer */ + if (pfn_timer != NULL) + pfn_timer(); + + TIREQ = TIREQ_TI4 | TIREQ_TF4; + } +} diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c index ab8a6cf218..6362f17f71 100644 --- a/firmware/target/arm/tcc780x/system-tcc780x.c +++ b/firmware/target/arm/tcc780x/system-tcc780x.c @@ -23,8 +23,6 @@ #include "system.h" #include "panic.h" -#if !defined(BOOTLOADER) - #define default_interrupt(name) \ extern __attribute__((weak,alias("UIRQ"))) void name (void) @@ -144,8 +142,6 @@ void irq_handler(void) "subs pc, lr, #4 \n"); /* Return from IRQ */ } -#endif /* !defined(BOOTLOADER) */ - /* TODO - these should live in the target-specific directories and once we understand what all the GPIO pins do, move the init to the @@ -254,8 +250,6 @@ void system_init(void) /* mask all interrupts */ IEN = 0; -#if !defined(BOOTLOADER) - /* Set DAI interrupts as FIQ, all others are IRQ. */ IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK); @@ -272,8 +266,6 @@ void system_init(void) } ALLMASK = 3; /* Global FIQ/IRQ unmask */ - -#endif /* !defined(BOOTLOADER) */ gpio_init(); clock_init(); diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c index ca6613a3ff..a6c8c1c060 100644 --- a/firmware/target/arm/tcc780x/timer-tcc780x.c +++ b/firmware/target/arm/tcc780x/timer-tcc780x.c @@ -81,26 +81,3 @@ void __timer_unregister(void) restore_interrupt(oldstatus); } - - -/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ -void TIMER0(void) -{ - if (TIREQ & TIREQ_TF0) /* Timer0 reached ref value */ - { - /* Run through the list of tick tasks */ - call_tick_tasks(); - - /* reset Timer 0 IRQ & ref flags */ - TIREQ = TIREQ_TI0 | TIREQ_TF0; - } - - if (TIREQ & TIREQ_TF4) /* Timer4 reached ref value */ - { - /* dispatch user timer */ - if (pfn_timer != NULL) - pfn_timer(); - - TIREQ = TIREQ_TI4 | TIREQ_TF4; - } -}