diff options
Diffstat (limited to 'lib_blackfin')
-rw-r--r-- | lib_blackfin/Makefile | 2 | ||||
-rw-r--r-- | lib_blackfin/board.c | 37 | ||||
-rw-r--r-- | lib_blackfin/config.mk | 10 | ||||
-rw-r--r-- | lib_blackfin/ins.S | 117 | ||||
-rw-r--r-- | lib_blackfin/outs.S | 60 | ||||
-rw-r--r-- | lib_blackfin/u-boot.lds.S | 49 |
6 files changed, 245 insertions, 30 deletions
diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index cbf47f0..eebb131 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -31,10 +31,12 @@ CFLAGS += -DBFIN_BOARD_NAME='"$(BOARD)"' LIB = $(obj)lib$(ARCH).a +SOBJS-y += ins.o SOBJS-y += memcmp.o SOBJS-y += memcpy.o SOBJS-y += memmove.o SOBJS-y += memset.o +SOBJS-y += outs.o COBJS-y += board.o COBJS-y += boot.o diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 6cade7d..90da2b4 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -14,6 +14,7 @@ #include <stdio_dev.h> #include <environment.h> #include <malloc.h> +#include <mmc.h> #include <net.h> #include <timestamp.h> #include <status_led.h> @@ -130,17 +131,26 @@ void init_cplbtables(void) dcplb_add(0xFF800000, L1_DMEMORY); ++i; - icplb_add(CONFIG_SYS_MONITOR_BASE & CPLB_PAGE_MASK, SDRAM_IKERNEL); - dcplb_add(CONFIG_SYS_MONITOR_BASE & CPLB_PAGE_MASK, SDRAM_DKERNEL); - ++i; + if (CONFIG_MEM_SIZE) { + uint32_t mbase = CONFIG_SYS_MONITOR_BASE; + uint32_t mend = mbase + CONFIG_SYS_MONITOR_LEN; + mbase &= CPLB_PAGE_MASK; + mend &= CPLB_PAGE_MASK; - /* If the monitor crosses a 4 meg boundary, we'll need - * to lock two entries for it. - */ - if ((CONFIG_SYS_MONITOR_BASE & CPLB_PAGE_MASK) != ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) & CPLB_PAGE_MASK)) { - icplb_add((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) & CPLB_PAGE_MASK, SDRAM_IKERNEL); - dcplb_add((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) & CPLB_PAGE_MASK, SDRAM_DKERNEL); + icplb_add(mbase, SDRAM_IKERNEL); + dcplb_add(mbase, SDRAM_DKERNEL); ++i; + + /* + * If the monitor crosses a 4 meg boundary, we'll need + * to lock two entries for it. We assume it doesn't + * cross two 4 meg boundaries ... + */ + if (mbase != mend) { + icplb_add(mend, SDRAM_IKERNEL); + dcplb_add(mend, SDRAM_DKERNEL); + ++i; + } } icplb_add(0x20000000, SDRAM_INON_CHBL); @@ -239,6 +249,8 @@ void board_init_f(ulong bootflag) bd->bi_vco = get_vco(); bd->bi_cclk = get_cclk(); bd->bi_sclk = get_sclk(); + bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; + bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; /* Initialize */ serial_early_puts("IRQ init\n"); @@ -262,7 +274,7 @@ void board_init_f(ulong bootflag) printf("System: %s MHz\n", strmhz(buf, get_sclk())); printf("RAM: "); - print_size(initdram(0), "\n"); + print_size(bd->bi_memsize, "\n"); #if defined(CONFIG_POST) post_init_f(); post_bootmode_init(); @@ -329,6 +341,11 @@ void board_init_r(gd_t * id, ulong dest_addr) nand_init(); /* go init the NAND */ #endif +#ifdef CONFIG_GENERIC_MMC + puts("MMC: "); + mmc_initialize(bd); +#endif + /* relocate environment function pointers etc. */ env_relocate(); diff --git a/lib_blackfin/config.mk b/lib_blackfin/config.mk index ce2fe67..323d28f 100644 --- a/lib_blackfin/config.mk +++ b/lib_blackfin/config.mk @@ -43,6 +43,11 @@ endif ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) ALL += $(obj)u-boot.ldr endif +ifeq ($(CONFIG_ENV_IS_EMBEDDED_IN_LDR),y) +CREATE_LDR_ENV = $(obj)tools/envcrc --binary > $(obj)env-ldr.o +else +CREATE_LDR_ENV = +endif SYM_PREFIX = _ @@ -53,9 +58,8 @@ LDR_FLAGS += --bmode $(subst BFIN_BOOT_,,$(CONFIG_BFIN_BOOT_MODE)) LDR_FLAGS += --use-vmas LDR_FLAGS += --initcode $(obj)cpu/$(CPU)/initcode.o ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_UART) -ifneq ($(ENV_IS_EMBEDDED_CUSTOM),ENV_IS_EMBEDDED_CUSTOM) -LDR_FLAGS += --punchit $$(($(CONFIG_ENV_OFFSET))):$$(($(CONFIG_ENV_SIZE))):$(obj)env-ldr.o -endif +LDR_FLAGS-$(CONFIG_ENV_IS_EMBEDDED_IN_LDR) += \ + --punchit $$(($(CONFIG_ENV_OFFSET))):$$(($(CONFIG_ENV_SIZE))):$(obj)env-ldr.o endif ifneq (,$(findstring s,$(MAKEFLAGS))) LDR_FLAGS += --quiet diff --git a/lib_blackfin/ins.S b/lib_blackfin/ins.S new file mode 100644 index 0000000..4519596 --- /dev/null +++ b/lib_blackfin/ins.S @@ -0,0 +1,117 @@ +/* + * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops + * + * Copyright 2004-2008 Analog Devices Inc. + * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl> + * Licensed under the GPL-2 or later. + */ + +#include <asm/blackfin.h> + +.align 2 + +#ifdef CONFIG_IPIPE +# define DO_CLI \ + [--sp] = rets; \ + [--sp] = (P5:0); \ + sp += -12; \ + call ___ipipe_disable_root_irqs_hw; \ + sp += 12; \ + (P5:0) = [sp++]; +# define CLI_INNER_NOP +#else +# define DO_CLI cli R3; +# define CLI_INNER_NOP nop; nop; nop; +#endif + +#ifdef CONFIG_IPIPE +# define DO_STI \ + sp += -12; \ + call ___ipipe_enable_root_irqs_hw; \ + sp += 12; \ +2: rets = [sp++]; +#else +# define DO_STI 2: sti R3; +#endif + +#ifdef CONFIG_BFIN_INS_LOWOVERHEAD +# define CLI_OUTER DO_CLI; +# define STI_OUTER DO_STI; +# define CLI_INNER 1: +# if ANOMALY_05000416 +# define STI_INNER nop; 2: nop; +# else +# define STI_INNER 2: +# endif +#else +# define CLI_OUTER +# define STI_OUTER +# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP; +# define STI_INNER DO_STI; +#endif + +/* + * Reads on the Blackfin are speculative. In Blackfin terms, this means they + * can be interrupted at any time (even after they have been issued on to the + * external bus), and re-issued after the interrupt occurs. + * + * If a FIFO is sitting on the end of the read, it will see two reads, + * when the core only sees one. The FIFO receives the read which is cancelled, + * and not delivered to the core. + * + * To solve this, interrupts are turned off before reads occur to I/O space. + * There are 3 versions of all these functions + * - turns interrupts off every read (higher overhead, but lower latency) + * - turns interrupts off every loop (low overhead, but longer latency) + * - DMA version, which do not suffer from this issue. DMA versions have + * different name (prefixed by dma_ ), and are located in + * ../kernel/bfin_dma_5xx.c + * Using the dma related functions are recommended for transfering large + * buffers in/out of FIFOs. + */ + +#define COMMON_INS(func, ops) \ +ENTRY(_ins##func) \ + P0 = R0; /* P0 = port */ \ + CLI_OUTER; /* 3 instructions before first read access */ \ + P1 = R1; /* P1 = address */ \ + P2 = R2; /* P2 = count */ \ + SSYNC; \ + \ + LSETUP(1f, 2f) LC0 = P2; \ + CLI_INNER; \ + ops; \ + STI_INNER; \ + \ + STI_OUTER; \ + RTS; \ +ENDPROC(_ins##func) + +COMMON_INS(l, \ + R0 = [P0]; \ + [P1++] = R0; \ +) + +COMMON_INS(w, \ + R0 = W[P0]; \ + W[P1++] = R0; \ +) + +COMMON_INS(w_8, \ + R0 = W[P0]; \ + B[P1++] = R0; \ + R0 = R0 >> 8; \ + B[P1++] = R0; \ +) + +COMMON_INS(b, \ + R0 = B[P0]; \ + B[P1++] = R0; \ +) + +COMMON_INS(l_16, \ + R0 = [P0]; \ + W[P1++] = R0; \ + R0 = R0 >> 16; \ + W[P1++] = R0; \ +) diff --git a/lib_blackfin/outs.S b/lib_blackfin/outs.S new file mode 100644 index 0000000..90c6033 --- /dev/null +++ b/lib_blackfin/outs.S @@ -0,0 +1,60 @@ +/* + * Implementation of outs{bwl} for BlackFin processors using zero overhead loops. + * + * Copyright 2005-2009 Analog Devices Inc. + * 2005 BuyWays BV + * Bas Vermeulen <bas@buyways.nl> + * + * Licensed under the GPL-2. + */ + +#include <asm/linkage.h> + +.align 2 + +ENTRY(_outsl) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; +.Llong_loop_s: R0 = [P1++]; +.Llong_loop_e: [P0] = R0; + RTS; +ENDPROC(_outsl) + +ENTRY(_outsw) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; +.Lword_loop_s: R0 = W[P1++]; +.Lword_loop_e: W[P0] = R0; + RTS; +ENDPROC(_outsw) + +ENTRY(_outsb) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; +.Lbyte_loop_s: R0 = B[P1++]; +.Lbyte_loop_e: B[P0] = R0; + RTS; +ENDPROC(_outsb) + +ENTRY(_outsw_8) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2; +.Lword8_loop_s: R1 = B[P1++]; + R0 = B[P1++]; + R0 = R0 << 8; + R0 = R0 + R1; +.Lword8_loop_e: W[P0] = R0; + RTS; +ENDPROC(_outsw_8) diff --git a/lib_blackfin/u-boot.lds.S b/lib_blackfin/u-boot.lds.S index 3604b78..3be341f 100644 --- a/lib_blackfin/u-boot.lds.S +++ b/lib_blackfin/u-boot.lds.S @@ -57,7 +57,14 @@ OUTPUT_ARCH(bfin) MEMORY { +#if CONFIG_MEM_SIZE ram : ORIGIN = CONFIG_SYS_MONITOR_BASE, LENGTH = CONFIG_SYS_MONITOR_LEN +# define ram_code ram +# define ram_data ram +#else +# define ram_code l1_code +# define ram_data l1_data +#endif l1_code : ORIGIN = L1_CODE_ORIGIN, LENGTH = L1_INST_SRAM_SIZE l1_data : ORIGIN = L1_DATA_B_SRAM, LENGTH = L1_DATA_B_SRAM_SIZE } @@ -65,27 +72,31 @@ MEMORY ENTRY(_start) SECTIONS { - .text : + .text.pre : { cpu/blackfin/start.o (.text .text.*) LDS_BOARD_TEXT + } >ram_code - __initcode_start = .; + .text.init : + { cpu/blackfin/initcode.o (.text .text.*) - __initcode_end = .; + } >ram_code + __initcode_lma = LOADADDR(.text.init); + __initcode_len = SIZEOF(.text.init); + .text : + { *(.text .text.*) - } >ram + } >ram_code .rodata : { . = ALIGN(4); - *(.rodata .rodata.*) - *(.rodata1) - *(.eh_frame) + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) . = ALIGN(4); - } >ram + } >ram_data .data : { @@ -96,14 +107,14 @@ SECTIONS *(.sdata2) *(.dynamic) CONSTRUCTORS - } >ram + } >ram_data .u_boot_cmd : { ___u_boot_cmd_start = .; *(.u_boot_cmd) ___u_boot_cmd_end = .; - } >ram + } >ram_data .text_l1 : { @@ -112,8 +123,10 @@ SECTIONS *(.l1.text) . = ALIGN(4); __etext_l1 = .; - } >l1_code AT>ram - __stext_l1_lma = LOADADDR(.text_l1); + } >l1_code AT>ram_code + __text_l1_lma = LOADADDR(.text_l1); + __text_l1_len = SIZEOF(.text_l1); + ASSERT (__text_l1_len <= L1_INST_SRAM_SIZE, "L1 text overflow!") .data_l1 : { @@ -123,17 +136,19 @@ SECTIONS *(.l1.bss) . = ALIGN(4); __edata_l1 = .; - } >l1_data AT>ram - __sdata_l1_lma = LOADADDR(.data_l1); + } >l1_data AT>ram_data + __data_l1_lma = LOADADDR(.data_l1); + __data_l1_len = SIZEOF(.data_l1); + ASSERT (__data_l1_len <= L1_DATA_B_SRAM_SIZE, "L1 data B overflow!") .bss : { . = ALIGN(4); - __bss_start = .; *(.sbss) *(.scommon) *(.dynbss) *(.bss .bss.*) *(COMMON) - __bss_end = .; - } >ram + } >ram_data + __bss_vma = ADDR(.bss); + __bss_len = SIZEOF(.bss); } |