forked from len0rd/rockbox
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
This commit is contained in:
parent
5e24a2c98c
commit
f62388f82c
6 changed files with 52 additions and 112 deletions
|
|
@ -57,7 +57,6 @@ extern int line;
|
||||||
#define MAX_LOAD_SIZE (8*1024*1024) /* Arbitrary, but plenty. */
|
#define MAX_LOAD_SIZE (8*1024*1024) /* Arbitrary, but plenty. */
|
||||||
|
|
||||||
/* The following function is just test/development code */
|
/* The following function is just test/development code */
|
||||||
#ifdef CPU_TCC77X
|
|
||||||
void show_debug_screen(void)
|
void show_debug_screen(void)
|
||||||
{
|
{
|
||||||
int button;
|
int button;
|
||||||
|
|
@ -65,7 +64,7 @@ void show_debug_screen(void)
|
||||||
int count = 0;
|
int count = 0;
|
||||||
bool do_power_off = false;
|
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) {
|
while (!do_power_off) {
|
||||||
line = 1;
|
line = 1;
|
||||||
button = button_get(false);
|
button = button_get(false);
|
||||||
|
|
@ -107,6 +106,7 @@ void show_debug_screen(void)
|
||||||
#endif
|
#endif
|
||||||
count++;
|
count++;
|
||||||
printf("Count: %d",count);
|
printf("Count: %d",count);
|
||||||
|
lcd_update();
|
||||||
sleep(HZ/10);
|
sleep(HZ/10);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -122,57 +122,6 @@ void show_debug_screen(void)
|
||||||
while (true);
|
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)
|
void* main(void)
|
||||||
{
|
{
|
||||||
#ifdef TCCBOOT
|
#ifdef TCCBOOT
|
||||||
|
|
@ -182,11 +131,10 @@ void* main(void)
|
||||||
|
|
||||||
system_init();
|
system_init();
|
||||||
power_init();
|
power_init();
|
||||||
#ifndef COWON_D2
|
|
||||||
/* The D2 doesn't enable threading or interrupts */
|
|
||||||
kernel_init();
|
kernel_init();
|
||||||
enable_irq();
|
enable_irq();
|
||||||
#endif
|
|
||||||
lcd_init();
|
lcd_init();
|
||||||
|
|
||||||
adc_init();
|
adc_init();
|
||||||
|
|
|
||||||
|
|
@ -1202,6 +1202,7 @@ drivers/pcf50606.c
|
||||||
target/arm/lcd-as-memframe.S
|
target/arm/lcd-as-memframe.S
|
||||||
target/arm/tcc780x/adc-tcc780x.c
|
target/arm/tcc780x/adc-tcc780x.c
|
||||||
target/arm/tcc780x/system-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/button-cowond2.c
|
||||||
target/arm/tcc780x/cowond2/lcd-cowond2.c
|
target/arm/tcc780x/cowond2/lcd-cowond2.c
|
||||||
target/arm/tcc780x/cowond2/power-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/tcc780x/cowond2/backlight-cowond2.c
|
||||||
target/arm/usb-tcc.c
|
target/arm/usb-tcc.c
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
target/arm/tcc780x/kernel-tcc780x.c
|
|
||||||
target/arm/tcc780x/timer-tcc780x.c
|
target/arm/tcc780x/timer-tcc780x.c
|
||||||
target/arm/wmcodec-telechips.c
|
target/arm/wmcodec-telechips.c
|
||||||
target/arm/tcc780x/debug-tcc780x.c
|
target/arm/tcc780x/debug-tcc780x.c
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,8 @@ start_loc:
|
||||||
ldr pc, =copied_start /* jump to the relocated start_loc: */
|
ldr pc, =copied_start /* jump to the relocated start_loc: */
|
||||||
|
|
||||||
copied_start:
|
copied_start:
|
||||||
#endif
|
#endif /* TCCBOOT */
|
||||||
#else
|
#endif /* BOOTLOADER */
|
||||||
/* We don't use interrupts in the bootloader */
|
|
||||||
|
|
||||||
/* Set up stack for IRQ mode */
|
/* Set up stack for IRQ mode */
|
||||||
mov r0,#0xd2
|
mov r0,#0xd2
|
||||||
|
|
@ -108,12 +107,14 @@ copied_start:
|
||||||
msr cpsr, r0
|
msr cpsr, r0
|
||||||
ldr sp, =fiq_stack
|
ldr sp, =fiq_stack
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
/* Load the banked FIQ mode registers with useful values here.
|
/* Load the banked FIQ mode registers with useful values here.
|
||||||
These values will be used in the FIQ handler in pcm-tcc780x.c */
|
These values will be used in the FIQ handler in pcm-tcc780x.c */
|
||||||
.equ DADO_BASE, 0xF0059020
|
.equ DADO_BASE, 0xF0059020
|
||||||
|
|
||||||
ldr r10, =DADO_BASE
|
ldr r10, =DADO_BASE
|
||||||
ldr r11, =dma_play_data
|
ldr r11, =dma_play_data
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Let abort and undefined modes use IRQ stack */
|
/* Let abort and undefined modes use IRQ stack */
|
||||||
mov r0,#0xd7
|
mov r0,#0xd7
|
||||||
|
|
@ -122,7 +123,6 @@ copied_start:
|
||||||
mov r0,#0xdb
|
mov r0,#0xdb
|
||||||
msr cpsr, r0
|
msr cpsr, r0
|
||||||
ldr sp, =irq_stack
|
ldr sp, =irq_stack
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Switch to supervisor mode */
|
/* Switch to supervisor mode */
|
||||||
mov r0,#0xd3
|
mov r0,#0xd3
|
||||||
|
|
@ -176,18 +176,19 @@ copied_start:
|
||||||
mcr p15, 0, r0, c7, c6, 0 /* Invalidate Dcache */
|
mcr p15, 0, r0, c7, c6, 0 /* Invalidate Dcache */
|
||||||
mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */
|
mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */
|
||||||
|
|
||||||
#if !defined(BOOTLOADER) && !defined(STUB)
|
#ifndef STUB
|
||||||
|
|
||||||
/* Copy exception handler code to address 0 */
|
/* Copy exception handler code to address 0 */
|
||||||
ldr r2, =_vectorsstart
|
mov r2, #0x0
|
||||||
ldr r3, =_vectorsend
|
ldr r3, =vectors_start
|
||||||
ldr r4, =_vectorscopy
|
ldr r4, =vectors_end
|
||||||
1:
|
1:
|
||||||
cmp r3, r2
|
cmp r4, r3
|
||||||
ldrhi r5, [r4], #4
|
ldrhi r5, [r3], #4
|
||||||
strhi r5, [r2], #4
|
strhi r5, [r2], #4
|
||||||
bhi 1b
|
bhi 1b
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
/* Copy the IRAM (SRAM) */
|
/* Copy the IRAM (SRAM) */
|
||||||
ldr r2, =_iramcopy
|
ldr r2, =_iramcopy
|
||||||
ldr r3, =_iramstart
|
ldr r3, =_iramstart
|
||||||
|
|
@ -226,7 +227,8 @@ copied_start:
|
||||||
ldrhi r5, [r2], #4
|
ldrhi r5, [r2], #4
|
||||||
strhi r5, [r3], #4
|
strhi r5, [r3], #4
|
||||||
bhi 1b
|
bhi 1b
|
||||||
#endif /* !BOOTLOADER,!STUB */
|
#endif /* !BOOTLOADER */
|
||||||
|
#endif /* !STUB */
|
||||||
|
|
||||||
/* Initialise bss section to zero */
|
/* Initialise bss section to zero */
|
||||||
ldr r2, =_edata
|
ldr r2, =_edata
|
||||||
|
|
@ -250,10 +252,9 @@ copied_start:
|
||||||
bl main
|
bl main
|
||||||
/* main() should never return */
|
/* main() should never return */
|
||||||
|
|
||||||
#ifndef BOOTLOADER
|
|
||||||
|
|
||||||
/* Exception handlers. Will be copied to address 0 after memory remapping */
|
/* 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]
|
ldr pc, [pc, #24]
|
||||||
ldr pc, [pc, #24]
|
ldr pc, [pc, #24]
|
||||||
|
|
@ -274,6 +275,7 @@ vectors:
|
||||||
.word reserved_handler
|
.word reserved_handler
|
||||||
.word irq_handler
|
.word irq_handler
|
||||||
.word fiq_handler
|
.word fiq_handler
|
||||||
|
vectors_end:
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
@ -304,13 +306,16 @@ data_abort_handler:
|
||||||
mov r1, #2
|
mov r1, #2
|
||||||
b UIE
|
b UIE
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
fiq_handler:
|
||||||
|
subs pc, lr, #4
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STUB)
|
#if defined(STUB)
|
||||||
UIE:
|
UIE:
|
||||||
b UIE
|
b UIE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We don't use interrupts in the bootloader */
|
|
||||||
|
|
||||||
/* Align stacks to cache line boundary */
|
/* Align stacks to cache line boundary */
|
||||||
.balign 16
|
.balign 16
|
||||||
|
|
||||||
|
|
@ -321,5 +326,3 @@ irq_stack:
|
||||||
/* 256 words of FIQ stack */
|
/* 256 words of FIQ stack */
|
||||||
.space 256*4
|
.space 256*4
|
||||||
fiq_stack:
|
fiq_stack:
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,25 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
TCFG(0) = TCFG_CLEAR | (0 << TCFG_SEL) | TCFG_IEN | TCFG_EN;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
|
|
||||||
#if !defined(BOOTLOADER)
|
|
||||||
|
|
||||||
#define default_interrupt(name) \
|
#define default_interrupt(name) \
|
||||||
extern __attribute__((weak,alias("UIRQ"))) void name (void)
|
extern __attribute__((weak,alias("UIRQ"))) void name (void)
|
||||||
|
|
||||||
|
|
@ -144,8 +142,6 @@ void irq_handler(void)
|
||||||
"subs pc, lr, #4 \n"); /* Return from IRQ */
|
"subs pc, lr, #4 \n"); /* Return from IRQ */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !defined(BOOTLOADER) */
|
|
||||||
|
|
||||||
|
|
||||||
/* TODO - these should live in the target-specific directories and
|
/* TODO - these should live in the target-specific directories and
|
||||||
once we understand what all the GPIO pins do, move the init to the
|
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 */
|
/* mask all interrupts */
|
||||||
IEN = 0;
|
IEN = 0;
|
||||||
|
|
||||||
#if !defined(BOOTLOADER)
|
|
||||||
|
|
||||||
/* Set DAI interrupts as FIQ, all others are IRQ. */
|
/* Set DAI interrupts as FIQ, all others are IRQ. */
|
||||||
IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK);
|
IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK);
|
||||||
|
|
||||||
|
|
@ -273,8 +267,6 @@ void system_init(void)
|
||||||
|
|
||||||
ALLMASK = 3; /* Global FIQ/IRQ unmask */
|
ALLMASK = 3; /* Global FIQ/IRQ unmask */
|
||||||
|
|
||||||
#endif /* !defined(BOOTLOADER) */
|
|
||||||
|
|
||||||
gpio_init();
|
gpio_init();
|
||||||
clock_init();
|
clock_init();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,26 +81,3 @@ void __timer_unregister(void)
|
||||||
|
|
||||||
restore_interrupt(oldstatus);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue