From cb0610802495d2f767c78a0b07a0b8359238f590 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 8 Dec 2008 23:31:05 +0000 Subject: Meg-FX: Enable a real tick in the bootloader. Do cleanups before switching to firmware and cache handling. Put proper main return address in lr. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19368 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/gigabeat.c | 20 ++++++++++++++- firmware/kernel.c | 7 ++---- firmware/target/arm/s3c2440/crt0.S | 1 + .../target/arm/s3c2440/gigabeat-fx/ata-target.h | 4 +++ .../target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c | 29 ++++++---------------- .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 9 +++++++ .../target/arm/s3c2440/gigabeat-fx/system-target.h | 3 +++ 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c index 11ab93a5e2..a3732b0e06 100644 --- a/bootloader/gigabeat.c +++ b/bootloader/gigabeat.c @@ -75,11 +75,14 @@ void main(void) int(*kernel_entry)(void); system_init(); + kernel_init(); /* Need the kernel to sleep */ + + enable_interrupt(IRQ_FIQ_STATUS); + lcd_init(); backlight_init(); button_init(); font_init(); - kernel_init(); /* Need the kernel to sleep */ adc_init(); lcd_setfont(FONT_SYSFIXED); @@ -192,6 +195,9 @@ void main(void) printf("Loading firmware"); + /* Flush out anything pending first */ + invalidate_icache(); + loadbuffer = (unsigned char*) 0x31000000; buffer_size = (unsigned char*)0x31400000 - loadbuffer; @@ -199,10 +205,22 @@ void main(void) if(rc < 0) error(EBOOTFILE, rc); + storage_close(); + system_prepare_fw_start(); + if (rc == EOK) { + invalidate_icache(); kernel_entry = (void*) loadbuffer; rc = kernel_entry(); } + +#if 0 + /* Halt */ + while (1) + core_idle(); +#else + /* Return and restart */ +#endif } diff --git a/firmware/kernel.c b/firmware/kernel.c index 730484ed51..920893818a 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -244,10 +244,7 @@ void timeout_register(struct timeout *tmo, timeout_cb_type callback, ****************************************************************************/ void sleep(int ticks) { -#if CONFIG_CPU == S3C2440 && defined(BOOTLOADER) - extern void delay(int ticks); - delay(ticks); -#elif defined(CPU_PP) && defined(BOOTLOADER) +#if defined(CPU_PP) && defined(BOOTLOADER) unsigned stop = USEC_TIMER + ticks * (1000000/HZ); while (TIME_BEFORE(USEC_TIMER, stop)) switch_thread(); @@ -265,7 +262,7 @@ void sleep(int ticks) void yield(void) { -#if ((CONFIG_CPU == S3C2440 || defined(ELIO_TPJ1022)) && defined(BOOTLOADER)) +#if ((defined(ELIO_TPJ1022)) && defined(BOOTLOADER)) /* Some targets don't like yielding in the bootloader */ #else switch_thread(); diff --git a/firmware/target/arm/s3c2440/crt0.S b/firmware/target/arm/s3c2440/crt0.S index a05fd78fe9..7de2c46437 100644 --- a/firmware/target/arm/s3c2440/crt0.S +++ b/firmware/target/arm/s3c2440/crt0.S @@ -467,6 +467,7 @@ stackmunge: ldr sp, =stackend /* Start the main function */ + adr lr, vectors ldr pc, =main /* Should never get here, but let's restart in case (also needed for diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h index b010e3a4d4..54d0964560 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h @@ -21,6 +21,10 @@ #ifndef ATA_TARGET_H #define ATA_TARGET_H +#ifdef BOOTLOADER +#define ATA_DRIVER_CLOSE +#endif + /* Plain C read & write loops */ #define PREFER_C_READING #define PREFER_C_WRITING diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c index 6a750c32e2..6cabc8dc81 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c @@ -24,7 +24,7 @@ #include "timer.h" #include "thread.h" -static inline void tick_set(unsigned int interval_in_ms) +void tick_start(unsigned int interval_in_ms) { /* * Based on default PCLK of 49.1568MHz - scaling chosen to give @@ -49,11 +49,6 @@ static inline void tick_set(unsigned int interval_in_ms) TCON |= 1 << 21; /* reset manual bit */ TCON &= ~(1 << 21); -} - -void tick_start(unsigned int interval_in_ms) -{ - tick_set(interval_in_ms); /* interval mode */ TCON |= 1 << 22; @@ -65,24 +60,14 @@ void tick_start(unsigned int interval_in_ms) } #ifdef BOOTLOADER -void delay(int ticks) +void tick_stop(void) { - volatile unsigned long counter; - - INTMSK |= TIMER4_MASK; - - tick_set(1000 * ticks / HZ); - - /* autoreload Off */ - TCON &= ~(1 << 22); - /* start timer 4 */ - TCON |= (1 << 20); - - do { - counter = TCNTO4; - } while(counter > 0); + s3c_regset32(&INTMSK, TIMER4_MASK); + TCON &= ~(1 << 20); + SRCPND = TIMER4_MASK; + INTPND = TIMER4_MASK; } -#endif /* BOOTLOADER */ +#endif void TIMER4(void) { diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c index 6d8108be49..43e2c408a2 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c @@ -143,6 +143,15 @@ void s3c_regclr32(volatile unsigned long *reg, unsigned long bits) s3c_regmod32(reg, 0, bits); } +#ifdef BOOTLOADER +void system_prepare_fw_start(void) +{ + tick_stop(); + disable_interrupt(IRQ_FIQ_STATUS); + INTMSK = 0xFFFFFFFF; +} +#endif + void system_init(void) { INTMSK = 0xFFFFFFFF; diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h index 43758ece08..320c595b99 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h @@ -28,6 +28,9 @@ #define CPUFREQ_NORMAL 98784000 #define CPUFREQ_MAX 296352000 +void system_prepare_fw_start(void); +void tick_stop(void); + /* Functions to set and clear regiser bits atomically */ /* Set and clear register bits */ -- cgit v1.2.3