diff options
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/lib/board.c | 259 | ||||
-rw-r--r-- | arch/arm/lib/cache-cp15.c | 22 | ||||
-rw-r--r-- | arch/arm/lib/cache-pl310.c | 115 | ||||
-rw-r--r-- | arch/arm/lib/cache.c | 20 |
5 files changed, 275 insertions, 146 deletions
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 03b1b5e4af..300c8fab2d 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o LIBGCC = $(obj)libgcc.o +ifndef CONFIG_SPL_BUILD GLSOBJS += _ashldi3.o GLSOBJS += _ashrdi3.o GLSOBJS += _divsi3.o @@ -39,13 +40,13 @@ GLCOBJS += div0.o COBJS-y += board.o COBJS-y += bootm.o COBJS-y += cache.o -ifndef CONFIG_SYS_NO_CP15_CACHE COBJS-y += cache-cp15.o -endif +COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o +endif SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 1a784a1e19..14a56f6f0a 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -42,7 +42,6 @@ #include <command.h> #include <malloc.h> #include <stdio_dev.h> -#include <timestamp.h> #include <version.h> #include <net.h> #include <serial.h> @@ -70,13 +69,6 @@ extern int AT91F_DataflashInit(void); extern void dataflash_print_info(void); #endif -#ifndef CONFIG_IDENT_STRING -#define CONFIG_IDENT_STRING "" -#endif - -const char version_string[] = - U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING; - #ifdef CONFIG_DRIVER_RTL8019 extern void rtl8019_get_enetaddr (uchar * addr); #endif @@ -92,26 +84,28 @@ extern void rtl8019_get_enetaddr (uchar * addr); ************************************************************************ * May be supplied by boards if desired */ -void inline __coloured_LED_init (void) {} -void coloured_LED_init (void) __attribute__((weak, alias("__coloured_LED_init"))); -void inline __red_LED_on (void) {} -void red_LED_on (void) __attribute__((weak, alias("__red_LED_on"))); -void inline __red_LED_off(void) {} +inline void __coloured_LED_init(void) {} +void coloured_LED_init(void) + __attribute__((weak, alias("__coloured_LED_init"))); +inline void __red_LED_on(void) {} +void red_LED_on(void) __attribute__((weak, alias("__red_LED_on"))); +inline void __red_LED_off(void) {} void red_LED_off(void) __attribute__((weak, alias("__red_LED_off"))); -void inline __green_LED_on(void) {} +inline void __green_LED_on(void) {} void green_LED_on(void) __attribute__((weak, alias("__green_LED_on"))); -void inline __green_LED_off(void) {} +inline void __green_LED_off(void) {} void green_LED_off(void) __attribute__((weak, alias("__green_LED_off"))); -void inline __yellow_LED_on(void) {} +inline void __yellow_LED_on(void) {} void yellow_LED_on(void) __attribute__((weak, alias("__yellow_LED_on"))); -void inline __yellow_LED_off(void) {} +inline void __yellow_LED_off(void) {} void yellow_LED_off(void) __attribute__((weak, alias("__yellow_LED_off"))); -void inline __blue_LED_on(void) {} +inline void __blue_LED_on(void) {} void blue_LED_on(void) __attribute__((weak, alias("__blue_LED_on"))); -void inline __blue_LED_off(void) {} +inline void __blue_LED_off(void) {} void blue_LED_off(void) __attribute__((weak, alias("__blue_LED_off"))); -/************************************************************************ +/* + ************************************************************************ * Init Utilities * ************************************************************************ * Some of this code should be moved into the core functions, @@ -122,30 +116,30 @@ void blue_LED_off(void) __attribute__((weak, alias("__blue_LED_off"))); #if defined(CONFIG_ARM_DCC) && !defined(CONFIG_BAUDRATE) #define CONFIG_BAUDRATE 115200 #endif -static int init_baudrate (void) +static int init_baudrate(void) { char tmp[64]; /* long enough for environment variables */ - int i = getenv_f("baudrate", tmp, sizeof (tmp)); + int i = getenv_f("baudrate", tmp, sizeof(tmp)); gd->baudrate = (i > 0) - ? (int) simple_strtoul (tmp, NULL, 10) + ? (int) simple_strtoul(tmp, NULL, 10) : CONFIG_BAUDRATE; return (0); } -static int display_banner (void) +static int display_banner(void) { - printf ("\n\n%s\n\n", version_string); - debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n", + printf("\n\n%s\n\n", version_string); + debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n", _TEXT_BASE, - _bss_start_ofs+_TEXT_BASE, _bss_end_ofs+_TEXT_BASE); + _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE); #ifdef CONFIG_MODEM_SUPPORT - debug ("Modem Support enabled\n"); + debug("Modem Support enabled\n"); #endif #ifdef CONFIG_USE_IRQ - debug ("IRQ Stack: %08lx\n", IRQ_STACK_START); - debug ("FIQ Stack: %08lx\n", FIQ_STACK_START); + debug("IRQ Stack: %08lx\n", IRQ_STACK_START); + debug("FIQ Stack: %08lx\n", FIQ_STACK_START); #endif return (0); @@ -158,23 +152,23 @@ static int display_banner (void) * gives a simple yet clear indication which part of the * initialization if failing. */ -static int display_dram_config (void) +static int display_dram_config(void) { int i; #ifdef DEBUG - puts ("RAM Configuration:\n"); + puts("RAM Configuration:\n"); - for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) { - printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); - print_size (gd->bd->bi_dram[i].size, "\n"); + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); + print_size(gd->bd->bi_dram[i].size, "\n"); } #else ulong size = 0; - for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) { + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) size += gd->bd->bi_dram[i].size; - } + puts("DRAM: "); print_size(size, "\n"); #endif @@ -183,11 +177,11 @@ static int display_dram_config (void) } #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) -static int init_func_i2c (void) +static int init_func_i2c(void) { - puts ("I2C: "); - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - puts ("ready\n"); + puts("I2C: "); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + puts("ready\n"); return (0); } #endif @@ -226,7 +220,7 @@ static int arm_pci_init(void) */ typedef int (init_fnc_t) (void); -int print_cpuinfo (void); +int print_cpuinfo(void); void __dram_init_banksize(void) { @@ -262,13 +256,10 @@ init_fnc_t *init_sequence[] = { init_func_i2c, #endif dram_init, /* configure available RAM banks */ -#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) - arm_pci_init, -#endif NULL, }; -void board_init_f (ulong bootflag) +void board_init_f(ulong bootflag) { bd_t *bd; init_fnc_t **init_fnc_ptr; @@ -280,21 +271,25 @@ void board_init_f (ulong bootflag) /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); - memset ((void*)gd, 0, sizeof (gd_t)); + memset((void *)gd, 0, sizeof(gd_t)); gd->mon_len = _bss_end_ofs; +#ifdef CONFIG_MACH_TYPE + gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ +#endif + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } - debug ("monitor len: %08lX\n", gd->mon_len); + debug("monitor len: %08lX\n", gd->mon_len); /* * Ram is setup, size stored in gd !! */ - debug ("ramsize: %08lX\n", gd->ram_size); + debug("ramsize: %08lX\n", gd->ram_size); #if defined(CONFIG_SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't @@ -315,7 +310,8 @@ void board_init_f (ulong bootflag) #ifndef CONFIG_ALT_LB_ADDR /* reserve kernel log buffer */ addr -= (LOGBUFF_RESERVE); - debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); + debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, + addr); #endif #endif @@ -323,13 +319,14 @@ void board_init_f (ulong bootflag) /* * reserve protected RAM */ - i = getenv_r ("pram", (char *)tmp, sizeof (tmp)); - reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM; + i = getenv_r("pram", (char *)tmp, sizeof(tmp)); + reg = (i > 0) ? simple_strtoul((const char *)tmp, NULL, 10) : + CONFIG_PRAM; addr -= (reg << 10); /* size is in kB */ - debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); + debug("Reserving %ldk for protected RAM at %08lx\n", reg, addr); #endif /* CONFIG_PRAM */ -#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) /* reserve TLB table */ addr -= (4096 * 4); @@ -337,30 +334,19 @@ void board_init_f (ulong bootflag) addr &= ~(0x10000 - 1); gd->tlb_addr = addr; - debug ("TLB table at: %08lx\n", addr); + debug("TLB table at: %08lx\n", addr); #endif /* round down to next 4 kB limit */ addr &= ~(4096 - 1); - debug ("Top of RAM usable for U-Boot at: %08lx\n", addr); - -#ifdef CONFIG_VFD -# ifndef PAGE_SIZE -# define PAGE_SIZE 4096 -# endif - /* - * reserve memory for VFD display (always full pages) - */ - addr -= vfd_setmem (addr); - gd->fb_base = addr; -#endif /* CONFIG_VFD */ + debug("Top of RAM usable for U-Boot at: %08lx\n", addr); #ifdef CONFIG_LCD #ifdef CONFIG_FB_ADDR gd->fb_base = CONFIG_FB_ADDR; #else /* reserve memory for LCD display (always full pages) */ - addr = lcd_setmem (addr); + addr = lcd_setmem(addr); gd->fb_base = addr; #endif /* CONFIG_FB_ADDR */ #endif /* CONFIG_LCD */ @@ -372,14 +358,14 @@ void board_init_f (ulong bootflag) addr -= gd->mon_len; addr &= ~(4096 - 1); - debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr); + debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr); -#ifndef CONFIG_PRELOADER +#ifndef CONFIG_SPL_BUILD /* * reserve memory for malloc() arena */ addr_sp = addr - TOTAL_MALLOC_LEN; - debug ("Reserving %dk for malloc() at: %08lx\n", + debug("Reserving %dk for malloc() at: %08lx\n", TOTAL_MALLOC_LEN >> 10, addr_sp); /* * (permanently) allocate a Board Info struct @@ -388,18 +374,18 @@ void board_init_f (ulong bootflag) addr_sp -= sizeof (bd_t); bd = (bd_t *) addr_sp; gd->bd = bd; - debug ("Reserving %zu Bytes for Board Info at: %08lx\n", + debug("Reserving %zu Bytes for Board Info at: %08lx\n", sizeof (bd_t), addr_sp); addr_sp -= sizeof (gd_t); id = (gd_t *) addr_sp; - debug ("Reserving %zu Bytes for Global Data at: %08lx\n", + debug("Reserving %zu Bytes for Global Data at: %08lx\n", sizeof (gd_t), addr_sp); /* setup stackpointer for exeptions */ gd->irq_sp = addr_sp; #ifdef CONFIG_USE_IRQ addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); - debug ("Reserving %zu Bytes for IRQ stack at: %08lx\n", + debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); #endif /* leave 3 words for abort-stack */ @@ -412,11 +398,11 @@ void board_init_f (ulong bootflag) gd->irq_sp = addr_sp; #endif - debug ("New Stack Pointer is: %08lx\n", addr_sp); + debug("New Stack Pointer is: %08lx\n", addr_sp); #ifdef CONFIG_POST post_bootmode_init(); - post_run (NULL, POST_ROM | post_bootmode_get(0)); + post_run(NULL, POST_ROM | post_bootmode_get(0)); #endif gd->bd->bi_baudrate = gd->baudrate; @@ -427,10 +413,10 @@ void board_init_f (ulong bootflag) gd->relocaddr = addr; gd->start_addr_sp = addr_sp; gd->reloc_off = addr - _TEXT_BASE; - debug ("relocation Offset is: %08lx\n", gd->reloc_off); - memcpy (id, (void *)gd, sizeof (gd_t)); + debug("relocation Offset is: %08lx\n", gd->reloc_off); + memcpy(id, (void *)gd, sizeof(gd_t)); - relocate_code (addr_sp, id, addr); + relocate_code(addr_sp, id, addr); /* NOTREACHED - relocate_code() does not return */ } @@ -439,7 +425,8 @@ void board_init_f (ulong bootflag) static char *failed = "*** failed ***\n"; #endif -/************************************************************************ +/* + ************************************************************************ * * This is the next part if the initialization sequence: we are now * running from RAM and have a "normal" C environment, i. e. global @@ -449,7 +436,7 @@ static char *failed = "*** failed ***\n"; ************************************************************************ */ -void board_init_r (gd_t *id, ulong dest_addr) +void board_init_r(gd_t *id, ulong dest_addr) { char *s; bd_t *bd; @@ -464,20 +451,26 @@ void board_init_r (gd_t *id, ulong dest_addr) gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ monitor_flash_len = _end_ofs; - debug ("monitor flash len: %08lX\n", monitor_flash_len); + /* + * Enable D$: + * I$, if needed, must be already enabled in start.S + */ + dcache_enable(); + + debug("monitor flash len: %08lX\n", monitor_flash_len); board_init(); /* Setup chipselects */ #ifdef CONFIG_SERIAL_MULTI serial_initialize(); #endif - debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr); + debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); #ifdef CONFIG_LOGBUFFER - logbuff_init_ptrs (); + logbuff_init_ptrs(); #endif #ifdef CONFIG_POST - post_output_backlog (); + post_output_backlog(); #endif /* The Malloc area is immediately below the monitor copy in DRAM */ @@ -485,34 +478,35 @@ void board_init_r (gd_t *id, ulong dest_addr) mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); #if !defined(CONFIG_SYS_NO_FLASH) - puts ("Flash: "); + puts("Flash: "); - if ((flash_size = flash_init ()) > 0) { + flash_size = flash_init(); + if (flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM - print_size (flash_size, ""); + print_size(flash_size, ""); /* * Compute and print flash CRC if flashchecksum is set to 'y' * * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX */ - s = getenv ("flashchecksum"); + s = getenv("flashchecksum"); if (s && (*s == 'y')) { - printf (" CRC: %08X", - crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size) - ); + printf(" CRC: %08X", crc32(0, + (const unsigned char *) CONFIG_SYS_FLASH_BASE, + flash_size)); } - putc ('\n'); + putc('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ - print_size (flash_size, "\n"); + print_size(flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ } else { - puts (failed); - hang (); + puts(failed); + hang(); } #endif #if defined(CONFIG_CMD_NAND) - puts ("NAND: "); + puts("NAND: "); nand_init(); /* go init the NAND */ #endif @@ -531,45 +525,44 @@ void board_init_r (gd_t *id, ulong dest_addr) #endif /* initialize environment */ - env_relocate (); + env_relocate(); -#ifdef CONFIG_VFD - /* must do this after the framebuffer is allocated */ - drv_vfd_init(); -#endif /* CONFIG_VFD */ +#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI) + arm_pci_init(); +#endif /* IP Address */ - gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr"); - stdio_init (); /* get the devices list going. */ + stdio_init(); /* get the devices list going. */ - jumptable_init (); + jumptable_init(); #if defined(CONFIG_API) /* Initialize API */ - api_init (); + api_init(); #endif - console_init_r (); /* fully init console as a device */ + console_init_r(); /* fully init console as a device */ #if defined(CONFIG_ARCH_MISC_INIT) /* miscellaneous arch dependent initialisations */ - arch_misc_init (); + arch_misc_init(); #endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ - misc_init_r (); + misc_init_r(); #endif /* set up exceptions */ - interrupt_init (); + interrupt_init(); /* enable exceptions */ - enable_interrupts (); + enable_interrupts(); /* Perform network card initialisation if necessary */ #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) /* XXX: this needs to be moved to board init */ - if (getenv ("ethaddr")) { + if (getenv("ethaddr")) { uchar enetaddr[6]; eth_getenv_enetaddr("ethaddr", enetaddr); smc_set_mac_addr(enetaddr); @@ -577,17 +570,17 @@ void board_init_r (gd_t *id, ulong dest_addr) #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ /* Initialize from environment */ - if ((s = getenv ("loadaddr")) != NULL) { - load_addr = simple_strtoul (s, NULL, 16); - } + s = getenv("loadaddr"); + if (s != NULL) + load_addr = simple_strtoul(s, NULL, 16); #if defined(CONFIG_CMD_NET) - if ((s = getenv ("bootfile")) != NULL) { - copy_filename (BootFile, s, sizeof (BootFile)); - } + s = getenv("bootfile"); + if (s != NULL) + copy_filename(BootFile, s, sizeof(BootFile)); #endif #ifdef BOARD_LATE_INIT - board_late_init (); + board_late_init(); #endif #ifdef CONFIG_BITBANGMII @@ -595,17 +588,17 @@ void board_init_r (gd_t *id, ulong dest_addr) #endif #if defined(CONFIG_CMD_NET) #if defined(CONFIG_NET_MULTI) - puts ("Net: "); + puts("Net: "); #endif eth_initialize(gd->bd); #if defined(CONFIG_RESET_PHY_R) - debug ("Reset Ethernet PHY\n"); + debug("Reset Ethernet PHY\n"); reset_phy(); #endif #endif #ifdef CONFIG_POST - post_run (NULL, POST_RAM | post_bootmode_get(0)); + post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) @@ -619,35 +612,35 @@ void board_init_r (gd_t *id, ulong dest_addr) #ifdef CONFIG_PRAM char *s; - if ((s = getenv ("pram")) != NULL) { - pram = simple_strtoul (s, NULL, 10); - } else { + s = getenv("pram"); + if (s != NULL) + pram = simple_strtoul(s, NULL, 10); + else pram = CONFIG_PRAM; - } #else - pram=0; + pram = 0; #endif #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR /* Also take the logbuffer into account (pram is in kB) */ - pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024; + pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; #endif #endif - sprintf ((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram); - setenv ("mem", (char *)memsz); + sprintf((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram); + setenv("mem", (char *)memsz); } #endif /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { - main_loop (); + main_loop(); } /* NOTREACHED - no way out of command loop except booting */ } -void hang (void) +void hang(void) { - puts ("### ERROR ### Please RESET the board ###\n"); + puts("### ERROR ### Please RESET the board ###\n"); for (;;); } diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index d9175f0583..e6c3eae6f9 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -24,7 +24,7 @@ #include <common.h> #include <asm/system.h> -#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) #define CACHE_SETUP 0x1a @@ -34,6 +34,12 @@ DECLARE_GLOBAL_DATA_PTR; +void __arm_init_before_mmu(void) +{ +} +void arm_init_before_mmu(void) + __attribute__((weak, alias("__arm_init_before_mmu"))); + static void cp_delay (void) { volatile int i; @@ -65,6 +71,7 @@ static inline void mmu_setup(void) int i; u32 reg; + arm_init_before_mmu(); /* Set up an identity-mapping for all 4GB, rw for everyone */ for (i = 0; i < 4096; i++) page_table[i] = i << 20 | (3 << 10) | 0x12; @@ -85,13 +92,18 @@ static inline void mmu_setup(void) set_cr(reg | CR_M); } +static int mmu_enabled(void) +{ + return get_cr() & CR_M; +} + /* cache_bit must be either CR_I or CR_C */ static void cache_enable(uint32_t cache_bit) { uint32_t reg; /* The data cache is not active unless the mmu is enabled too */ - if (cache_bit == CR_C) + if ((cache_bit == CR_C) && !mmu_enabled()) mmu_setup(); reg = get_cr(); /* get control reg. */ cp_delay(); @@ -110,7 +122,7 @@ static void cache_disable(uint32_t cache_bit) return; /* if disabling data cache, disable mmu too */ cache_bit |= CR_M; - flush_cache(0, ~0); + flush_dcache_all(); } reg = get_cr(); cp_delay(); @@ -118,7 +130,7 @@ static void cache_disable(uint32_t cache_bit) } #endif -#ifdef CONFIG_SYS_NO_ICACHE +#ifdef CONFIG_SYS_ICACHE_OFF void icache_enable (void) { return; @@ -150,7 +162,7 @@ int icache_status(void) } #endif -#ifdef CONFIG_SYS_NO_DCACHE +#ifdef CONFIG_SYS_DCACHE_OFF void dcache_enable (void) { return; diff --git a/arch/arm/lib/cache-pl310.c b/arch/arm/lib/cache-pl310.c new file mode 100644 index 0000000000..36c629ce51 --- /dev/null +++ b/arch/arm/lib/cache-pl310.c @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <linux/types.h> +#include <asm/io.h> +#include <asm/armv7.h> +#include <asm/pl310.h> +#include <config.h> + +struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + +static void pl310_cache_sync(void) +{ + writel(0, &pl310->pl310_cache_sync); +} + +static void pl310_background_op_all_ways(u32 *op_reg) +{ + u32 assoc_16, associativity, way_mask; + + assoc_16 = readl(&pl310->pl310_aux_ctrl) & + PL310_AUX_CTRL_ASSOCIATIVITY_MASK; + if (assoc_16) + associativity = 16; + else + associativity = 8; + + way_mask = (1 << associativity) - 1; + /* Invalidate all ways */ + writel(way_mask, op_reg); + /* Wait for all ways to be invalidated */ + while (readl(op_reg) && way_mask) + ; + pl310_cache_sync(); +} + +void v7_outer_cache_inval_all(void) +{ + pl310_background_op_all_ways(&pl310->pl310_inv_way); +} + +void v7_outer_cache_flush_all(void) +{ + pl310_background_op_all_ways(&pl310->pl310_clean_inv_way); +} + +/* Flush(clean invalidate) memory from start to stop-1 */ +void v7_outer_cache_flush_range(u32 start, u32 stop) +{ + /* PL310 currently supports only 32 bytes cache line */ + u32 pa, line_size = 32; + + /* + * Align to the beginning of cache-line - this ensures that + * the first 5 bits are 0 as required by PL310 TRM + */ + start &= ~(line_size - 1); + + for (pa = start; pa < stop; pa = pa + line_size) + writel(pa, &pl310->pl310_clean_inv_line_pa); + + pl310_cache_sync(); +} + +/* invalidate memory from start to stop-1 */ +void v7_outer_cache_inval_range(u32 start, u32 stop) +{ + /* PL310 currently supports only 32 bytes cache line */ + u32 pa, line_size = 32; + + /* + * If start address is not aligned to cache-line flush the first + * line to prevent affecting somebody else's buffer + */ + if (start & (line_size - 1)) { + v7_outer_cache_flush_range(start, start + 1); + /* move to next cache line */ + start = (start + line_size - 1) & ~(line_size - 1); + } + + /* + * If stop address is not aligned to cache-line flush the last + * line to prevent affecting somebody else's buffer + */ + if (stop & (line_size - 1)) { + v7_outer_cache_flush_range(stop, stop + 1); + /* align to the beginning of this cache line */ + stop &= ~(line_size - 1); + } + + for (pa = start; pa < stop; pa = pa + line_size) + writel(pa, &pl310->pl310_inv_line_pa); + + pl310_cache_sync(); +} diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 30686fe69b..92b61a2653 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -25,7 +25,7 @@ #include <common.h> -void flush_cache (unsigned long dummy1, unsigned long dummy2) +void __flush_cache(unsigned long start, unsigned long size) { #if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136) void arm1136_cache_flush(void); @@ -38,10 +38,18 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) /* disable write buffer as well (page 2-22) */ asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); #endif -#ifdef CONFIG_OMAP34XX - void v7_flush_cache_all(void); - - v7_flush_cache_all(); -#endif return; } +void flush_cache(unsigned long start, unsigned long size) + __attribute__((weak, alias("__flush_cache"))); + +/* + * Default implementation: + * do a range flush for the entire range + */ +void __flush_dcache_all(void) +{ + flush_cache(0, ~0); +} +void flush_dcache_all(void) + __attribute__((weak, alias("__flush_dcache_all"))); |