From d95c39072ace1a7aeaad3ee49ed668399b4862bd Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 13 Apr 2007 20:55:48 +0000 Subject: Portal Player: Add invalidate_icache and flush_icache. Flush the cache on the core for newborn threads. In doing so, move more ARM stuff to the target tree and organize it to make a clean job of it. If anything isn't appropriate for some particular device give a hollar or even just fix it by some added #ifdefing. I was informed that the PP targets are register compatible so I'm going off that advice. The Sansa likes it though. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13144 a1c6a512-1295-4272-9138-f99709370657 --- .../target/arm/gigabeat/meg-fx/system-meg-fx.h | 32 +++++ .../target/arm/gigabeat/meg-fx/system-target.h | 31 ----- firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | 14 +- firmware/target/arm/system-pp.h | 49 +++++++ firmware/target/arm/system-target.h | 155 +++++++++++++++++++++ firmware/target/coldfire/system-target.h | 4 + 6 files changed, 242 insertions(+), 43 deletions(-) create mode 100644 firmware/target/arm/gigabeat/meg-fx/system-meg-fx.h delete mode 100644 firmware/target/arm/gigabeat/meg-fx/system-target.h create mode 100644 firmware/target/arm/system-pp.h create mode 100644 firmware/target/arm/system-target.h (limited to 'firmware/target') diff --git a/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.h b/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.h new file mode 100644 index 0000000000..7d598af360 --- /dev/null +++ b/firmware/target/arm/gigabeat/meg-fx/system-meg-fx.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Greg White + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "mmu-meg-fx.h" + +#define HAVE_INVALIDATE_ICACHE +static inline void invalidate_icache(void) +{ + clean_dcache(); + asm volatile( + "mov r0, #0 \n" + "mcr p15, 0, r0, c7, c5, 0 \n" + : : : "r0" + ); +} + diff --git a/firmware/target/arm/gigabeat/meg-fx/system-target.h b/firmware/target/arm/gigabeat/meg-fx/system-target.h deleted file mode 100644 index e5d15d643e..0000000000 --- a/firmware/target/arm/gigabeat/meg-fx/system-target.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Greg White - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "mmu-meg-fx.h" - -static inline void invalidate_icache(void) -{ - clean_dcache(); - asm volatile( - "mov r0, #0 \n" - "mcr p15, 0, r0, c7, c5, 0 \n" - : : : "r0" - ); -} - diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c index 3e8246b367..93d79633b1 100644 --- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c @@ -112,16 +112,6 @@ static inline void lcd_write_reg(unsigned int reg, unsigned int data) lcd_send_msg(0x72, data); } -static inline void cache_flush(void) -{ -#ifndef BOOTLOADER - outl(inl(0xf000f044) | 0x2, 0xf000f044); - while ((CACHE_CTL & 0x8000) != 0) - { - } -#endif -} - /* The LCD controller gets passed the address of the framebuffer, but can only use the physical, not the remapped, address. This is a quick and dirty way of correcting it */ @@ -271,7 +261,7 @@ inline void lcd_update_rect(int x, int y, int width, int height) memcpy(((char*)&lcd_driver_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); - cache_flush(); + flush_icache(); /* Restart DMA */ LCD_REG_6 |= 1; @@ -287,7 +277,7 @@ inline void lcd_update(void) /* Copy the Rockbox framebuffer to the second framebuffer */ memcpy(lcd_driver_framebuffer, lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); - cache_flush(); + flush_icache(); /* Restart DMA */ LCD_REG_6 |= 1; diff --git a/firmware/target/arm/system-pp.h b/firmware/target/arm/system-pp.h new file mode 100644 index 0000000000..05fd8b6edf --- /dev/null +++ b/firmware/target/arm/system-pp.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Alan Korr + * Copyright (C) 2007 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#define inl(a) (*(volatile unsigned long *) (a)) +#define outl(a,b) (*(volatile unsigned long *) (b) = (a)) +#define inb(a) (*(volatile unsigned char *) (a)) +#define outb(a,b) (*(volatile unsigned char *) (b) = (a)) +#define inw(a) (*(volatile unsigned short *) (a)) +#define outw(a,b) (*(volatile unsigned short *) (b) = (a)) +extern unsigned int ipod_hw_rev; + +static inline void udelay(unsigned usecs) +{ + unsigned stop = USEC_TIMER + usecs; + while (TIME_BEFORE(USEC_TIMER, stop)); +} + +unsigned int current_core(void); + +#define HAVE_INVALIDATE_ICACHE +static inline void invalidate_icache(void) +{ + outl(inl(0xf000f044) | 0x6, 0xf000f044); + while ((CACHE_CTL & 0x8000) != 0); +} + +#define HAVE_FLUSH_ICACHE +static inline void flush_icache(void) +{ + outl(inl(0xf000f044) | 0x2, 0xf000f044); + while ((CACHE_CTL & 0x8000) != 0); +} diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h new file mode 100644 index 0000000000..ceb8be2079 --- /dev/null +++ b/firmware/target/arm/system-target.h @@ -0,0 +1,155 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Alan Korr + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef SYSTEM_TARGET_H +#define SYSTEM_TARGET_H + +#define nop \ + asm volatile ("nop") + +/* This gets too complicated otherwise with all the ARM variation and would + have conflicts with another system-target.h elsewhere so include a + subheader from here. */ + +#ifdef CPU_PP +#include "system-pp.h" +#elif CONFIG_CPU == S3C2440 +#include "system-meg-fx.h" +#endif + +/* TODO: Implement set_irq_level and check CPU frequencies */ + +#if CONFIG_CPU == S3C2440 + +#define CPUFREQ_DEFAULT 98784000 +#define CPUFREQ_NORMAL 98784000 +#define CPUFREQ_MAX 296352000 + +#elif CONFIG_CPU == PNX0101 + +#define CPUFREQ_DEFAULT 12000000 +#define CPUFREQ_NORMAL 48000000 +#define CPUFREQ_MAX 60000000 + +#else + +#define CPUFREQ_DEFAULT_MULT 8 +#define CPUFREQ_DEFAULT 24000000 +#define CPUFREQ_NORMAL_MULT 10 +#define CPUFREQ_NORMAL 30000000 +#define CPUFREQ_MAX_MULT 25 +#define CPUFREQ_MAX 75000000 + +#endif + +static inline uint16_t swap16(uint16_t value) + /* + result[15..8] = value[ 7..0]; + result[ 7..0] = value[15..8]; + */ +{ + return (value >> 8) | (value << 8); +} + +static inline uint32_t swap32(uint32_t value) + /* + result[31..24] = value[ 7.. 0]; + result[23..16] = value[15.. 8]; + result[15.. 8] = value[23..16]; + result[ 7.. 0] = value[31..24]; + */ +{ + uint32_t tmp; + + asm volatile ( + "eor %1, %0, %0, ror #16 \n\t" + "bic %1, %1, #0xff0000 \n\t" + "mov %0, %0, ror #8 \n\t" + "eor %0, %0, %1, lsr #8 \n\t" + : "+r" (value), "=r" (tmp) + ); + return value; +} + +static inline uint32_t swap_odd_even32(uint32_t value) +{ + /* + result[31..24],[15.. 8] = value[23..16],[ 7.. 0] + result[23..16],[ 7.. 0] = value[31..24],[15.. 8] + */ + uint32_t tmp; + + asm volatile ( /* ABCD */ + "bic %1, %0, #0x00ff00 \n\t" /* AB.D */ + "bic %0, %0, #0xff0000 \n\t" /* A.CD */ + "mov %0, %0, lsr #8 \n\t" /* .A.C */ + "orr %0, %0, %1, lsl #8 \n\t" /* B.D.|.A.C */ + : "+r" (value), "=r" (tmp) /* BADC */ + ); + return value; +} + +#define HIGHEST_IRQ_LEVEL (1) + +static inline int set_irq_level(int level) +{ + unsigned long cpsr; + /* Read the old level and set the new one */ + asm volatile ("mrs %0,cpsr" : "=r" (cpsr)); + asm volatile ("msr cpsr_c,%0" + : : "r" ((cpsr & ~0x80) | (level << 7))); + return (cpsr >> 7) & 1; +} + +static inline void set_fiq_handler(void(*fiq_handler)(void)) +{ + /* Install the FIQ handler */ + *((unsigned int*)(15*4)) = (unsigned int)fiq_handler; +} + +static inline void enable_fiq(void) +{ + /* Clear FIQ disable bit */ + asm volatile ( + "mrs r0, cpsr \n"\ + "bic r0, r0, #0x40 \n"\ + "msr cpsr_c, r0 " + : : : "r0" + ); +} + +static inline void disable_fiq(void) +{ + /* Set FIQ disable bit */ + asm volatile ( + "mrs r0, cpsr \n"\ + "orr r0, r0, #0x40 \n"\ + "msr cpsr_c, r0 " + : : : "r0" + ); +} + +#if CONFIG_CPU == PNX0101 +typedef void (*interrupt_handler_t)(void); + +void irq_set_int_handler(int n, interrupt_handler_t handler); +void irq_enable_int(int n); +void irq_disable_int(int n); +#endif + +#endif /* SYSTEM_TARGET_H */ diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h index 40542353be..6f1b2eb4ae 100644 --- a/firmware/target/coldfire/system-target.h +++ b/firmware/target/coldfire/system-target.h @@ -19,6 +19,9 @@ #ifndef SYSTEM_TARGET_H #define SYSTEM_TARGET_H +#define nop \ + asm volatile ("trapf") + #define or_l(mask, address) \ asm \ ("or.l %0,(%1)" \ @@ -147,6 +150,7 @@ static inline uint32_t swap_odd_even32(uint32_t value) return value; } +#define HAVE_INVALIDATE_ICACHE static inline void invalidate_icache(void) { asm volatile ("move.l #0x01000000,%d0\n" -- cgit v1.2.3