From 52789143a2090a77cbdda76c573a1b75cd460a9a Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Sun, 1 Nov 2015 15:40:00 +0200 Subject: [PATCH 01/21] sparc: Move SYS_SPARC_NWINDOWS to Kconfig Signed-off-by: Francois Retief --- arch/sparc/Kconfig | 9 +++++++++ arch/sparc/cpu/leon3/start.S | 5 +++++ include/configs/gr_cpci_ax2000.h | 3 --- include/configs/gr_ep2s60.h | 3 --- include/configs/gr_xc3s_1500.h | 3 --- include/configs/grsim.h | 3 --- include/configs/grsim_leon2.h | 3 --- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 04dc08f41f..1d1347b167 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -12,6 +12,15 @@ config LEON3 bool select LEON +config SYS_SPARC_NWINDOWS + int "Number of SPARC register windows" + range 2 32 + default "8" + help + Specify the number of SPARC register windows implemented by this + processor. A SPARC implementation can have from 2 to 32 windows. + If unsure, choose 8. + choice prompt "Board select" optional diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index 203114970b..156601027a 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -20,6 +20,11 @@ #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA #endif +/* Default number of SPARC register windows */ +#ifndef CONFIG_SYS_SPARC_NWINDOWS +#define CONFIG_SYS_SPARC_NWINDOWS 8 +#endif + /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ wr %g0, 0xfe0, %psr; \ diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 5bbf1aaae8..67538d05a7 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -42,9 +42,6 @@ /* CPU / AMBA BUS configuration */ #define CONFIG_SYS_CLK_FREQ 20000000 /* 20MHz */ -/* Number of SPARC register windows */ -#define CONFIG_SYS_SPARC_NWINDOWS 8 - /* * Serial console configuration */ diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index b55ca77a87..387596d6b3 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -26,9 +26,6 @@ /* CPU / AMBA BUS configuration */ #define CONFIG_SYS_CLK_FREQ 96000000 /* 96MHz */ -/* Number of SPARC register windows */ -#define CONFIG_SYS_SPARC_NWINDOWS 8 - /* Define this is the GR-2S60-MEZZ mezzanine is available and you * want to use the USB and GRETH functionality of the board */ diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index d086b694c2..5fb800bf21 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -23,9 +23,6 @@ /* CPU / AMBA BUS configuration */ #define CONFIG_SYS_CLK_FREQ 40000000 /* 40MHz */ -/* Number of SPARC register windows */ -#define CONFIG_SYS_SPARC_NWINDOWS 8 - /* * Serial console configuration */ diff --git a/include/configs/grsim.h b/include/configs/grsim.h index e1f7dc3bf6..932f330e1e 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -34,9 +34,6 @@ /* CPU / AMBA BUS configuration */ #define CONFIG_SYS_CLK_FREQ 40000000 /* 40MHz */ -/* Number of SPARC register windows */ -#define CONFIG_SYS_SPARC_NWINDOWS 8 - /* * Serial console configuration */ diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index 83fd7fae50..83022e8542 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -29,9 +29,6 @@ /* CPU / AMBA BUS configuration */ #define CONFIG_SYS_CLK_FREQ 40000000 /* 40MHz */ -/* Number of SPARC register windows */ -#define CONFIG_SYS_SPARC_NWINDOWS 8 - /* * Serial console configuration */ From be7357a6cc16dec39be2043911ced4ac19d36044 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 15:56:45 +0200 Subject: [PATCH 02/21] sparc: Remove version_string variable from start.S file Remove the version_string variable from start.S file. A weak variable is also set in the cmd_version.c file. No need for architecture override. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/start.S | 14 +++----------- arch/sparc/cpu/leon3/start.S | 13 +++---------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index 974de76852..fa1534f3ff 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -1,6 +1,7 @@ /* This is where the SPARC/LEON3 starts - * Copyright (C) 2007, - * Daniel Hellstrom, daniel@gaisler.com + * + * Copyright (C) 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,7 +13,6 @@ #include #include #include -#include /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ @@ -197,14 +197,6 @@ _trap_table: SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7 SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff -/* - * Version string - */ - - .data - .globl version_string -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" .align 4 diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index 156601027a..fe4795cc9a 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -1,6 +1,7 @@ /* This is where the SPARC/LEON3 starts - * Copyright (C) 2007, - * Daniel Hellstrom, daniel@gaisler.com + * + * Copyright (C) 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,7 +13,6 @@ #include #include #include -#include #include /* Default Plug&Play I/O area */ @@ -208,15 +208,8 @@ _trap_table: SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7 SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff -/* - * Version string - */ - .data .extern leon3_snooping_avail - .globl version_string -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" .extern _nomem_amba_init, _nomem_memory_ctrl_init From f33f888d0e6c5c3f8eb880219bbc87b938832607 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 22 Jan 2010 11:57:49 +0100 Subject: [PATCH 03/21] sparc: Added function that checks if IRQ is on or off Signed-off-by: Daniel Hellstrom --- arch/sparc/include/asm/irq.h | 3 +++ arch/sparc/lib/interrupts.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/arch/sparc/include/asm/irq.h b/arch/sparc/include/asm/irq.h index 2faf7a074e..5d0f7564e9 100644 --- a/arch/sparc/include/asm/irq.h +++ b/arch/sparc/include/asm/irq.h @@ -32,4 +32,7 @@ extern int intLock(void); /* Sets the PIL to oldLevel */ extern void intUnlock(int oldLevel); +/* Return non-zero if interrupts are currently enabled */ +extern int interrupt_is_enabled(void); + #endif diff --git a/arch/sparc/lib/interrupts.c b/arch/sparc/lib/interrupts.c index b7c3993619..b8f2efb303 100644 --- a/arch/sparc/lib/interrupts.c +++ b/arch/sparc/lib/interrupts.c @@ -47,6 +47,13 @@ int disable_interrupts(void) return intLock(); } +int interrupt_is_enabled(void) +{ + if (get_pil() == 15) + return 0; + return 1; +} + int interrupt_init(void) { int ret; From 58e5585625d06530cf52ffc2b7b9a188dc46bffe Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 23 Nov 2015 09:49:57 +0200 Subject: [PATCH 04/21] sparc: leon3: Clear GD_FLAG_SERIAL_READY flag on AMBA failure Clear the GD_FLG_SERIAL_READY flag on AMBA P&P lookup failure so that the panic function can use DEBUG_UART driver. drivers/serial/serial.c set this flag before calling this function, preventing DEBUG_UART code from running. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index 66b3773027..15d022673d 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -29,6 +29,7 @@ static int leon3_serial_init(void) /* find UART */ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { + gd->flags &= ~GD_FLG_SERIAL_READY; panic("%s: apbuart not found!\n", __func__); return -1; /* didn't find hardware */ } From ff0b9b77c2c86e9c6cdb572a258b29f24fcd754a Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 22 Jan 2010 11:49:04 +0100 Subject: [PATCH 05/21] sparc: Serial baud rate register support multiple buses with different frequency Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon2/serial.c | 2 +- arch/sparc/cpu/leon3/serial.c | 17 ++++++++++++++--- arch/sparc/include/asm/global_data.h | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c index 603364ee0b..460abd1d9f 100644 --- a/arch/sparc/cpu/leon2/serial.c +++ b/arch/sparc/cpu/leon2/serial.c @@ -120,7 +120,7 @@ static void leon2_serial_setbrg(void) if (!gd->baudrate) gd->baudrate = CONFIG_BAUDRATE; - scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); + scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, gd->baudrate); writel(scaler, &uart->UART_Scaler); } diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index 15d022673d..5348a78303 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -20,6 +20,11 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_SYS_GRLIB_APBUART_INDEX 0 #endif +static unsigned apbuart_calc_scaler(unsigned apbuart_freq, unsigned baud) +{ + return (((apbuart_freq * 10) / (baud * 8)) - 5) / 10; +} + static int leon3_serial_init(void) { ambapp_dev_apbuart *uart; @@ -37,8 +42,11 @@ static int leon3_serial_init(void) /* found apbuart, let's init .. */ uart = (ambapp_dev_apbuart *) apbdev.address; + /* APBUART Frequency is equal to bus frequency */ + gd->arch.uart_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); + /* Set scaler / baud rate */ - tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + tmp = apbuart_calc_scaler(gd->arch.uart_freq, CONFIG_BAUDRATE); writel(tmp, &uart->scaler); /* Let bit 11 be unchanged (debug bit for GRMON) */ @@ -123,7 +131,10 @@ static void leon3_serial_setbrg(void) if (!gd->baudrate) gd->baudrate = CONFIG_BAUDRATE; - scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10; + if (!gd->arch.uart_freq) + gd->arch.uart_freq = CONFIG_SYS_CLK_FREQ; + + scaler = apbuart_calc_scaler(gd->arch.uart_freq, gd->baudrate); writel(scaler, &uart->scaler); } @@ -156,7 +167,7 @@ __weak struct serial_device *default_serial_console(void) static inline void _debug_uart_init(void) { ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; - uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + uart->scaler = apbuart_calc_scaler(CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE; } diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index 0680a56758..71820f095d 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -16,6 +16,7 @@ /* Architecture-specific global data */ struct arch_global_data { void *uart; + unsigned int uart_freq; }; #include From c2b37a0d558b169a8b2379e64329f19a4a5ee37f Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Fri, 30 Oct 2015 13:23:41 +0200 Subject: [PATCH 06/21] sparc: leon3: Updated serial driver to use CONFIG_CONS_INDEX Updated the LEON3 serial driver to make use of the CONFIG_CONS_INDEX option to select which serial port the console will use. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/serial.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index 5348a78303..bc6e7a172e 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -17,8 +17,13 @@ DECLARE_GLOBAL_DATA_PTR; /* Select which UART that will become u-boot console */ #ifndef CONFIG_SYS_GRLIB_APBUART_INDEX +/* Try to use CONFIG_CONS_INDEX, if available, it is numbered from 1 */ +#ifdef CONFIG_CONS_INDEX +#define CONFIG_SYS_GRLIB_APBUART_INDEX (CONFIG_CONS_INDEX - 1) +#else #define CONFIG_SYS_GRLIB_APBUART_INDEX 0 #endif +#endif static unsigned apbuart_calc_scaler(unsigned apbuart_freq, unsigned baud) { From a5b629a33e717e794db8db5b0fedbd3aa254e711 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Sat, 21 Nov 2015 17:07:48 +0200 Subject: [PATCH 07/21] sparc: Fix whitespace in cpu/leon2/cpu_init.c Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/cpu_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/sparc/cpu/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index 6e07fe6bb4..695ee028b3 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -50,17 +50,17 @@ void cpu_init_f(void) /* cache */ - /* I/O port setup */ + /* I/O port setup */ #ifdef LEON2_IO_PORT_DIR - leon2->PIO_Direction = LEON2_IO_PORT_DIR; + leon2->PIO_Direction = LEON2_IO_PORT_DIR; #endif #ifdef LEON2_IO_PORT_DATA - leon2->PIO_Data = LEON2_IO_PORT_DATA; + leon2->PIO_Data = LEON2_IO_PORT_DATA; #endif #ifdef LEON2_IO_PORT_INT - leon2->PIO_Interrupt = LEON2_IO_PORT_INT; + leon2->PIO_Interrupt = LEON2_IO_PORT_INT; #else - leon2->PIO_Interrupt = 0; + leon2->PIO_Interrupt = 0; #endif } From e17c5200c7e9a802783a53d4f4457fa68f7fa074 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 14:29:32 +0200 Subject: [PATCH 08/21] sparc: Initial ground work for generic board initialization Initial ground work in preperation for generic board initialization code for the SPARC architecture. Signed-off-by: Francois Retief --- arch/Kconfig | 1 + arch/sparc/cpu/leon2/cpu.c | 4 ++-- arch/sparc/cpu/leon2/cpu_init.c | 21 +++++++++++---------- arch/sparc/cpu/leon3/cpu.c | 4 ++-- arch/sparc/cpu/leon3/cpu_init.c | 17 +++++++++-------- arch/sparc/include/asm/config.h | 4 +++- arch/sparc/include/asm/u-boot.h | 7 +++++++ arch/sparc/lib/Makefile | 8 ++++++-- common/board_r.c | 3 ++- 9 files changed, 43 insertions(+), 26 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 25dcf4a1a3..6489cc9406 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -97,6 +97,7 @@ config SH config SPARC bool "SPARC architecture" + select HAVE_GENERIC_BOARD select CREATE_ARCH_SYMLINK config X86 diff --git a/arch/sparc/cpu/leon2/cpu.c b/arch/sparc/cpu/leon2/cpu.c index 380c397be0..22e63e3869 100644 --- a/arch/sparc/cpu/leon2/cpu.c +++ b/arch/sparc/cpu/leon2/cpu.c @@ -1,7 +1,7 @@ /* CPU specific code for the LEON2 CPU * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ diff --git a/arch/sparc/cpu/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index 695ee028b3..581f057269 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -1,8 +1,8 @@ /* Initializes CPU and basic hardware such as memory * controllers, IRQ controller and system timer 0. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -18,14 +18,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* reset CPU (jump to 0, without reset) */ -void start(void); - -struct { - gd_t gd_area; - bd_t bd; -} global_data; - /* * Breath some life into the CPU... * @@ -69,6 +61,15 @@ void cpu_init_f2(void) } +int arch_cpu_init(void) +{ + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->bus_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + /* * initialize higher level parts of CPU like time base and timers */ diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c index 8ab315016b..d57bf2fc87 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -1,7 +1,7 @@ /* CPU specific code for the LEON3 CPU * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index b140da31b1..a0526cd36c 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -27,19 +27,11 @@ DECLARE_GLOBAL_DATA_PTR; -/* reset CPU (jump to 0, without reset) */ -void start(void); - ambapp_dev_irqmp *irqmp = NULL; ambapp_dev_gptimer *gptimer = NULL; unsigned int gptimer_irq = 0; int leon3_snooping_avail = 0; -struct { - gd_t gd_area; - bd_t bd; -} global_data; - /* * Breath some life into the CPU... * @@ -71,6 +63,15 @@ void cpu_init_f2(void) ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); } +int arch_cpu_init(void) +{ + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->bus_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + /* * initialize higher level parts of CPU like time base and timers */ diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h index fd0b5513ee..c884b250fe 100644 --- a/arch/sparc/include/asm/config.h +++ b/arch/sparc/include/asm/config.h @@ -1,5 +1,6 @@ /* - * Copyright 2009 Freescale Semiconductor, Inc. + * Copyright 2015, + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -7,6 +8,7 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ +#define CONFIG_SYS_GENERIC_GLOBAL_DATA #define CONFIG_NEEDS_MANUAL_RELOC #define CONFIG_LMB diff --git a/arch/sparc/include/asm/u-boot.h b/arch/sparc/include/asm/u-boot.h index 5f12e58131..4c4b5f218a 100644 --- a/arch/sparc/include/asm/u-boot.h +++ b/arch/sparc/include/asm/u-boot.h @@ -17,6 +17,11 @@ #ifndef __U_BOOT_H__ #define __U_BOOT_H__ +#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include +#else + /* * Currently, this Board information is not passed to * Linux kernel from U-Boot, but may be passed to other @@ -44,6 +49,8 @@ typedef struct bd_info { #endif /* __ASSEMBLY__ */ +#endif /* !CONFIG_SYS_GENERIC_BOARD */ + /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_SPARC diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index e69b9ba426..6bddd4c8a1 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -1,9 +1,13 @@ # -# (C) Copyright 2000-2006 +# (C) Copyright 2000-2015 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # SPDX-License-Identifier: GPL-2.0+ # -obj-y = board.o cache.o interrupts.o time.o +obj-y = cache.o interrupts.o time.o obj-$(CONFIG_CMD_BOOTM) += bootm.o + +ifndef CONFIG_SYS_GENERIC_BOARD +obj-y += board.o +endif diff --git a/common/board_r.c b/common/board_r.c index a41fb547a3..f1dfa68fd5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -813,7 +813,8 @@ init_fnc_t init_sequence_r[] = { initr_flash, #endif INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) || \ + defined(CONFIG_SPARC) /* initialize higher level parts of CPU like time base and timers */ cpu_init_r, #endif From d67269ba70f471a33ea64fcddc698cacce14e14a Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 15:48:41 +0200 Subject: [PATCH 09/21] sparc: leon3: Move snoop detection from startup.S to arch_cpu_init() Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/cpu_init.c | 13 ++++++++++++- arch/sparc/cpu/leon3/start.S | 15 --------------- arch/sparc/cpu/leon3/usb_uhci.c | 7 ++++--- arch/sparc/include/asm/global_data.h | 7 +++++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index a0526cd36c..421859e0e2 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -30,7 +30,6 @@ DECLARE_GLOBAL_DATA_PTR; ambapp_dev_irqmp *irqmp = NULL; ambapp_dev_gptimer *gptimer = NULL; unsigned int gptimer_irq = 0; -int leon3_snooping_avail = 0; /* * Breath some life into the CPU... @@ -63,12 +62,24 @@ void cpu_init_f2(void) ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); } +/* If cache snooping is available in hardware the result will be set + * to 0x800000, otherwise 0. + */ +static unsigned int snoop_detect(void) +{ + unsigned int result; + asm("lda [%%g0] 2, %0" : "=r"(result)); + return result & 0x00800000; +} + int arch_cpu_init(void) { gd->cpu_clk = CONFIG_SYS_CLK_FREQ; gd->bus_clk = CONFIG_SYS_CLK_FREQ; gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + gd->arch.snooping_available = snoop_detect(); + return 0; } diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index fe4795cc9a..1988ee1f6b 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -209,8 +209,6 @@ _trap_table: SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff - .extern leon3_snooping_avail - .section ".text" .extern _nomem_amba_init, _nomem_memory_ctrl_init .align 4 @@ -401,19 +399,6 @@ prom_relocate_loop: nop nop -/* If CACHE snooping is available in hardware the - * variable leon3_snooping_avail will be set to - * 0x800000 else 0. - */ -snoop_detect: - sethi %hi(0x00800000), %o0 - lda [%g0] 2, %o1 - and %o0, %o1, %o0 - sethi %hi(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE), %o1 - st %o0, [%lo(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE)+%o1] - -/* call relocate*/ - nop /* Call relocated init functions */ jump: SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c index 1be84c646b..242b83fbcf 100644 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ b/arch/sparc/cpu/leon3/usb_uhci.c @@ -85,10 +85,11 @@ #include #include "usb_uhci.h" +DECLARE_GLOBAL_DATA_PTR; + #define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */ #define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */ -extern int leon3_snooping_avail; /* #define out16r(address,data) (*(unsigned short *)(address) = \ (unsigned short)( \ @@ -573,7 +574,7 @@ void usb_check_skel(void) if (qh_cntrl.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ dev = (struct usb_device *)qh_cntrl.dev_ptr; /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) + if (!gd->arch.snooping_avail) sparc_dcache_flush_all(); usb_get_td_status(&tmp_td[0], dev); /* update status */ if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ @@ -584,7 +585,7 @@ void usb_check_skel(void) if (qh_bulk.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ dev = (struct usb_device *)qh_bulk.dev_ptr; /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) + if (!gd->arch.snooping_avail) sparc_dcache_flush_all(); usb_get_td_status(&tmp_td[0], dev); /* update status */ if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index 71820f095d..8c6557ad1f 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -2,8 +2,8 @@ * (C) Copyright 2002-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham, Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -17,6 +17,9 @@ struct arch_global_data { void *uart; unsigned int uart_freq; +#ifdef CONFIG_LEON3 + unsigned int snooping_available; +#endif }; #include From 574be25ea1b88ff1b7d213584b04b754f187e25d Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Thu, 29 Oct 2015 12:58:52 +0200 Subject: [PATCH 10/21] sparc: leon3: Move ambapp_bus_init() call to arch_cpu_init() function Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/ambapp.c | 2 +- arch/sparc/cpu/leon3/cpu_init.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index b8ac05faf1..47769cffd7 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -40,7 +40,7 @@ extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend, int index, int type, struct ambapp_find_ahb_info *result); /************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/ -struct ambapp_bus ambapp_plb; +struct ambapp_bus ambapp_plb __section(.data); void ambapp_bus_init( unsigned int ioarea, diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 421859e0e2..20a6a256f0 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -56,10 +56,6 @@ void cpu_init_f(void) */ void cpu_init_f2(void) { - /* Initialize the AMBA Plug & Play bus structure, the bus - * structure represents the AMBA bus that the CPU is located at. - */ - ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); } /* If cache snooping is available in hardware the result will be set @@ -80,6 +76,11 @@ int arch_cpu_init(void) gd->arch.snooping_available = snoop_detect(); + /* Initialize the AMBA Plug & Play bus structure, the bus + * structure represents the AMBA bus that the CPU is located at. + */ + ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); + return 0; } From cb31eaa4b3e870e4520dd0ce6f9ce326dc9cf50b Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 22 Sep 2010 17:42:29 +0200 Subject: [PATCH 11/21] sparc: leon3: Clear all unused GPTIMER registers. Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/cpu_init.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 20a6a256f0..0ce2f89dff 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -90,7 +90,7 @@ int arch_cpu_init(void) int cpu_init_r(void) { ambapp_apbdev apbdev; - int index, cpu; + int index, cpu, ntimers, i; ambapp_dev_gptimer *timer = NULL; unsigned int bus_freq; @@ -135,6 +135,14 @@ int cpu_init_r(void) timer->scalar = timer->scalar_reload = (((bus_freq / 1000) + 500) / 1000) - 1; + /* Clear All Timers */ + ntimers = timer->config & 0x7; + for (i = 0; i < ntimers; i++) { + timer->e[i].ctrl = GPTIMER_CTRL_IP; + timer->e[i].rld = 0; + timer->e[i].ctrl = GPTIMER_CTRL_LD; + } + index++; } if (!gptimer) { From a62bba15b5a02accb8f6de3b47a525eab4f50302 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Thu, 29 Oct 2015 00:02:48 +0200 Subject: [PATCH 12/21] sparc: leon3: Updates for generic board initialization Reworked the LEON3 start.S code to call board_init_f function at startup. Also implemented the relocate_code function in assembly to relocate the monitor and setup the stack pointer before calling relocated board_init_r. Add the CONFIG_SYS_GENERIC_BOARD variable to all the LEON3 boards. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/cpu_init.c | 11 -- arch/sparc/cpu/leon3/start.S | 248 ++++++++++++++++++------------- include/configs/gr_cpci_ax2000.h | 2 + include/configs/gr_ep2s60.h | 2 + include/configs/gr_xc3s_1500.h | 2 + include/configs/grsim.h | 2 + 6 files changed, 151 insertions(+), 116 deletions(-) diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 0ce2f89dff..9c7665783c 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -47,17 +47,6 @@ void cpu_init_f(void) #endif } -/* Routine called from start.S, - * - * Run from FLASH/PROM: - * - memory controller has already been setup up, stack can be used - * - global variables available for read/writing - * - constants avaiable - */ -void cpu_init_f2(void) -{ -} - /* If cache snooping is available in hardware the result will be set * to 0x800000, otherwise 0. */ diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index 1988ee1f6b..52e82b5e33 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -257,11 +257,18 @@ wiminit: set WIM_INIT, %g3 mov %g3, %wim -stackp: +stackinit: set CONFIG_SYS_INIT_SP_OFFSET, %fp andn %fp, 0x0f, %fp sub %fp, 64, %sp +tbrinit: + set CONFIG_SYS_TEXT_BASE, %g2 + wr %g0, %g2, %tbr + nop + nop + nop + /* Obtain the address of _GLOBAL_OFFSET_TABLE_ */ SPARC_PIC_THUNK_CALL(l7) @@ -298,25 +305,50 @@ cpu_init_unreloc: call cpu_init_f nop -/* un relocated start address of monitor */ -#define TEXT_START _text +board_init_unreloc: + call board_init_f + clr %o0 ! boot_flags -/* un relocated end address of monitor */ -#define DATA_END __init_end +dead_unreloc: + mov 1, %g1 ! For GRMON2 to exit normally. + ta 0 ! If board_init_f call returns.. (unlikely) + nop + nop + ba dead_unreloc ! infinte loop + nop +!------------------------------------------------------------------------------- + +/* void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM after + * relocating the monitor code. + * + * %o0 = Relocated stack pointer + * %o1 = Relocated global data pointer + * %o2 = Relocated text pointer + * + * %l7 = _GLOBAL_OFFSET_TABLE_ address + */ + .globl relocate_code + .type relocate_code, #function + .align 4 +relocate_code: + !SPARC_PIC_THUNK_CALL(l7) reloc: - SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) - SPARC_LOAD_ADDRESS(DATA_END, l7, g3) - set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 -reloc_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne reloc_loop - inc 16,%g4 + SPARC_LOAD_ADDRESS(_text, l7, g2) ! start address of monitor + SPARC_LOAD_ADDRESS(__init_end, l7, g3) ! end address of monitor + mov %o2, %g4 ! relocation address + sub %g4, %g2, %g6 ! relocation offset + /* copy .text & .data to relocated address */ +10: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 ! src += 16 + cmp %g2, %g3 + bcs 10b ! while (src < end) + inc 16, %g4 ! dst += 16 clr %l0 clr %l1 @@ -331,49 +363,42 @@ reloc_loop: * */ + /* clear the relocated .bss area */ clr_bss: -/* clear bss area (the relocated) */ SPARC_LOAD_ADDRESS(__bss_start, l7, g2) SPARC_LOAD_ADDRESS(__bss_end, l7, g3) - sub %g3,%g2,%g3 + sub %g3,%g2,%g3 ! length of .bss area add %g3,%g4,%g3 + /* clearing 16byte a time ==> linker script need to align to 16 byte offset */ clr %g1 /* std %g0 uses g0 and g1 */ -/* clearing 16byte a time ==> linker script need to align to 16 byte offset */ -clr_bss_16: - std %g0,[%g4] - std %g0,[%g4+8] - inc 16,%g4 - cmp %g3,%g4 - bne clr_bss_16 +20: + std %g0, [%g4] + std %g0, [%g4+8] + inc 16, %g4 ! ptr += 16 + cmp %g4, %g3 + bcs 20b ! while (ptr < end) nop -/* add offsets to GOT table */ + /* add offsets to GOT table */ fixup_got: SPARC_LOAD_ADDRESS(__got_start, l7, g4) + add %g4, %g6, %g4 SPARC_LOAD_ADDRESS(__got_end, l7, g3) -/* - * new got offset = (old GOT-PTR (read with ld) - - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + - * Destination Address (from define) - */ - set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %g4,%g2,%g4 - sub %g4,%g1,%g4 - add %g3,%g2,%g3 - sub %g3,%g1,%g3 - sub %g2,%g1,%g2 ! prepare register with (new base address) - - ! (old base address) -got_loop: - ld [%g4],%l0 ! load old GOT-PTR - add %l0,%g2,%l0 ! increase with (new base address) - - ! (old base) - st %l0,[%g4] - inc 4,%g4 - cmp %g3,%g4 - bne got_loop + add %g3, %g6, %g3 +30: ld [%g4], %l0 +#ifdef CONFIG_RELOC_GOT_SKIP_NULL + cmp %l0, 0 + be 32f +#endif + add %l0, %g6, %l0 ! relocate GOT pointer + st %l0, [%g4] +32: inc 4, %g4 ! ptr += 4 + cmp %g4, %g3 + bcs 30b ! while (ptr < end) nop +#if 0 /* FIXME: Relocated PROM address should be calculated! */ + prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) @@ -389,35 +414,46 @@ prom_relocate_loop: bne prom_relocate_loop inc 16,%g4 +#endif + +! %o0 = stack pointer (relocated) +! %o1 = global data pointer (relocated) +! %o2 = text pointer (relocated) + +! %g6 = relocation offset +! %l7 = _GLOBAL_OFFSET_TABLE_ + /* Trap table has been moved, lets tell CPU about * the new trap table address */ - - set CONFIG_SYS_RELOC_MONITOR_BASE, %g2 - wr %g0, %g2, %tbr +update_trap_table_address: + wr %g0, %o2, %tbr nop nop nop -/* Call relocated init functions */ -jump: - SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +update_stack_pointers: + mov %o0, %fp + andn %fp, 0x0f, %fp ! align to 16 bytes + add %fp, -64, %fp ! make space for a window push + mov %fp, %sp ! setup stack pointer - SPARC_LOAD_ADDRESS(board_init_f, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +jump_board_init_r: + mov %o1, %o0 ! relocated global data pointer + mov %o2, %o1 ! relocated text pointer + SPARC_LOAD_ADDRESS(board_init_r, l7, o3) + add %o3, %g6, %o3 ! add relocation offset + call %o3 + nop -dead: ta 0 ! if call returns... - nop +dead: + mov 1, %g1 ! For GRMON2 to exit normally. + ta 0 ! if call returns.. (unlikely) + nop + b dead ! infinte loop + nop + +!------------------------------------------------------------------------------ /* Interrupt handler caller, * reg L7: interrupt number @@ -446,54 +482,56 @@ _irq_entry: RESTORE_ALL -!Window overflow trap handler. +!------------------------------------------------------------------------------ + +/* + * Window overflow trap handler + */ .global _window_overflow _window_overflow: mov %wim, %l3 ! Calculate next WIM - mov %g1, %l7 - srl %l3, 1, %g1 - sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4 - or %l4, %g1, %g1 - + mov %g1, %l7 + srl %l3, 1, %g1 + sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4 + or %g1, %l4, %g1 save ! Get into window to be saved. - mov %g1, %wim - nop; - nop; - nop - st %l0, [%sp + 0]; - st %l1, [%sp + 4]; - st %l2, [%sp + 8]; - st %l3, [%sp + 12]; - st %l4, [%sp + 16]; - st %l5, [%sp + 20]; - st %l6, [%sp + 24]; - st %l7, [%sp + 28]; - st %i0, [%sp + 32]; - st %i1, [%sp + 36]; - st %i2, [%sp + 40]; - st %i3, [%sp + 44]; - st %i4, [%sp + 48]; - st %i5, [%sp + 52]; - st %i6, [%sp + 56]; - st %i7, [%sp + 60]; + mov %g1, %wim + nop; nop; nop + st %l0, [%sp + 0] ! Save window to the stack + st %l1, [%sp + 4] + st %l2, [%sp + 8] + st %l3, [%sp + 12] + st %l4, [%sp + 16] + st %l5, [%sp + 20] + st %l6, [%sp + 24] + st %l7, [%sp + 28] + st %i0, [%sp + 32] + st %i1, [%sp + 36] + st %i2, [%sp + 40] + st %i3, [%sp + 44] + st %i4, [%sp + 48] + st %i5, [%sp + 52] + st %i6, [%sp + 56] + st %i7, [%sp + 60] restore ! Go back to trap window. - mov %l7, %g1 + mov %l7, %g1 jmp %l1 ! Re-execute save. - rett %l2 - -/* Window underflow trap handler. */ + rett %l2 +/* + * Window underflow trap handler + */ .global _window_underflow _window_underflow: - mov %wim, %l3 ! Calculate next WIM - sll %l3, 1, %l4 - srl %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5 - or %l5, %l4, %l5 - mov %l5, %wim + mov %wim, %l3 ! Calculate next WIM + srl %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5 + sll %l3, 1, %l4 + or %l5, %l4, %l5 + mov %l5, %wim nop; nop; nop restore ! Two restores to get into the restore ! window to restore @@ -516,9 +554,9 @@ _window_underflow: save ! Get back to the trap window. save jmp %l1 ! Re-execute restore. - rett %l2 + rett %l2 - retl +!------------------------------------------------------------------------------ _nmi_trap: nop diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 67538d05a7..a16f59a891 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -14,6 +14,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define CONFIG_SYS_GENERIC_BOARD + /* * High Level Configuration Options * (easy to change) diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 387596d6b3..f472179dd6 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -15,6 +15,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define CONFIG_SYS_GENERIC_BOARD + /* * High Level Configuration Options * (easy to change) diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 5fb800bf21..8598ac1881 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -13,6 +13,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define CONFIG_SYS_GENERIC_BOARD + /* * High Level Configuration Options * (easy to change) diff --git a/include/configs/grsim.h b/include/configs/grsim.h index 932f330e1e..e280dee9e9 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -13,6 +13,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define CONFIG_SYS_GENERIC_BOARD + /* * High Level Configuration Options * (easy to change) From c837901bf15616dd08997c30461e0f62bcd55245 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Sat, 21 Nov 2015 13:25:41 +0200 Subject: [PATCH 13/21] sparc: leon2: Updates for generic board initialization Reworked the LEON2 start.S code to call board_init_f function at startup. Also implemented the relocate_code function in assembly to relocate the monitor and setup the stack pointer before calling relocated board_init_r. Add the CONFIG_SYS_GENERIC_BOARD variable to all the LEON2 boards. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/cpu_init.c | 5 - arch/sparc/cpu/leon2/start.S | 177 +++++++++++++++++++------------- include/configs/grsim_leon2.h | 6 +- 3 files changed, 111 insertions(+), 77 deletions(-) diff --git a/arch/sparc/cpu/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index 581f057269..5630b095d4 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -56,11 +56,6 @@ void cpu_init_f(void) #endif } -void cpu_init_f2(void) -{ - -} - int arch_cpu_init(void) { gd->cpu_clk = CONFIG_SYS_CLK_FREQ; diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index fa1534f3ff..7362ae134d 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -310,30 +310,62 @@ leon2_init_stackp: andn %fp, 0x0f, %fp sub %fp, 64, %sp +leon2_init_tbr: + set CONFIG_SYS_TEXT_BASE, %g2 + wr %g0, %g2, %tbr + nop + nop + nop + cpu_init_unreloc: call cpu_init_f nop +board_init_unreloc: + call board_init_f + clr %o0 ! boot_flags + +dead_unreloc: + ba dead_unreloc ! infinte loop + nop + +!------------------------------------------------------------------------------- + +/* void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM after + * relocating the monitor code. + * + * %o0 = Relocated stack pointer + * %o1 = Relocated global data pointer + * %o2 = Relocated text pointer + */ + .globl relocate_code + .type relocate_code, #function + .align 4 +relocate_code: + SPARC_PIC_THUNK_CALL(l7) + /* un relocated start address of monitor */ #define TEXT_START _text /* un relocated end address of monitor */ #define DATA_END __init_end - SPARC_PIC_THUNK_CALL(l7) reloc: SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) SPARC_LOAD_ADDRESS(DATA_END, l7, g3) - set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 -reloc_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne reloc_loop - inc 16,%g4 + mov %o2, %g4 ! relocation address + sub %g4, %g2, %g6 ! relocation offset + /* copy .text & .data to relocated address */ +10: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 ! src += 16 + cmp %g2, %g3 + bcs 10b ! while (src < end) + inc 16, %g4 ! dst += 16 clr %l0 clr %l1 @@ -348,49 +380,42 @@ reloc_loop: * */ + /* clear bss area (the relocated) */ clr_bss: -/* clear bss area (the relocated) */ SPARC_LOAD_ADDRESS(__bss_start, l7, g2) SPARC_LOAD_ADDRESS(__bss_end, l7, g3) - sub %g3,%g2,%g3 + sub %g3,%g2,%g3 ! length of .bss area add %g3,%g4,%g3 + /* clearing 16byte a time ==> linker script need to align to 16 byte offset */ clr %g1 /* std %g0 uses g0 and g1 */ -/* clearing 16byte a time ==> linker script need to align to 16 byte offset */ -clr_bss_16: - std %g0,[%g4] - std %g0,[%g4+8] - inc 16,%g4 - cmp %g3,%g4 - bne clr_bss_16 +20: + std %g0, [%g4] + std %g0, [%g4+8] + inc 16, %g4 ! ptr += 16 + cmp %g4, %g3 + bcs 20b ! while (ptr < end) nop -/* add offsets to GOT table */ + /* add offsets to GOT table */ fixup_got: SPARC_LOAD_ADDRESS(__got_start, l7, g4) + add %g4, %g6, %g4 SPARC_LOAD_ADDRESS(__got_end, l7, g3) -/* - * new got offset = (old GOT-PTR (read with ld) - - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + - * Destination Address (from define) - */ - set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %g4,%g2,%g4 - sub %g4,%g1,%g4 - add %g3,%g2,%g3 - sub %g3,%g1,%g3 - sub %g2,%g1,%g2 ! prepare register with (new base address) - - ! (old base address) -got_loop: - ld [%g4],%l0 ! load old GOT-PTR - add %l0,%g2,%l0 ! increase with (new base address) - - ! (old base) - st %l0,[%g4] - inc 4,%g4 - cmp %g3,%g4 - bne got_loop + add %g3, %g6, %g3 +30: ld [%g4], %l0 ! load old GOT-PTR +#ifdef CONFIG_RELOC_GOT_SKIP_NULL + cmp %l0, 0 + be 32f +#endif + add %l0, %g6, %l0 ! relocate GOT pointer + st %l0, [%g4] +32: inc 4, %g4 ! ptr += 4 + cmp %g4, %g3 + bcs 30b ! while (ptr < end) nop +#if 0 /* FIXME: Relocated PROM address should be calculated! */ + prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) @@ -406,33 +431,42 @@ prom_relocate_loop: bne prom_relocate_loop inc 16,%g4 +#endif + +! %o0 = stack pointer (relocated) +! %o1 = global data pointer (relocated) +! %o2 = text pointer (relocated) + +! %g6 = relocation offset +! %l7 = _GLOBAL_OFFSET_TABLE_ + /* Trap table has been moved, lets tell CPU about * the new trap table address */ - - set CONFIG_SYS_RELOC_MONITOR_BASE, %g2 - wr %g0, %g2, %tbr - -/* call relocate*/ +update_trap_table_address: + wr %g0, %o2, %tbr + nop + nop nop -/* Call relocated init functions */ -jump: - SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 - SPARC_LOAD_ADDRESS(board_init_f, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +update_stack_pointers: + mov %o0, %fp + andn %fp, 0x0f, %fp ! align to 16 bytes + add %fp, -64, %fp ! make space for a window push + mov %fp, %sp ! setup stack pointer + +jump_board_init_r: + mov %o1, %o0 ! relocated global data pointer + mov %o2, %o1 ! relocated text pointer + SPARC_LOAD_ADDRESS(board_init_r, l7, o3) + add %o3, %g6, %o3 ! add relocation offset + call %o3 + nop dead: ta 0 ! if call returns... - nop + nop + +!------------------------------------------------------------------------------ /* Interrupt handler caller, * reg L7: interrupt number @@ -461,7 +495,11 @@ _irq_entry: RESTORE_ALL -!Window overflow trap handler. +!------------------------------------------------------------------------------ + +/* + * Window overflow trap handler. + */ .global _window_overflow _window_overflow: @@ -469,14 +507,12 @@ _window_overflow: mov %wim, %l3 ! Calculate next WIM mov %g1, %l7 srl %l3, 1, %g1 - sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4 + sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4 or %l4, %g1, %g1 save ! Get into window to be saved. mov %g1, %wim - nop; - nop; - nop + nop; nop; nop st %l0, [%sp + 0]; st %l1, [%sp + 4]; st %l2, [%sp + 8]; @@ -498,8 +534,9 @@ _window_overflow: jmp %l1 ! Re-execute save. rett %l2 -/* Window underflow trap handler. */ - +/* + * Window underflow trap handler. + */ .global _window_underflow _window_underflow: @@ -533,7 +570,7 @@ _window_underflow: jmp %l1 ! Re-execute restore. rett %l2 - retl +!------------------------------------------------------------------------------ _nmi_trap: nop diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index 83022e8542..2f7a5628f1 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -3,8 +3,8 @@ * (C) Copyright 2003-2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,6 +12,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define CONFIG_SYS_GENERIC_BOARD + /* * High Level Configuration Options * (easy to change) From c97088c3cfa84e7e53fddd26896f145cc8c431a2 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 15:18:22 +0200 Subject: [PATCH 14/21] sparc: Update cpu_init.c to use generic timer infrastructure Introduce the CONFIG_SYS_TIMER_* macros in include/asm/config.h to make use of the generic timer infrastructure in lib/time.c. Created a timer_init() function to initialize the timer hardware and update the #ifdef in board_init_f to allow this function to be called during the start-up sequence. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/cpu_init.c | 37 +++++--- arch/sparc/cpu/leon3/cpu_init.c | 131 +++++++++++++++------------ arch/sparc/include/asm/config.h | 4 + arch/sparc/include/asm/global_data.h | 1 + arch/sparc/lib/interrupts.c | 5 - common/board_f.c | 3 +- 6 files changed, 106 insertions(+), 75 deletions(-) diff --git a/arch/sparc/cpu/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index 5630b095d4..b4d91e5039 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -54,6 +55,9 @@ void cpu_init_f(void) #else leon2->PIO_Interrupt = 0; #endif + + /* disable timers */ + leon2->Timer_Control_1 = leon2->Timer_Control_2 = 0; } int arch_cpu_init(void) @@ -66,17 +70,11 @@ int arch_cpu_init(void) } /* - * initialize higher level parts of CPU like time base and timers + * initialize higher level parts of CPU */ int cpu_init_r(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - /* initialize prescaler common to all timers to 1MHz */ - leon2->Scaler_Counter = leon2->Scaler_Reload = - (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; - - return (0); + return 0; } /* Uses Timer 0 to get accurate @@ -106,11 +104,6 @@ int timer_interrupt_init_cpu(void) return LEON2_TIMER1_IRQNO; } -ulong get_tbclk(void) -{ - return TIMER_BASE_CLK; -} - /* * This function is intended for SHORT delays only. */ @@ -125,3 +118,21 @@ unsigned long cpu_ticks2usec(unsigned long ticks) { return ticks * US_PER_TICK; } + +int timer_init(void) +{ + LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS; + + /* initialize prescaler common to all timers to 1MHz */ + leon2->Scaler_Counter = leon2->Scaler_Reload = + (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; + + /* SYS_HZ ticks per second */ + leon2->Timer_Counter_1 = 0; + leon2->Timer_Reload_1 = (CONFIG_SYS_TIMER_RATE / CONFIG_SYS_HZ) - 1; + leon2->Timer_Control_1 = LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | + LEON2_TIMER_CTRL_LD; + + CONFIG_SYS_TIMER_COUNTER = (void *)&leon2->Timer_Counter_1; + return 0; +} diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 9c7665783c..88f82c95a8 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -22,14 +23,17 @@ #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA #endif +/* Select which TIMER that will become the time base */ +#ifndef CONFIG_SYS_GRLIB_GPTIMER_INDEX +#define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0 +#endif + #define TIMER_BASE_CLK 1000000 #define US_PER_TICK (1000000 / CONFIG_SYS_HZ) DECLARE_GLOBAL_DATA_PTR; ambapp_dev_irqmp *irqmp = NULL; -ambapp_dev_gptimer *gptimer = NULL; -unsigned int gptimer_irq = 0; /* * Breath some life into the CPU... @@ -59,6 +63,9 @@ static unsigned int snoop_detect(void) int arch_cpu_init(void) { + ambapp_apbdev apbdev; + int index; + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; gd->bus_clk = CONFIG_SYS_CLK_FREQ; gd->ram_size = CONFIG_SYS_SDRAM_SIZE; @@ -70,6 +77,35 @@ int arch_cpu_init(void) */ ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); + /* Initialize/clear all the timers in the system. + */ + for (index = 0; ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_GPTIMER, index, &apbdev) == 1; index++) { + ambapp_dev_gptimer *timer; + unsigned int bus_freq; + int i, ntimers; + + timer = (ambapp_dev_gptimer *)apbdev.address; + + /* Different buses may have different frequency, the + * frequency of the bus tell in which frequency the timer + * prescaler operates. + */ + bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); + + /* Initialize prescaler common to all timers to 1MHz */ + timer->scalar = timer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; + + /* Clear all timers */ + ntimers = timer->config & 0x7; + for (i = 0; i < ntimers; i++) { + timer->e[i].ctrl = GPTIMER_CTRL_IP; + timer->e[i].rld = 0; + timer->e[i].ctrl = GPTIMER_CTRL_LD; + } + } + return 0; } @@ -79,9 +115,7 @@ int arch_cpu_init(void) int cpu_init_r(void) { ambapp_apbdev apbdev; - int index, cpu, ntimers, i; - ambapp_dev_gptimer *timer = NULL; - unsigned int bus_freq; + int cpu; /* * Find AMBA APB IRQMP Controller, @@ -104,40 +138,6 @@ int cpu_init_r(void) irqmp->cpu_force[cpu] = 0; } - /* timer */ - index = 0; - while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, - index, &apbdev) == 1) { - timer = (ambapp_dev_gptimer *)apbdev.address; - if (gptimer == NULL) { - gptimer = timer; - gptimer_irq = apbdev.irq; - } - - /* Different buses may have different frequency, the - * frequency of the bus tell in which frequency the timer - * prescaler operates. - */ - bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - - /* initialize prescaler common to all timers to 1MHz */ - timer->scalar = timer->scalar_reload = - (((bus_freq / 1000) + 500) / 1000) - 1; - - /* Clear All Timers */ - ntimers = timer->config & 0x7; - for (i = 0; i < ntimers; i++) { - timer->e[i].ctrl = GPTIMER_CTRL_IP; - timer->e[i].rld = 0; - timer->e[i].ctrl = GPTIMER_CTRL_LD; - } - - index++; - } - if (!gptimer) { - printf("%s: gptimer not found!\n", __func__); - return 1; - } return 0; } @@ -151,25 +151,9 @@ void cpu_wait_ticks(unsigned long ticks) while (get_timer(start) < ticks) ; } -/* initiate and setup timer0 interrupt to configured HZ. Base clock is 1MHz. - * Return irq number for timer int or a negative number for - * dealing with self - */ int timer_interrupt_init_cpu(void) { - /* SYS_HZ ticks per second */ - gptimer->e[0].val = 0; - gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; - gptimer->e[0].ctrl = - (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | - GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); - - return gptimer_irq; -} - -ulong get_tbclk(void) -{ - return TIMER_BASE_CLK; + return -1; } /* @@ -186,3 +170,38 @@ unsigned long cpu_ticks2usec(unsigned long ticks) { return ticks * US_PER_TICK; } + +int timer_init(void) +{ + ambapp_dev_gptimer_element *tmr; + ambapp_dev_gptimer *gptimer; + ambapp_apbdev apbdev; + unsigned bus_freq; + + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, + CONFIG_SYS_GRLIB_GPTIMER_INDEX, &apbdev) != 1) { + panic("%s: gptimer not found!\n", __func__); + return -1; + } + + gptimer = (ambapp_dev_gptimer *) apbdev.address; + + /* Different buses may have different frequency, the + * frequency of the bus tell in which frequency the timer + * prescaler operates. + */ + bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); + + /* initialize prescaler common to all timers to 1MHz */ + gptimer->scalar = gptimer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; + + tmr = (ambapp_dev_gptimer_element *)&gptimer->e[0]; + + tmr->val = 0; + tmr->rld = ~0; + tmr->ctrl = GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | GPTIMER_CTRL_LD; + + CONFIG_SYS_TIMER_COUNTER = (void *)&tmr->val; + return 0; +} diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h index c884b250fe..455fbc1b73 100644 --- a/arch/sparc/include/asm/config.h +++ b/arch/sparc/include/asm/config.h @@ -14,4 +14,8 @@ #define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH +#define CONFIG_SYS_TIMER_RATE 1000000 /* 1MHz */ +#define CONFIG_SYS_TIMER_COUNTER gd->arch.timer +#define CONFIG_SYS_TIMER_COUNTS_DOWN + #endif diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index 8c6557ad1f..af38d17b0d 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -15,6 +15,7 @@ /* Architecture-specific global data */ struct arch_global_data { + void *timer; void *uart; unsigned int uart_freq; #ifdef CONFIG_LEON3 diff --git a/arch/sparc/lib/interrupts.c b/arch/sparc/lib/interrupts.c index b8f2efb303..fab26c62dd 100644 --- a/arch/sparc/lib/interrupts.c +++ b/arch/sparc/lib/interrupts.c @@ -81,11 +81,6 @@ void timer_interrupt(struct pt_regs *regs) timestamp++; } -ulong get_timer(ulong base) -{ - return (timestamp - base); -} - void timer_interrupt_init(void) { int irq; diff --git a/common/board_f.c b/common/board_f.c index b035c90ff3..2dd10b9819 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -808,7 +808,8 @@ static init_fnc_t init_sequence_f[] = { init_timebase, #endif #if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ - defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) + defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \ + defined(CONFIG_SPARC) timer_init, /* initialize timer */ #endif #ifdef CONFIG_SYS_ALLOC_DPRAM From 1e85ccec536f86a96e5e317b5a59a6f5180451f3 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 23 Nov 2015 13:05:44 +0200 Subject: [PATCH 15/21] sparc: Update PROM initialization code for generic board Fixed the prom_relocate() function in start.S file by reserving memory in the board_init_f sequence and saving the offset to the __prom_start_reloc variable. This value is used as the destination when relocating the PROM. Add the prom_init() function to the end of the board_init_r sequence. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/prom.c | 2 ++ arch/sparc/cpu/leon2/start.S | 28 ++++++++++++++-------------- arch/sparc/cpu/leon3/prom.c | 2 ++ arch/sparc/cpu/leon3/start.S | 28 ++++++++++++++-------------- common/board_f.c | 17 +++++++++++++++++ common/board_r.c | 7 +++++++ 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/arch/sparc/cpu/leon2/prom.c b/arch/sparc/cpu/leon2/prom.c index cd2571f0d6..7829e7abb2 100644 --- a/arch/sparc/cpu/leon2/prom.c +++ b/arch/sparc/cpu/leon2/prom.c @@ -25,6 +25,8 @@ extern struct linux_romvec *kernel_arg_promvec; #define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) #define PROM_DATA __attribute__ ((__section__ (".prom.data"))) +void *__prom_start_reloc; /* relocated prom_start address */ + /* for __va */ extern int __prom_start; #define PAGE_OFFSET 0xf0000000 diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index 7362ae134d..1b404da362 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -414,24 +414,24 @@ fixup_got: bcs 30b ! while (ptr < end) nop -#if 0 /* FIXME: Relocated PROM address should be calculated! */ - prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) - set CONFIG_SYS_PROM_OFFSET, %g4 + /* + * Calculated addres is stored in this variable by + * reserve_prom() function in common/board_f.c + */ + SPARC_LOAD_ADDRESS(__prom_start_reloc, l7, g4) + ld [%g4], %g4 -prom_relocate_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne prom_relocate_loop - inc 16,%g4 - -#endif +40: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 + cmp %g2, %g3 + bcs 40b + inc 16, %g4 ! %o0 = stack pointer (relocated) ! %o1 = global data pointer (relocated) diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index c391be7420..1f185b776b 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -33,6 +33,8 @@ DECLARE_GLOBAL_DATA_PTR; ambapp_dev_gptimer *gptimer; +void *__prom_start_reloc; /* relocated prom_start address */ + /* for __va */ extern int __prom_start; #define PAGE_OFFSET 0xf0000000 diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index 52e82b5e33..1527d72a6d 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -397,24 +397,24 @@ fixup_got: bcs 30b ! while (ptr < end) nop -#if 0 /* FIXME: Relocated PROM address should be calculated! */ - prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) - set CONFIG_SYS_PROM_OFFSET, %g4 + /* + * Calculated addres is stored in this variable by + * reserve_prom() function in common/board_f.c + */ + SPARC_LOAD_ADDRESS(__prom_start_reloc, l7, g4) + ld [%g4], %g4 -prom_relocate_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne prom_relocate_loop - inc 16,%g4 - -#endif +40: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 + cmp %g2, %g3 + bcs 40b + inc 16, %g4 ! %o0 = stack pointer (relocated) ! %o1 = global data pointer (relocated) diff --git a/common/board_f.c b/common/board_f.c index 2dd10b9819..8325dc333c 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -357,6 +357,20 @@ static int setup_dest_addr(void) return 0; } +#if defined(CONFIG_SPARC) +static int reserve_prom(void) +{ + /* defined in arch/sparc/cpu/leon?/prom.c */ + extern void *__prom_start_reloc; + int size = 8192; /* page table = 2k, prom = 6k */ + gd->relocaddr -= size; + __prom_start_reloc = map_sysmem(gd->relocaddr + 2048, size - 2048); + debug("Reserving %dk for PROM and page table at %08lx\n", size, + gd->relocaddr); + return 0; +} +#endif + #if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) static int reserve_logbuffer(void) { @@ -909,6 +923,9 @@ static init_fnc_t init_sequence_f[] = { /* Blackfin u-boot monitor should be on top of the ram */ reserve_uboot, #endif +#if defined(CONFIG_SPARC) + reserve_prom, +#endif #if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) reserve_logbuffer, #endif diff --git a/common/board_r.c b/common/board_r.c index f1dfa68fd5..3bf49fdfb3 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -66,6 +66,10 @@ DECLARE_GLOBAL_DATA_PTR; +#if defined(CONFIG_SPARC) +extern int prom_init(void); +#endif + ulong monitor_flash_len; __weak int board_flash_wp_on(void) @@ -933,6 +937,9 @@ init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_PS2KBD initr_kbd, +#endif +#if defined(CONFIG_SPARC) + prom_init, #endif run_main_loop, }; From 4c547754f525729e0e81389d94b26f2bea80741c Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 16:49:02 +0200 Subject: [PATCH 16/21] sparc: Add CONFIG_DISPLAY_BOARDINFO variable to all LEON boards Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/cpu.c | 10 ++++++++++ arch/sparc/cpu/leon3/cpu.c | 10 ++++++++++ include/configs/gr_cpci_ax2000.h | 3 ++- include/configs/gr_ep2s60.h | 3 ++- include/configs/gr_xc3s_1500.h | 3 ++- include/configs/grsim.h | 3 ++- include/configs/grsim_leon2.h | 3 ++- 7 files changed, 30 insertions(+), 5 deletions(-) diff --git a/arch/sparc/cpu/leon2/cpu.c b/arch/sparc/cpu/leon2/cpu.c index 22e63e3869..d044c3abc7 100644 --- a/arch/sparc/cpu/leon2/cpu.c +++ b/arch/sparc/cpu/leon2/cpu.c @@ -22,6 +22,16 @@ int checkcpu(void) return 0; } +#ifdef CONFIG_DISPLAY_CPUINFO + +int print_cpuinfo(void) +{ + printf("CPU: LEON2\n"); + return 0; +} + +#endif + /* ------------------------------------------------------------------------- */ void cpu_reset(void) diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c index d57bf2fc87..7034be60ec 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -25,6 +25,16 @@ int checkcpu(void) return 0; } +#ifdef CONFIG_DISPLAY_CPUINFO + +int print_cpuinfo(void) +{ + printf("CPU: LEON3\n"); + return 0; +} + +#endif + /* ------------------------------------------------------------------------- */ void cpu_reset(void) diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index a16f59a891..c3b1729326 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -15,6 +15,7 @@ #define __CONFIG_H__ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * High Level Configuration Options @@ -343,7 +344,7 @@ #undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ -#define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000" +#define CONFIG_IDENT_STRING " Gaisler LEON3 GR-CPCI-AX2000" /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index f472179dd6..45163edd8d 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -16,6 +16,7 @@ #define __CONFIG_H__ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * High Level Configuration Options @@ -313,7 +314,7 @@ #undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ -#define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60" +#define CONFIG_IDENT_STRING " Gaisler LEON3 EP2S60" /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 8598ac1881..f675b75843 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -14,6 +14,7 @@ #define __CONFIG_H__ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * High Level Configuration Options @@ -275,7 +276,7 @@ #undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ -#define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500" +#define CONFIG_IDENT_STRING " Gaisler LEON3 GR-XC3S-1500" /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" diff --git a/include/configs/grsim.h b/include/configs/grsim.h index e280dee9e9..47c357322d 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -14,6 +14,7 @@ #define __CONFIG_H__ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * High Level Configuration Options @@ -294,7 +295,7 @@ /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" -#define CONFIG_IDENT_STRING "Gaisler GRSIM" +#define CONFIG_IDENT_STRING " Gaisler GRSIM" /* TSIM command: * $ ./tsim-leon3 -mmu -cas diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index 2f7a5628f1..0a5292e9fd 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -13,6 +13,7 @@ #define __CONFIG_H__ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * High Level Configuration Options @@ -290,6 +291,6 @@ /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" -#define CONFIG_IDENT_STRING "Gaisler GRSIM LEON2" +#define CONFIG_IDENT_STRING " Gaisler GRSIM LEON2" #endif /* __CONFIG_H */ From 78536bc4d381a75dac2dc65f59fcfdd72ff3e693 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 27 Oct 2014 15:56:01 +0200 Subject: [PATCH 17/21] sparc: Use microseconds instead of ticks for timeout We now use the generic delay method which specifies the timeout as microseconds instead of ticks. Signed-off-by: Francois Retief --- drivers/net/greth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 0624eb8cac..088cb229da 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -245,7 +245,7 @@ int greth_init_phy(greth_priv * dev, bd_t * bis) debug("GRETH PHY ADDRESS: %d\n", phyaddr); /* X msecs to ticks */ - timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000); + timeout = GRETH_PHY_TIMEOUT_MS * 1000; /* Get system timer0 current value * Total timeout is 5s From 36594a1dfb96e5ebb54996fb36769d45cda38207 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 22 Jan 2010 13:50:22 +0100 Subject: [PATCH 18/21] sparc: Removed USB stop from linux bootm, arch-independent bootm stop USB Signed-off-by: Daniel Hellstrom --- arch/sparc/lib/bootm.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/sparc/lib/bootm.c b/arch/sparc/lib/bootm.c index 9e2b78464d..927a351013 100644 --- a/arch/sparc/lib/bootm.c +++ b/arch/sparc/lib/bootm.c @@ -19,10 +19,6 @@ extern image_header_t header; extern void srmmu_init_cpu(unsigned int entry); extern void prepare_bootargs(char *bootargs); -#ifdef CONFIG_USB_UHCI -extern int usb_lowlevel_stop(int index); -#endif - /* sparc kernel argument (the ROM vector) */ struct linux_romvec *kernel_arg_promvec; @@ -111,10 +107,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t * im linux_hdr->linuxver_minor, linux_hdr->linuxver_revision); #endif -#ifdef CONFIG_USB_UHCI - usb_lowlevel_stop(); -#endif - /* set basic boot params in kernel header now that it has been * extracted and is writeable. */ From 6c4359aa7284bf7bc6d9f83a2c6dceb406726388 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 22 Jan 2010 13:25:03 +0100 Subject: [PATCH 19/21] sparc: leon3: Added CPU count and frequency detection. Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/cpu.c | 46 +++++++++++++++++++++++++++++++++- arch/sparc/include/asm/leon3.h | 13 ++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c index 7034be60ec..149e5c69e6 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -13,15 +13,59 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; extern void _reset_reloc(void); +int leon_cpu_cnt = 1; +int leon_ver = 3; +unsigned int leon_cpu_freq = CONFIG_SYS_CLK_FREQ; + +int cpu_freq(void) +{ + ambapp_ahbdev dev; + + if (leon_ver == 3) { + ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON3, 0, &dev); + } else { + ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON4, 0, &dev); + } + + leon_cpu_freq = ambapp_bus_freq(&ambapp_plb, dev.ahb_bus_index); + + return 0; +} + int checkcpu(void) { + int cnt; + char str[4]; + /* check LEON version here */ - printf("CPU: LEON3\n"); + cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, GAISLER_LEON3); + if (cnt <= 0) { + cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON4); + if (cnt > 0) + leon_ver = 4; + } + + cpu_freq(); + + str[0] = '\0'; + if (cnt > 1) { + leon_cpu_cnt = cnt; + str[0] = '0' + cnt; + str[1] = 'x'; + str[2] = '\0'; + } + printf("CPU: %sLEON%d @ %dMHz\n", str, leon_ver, + leon_cpu_freq / 1000000); + return 0; } diff --git a/arch/sparc/include/asm/leon3.h b/arch/sparc/include/asm/leon3.h index 6ee1ea8744..a9f32b9b90 100644 --- a/arch/sparc/include/asm/leon3.h +++ b/arch/sparc/include/asm/leon3.h @@ -19,4 +19,17 @@ * ctrl, memory controllers etc. */ + +#ifndef __ASSEMBLER__ +/* The frequency of the CPU */ +extern unsigned int leon_cpu_freq; + +/* Number of LEON processors in system */ +extern int leon_cpu_cnt; + +/* Ver/subversion of CPU */ +extern int leon_ver; + +#endif /* __ASSEMBLER__ */ + #endif From f376c42f3b28862326ea378b0b6cc6b9b699d0c0 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 22 Jan 2010 12:02:40 +0100 Subject: [PATCH 20/21] sparc: leon3: Added busy wait function, made wait_ms() work when IRQ is disabled Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/cpu_init.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 88f82c95a8..9e294bfd0e 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -141,14 +142,41 @@ int cpu_init_r(void) return 0; } +/* Busy wait a number of ms */ +void cpu_wait_ms_busy(unsigned long ms) +{ + unsigned int ms_delay; + volatile unsigned int tmp; + + /* ~10-20 cycles per decrement */ + ms_delay = leon_cpu_freq / (1000 * 10); + do { + /* Wait ~1ms */ + tmp = ms_delay; + while (tmp-- > 0) + ; + } while (--ms > 0); +} + /* Uses Timer 0 to get accurate * pauses. Max 2 raised to 32 ticks * */ void cpu_wait_ticks(unsigned long ticks) { - unsigned long start = get_timer(0); - while (get_timer(start) < ticks) ; + unsigned long start; + + if (interrupt_is_enabled()) { + start = get_timer(0); + while (get_timer(start) < ticks) + ; + } else { + /* Interrupts disabled, this means that we cannot + * use get_timer(), it relies on IRQ. Instead the + * CPU frequency is used. + */ + cpu_wait_ms_busy(ticks2usec(ticks) / 1000); + } } int timer_interrupt_init_cpu(void) From 7a4fb11b85939b47738283c3a7ae7f461468e274 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Sat, 21 Nov 2015 23:15:07 +0200 Subject: [PATCH 21/21] sparc: Remove non-generic board init files: board.c, time.c Remove the board.c and time.c files and all associated non-generic board initialization code. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/cpu_init.c | 45 +--- arch/sparc/cpu/leon2/interrupts.c | 14 -- arch/sparc/cpu/leon3/cpu_init.c | 60 ----- arch/sparc/cpu/leon3/interrupts.c | 11 - arch/sparc/include/asm/u-boot.h | 43 +--- arch/sparc/lib/Makefile | 6 +- arch/sparc/lib/board.c | 398 ------------------------------ arch/sparc/lib/interrupts.c | 30 --- arch/sparc/lib/time.c | 62 ----- 9 files changed, 7 insertions(+), 662 deletions(-) delete mode 100644 arch/sparc/lib/board.c delete mode 100644 arch/sparc/lib/time.c diff --git a/arch/sparc/cpu/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index b4d91e5039..9dfb99cb0f 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -14,9 +14,6 @@ #include -#define TIMER_BASE_CLK 1000000 -#define US_PER_TICK (1000000 / CONFIG_SYS_HZ) - DECLARE_GLOBAL_DATA_PTR; /* @@ -77,48 +74,8 @@ int cpu_init_r(void) return 0; } -/* Uses Timer 0 to get accurate - * pauses. Max 2 raised to 32 ticks - * +/* initiate and setup timer0 to configured HZ. Base clock is 1MHz. */ -void cpu_wait_ticks(unsigned long ticks) -{ - unsigned long start = get_timer(0); - while (get_timer(start) < ticks) ; -} - -/* initiate and setup timer0 interrupt to configured HZ. Base clock is 1MHz. - * Return irq number for timer int or a negative number for - * dealing with self - */ -int timer_interrupt_init_cpu(void) -{ - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - /* SYS_HZ ticks per second */ - leon2->Timer_Counter_1 = 0; - leon2->Timer_Reload_1 = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; - leon2->Timer_Control_1 = - (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD); - - return LEON2_TIMER1_IRQNO; -} - -/* - * This function is intended for SHORT delays only. - */ -unsigned long cpu_usec2ticks(unsigned long usec) -{ - if (usec < US_PER_TICK) - return 1; - return usec / US_PER_TICK; -} - -unsigned long cpu_ticks2usec(unsigned long ticks) -{ - return ticks * US_PER_TICK; -} - int timer_init(void) { LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS; diff --git a/arch/sparc/cpu/leon2/interrupts.c b/arch/sparc/cpu/leon2/interrupts.c index f78ec8a410..602e4a67ba 100644 --- a/arch/sparc/cpu/leon2/interrupts.c +++ b/arch/sparc/cpu/leon2/interrupts.c @@ -118,20 +118,6 @@ int interrupt_init_cpu(void) /****************************************************************************/ -/* Handle Timer 0 IRQ */ -void timer_interrupt_cpu(void *arg) -{ - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - leon2->Timer_Control_1 = - (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD); - - /* nothing to do here */ - return; -} - -/****************************************************************************/ - /* * Install and free a interrupt handler. */ diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 9e294bfd0e..f25388cf84 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -29,9 +28,6 @@ #define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0 #endif -#define TIMER_BASE_CLK 1000000 -#define US_PER_TICK (1000000 / CONFIG_SYS_HZ) - DECLARE_GLOBAL_DATA_PTR; ambapp_dev_irqmp *irqmp = NULL; @@ -142,63 +138,7 @@ int cpu_init_r(void) return 0; } -/* Busy wait a number of ms */ -void cpu_wait_ms_busy(unsigned long ms) -{ - unsigned int ms_delay; - volatile unsigned int tmp; - - /* ~10-20 cycles per decrement */ - ms_delay = leon_cpu_freq / (1000 * 10); - do { - /* Wait ~1ms */ - tmp = ms_delay; - while (tmp-- > 0) ; - } while (--ms > 0); -} - -/* Uses Timer 0 to get accurate - * pauses. Max 2 raised to 32 ticks - * - */ -void cpu_wait_ticks(unsigned long ticks) -{ - unsigned long start; - - if (interrupt_is_enabled()) { - start = get_timer(0); - while (get_timer(start) < ticks) - ; - } else { - /* Interrupts disabled, this means that we cannot - * use get_timer(), it relies on IRQ. Instead the - * CPU frequency is used. - */ - cpu_wait_ms_busy(ticks2usec(ticks) / 1000); - } -} - -int timer_interrupt_init_cpu(void) -{ - return -1; -} - -/* - * This function is intended for SHORT delays only. - */ -unsigned long cpu_usec2ticks(unsigned long usec) -{ - if (usec < US_PER_TICK) - return 1; - return usec / US_PER_TICK; -} - -unsigned long cpu_ticks2usec(unsigned long ticks) -{ - return ticks * US_PER_TICK; -} - int timer_init(void) { ambapp_dev_gptimer_element *tmr; diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index 2312b58d29..00c3288774 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -124,17 +124,6 @@ int interrupt_init_cpu(void) /****************************************************************************/ -/* Handle Timer 0 IRQ */ -void timer_interrupt_cpu(void *arg) -{ - gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | - GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); - /* nothing to do here */ - return; -} - -/****************************************************************************/ - /* * Install and free a interrupt handler. */ diff --git a/arch/sparc/include/asm/u-boot.h b/arch/sparc/include/asm/u-boot.h index 4c4b5f218a..9b9a71d553 100644 --- a/arch/sparc/include/asm/u-boot.h +++ b/arch/sparc/include/asm/u-boot.h @@ -2,56 +2,23 @@ * (C) Copyright 2000 - 2002 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007, From asm-ppc/u-boot.h - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ - ******************************************************************** - * NOTE: This header file defines an interface to U-Boot. Including - * this (unmodified) header file in another file is considered normal - * use of U-Boot, and does *not* fall under the heading of "derived - * work". - ******************************************************************** */ #ifndef __U_BOOT_H__ #define __U_BOOT_H__ -#ifdef CONFIG_SYS_GENERIC_BOARD -/* Use the generic board which requires a unified bd_info */ -#include -#else - -/* - * Currently, this Board information is not passed to +/* Currently, this board information is not passed to * Linux kernel from U-Boot, but may be passed to other * Operating systems. This is because U-boot emulates * a SUN PROM loader (from Linux point of view). - * - * include/asm-sparc/u-boot.h */ - -#ifndef __ASSEMBLY__ - -typedef struct bd_info { - unsigned long bi_memstart; /* start of DRAM memory */ - phys_size_t bi_memsize; /* size of DRAM memory in bytes */ - unsigned long bi_flashstart; /* start of FLASH memory */ - unsigned long bi_flashsize; /* size of FLASH memory */ - unsigned long bi_flashoffset; /* reserved area for startup monitor */ - unsigned long bi_sramstart; /* start of SRAM memory */ - unsigned long bi_sramsize; /* size of SRAM memory */ - unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ - unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ - unsigned long bi_intfreq; /* Internal Freq, in MHz */ - unsigned long bi_busfreq; /* Bus Freq, in MHz */ -} bd_t; - -#endif /* __ASSEMBLY__ */ - -#endif /* !CONFIG_SYS_GENERIC_BOARD */ +#include /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_SPARC -#endif /* __U_BOOT_H__ */ +#endif diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 6bddd4c8a1..6b7ad6d155 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -5,9 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y = cache.o interrupts.o time.o +obj-y = cache.o interrupts.o obj-$(CONFIG_CMD_BOOTM) += bootm.o - -ifndef CONFIG_SYS_GENERIC_BOARD -obj-y += board.o -endif diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c deleted file mode 100644 index 10475d1082..0000000000 --- a/arch/sparc/lib/board.c +++ /dev/null @@ -1,398 +0,0 @@ -/* SPARC Board initialization - * - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_CMD_IDE) -#include -#endif -#ifdef CONFIG_STATUS_LED -#include -#endif -#include -#include -#include -#if defined(CONFIG_POST) -#include -#endif -#ifdef CONFIG_PS2KBD -#include -#endif -#ifdef CONFIG_CMD_AMBAPP -#include -#endif - -#ifdef CONFIG_BITBANGMII -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/* Debug options -#define DEBUG_INIT_SEQUENCE -#define DEBUG_MEM_LAYOUT -#define DEBUG_COMMANDS -*/ - -extern void timer_interrupt_init(void); -extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); -extern int prom_init(void); - -#if defined(CONFIG__CMD_DOC) -void doc_init(void); -#endif - -#if !defined(CONFIG_SYS_NO_FLASH) -static char *failed = "*** failed ***\n"; -#endif - -#include - -ulong monitor_flash_len; - -/************************************************************************ - * Init Utilities * - ************************************************************************ - * Some of this code should be moved into the core functions, - * but let's get it working (again) first... - */ - -static int init_baudrate(void) -{ - gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); - return 0; -} - -/***********************************************************************/ - -/* - * All attempts to come up with a "common" initialization sequence - * that works for all boards and architectures failed: some of the - * requirements are just _too_ different. To get rid of the resulting - * mess of board dependend #ifdef'ed code we now make the whole - * initialization sequence configurable to the user. - * - * The requirements for any new initalization function is simple: it - * receives a pointer to the "global data" structure as it's only - * argument, and returns an integer return code, where 0 means - * "continue" and != 0 means "fatal error, hang the system". - */ -typedef int (init_fnc_t) (void); - -#define WATCHDOG_RESET(x) - -/************************************************************************ - * Initialization sequence * - ************************************************************************ - */ - -init_fnc_t *init_sequence[] = { - -#if defined(CONFIG_BOARD_EARLY_INIT_F) - board_early_init_f, -#endif - serial_init, - - init_timebase, - -#if defined(CONFIG_CMD_AMBAPP) - ambapp_init_reloc, -#endif - - env_init, - - init_baudrate, - - console_init_f, - display_options, - - checkcpu, - checkboard, -#if defined(CONFIG_MISC_INIT_F) - misc_init_f, -#endif - -#ifdef CONFIG_POST - post_init_f, -#endif - - NULL, /* Terminate this list, - * beware: this list will be relocated - * which means that NULL will become - * NULL+RELOC_OFFSET. We simply make - * NULL be -RELOC_OFFSET instead. - */ -}; - -/************************************************************************ - * - * This is the SPARC board initialization routine, running from RAM. - * - ************************************************************************ - */ -#ifdef DEBUG_INIT_SEQUENCE -char *str_init_seq = "INIT_SEQ 00\n"; -char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n"; -#endif - -void board_init_f(ulong bootflag) -{ - bd_t *bd; - init_fnc_t **init_fnc_ptr; - int j; - -#ifndef CONFIG_SYS_NO_FLASH - ulong flash_size; -#endif - - gd = (gd_t *) (CONFIG_SYS_GBL_DATA_OFFSET); - - /* Clear initial global data */ - memset((void *)gd, 0, sizeof(gd_t)); - - gd->bd = (bd_t *) (gd + 1); /* At end of global data */ - gd->baudrate = CONFIG_BAUDRATE; - gd->cpu_clk = CONFIG_SYS_CLK_FREQ; - - bd = gd->bd; - bd->bi_memstart = CONFIG_SYS_RAM_BASE; - bd->bi_memsize = CONFIG_SYS_RAM_SIZE; - bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; -#if defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE) - bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; - bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; -#endif - bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */ - - gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ - gd->reloc_off = CONFIG_SYS_RELOC_MONITOR_BASE - CONFIG_SYS_MONITOR_BASE; - - for (init_fnc_ptr = init_sequence, j = 0; *init_fnc_ptr; - ++init_fnc_ptr, j++) { -#ifdef DEBUG_INIT_SEQUENCE - if (j > 9) - str_init_seq[9] = '0' + (j / 10); - str_init_seq[10] = '0' + (j - (j / 10) * 10); - serial_puts(str_init_seq); -#endif - if ((*init_fnc_ptr + gd->reloc_off) () != 0) { - hang(); - } - } -#ifdef DEBUG_INIT_SEQUENCE - serial_puts(str_init_seq_done); -#endif - - /* - * Now that we have DRAM mapped and working, we can - * relocate the code and continue running from DRAM. - * - * Reserve memory at end of RAM for (top down in that order): - * - kernel log buffer - * - protected RAM - * - LCD framebuffer - * - monitor code - * - board info struct - */ -#ifdef DEBUG_MEM_LAYOUT - printf("CONFIG_SYS_MONITOR_BASE: 0x%lx\n", CONFIG_SYS_MONITOR_BASE); - printf("CONFIG_ENV_ADDR: 0x%lx\n", CONFIG_ENV_ADDR); - printf("CONFIG_SYS_RELOC_MONITOR_BASE: 0x%lx (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, - CONFIG_SYS_MONITOR_LEN); - printf("CONFIG_SYS_MALLOC_BASE: 0x%lx (%d)\n", CONFIG_SYS_MALLOC_BASE, - CONFIG_SYS_MALLOC_LEN); - printf("CONFIG_SYS_INIT_SP_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, - CONFIG_SYS_STACK_SIZE); - printf("CONFIG_SYS_PROM_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_PROM_OFFSET, - CONFIG_SYS_PROM_SIZE); - printf("CONFIG_SYS_GBL_DATA_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, - GENERATED_GBL_DATA_SIZE); -#endif - -#ifdef CONFIG_POST - post_bootmode_init(); - post_run(NULL, POST_ROM | post_bootmode_get(0)); -#endif - -#if defined(CONFIG_NEEDS_MANUAL_RELOC) - /* - * We have to relocate the command table manually - */ - fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd), - ll_entry_count(cmd_tbl_t, cmd)); -#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */ - -#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) - puts("AMBA:\n"); - do_ambapp_print(NULL, 0, 0, NULL); -#endif - - /* initialize higher level parts of CPU like time base and timers */ - cpu_init_r(); - - /* start timer */ - timer_interrupt_init(); - - /* - * Enable Interrupts before any calls to udelay, - * the flash driver may use udelay resulting in - * a hang if not timer0 IRQ is enabled. - */ - interrupt_init(); - - /* The Malloc area is immediately below the monitor copy in RAM */ - mem_malloc_init(CONFIG_SYS_MALLOC_BASE, - CONFIG_SYS_MALLOC_END - CONFIG_SYS_MALLOC_BASE); - -#if !defined(CONFIG_SYS_NO_FLASH) - puts("Flash: "); - - if ((flash_size = flash_init()) > 0) { -# ifdef CONFIG_SYS_FLASH_CHECKSUM - print_size(flash_size, ""); - /* - * Compute and print flash CRC if flashchecksum is set to 'y' - * - * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX - */ - if (getenv_yesno("flashchecksum") == 1) { - printf(" CRC: %08lX", - crc32(0, (const unsigned char *)CONFIG_SYS_FLASH_BASE, - flash_size) - ); - } - putc('\n'); -# else /* !CONFIG_SYS_FLASH_CHECKSUM */ - print_size(flash_size, "\n"); -# endif /* CONFIG_SYS_FLASH_CHECKSUM */ - } else { - puts(failed); - hang(); - } - - bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; /* update start of FLASH memory */ - bd->bi_flashsize = flash_size; /* size of FLASH memory (final value) */ -#if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE - bd->bi_flashoffset = monitor_flash_len; /* reserved area for startup monitor */ -#else - bd->bi_flashoffset = 0; -#endif -#else /* CONFIG_SYS_NO_FLASH */ - bd->bi_flashsize = 0; - bd->bi_flashstart = 0; - bd->bi_flashoffset = 0; -#endif /* !CONFIG_SYS_NO_FLASH */ - -#ifdef CONFIG_SPI -# if !defined(CONFIG_ENV_IS_IN_EEPROM) - spi_init_f(); -# endif - spi_init_r(); -#endif - - /* relocate environment function pointers etc. */ - env_relocate(); - -#if defined(CONFIG_BOARD_LATE_INIT) - board_late_init(); -#endif - -#ifdef CONFIG_ID_EEPROM - mac_read_from_eeprom(); -#endif - -#if defined(CONFIG_PCI) - /* - * Do pci configuration - */ - pci_init(); -#endif - - /* Initialize stdio devices */ - stdio_init(); - - /* Initialize the jump table for applications */ - jumptable_init(); - - /* Initialize the console (after the relocation and devices init) */ - console_init_r(); - -#ifdef CONFIG_STATUS_LED - status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); -#endif - - udelay(20); - - /* Initialize from environment */ - load_addr = getenv_ulong("loadaddr", 16, load_addr); - - WATCHDOG_RESET(); - -#if defined(CONFIG_CMD_DOC) - WATCHDOG_RESET(); - puts("DOC: "); - doc_init(); -#endif - -#ifdef CONFIG_BITBANGMII - bb_miiphy_init(); -#endif -#if defined(CONFIG_CMD_NET) - WATCHDOG_RESET(); - puts("Net: "); - eth_initialize(); -#endif - -#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) - WATCHDOG_RESET(); - debug("Reset Ethernet PHY\n"); - reset_phy(); -#endif - -#ifdef CONFIG_POST - post_run(NULL, POST_RAM | post_bootmode_get(0)); -#endif - -#if defined(CONFIG_CMD_IDE) - WATCHDOG_RESET(); - puts("IDE: "); - ide_init(); -#endif /* CONFIG_CMD_IDE */ - -#ifdef CONFIG_LAST_STAGE_INIT - WATCHDOG_RESET(); - /* - * Some parts can be only initialized if all others (like - * Interrupts) are up and running (i.e. the PC-style ISA - * keyboard). - */ - last_stage_init(); -#endif - -#ifdef CONFIG_PS2KBD - puts("PS/2: "); - kbd_init(); -#endif - prom_init(); - - /* main_loop */ - for (;;) { - WATCHDOG_RESET(); - main_loop(); - } - -} - -/************************************************************************/ diff --git a/arch/sparc/lib/interrupts.c b/arch/sparc/lib/interrupts.c index fab26c62dd..cb73d17999 100644 --- a/arch/sparc/lib/interrupts.c +++ b/arch/sparc/lib/interrupts.c @@ -66,33 +66,3 @@ int interrupt_init(void) return ret; } - -/* timer interrupt/overflow counter */ -static volatile ulong timestamp = 0; - -/* regs can not be used here! regs is actually the pointer given in - * irq_install_handler - */ -void timer_interrupt(struct pt_regs *regs) -{ - /* call cpu specific function from $(CPU)/interrupts.c */ - timer_interrupt_cpu((void *)regs); - - timestamp++; -} - -void timer_interrupt_init(void) -{ - int irq; - - timestamp = 0; - - irq = timer_interrupt_init_cpu(); - - if (irq < 0) { - /* cpu specific code handled the interrupt registration it self */ - return; - } - /* register interrupt handler for timer */ - irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL); -} diff --git a/arch/sparc/lib/time.c b/arch/sparc/lib/time.c deleted file mode 100644 index 50a09ad17a..0000000000 --- a/arch/sparc/lib/time.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (C) Copyright 2000, 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -/* Implemented by SPARC CPUs */ -extern void cpu_wait_ticks(unsigned long ticks); -extern unsigned long cpu_usec2ticks(unsigned long usec); -extern unsigned long cpu_ticks2usec(unsigned long ticks); - -/* ------------------------------------------------------------------------- */ - -void wait_ticks(unsigned long ticks) -{ - cpu_wait_ticks(ticks); -} - -/* - * This function is intended for SHORT delays only. - */ -unsigned long usec2ticks(unsigned long usec) -{ - return cpu_usec2ticks(usec); -} - -/* ------------------------------------------------------------------------- */ - -/* - * We implement the delay by converting the delay (the number of - * microseconds to wait) into a number of time base ticks; then we - * watch the time base until it has incremented by that amount. - */ -void __udelay(unsigned long usec) -{ - ulong ticks = usec2ticks(usec); - - wait_ticks(ticks); -} - -/* ------------------------------------------------------------------------- */ - -unsigned long ticks2usec(unsigned long ticks) -{ - return cpu_ticks2usec(ticks); -} - -/* ------------------------------------------------------------------------- */ - -int init_timebase(void) -{ - - return (0); -} - -/* ------------------------------------------------------------------------- */