diff options
Diffstat (limited to 'arch')
32 files changed, 653 insertions, 606 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 4f738195d8..25dcf4a1a3 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -24,6 +24,7 @@ config ARM select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64 select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL config AVR32 @@ -63,6 +64,10 @@ config NIOS2 bool "Nios II architecture" select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + select OF_CONTROL + select DM + select CPU config OPENRISC bool "OpenRISC architecture" @@ -71,6 +76,7 @@ config PPC bool "PowerPC architecture" select HAVE_PRIVATE_LIBGCC select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL config SANDBOX diff --git a/arch/arm/include/asm/arch-lpc32xx/config.h b/arch/arm/include/asm/arch-lpc32xx/config.h index 2d082ef40d..845ba4f606 100644 --- a/arch/arm/include/asm/arch-lpc32xx/config.h +++ b/arch/arm/include/asm/arch-lpc32xx/config.h @@ -9,7 +9,6 @@ #ifndef _LPC32XX_CONFIG_H #define _LPC32XX_CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD /* Basic CPU architecture */ #define CONFIG_ARCH_CPU_INIT diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 4c3a94af57..80548ebbf6 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -82,31 +82,11 @@ ENTRY(_main) #else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endif - mov r2, sp - sub sp, sp, #GD_SIZE /* allocate one GD above SP */ -#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ - mov r3, sp - bic r3, r3, #7 - mov sp, r3 -#else - bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ -#endif - mov r9, sp /* GD is above SP */ - mov r1, sp + mov r0, sp + bl board_init_f_mem + mov sp, r0 + mov r0, #0 -clr_gd: - cmp r1, r2 /* while not at end of GD */ -#if defined(CONFIG_CPU_V7M) - itt lo -#endif - strlo r0, [r1] /* clear 32-bit GD word */ - addlo r1, r1, #4 /* move to next */ - blo clr_gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) - sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN - str sp, [r9, #GD_MALLOC_BASE] -#endif - /* mov r0, #0 not needed due to above code */ bl board_init_f #if ! defined(CONFIG_SPL_BUILD) diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 8b34e04dad..cef1c7171c 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -74,19 +74,10 @@ ENTRY(_main) #else ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) #endif - sub x18, x0, #GD_SIZE /* allocate one GD above SP */ - bic x18, x18, #0x7 /* 8-byte alignment for GD */ -zero_gd: - sub x0, x0, #0x8 - str xzr, [x0] - cmp x0, x18 - b.gt zero_gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) - ldr x0, =CONFIG_SYS_MALLOC_F_LEN - sub x0, x18, x0 - str x0, [x18, #GD_MALLOC_BASE] -#endif bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ + bl board_init_f_mem + mov sp, x0 + mov x0, #0 bl board_init_f diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c index e7df6d3d7b..7bdac3b12d 100644 --- a/arch/arm/mach-zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -20,7 +20,6 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - preloader_console_init(); arch_cpu_init(); board_init_r(NULL, 0); } @@ -28,6 +27,7 @@ void board_init_f(ulong dummy) #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void) { + preloader_console_init(); board_init(); } #endif diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 953d3a15ee..14f46a8f04 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -25,6 +25,7 @@ _start: addi r8, r0, __end mts rslr, r8 + /* TODO: Redo this code to call board_init_f_mem() */ #if defined(CONFIG_SPL_BUILD) addi r1, r0, CONFIG_SPL_STACK_ADDR mts rshr, r1 @@ -141,6 +142,7 @@ _start: ori r12, r12, 0x1a0 mts rmsr, r12 + /* TODO: Redo this code to call board_init_f_mem() */ clear_bss: /* clear BSS segments */ addi r5, r0, __bss_start diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 8ae7f6edd3..bb4fb2ac3a 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -4,15 +4,11 @@ menu "Nios II architecture" config SYS_ARCH default "nios2" -choice - prompt "Target select" - optional - -config TARGET_NIOS2_GENERIC - bool "Support nios2-generic" - -endchoice - -source "board/altera/nios2-generic/Kconfig" +config SYS_CONFIG_NAME + string "Board header file" + help + This option should contain the base name of board header file. + The header file include/configs/<CONFIG_SYS_CONFIG_NAME>.h + should be included from include/config.h. endmenu diff --git a/arch/nios2/cpu/Makefile b/arch/nios2/cpu/Makefile index 3fe7847160..185ca3cdb7 100644 --- a/arch/nios2/cpu/Makefile +++ b/arch/nios2/cpu/Makefile @@ -7,5 +7,5 @@ extra-y = start.o obj-y = exceptions.o -obj-y += cpu.o interrupts.o sysid.o traps.o +obj-y += cpu.o interrupts.o traps.o obj-y += fdt.o diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c index 39ae97221c..ff0fa20798 100644 --- a/arch/nios2/cpu/cpu.c +++ b/arch/nios2/cpu/cpu.c @@ -6,25 +6,18 @@ */ #include <common.h> -#include <asm/nios2.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> #include <asm/cache.h> DECLARE_GLOBAL_DATA_PTR; -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) -extern void display_sysid (void); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ - #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { - printf ("CPU : Nios-II\n"); -#if !defined(CONFIG_SYS_NIOS_SYSID_BASE) - printf ("SYSID : <unknown>\n"); -#else - display_sysid (); -#endif - return (0); + printf("CPU: Nios-II\n"); + return 0; } #endif /* CONFIG_DISPLAY_CPUINFO */ @@ -32,29 +25,120 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { disable_interrupts(); /* indirect call to go beyond 256MB limitation of toolchain */ - nios2_callr(CONFIG_SYS_RESET_ADDR); + nios2_callr(gd->arch.reset_addr); return 0; } -int dcache_status(void) +/* + * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the + * exception address. Define CONFIG_ROM_STUBS to prevent + * the copy (e.g. exception in flash or in other + * softare/firmware component). + */ +#ifndef CONFIG_ROM_STUBS +static void copy_exception_trampoline(void) { - return 1; + extern int _except_start, _except_end; + void *except_target = (void *)gd->arch.exception_addr; + + if (&_except_start != except_target) { + memcpy(except_target, &_except_start, + &_except_end - &_except_start); + flush_cache(gd->arch.exception_addr, + &_except_end - &_except_start); + } } +#endif -void dcache_enable(void) +int arch_cpu_init_dm(void) { - flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); + struct udevice *dev; + int ret; + + ret = uclass_first_device(UCLASS_CPU, &dev); + if (ret) + return ret; + if (!dev) + return -ENODEV; + + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +#ifndef CONFIG_ROM_STUBS + copy_exception_trampoline(); +#endif + + return 0; } -void dcache_disable(void) +static int altera_nios2_get_desc(struct udevice *dev, char *buf, int size) { - flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); + const char *cpu_name = "Nios-II"; + + if (size < strlen(cpu_name)) + return -ENOSPC; + strcpy(buf, cpu_name); + + return 0; } -int arch_cpu_init(void) +static int altera_nios2_get_info(struct udevice *dev, struct cpu_info *info) { - gd->cpu_clk = CONFIG_SYS_CLK_FREQ; - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + info->cpu_freq = gd->cpu_clk; + info->features = (1 << CPU_FEAT_L1_CACHE) | + (gd->arch.has_mmu ? (1 << CPU_FEAT_MMU) : 0); return 0; } + +static int altera_nios2_get_count(struct udevice *dev) +{ + return 1; +} + +static int altera_nios2_probe(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + + gd->cpu_clk = fdtdec_get_int(blob, node, + "clock-frequency", 0); + gd->arch.dcache_line_size = fdtdec_get_int(blob, node, + "dcache-line-size", 0); + gd->arch.icache_line_size = fdtdec_get_int(blob, node, + "icache-line-size", 0); + gd->arch.dcache_size = fdtdec_get_int(blob, node, + "dcache-size", 0); + gd->arch.icache_size = fdtdec_get_int(blob, node, + "icache-size", 0); + gd->arch.reset_addr = fdtdec_get_int(blob, node, + "altr,reset-addr", 0); + gd->arch.exception_addr = fdtdec_get_int(blob, node, + "altr,exception-addr", 0); + gd->arch.has_initda = fdtdec_get_int(blob, node, + "altr,has-initda", 0); + gd->arch.has_mmu = fdtdec_get_int(blob, node, + "altr,has-mmu", 0); + gd->arch.io_region_base = gd->arch.has_mmu ? 0xe0000000 : 0x8000000; + + return 0; +} + +static const struct cpu_ops altera_nios2_ops = { + .get_desc = altera_nios2_get_desc, + .get_info = altera_nios2_get_info, + .get_count = altera_nios2_get_count, +}; + +static const struct udevice_id altera_nios2_ids[] = { + { .compatible = "altr,nios2-1.0" }, + { .compatible = "altr,nios2-1.1" }, + { } +}; + +U_BOOT_DRIVER(altera_nios2) = { + .name = "altera_nios2", + .id = UCLASS_CPU, + .of_match = altera_nios2_ids, + .probe = altera_nios2_probe, + .ops = &altera_nios2_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c index 9d7e193e28..1599674353 100644 --- a/arch/nios2/cpu/interrupts.c +++ b/arch/nios2/cpu/interrupts.c @@ -8,43 +8,14 @@ * SPDX-License-Identifier: GPL-2.0+ */ - +#include <common.h> +#include <command.h> #include <asm/nios2.h> #include <asm/types.h> #include <asm/io.h> #include <asm/ptrace.h> -#include <common.h> -#include <command.h> -#include <watchdog.h> -#ifdef CONFIG_STATUS_LED -#include <status_led.h> -#endif - -typedef volatile struct { - unsigned status; /* Timer status reg */ - unsigned control; /* Timer control reg */ - unsigned periodl; /* Timeout period low */ - unsigned periodh; /* Timeout period high */ - unsigned snapl; /* Snapshot low */ - unsigned snaph; /* Snapshot high */ -} nios_timer_t; - -/* status register */ -#define NIOS_TIMER_TO (1 << 0) /* Timeout */ -#define NIOS_TIMER_RUN (1 << 1) /* Timer running */ - -/* control register */ -#define NIOS_TIMER_ITO (1 << 0) /* Timeout int ena */ -#define NIOS_TIMER_CONT (1 << 1) /* Continuous mode */ -#define NIOS_TIMER_START (1 << 2) /* Start timer */ -#define NIOS_TIMER_STOP (1 << 3) /* Stop timer */ - -#if defined(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ) -#error CONFIG_SYS_NIOS_TMRIRQ not defined (see documentation) -#endif - -/****************************************************************************/ +/*************************************************************************/ struct irq_action { interrupt_handler_t *handler; void *arg; @@ -53,111 +24,6 @@ struct irq_action { static struct irq_action vecs[32]; -/*************************************************************************/ -volatile ulong timestamp = 0; - -void reset_timer (void) -{ - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - - /* From Embedded Peripherals Handbook: - * - * "When the hardware is configured with Writeable period - * disabled, writing to one of the period_n registers causes - * the counter to reset to the fixed Timeout Period specified - * at system generation time." - * - * Here we force a reload to prevent early timeouts from - * get_timer() when the interrupt period is greater than - * than 1 msec. - * - * Simply write to periodl with its own value to force an - * internal counter reload, THEN reset the timestamp. - */ - writel (readl (&tmr->periodl), &tmr->periodl); - timestamp = 0; - - /* From Embedded Peripherals Handbook: - * - * "Writing to one of the period_n registers stops the internal - * counter, except when the hardware is configured with Start/Stop - * control bits off. If Start/Stop control bits is off, writing - * either register does not stop the counter." - * - * In order to accomodate either configuration, the control - * register is re-written. If the counter is stopped, it will - * be restarted. If it is running, the write is essentially - * a nop. - */ - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - -} - -ulong get_timer (ulong base) -{ - WATCHDOG_RESET (); - return (timestamp - base); -} - -/* - * This function is derived from Blackfin code (read timebase as long long). - * On Nios2 it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from Blackfin code. - * On Nios2 it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} - -/* The board must handle this interrupt if a timer is not - * provided. - */ -#if defined(CONFIG_SYS_NIOS_TMRBASE) -void tmr_isr (void *arg) -{ - nios_timer_t *tmr = (nios_timer_t *)arg; - /* Interrupt is cleared by writing anything to the - * status register. - */ - writel (0, &tmr->status); - timestamp += CONFIG_SYS_NIOS_TMRMS; -#ifdef CONFIG_STATUS_LED - status_led_tick(timestamp); -#endif -} - -static void tmr_init (void) -{ - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - - writel (0, &tmr->status); - writel (0, &tmr->control); - writel (NIOS_TIMER_STOP, &tmr->control); - -#if defined(CONFIG_SYS_NIOS_TMRCNT) - writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl); - writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh); -#endif - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr); -} - -#endif /* CONFIG_SYS_NIOS_TMRBASE */ - -/*************************************************************************/ int disable_interrupts (void) { int val = rdctl (CTL_STATUS); @@ -245,10 +111,6 @@ int interrupt_init (void) vecs[i].count = 0; } -#if defined(CONFIG_SYS_NIOS_TMRBASE) - tmr_init (); -#endif - enable_interrupts (); return (0); } diff --git a/arch/nios2/cpu/start.S b/arch/nios2/cpu/start.S index 6af9b4e943..8758e7e847 100644 --- a/arch/nios2/cpu/start.S +++ b/arch/nios2/cpu/start.S @@ -9,30 +9,38 @@ #include <config.h> #include <version.h> -/************************************************************************* - * RESTART - ************************************************************************/ +/* + * icache and dcache configuration used only for start.S. + * the values are chosen so that it will work for all configuration. + */ +#define ICACHE_LINE_SIZE 32 /* fixed 32 */ +#define ICACHE_SIZE_MAX 0x10000 /* 64k max */ +#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */ +#define DCACHE_SIZE_MAX 0x10000 /* 64k max */ + /* RESTART */ .text - .global _start + .global _start, _except_start, _except_end _start: wrctl status, r0 /* Disable interrupts */ - /* ICACHE INIT -- only the icache line at the reset address + /* + * ICACHE INIT -- only the icache line at the reset address * is invalidated at reset. So the init must stay within * the cache line size (8 words). If GERMS is used, we'll * just be invalidating the cache a second time. If cache * is not implemented initi behaves as nop. */ - ori r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE) - movhi r5, %hi(CONFIG_SYS_ICACHE_SIZE) - ori r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE) + ori r4, r0, %lo(ICACHE_LINE_SIZE) + movhi r5, %hi(ICACHE_SIZE_MAX) + ori r5, r5, %lo(ICACHE_SIZE_MAX) 0: initi r5 sub r5, r5, r4 bgt r5, r0, 0b br _except_end /* Skip the tramp */ - /* EXCEPTION TRAMPOLINE -- the following gets copied + /* + * EXCEPTION TRAMPOLINE -- the following gets copied * to the exception address (below), but is otherwise at the * default exception vector offset (0x0020). */ @@ -42,24 +50,26 @@ _except_start: jmp et _except_end: - /* INTERRUPTS -- for now, all interrupts masked and globally + /* + * INTERRUPTS -- for now, all interrupts masked and globally * disabled. */ wrctl ienable, r0 /* All disabled */ - /* DCACHE INIT -- if dcache not implemented, initd behaves as + /* + * DCACHE INIT -- if dcache not implemented, initd behaves as * nop. */ - movhi r4, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE) - movhi r5, %hi(CONFIG_SYS_DCACHE_SIZE) - ori r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE) + ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN) + movhi r5, %hi(DCACHE_SIZE_MAX) + ori r5, r5, %lo(DCACHE_SIZE_MAX) mov r6, r0 1: initd 0(r6) add r6, r6, r4 bltu r6, r5, 1b - /* RELOCATE CODE, DATA & COMMAND TABLE -- the following code + /* + * RELOCATE CODE, DATA & COMMAND TABLE -- the following code * assumes code, data and the command table are all * contiguous. This lets us relocate everything as a single * block. Make sure the linker script matches this ;-) @@ -73,8 +83,9 @@ _cur: movhi r5, %hi(_cur - _start) ori r5, r5, %lo(_start) /* r5 <- linked _start */ beq r4, r5, 3f - movhi r6, %hi(_edata) - ori r6, r6, %lo(_edata) + movhi r6, %hi(CONFIG_SYS_MONITOR_LEN) + ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) + add r6, r6, r5 2: ldwio r7, 0(r4) addi r4, r4, 4 stwio r7, 0(r5) @@ -82,50 +93,13 @@ _cur: movhi r5, %hi(_cur - _start) bne r5, r6, 2b 3: - /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent - * and between __bss_start and __bss_end. - */ - movhi r5, %hi(__bss_start) - ori r5, r5, %lo(__bss_start) - movhi r6, %hi(__bss_end) - ori r6, r6, %lo(__bss_end) - beq r5, r6, 5f - -4: stwio r0, 0(r5) - addi r5, r5, 4 - bne r5, r6, 4b -5: - /* JUMP TO RELOC ADDR */ movhi r4, %hi(_reloc) ori r4, r4, %lo(_reloc) jmp r4 _reloc: - /* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the - * exception address. Define CONFIG_ROM_STUBS to prevent - * the copy (e.g. exception in flash or in other - * softare/firmware component). - */ -#if !defined(CONFIG_ROM_STUBS) - movhi r4, %hi(_except_start) - ori r4, r4, %lo(_except_start) - movhi r5, %hi(_except_end) - ori r5, r5, %lo(_except_end) - movhi r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) - ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) - beq r4, r6, 7f /* Skip if at proper addr */ - -6: ldwio r7, 0(r4) - stwio r7, 0(r6) - addi r4, r4, 4 - addi r6, r6, 4 - bne r4, r5, 6b -7: -#endif - - /* STACK INIT -- zero top two words for call back chain. - */ + /* STACK INIT -- zero top two words for call back chain. */ movhi sp, %hi(CONFIG_SYS_INIT_SP) ori sp, sp, %lo(CONFIG_SYS_INIT_SP) addi sp, sp, -8 @@ -133,80 +107,64 @@ _reloc: stw r0, 4(sp) mov fp, sp - /* - * Call board_init_f -- never returns - */ + /* Allocate and zero GD, update SP */ + mov r4, sp + movhi r2, %hi(board_init_f_mem@h) + ori r2, r2, %lo(board_init_f_mem@h) + callr r2 + + /* Update stack- and frame-pointers */ + mov sp, r2 + mov fp, sp + + /* Call board_init_f -- never returns */ mov r4, r0 movhi r2, %hi(board_init_f@h) ori r2, r2, %lo(board_init_f@h) callr r2 - /* NEVER RETURNS -- but branch to the _start just + /* + * NEVER RETURNS -- but branch to the _start just * in case ;-) */ br _start - - -/* - * relocate_code -- Nios2 handles the relocation above. But - * the generic board code monkeys with the heap, stack, etc. - * (it makes some assumptions that may not be appropriate - * for Nios). Nevertheless, we capitulate here. - * - * We'll call the board_init_r from here since this isn't - * supposed to return. - * - * void relocate_code (ulong sp, gd_t *global_data, - * ulong reloc_addr) - * __attribute__ ((noreturn)); - */ + /* + * relocate_code -- Nios2 handles the relocation above. But + * the generic board code monkeys with the heap, stack, etc. + * (it makes some assumptions that may not be appropriate + * for Nios). Nevertheless, we capitulate here. + * + * We'll call the board_init_r from here since this isn't + * supposed to return. + * + * void relocate_code (ulong sp, gd_t *global_data, + * ulong reloc_addr) + * __attribute__ ((noreturn)); + */ .text .global relocate_code relocate_code: mov sp, r4 /* Set the new sp */ mov r4, r5 - movhi r8, %hi(board_init_r@h) - ori r8, r8, %lo(board_init_r@h) - callr r8 - ret -/* - * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in - * the core. For simple delay loops, we do our best by counting - * instruction cycles. - * - * Instruction performance varies based on the core. For cores - * with icache and static/dynamic branch prediction (II/f, II/s): - * - * Normal ALU (e.g. add, cmp, etc): 1 cycle - * Branch (correctly predicted, taken): 2 cycles - * Negative offset is predicted (II/s). - * - * For cores without icache and no branch prediction (II/e): - * - * Normal ALU (e.g. add, cmp, etc): 6 cycles - * Branch (no prediction): 6 cycles - * - * For simplicity, if an instruction cache is implemented we - * assume II/f or II/s. Otherwise, we use the II/e. - * - */ - .globl dly_clks + /* + * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent + * and between __bss_start and __bss_end. + */ + movhi r5, %hi(__bss_start) + ori r5, r5, %lo(__bss_start) + movhi r6, %hi(__bss_end) + ori r6, r6, %lo(__bss_end) + beq r5, r6, 5f -dly_clks: +4: stwio r0, 0(r5) + addi r5, r5, 4 + bne r5, r6, 4b +5: -#if (CONFIG_SYS_ICACHE_SIZE > 0) - subi r4, r4, 3 /* 3 clocks/loop */ -#else - subi r4, r4, 12 /* 12 clocks/loop */ -#endif - bge r4, r0, dly_clks + movhi r8, %hi(board_init_r@h) + ori r8, r8, %lo(board_init_r@h) + callr r8 ret - - .data - .globl version_string - -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" diff --git a/arch/nios2/cpu/sysid.c b/arch/nios2/cpu/sysid.c deleted file mode 100644 index 50819b2424..0000000000 --- a/arch/nios2/cpu/sysid.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) - -#include <command.h> -#include <asm/io.h> -#include <linux/time.h> - -typedef volatile struct { - unsigned id; /* The system build id */ - unsigned timestamp; /* Timestamp */ -} nios_sysid_t; - -void display_sysid (void) -{ - nios_sysid_t *sysid = (nios_sysid_t *)CONFIG_SYS_NIOS_SYSID_BASE; - struct tm t; - char asc[32]; - time_t stamp; - - stamp = readl (&sysid->timestamp); - localtime_r (&stamp, &t); - asctime_r (&t, asc); - printf ("SYSID : %08lx, %s", readl (&sysid->id), asc); - -} - -int do_sysid (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - display_sysid (); - return (0); -} - -U_BOOT_CMD( - sysid, 1, 1, do_sysid, - "display Nios-II system id", - "" -); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ diff --git a/arch/nios2/cpu/u-boot.lds b/arch/nios2/cpu/u-boot.lds index 6e174be2c0..3bd3f2c520 100644 --- a/arch/nios2/cpu/u-boot.lds +++ b/arch/nios2/cpu/u-boot.lds @@ -50,9 +50,11 @@ SECTIONS *(.gnu.linkonce.d*) } - . = ALIGN(16); - _gp = .; /* Global pointer addr */ - PROVIDE (gp = .); + /* + * gp - Since we don't use gp for small data with option "-G0", + * we will use gp as global data pointer. The _gp location is + * not needed. + */ .sdata : { @@ -65,6 +67,12 @@ SECTIONS _edata = .; PROVIDE (edata = .); + /* + * _end - This is end of u-boot.bin image. + * dtb will be appended here to make u-boot-dtb.bin + */ + _end = .; + /* UNINIT DATA - Small uninitialized data is first so it's * adjacent to sdata and can be referenced via gp. The normal * bss follows. We keep it adjacent to simplify init code. diff --git a/arch/nios2/dts/.gitignore b/arch/nios2/dts/.gitignore new file mode 100644 index 0000000000..b60ed208c7 --- /dev/null +++ b/arch/nios2/dts/.gitignore @@ -0,0 +1 @@ +*.dtb diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts new file mode 100644 index 0000000000..a3cfacb98a --- /dev/null +++ b/arch/nios2/dts/3c120_devboard.dts @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * This file is generated by sopc2dts. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/ { + model = "altr,qsys_ghrd_3c120"; + compatible = "altr,qsys_ghrd_3c120"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu: cpu@0x0 { + device_type = "cpu"; + compatible = "altr,nios2-1.0"; + reg = <0x00000000>; + interrupt-controller; + #interrupt-cells = <1>; + clock-frequency = <125000000>; + dcache-line-size = <32>; + icache-line-size = <32>; + dcache-size = <32768>; + icache-size = <32768>; + altr,implementation = "fast"; + altr,pid-num-bits = <8>; + altr,tlb-num-ways = <16>; + altr,tlb-num-entries = <128>; + altr,tlb-ptr-sz = <7>; + altr,has-div = <1>; + altr,has-mul = <1>; + altr,reset-addr = <0xc2800000>; + altr,fast-tlb-miss-addr = <0xc7fff400>; + altr,exception-addr = <0xd0000020>; + altr,has-initda = <1>; + altr,has-mmu = <1>; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x10000000 0x08000000>, + <0x07fff400 0x00000400>; + }; + + sopc@0 { + device_type = "soc"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + compatible = "altr,avalon", "simple-bus"; + bus-frequency = <125000000>; + + pb_cpu_to_io: bridge@0x8000000 { + compatible = "simple-bus"; + reg = <0x08000000 0x00800000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00002000 0x08002000 0x00002000>, + <0x00004000 0x08004000 0x00000400>, + <0x00004400 0x08004400 0x00000040>, + <0x00004800 0x08004800 0x00000040>, + <0x00004c80 0x08004c80 0x00000020>, + <0x00004cc0 0x08004cc0 0x00000010>, + <0x00004ce0 0x08004ce0 0x00000010>, + <0x00004d00 0x08004d00 0x00000010>, + <0x00004d40 0x08004d40 0x00000008>, + <0x00004d50 0x08004d50 0x00000008>, + <0x00008000 0x08008000 0x00000020>, + <0x00400000 0x08400000 0x00000020>; + + timer_1ms: timer@0x400000 { + compatible = "altr,timer-1.0"; + reg = <0x00400000 0x00000020>; + interrupt-parent = <&cpu>; + interrupts = <11>; + clock-frequency = <125000000>; + }; + + timer_0: timer@0x8000 { + compatible = "altr,timer-1.0"; + reg = < 0x00008000 0x00000020 >; + interrupt-parent = < &cpu >; + interrupts = < 5 >; + clock-frequency = < 125000000 >; + }; + + sysid: sysid@0x4d40 { + compatible = "altr,sysid-1.0"; + reg = <0x00004d40 0x00000008>; + }; + + jtag_uart: serial@0x4d50 { + compatible = "altr,juart-1.0"; + reg = <0x00004d50 0x00000008>; + interrupt-parent = <&cpu>; + interrupts = <1>; + }; + + tse_mac: ethernet@0x4000 { + compatible = "altr,tse-1.0"; + reg = <0x00004000 0x00000400>, + <0x00004400 0x00000040>, + <0x00004800 0x00000040>, + <0x00002000 0x00002000>; + reg-names = "control_port", "rx_csr", "tx_csr", "s1"; + interrupt-parent = <&cpu>; + interrupts = <2 3>; + interrupt-names = "rx_irq", "tx_irq"; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + max-frame-size = <1518>; + local-mac-address = [ 00 00 00 00 00 00 ]; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; + tse_mac_mdio: mdio { + compatible = "altr,tse-mdio"; + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@18 { + reg = <18>; + device_type = "ethernet-phy"; + }; + }; + }; + + uart: serial@0x4c80 { + compatible = "altr,uart-1.0"; + reg = <0x00004c80 0x00000020>; + interrupt-parent = <&cpu>; + interrupts = <10>; + current-speed = <115200>; + clock-frequency = <62500000>; + }; + + user_led_pio_8out: gpio@0x4cc0 { + compatible = "altr,pio-1.0"; + reg = <0x00004cc0 0x00000010>; + resetvalue = <255>; + altr,gpio-bank-width = <8>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "led"; + }; + + user_dipsw_pio_8in: gpio@0x4ce0 { + compatible = "altr,pio-1.0"; + reg = <0x00004ce0 0x00000010>; + interrupt-parent = <&cpu>; + interrupts = <8>; + edge_type = <2>; + level_trigger = <0>; + resetvalue = <0>; + altr,gpio-bank-width = <8>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "dipsw"; + }; + + user_pb_pio_4in: gpio@0x4d00 { + compatible = "altr,pio-1.0"; + reg = <0x00004d00 0x00000010>; + interrupt-parent = <&cpu>; + interrupts = <9>; + edge_type = <2>; + level_trigger = <0>; + resetvalue = <0>; + altr,gpio-bank-width = <4>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "pb"; + }; + }; + + cfi_flash_64m: flash@0x0 { + compatible = "cfi-flash"; + reg = <0x00000000 0x04000000>; + bank-width = <2>; + device-width = <1>; + #address-cells = <1>; + #size-cells = <1>; + + partition@800000 { + reg = <0x00800000 0x01e00000>; + label = "JFFS2 Filesystem"; + }; + }; + }; + + chosen { + bootargs = "debug console=ttyJ0,115200"; + stdout-path = &jtag_uart; + }; +}; diff --git a/arch/nios2/dts/Makefile b/arch/nios2/dts/Makefile new file mode 100644 index 0000000000..b40eca9e0a --- /dev/null +++ b/arch/nios2/dts/Makefile @@ -0,0 +1,11 @@ +dtb-y += $(CONFIG_DEFAULT_DEVICE_TREE:"%"=%).dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/nios2/dts/include/dt-bindings b/arch/nios2/dts/include/dt-bindings new file mode 120000 index 0000000000..0cecb3d080 --- /dev/null +++ b/arch/nios2/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../include/dt-bindings
\ No newline at end of file diff --git a/arch/nios2/include/asm/cache.h b/arch/nios2/include/asm/cache.h index 9b87c9f755..dde43cd6fc 100644 --- a/arch/nios2/include/asm/cache.h +++ b/arch/nios2/include/asm/cache.h @@ -8,18 +8,11 @@ #ifndef __ASM_NIOS2_CACHE_H_ #define __ASM_NIOS2_CACHE_H_ -extern void flush_dcache (unsigned long start, unsigned long size); -extern void flush_icache (unsigned long start, unsigned long size); - /* - * Valid L1 data cache line sizes for the NIOS2 architecture are 4, 16, and 32 - * bytes. If the board configuration has not specified one we default to the - * largest of these values for alignment of DMA buffers. + * Valid L1 data cache line sizes for the NIOS2 architecture are 4, + * 16, and 32 bytes. We default to the largest of these values for + * alignment of DMA buffers. */ -#ifdef CONFIG_SYS_CACHELINE_SIZE -#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE -#else #define ARCH_DMA_MINALIGN 32 -#endif #endif /* __ASM_NIOS2_CACHE_H_ */ diff --git a/arch/nios2/include/asm/config.h b/arch/nios2/include/asm/config.h index 9c13848ea2..cd29734789 100644 --- a/arch/nios2/include/asm/config.h +++ b/arch/nios2/include/asm/config.h @@ -7,6 +7,4 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA - #endif diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h index 1350e3b96f..1562d35f0d 100644 --- a/arch/nios2/include/asm/dma-mapping.h +++ b/arch/nios2/include/asm/dma-mapping.h @@ -1,23 +1,24 @@ #ifndef __ASM_NIOS2_DMA_MAPPING_H #define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <memalign.h> +#include <asm/io.h> + +/* + * dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. - * - * IO_REGION_BASE should be defined in board config header file - * 0x80000000 for nommu, 0xe0000000 for mmu */ - static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) { - void *addr = malloc(len + CONFIG_SYS_DCACHELINE_SIZE); + unsigned long addr = (unsigned long)malloc_cache_aligned(len); + if (!addr) - return 0; - flush_dcache((unsigned long)addr, len + CONFIG_SYS_DCACHELINE_SIZE); - *handle = ((unsigned long)addr + - (CONFIG_SYS_DCACHELINE_SIZE - 1)) & - ~(CONFIG_SYS_DCACHELINE_SIZE - 1) & ~(IO_REGION_BASE); - return (void *)(*handle | IO_REGION_BASE); -} + return NULL; + + invalidate_dcache_range(addr, addr + len); + if (handle) + *handle = addr; + return ioremap(addr, len); +} #endif /* __ASM_NIOS2_DMA_MAPPING_H */ diff --git a/arch/nios2/include/asm/global_data.h b/arch/nios2/include/asm/global_data.h index 580b0199bb..d6a2cfab4f 100644 --- a/arch/nios2/include/asm/global_data.h +++ b/arch/nios2/include/asm/global_data.h @@ -9,6 +9,15 @@ /* Architecture-specific global data */ struct arch_global_data { + u32 dcache_line_size; + u32 icache_line_size; + u32 dcache_size; + u32 icache_size; + u32 reset_addr; + u32 exception_addr; + int has_initda; + int has_mmu; + u32 io_region_base; }; #include <asm-generic/global_data.h> diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h index 908381f5f7..306ab4c9f2 100644 --- a/arch/nios2/include/asm/gpio.h +++ b/arch/nios2/include/asm/gpio.h @@ -1,79 +1 @@ -/* - * nios2 gpio driver - * - * This gpio core is described in http://nioswiki.com/GPIO - * bit[0] data - * bit[1] output enable - * - * When CONFIG_SYS_GPIO_BASE is not defined, the board may either - * provide its own driver or the altera_pio driver may be used. - * - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _ASM_NIOS2_GPIO_H_ -#define _ASM_NIOS2_GPIO_H_ - -#ifdef CONFIG_SYS_GPIO_BASE -#include <asm/io.h> - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline int gpio_free(unsigned gpio) -{ - return 0; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2)); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2)); - return 0; -} - -static inline int gpio_get_value(unsigned gpio) -{ - return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2)); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2)); -} - -static inline int gpio_is_valid(int number) -{ - return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH; -} -#else -#ifdef CONFIG_ALTERA_PIO -extern int altera_pio_init(u32 base, u8 width, char iot, - u32 rstval, u32 negmask, - const char *label); - -extern void altera_pio_info(void); -#define gpio_status() altera_pio_info() -#endif - -extern int gpio_request(unsigned gpio, const char *label); -extern int gpio_free(unsigned gpio); -extern int gpio_direction_input(unsigned gpio); -extern int gpio_direction_output(unsigned gpio, int value); -extern int gpio_get_value(unsigned gpio); -extern void gpio_set_value(unsigned gpio, int value); -extern int gpio_is_valid(int number); -#endif /* CONFIG_SYS_GPIO_BASE */ - -#endif /* _ASM_NIOS2_GPIO_H_ */ +#include <asm-generic/gpio.h> diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h index 69ab23e5f0..e7da35b0c9 100644 --- a/arch/nios2/include/asm/io.h +++ b/arch/nios2/include/asm/io.h @@ -39,12 +39,18 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) static inline phys_addr_t virt_to_phys(void * vaddr) { - return (phys_addr_t)(vaddr); + DECLARE_GLOBAL_DATA_PTR; + if (gd->arch.has_mmu) + return (phys_addr_t)vaddr & 0x1fffffff; + else + return (phys_addr_t)vaddr & 0x7fffffff; } -extern unsigned char inb (unsigned char *port); -extern unsigned short inw (unsigned short *port); -extern unsigned inl (unsigned port); +static inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + DECLARE_GLOBAL_DATA_PTR; + return (void *)(gd->arch.io_region_base | physaddr); +} #define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v)) #define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v)) @@ -111,4 +117,59 @@ static inline void outsl (unsigned long port, const void *src, unsigned long cou while (count--) outl (*p++, port); } +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a) +#define in_arch(type,endian,a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a,v) out_arch(l,le32,a,v) +#define out_le16(a,v) out_arch(w,le16,a,v) + +#define in_le32(a) in_arch(l,le32,a) +#define in_le16(a) in_arch(w,le16,a) + +#define out_be32(a,v) out_arch(l,be32,a,v) +#define out_be16(a,v) out_arch(w,be16,a,v) + +#define in_be32(a) in_arch(l,be32,a) +#define in_be16(a) in_arch(w,be16,a) + +#define out_8(a,v) __raw_writeb(v,a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + #endif /* __ASM_NIOS2_IO_H_ */ diff --git a/arch/nios2/include/asm/psr.h b/arch/nios2/include/asm/psr.h deleted file mode 100644 index 3ebb2a011e..0000000000 --- a/arch/nios2/include/asm/psr.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_NIOS2_PSR_H_ -#define __ASM_NIOS2_PSR_H_ - - -#endif /* __ASM_NIOS2_PSR_H_ */ diff --git a/arch/nios2/include/asm/sections.h b/arch/nios2/include/asm/sections.h index f0da75dcf3..2b8c516038 100644 --- a/arch/nios2/include/asm/sections.h +++ b/arch/nios2/include/asm/sections.h @@ -1,11 +1 @@ -/* - * Copyright (c) 2012 The Chromium OS Authors. - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_NIOS2_SECTIONS_H -#define __ASM_NIOS2_SECTIONS_H - #include <asm-generic/sections.h> - -#endif diff --git a/arch/nios2/include/asm/system.h b/arch/nios2/include/asm/system.h index 6213a16eda..b15853563e 100644 --- a/arch/nios2/include/asm/system.h +++ b/arch/nios2/include/asm/system.h @@ -45,4 +45,6 @@ "callr %0" \ : : "r" (addr)) +void display_sysid(void); + #endif /* __ASM_NIOS2_SYSTEM_H */ diff --git a/arch/nios2/include/asm/unaligned.h b/arch/nios2/include/asm/unaligned.h index 779117c4bc..6cecbbb211 100644 --- a/arch/nios2/include/asm/unaligned.h +++ b/arch/nios2/include/asm/unaligned.h @@ -1,6 +1 @@ -#ifndef _ASM_NIOS2_UNALIGNED_H -#define _ASM_NIOS2_UNALIGNED_H - #include <asm-generic/unaligned.h> - -#endif /* _ASM_NIOS2_UNALIGNED_H */ diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile index 079378a905..e35d2e92a2 100644 --- a/arch/nios2/lib/Makefile +++ b/arch/nios2/lib/Makefile @@ -8,4 +8,3 @@ obj-y += cache.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += libgcc.o -obj-y += time.o diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index c730a3fd08..4e5c269193 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -6,9 +6,6 @@ */ #include <common.h> -#include <command.h> -#include <asm/byteorder.h> -#include <asm/cache.h> #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */ @@ -40,8 +37,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima /* flushes data and instruction caches before calling the kernel */ disable_interrupts(); - flush_dcache((ulong)kernel, CONFIG_SYS_DCACHE_SIZE); - flush_icache((ulong)kernel, CONFIG_SYS_ICACHE_SIZE); + flush_dcache_all(); debug("bootargs=%s @ 0x%lx\n", commandline, (ulong)&commandline); debug("initrd=0x%lx-0x%lx\n", (ulong)initrd_start, (ulong)initrd_end); diff --git a/arch/nios2/lib/cache.S b/arch/nios2/lib/cache.S deleted file mode 100644 index 683f005994..0000000000 --- a/arch/nios2/lib/cache.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> - - .text - - .global flush_dcache - -flush_dcache: - add r5, r5, r4 - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - ret - - - .global flush_icache - -flush_icache: - add r5, r5, r4 - movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE) -1: flushi r4 - add r4, r4, r8 - bltu r4, r5, 1b - ret - - .global flush_dcache_range - -flush_dcache_range: - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - ret - - .global flush_cache - -flush_cache: - add r5, r5, r4 - mov r9, r4 - mov r10, r5 - - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - - mov r4, r9 - mov r5, r10 - movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE) -1: flushi r4 - add r4, r4, r8 - bltu r4, r5, 1b - - sync - flushp - ret diff --git a/arch/nios2/lib/cache.c b/arch/nios2/lib/cache.c new file mode 100644 index 0000000000..7c74e1adfe --- /dev/null +++ b/arch/nios2/lib/cache.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> + * Copyright (C) 2009, Wind River Systems Inc + * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cache.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void __flush_dcache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" flushda 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __flush_dcache_all(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + if (end > start + gd->arch.dcache_size) + end = start + gd->arch.dcache_size; + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" flushd 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __invalidate_dcache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" initda 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __flush_icache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.icache_line_size - 1); + end += (gd->arch.icache_line_size - 1); + end &= ~(gd->arch.icache_line_size - 1); + + if (end > start + gd->arch.icache_size) + end = start + gd->arch.icache_size; + + for (addr = start; addr < end; addr += gd->arch.icache_line_size) { + __asm__ __volatile__ (" flushi %0\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } + __asm__ __volatile(" flushp\n"); +} + +void flush_dcache_all(void) +{ + __flush_dcache_all(0, gd->arch.dcache_size); + __flush_icache(0, gd->arch.icache_size); +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + if (gd->arch.has_initda) + __flush_dcache(start, end); + else + __flush_dcache_all(start, end); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + if (gd->arch.has_initda) + __flush_dcache(start, start + size); + else + __flush_dcache_all(start, start + size); + __flush_icache(start, start + size); +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + if (gd->arch.has_initda) + __invalidate_dcache(start, end); + else + __flush_dcache_all(start, end); +} + +int dcache_status(void) +{ + return 1; +} + +void dcache_enable(void) +{ + flush_dcache_all(); +} + +void dcache_disable(void) +{ + flush_dcache_all(); +} diff --git a/arch/nios2/lib/time.c b/arch/nios2/lib/time.c deleted file mode 100644 index d39604579c..0000000000 --- a/arch/nios2/lib/time.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2003, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <watchdog.h> - - -extern void dly_clks( unsigned long ticks ); - -void __udelay(unsigned long usec) -{ - /* The Nios core doesn't have a timebase, so we do our - * best for now and call a low-level loop that counts - * cpu clocks. - */ - unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec; - dly_clks (cnt); -} |