From ed4cba79d640daa33806fa228c1a10c6bf9e2101 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sat, 12 Feb 2011 15:11:52 +1100 Subject: [PATCH] x86: Use Cache-As-RAM for initial stack --- arch/i386/cpu/sc520/Makefile | 1 + arch/i386/cpu/sc520/sc520_asm.S | 6 +-- arch/i386/cpu/sc520/sc520_car.S | 94 +++++++++++++++++++++++++++++++++ arch/i386/cpu/start.S | 35 ++++++------ include/configs/eNET.h | 20 +++++++ 5 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 arch/i386/cpu/sc520/sc520_car.S diff --git a/arch/i386/cpu/sc520/Makefile b/arch/i386/cpu/sc520/Makefile index b962b02327..3c25cbaa51 100644 --- a/arch/i386/cpu/sc520/Makefile +++ b/arch/i386/cpu/sc520/Makefile @@ -37,6 +37,7 @@ COBJS-$(CONFIG_SYS_SC520_SSI) += sc520_ssi.o COBJS-$(CONFIG_SYS_SC520_TIMER) += sc520_timer.o SOBJS-$(CONFIG_SYS_SC520) += sc520_asm.o +SOBJS-$(CONFIG_SYS_SC520) += sc520_car.o SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/i386/cpu/sc520/sc520_asm.S b/arch/i386/cpu/sc520/sc520_asm.S index 9f6cce3188..901aa61fdf 100644 --- a/arch/i386/cpu/sc520/sc520_asm.S +++ b/arch/i386/cpu/sc520/sc520_asm.S @@ -515,7 +515,7 @@ bad_ram: dram_done: /* Restore Boot Flags */ movl %ebx, %ebp - jmp mem_init_ret + ret #if CONFIG_SYS_SDRAM_ECC_ENABLE .globl init_ecc @@ -560,7 +560,7 @@ set_ecc: movb %al,(%edi) out: - jmp init_ecc_ret + ret #endif /* @@ -605,4 +605,4 @@ bank3: movl (%edi), %eax done: movl %edx, %eax - jmp get_mem_size_ret + ret diff --git a/arch/i386/cpu/sc520/sc520_car.S b/arch/i386/cpu/sc520/sc520_car.S new file mode 100644 index 0000000000..22f5225311 --- /dev/null +++ b/arch/i386/cpu/sc520/sc520_car.S @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2010 + * Graeme Russ . + * + * 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 +#include +#include + +.section .text + +.globl car_init +car_init: + /* + * How to enable Cache-As-RAM for the AMD Elan SC520: + * 1. Turn off the CPU Cache (may not be strictly required) + * 2. Set code execution PAR (usually the BOOTCS region) to be + * non-cachable + * 3. Create a Cachable PAR Region for an area of memory which is + * a) NOT where the code is being executed + * b) NOT SDRAM (Controller not initialised yet) + * c) WILL response to read requests + * The easiest way to do this is to create a second BOOTCS + * PAR mappnig with an address != the PAR in step 2 + * 4. Issue a wbinvd to invalidate the CPU cache + * 5. Turn on the CPU Cache + * 6. Read 16kB from the cached PAR region setup in step 3 + * 7. Turn off the CPU Cache (but DO NOT issue a wbinvd) + * + * The following code uses PAR2 as the cached PAR (PAR0 and PAR1 + * are avoided as these are the only two PARs which can be used + * as PCI BUS Memory regions which the board might require) + * + * The configuration of PAR2 must be set in the board configuration + * file as CONFIG_SYS_SC520_CAR_PAR + */ + + /* Configure Cache-As-RAM PAR */ + movl $CONFIG_SYS_SC520_CAR_PAR, %eax + movl $SC520_PAR2, %edi + movl %eax, (%edi) + + /* Trash the cache then turn it on */ + wbinvd + movl %cr0, %eax + andl $~(X86_CR0_NW | X86_CR0_CD), %eax + movl %eax, %cr0 + + /* + * The cache is now enabled and empty. Map a region of memory to + * it by reading that region. + */ + movl $CONFIG_SYS_CAR_ADDR, %esi + movl $CONFIG_SYS_CAR_SIZE, %ecx + shrl $2, %ecx /* we are reading longs */ + cld + rep lodsl + + /* Turn off the cache, but don't trash it */ + movl %cr0, %eax + orl $(X86_CR0_NW | X86_CR0_CD), %eax + movl %eax, %cr0 + + /* Clear the CAR region */ + xorl %eax, %eax + movl $CONFIG_SYS_CAR_ADDR, %edi + movl $CONFIG_SYS_CAR_SIZE, %ecx + shrl $2, %ecx /* we are writing longs */ + rep stosl + + /* + * Done - We should now have CONFIG_SYS_CAR_SIZE bytes of + * Cache-As-RAM + */ + jmp car_init_ret diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S index 0ce97134d5..df9ca0d277 100644 --- a/arch/i386/cpu/start.S +++ b/arch/i386/cpu/start.S @@ -72,41 +72,40 @@ _start: .globl early_board_init_ret early_board_init_ret: + /* Initialise Cache-As-RAM */ + jmp car_init +.globl car_init_ret +car_init_ret: + /* + * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, + * or fully initialised SDRAM - we really don't care which) + * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack + */ + movl $CONFIG_SYS_INIT_SP_ADDR, %esp + /* Skip memory initialization if not starting from cold-reset */ movl %ebx, %ecx andl $GD_FLG_COLD_BOOT, %ecx jz skip_mem_init /* size memory */ - jmp mem_init -.globl mem_init_ret -mem_init_ret: + call mem_init skip_mem_init: /* fetch memory size (into %eax) */ - jmp get_mem_size -.globl get_mem_size_ret -get_mem_size_ret: + call get_mem_size + movl %eax, %esp #if CONFIG_SYS_SDRAM_ECC_ENABLE /* Skip ECC initialization if not starting from cold-reset */ movl %ebx, %ecx andl $GD_FLG_COLD_BOOT, %ecx - jz init_ecc_ret - jmp init_ecc + jz skip_ecc_init + call init_ecc -.globl init_ecc_ret -init_ecc_ret: +skip_init_ecc: #endif - /* Check we have enough memory for stack */ - movl $CONFIG_SYS_STACK_SIZE, %ecx - cmpl %ecx, %eax - jb die -mem_ok: - /* Set stack pointer to upper memory limit*/ - movl %eax, %esp - /* Test the stack */ pushl $0 popl %ecx diff --git a/include/configs/eNET.h b/include/configs/eNET.h index 8b55cd3987..0891e1b27b 100644 --- a/include/configs/eNET.h +++ b/include/configs/eNET.h @@ -161,6 +161,10 @@ * 256kB Monitor */ #define CONFIG_SYS_STACK_SIZE 0x8000 +#define CONFIG_SYS_CAR_ADDR 0x19200000 +#define CONFIG_SYS_CAR_SIZE 0x00004000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_CAR_ADDR + \ + CONFIG_SYS_CAR_SIZE) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024) @@ -478,6 +482,22 @@ */ #define CONFIG_SYS_SC520_BOOTCS_PAR 0x8a01f800 +/*----------------------------------------------------------------------- + * Cache-As-RAM (Targets Boot Flash) + * + * 100 1 0 0 0 0001111 011001001000000000 }- 0x903d9200 + * \ / | | | | \--+--/ \-------+--------/ + * | | | | | | +------------ Start at 0x19200000 + * | | | | | +------------------------- 64k Region Size + * | | | | | ((15 + 1) * 4kB) + * | | | | +------------------------------ 4kB Page Size + * | | | +-------------------------------- Writes Enabled + * | | +---------------------------------- Caching Enabled + * | +------------------------------------ Execution Prevented + * +--------------------------------------- BOOTCS + */ +#define CONFIG_SYS_SC520_CAR_PAR 0x903d9200 + /*----------------------------------------------------------------------- * PAR for Low Level I/O (LEDs, Hex Switches etc) - 33 Bytes @ 0x1000, GPCS6 * -- 2.39.5