[U-Boot] [PATCH v1 00/21] sparc: Update SPARC architecture to generic board init

The SPARC architecture has not yet been updated to the new generic board init codebase. This patch series is an first attempt at that.
The changes has been tested on a TSIM simulator (grsim_defconfig).
Any feedback, comments or suggestions would be appreciated.
Daniel Hellstrom (6): sparc: Added function that checks if IRQ is on or off sparc: Serial baud rate register support multiple buses with different frequency sparc: leon3: Clear all unused GPTIMER registers. sparc: Removed USB stop from linux bootm, arch-independent bootm stop USB sparc: leon3: Added CPU count and frequency detection. sparc: leon3: Added busy wait function, made wait_ms() work when IRQ is disabled
Francois Retief (15): sparc: Move SYS_SPARC_NWINDOWS to Kconfig sparc: Remove version_string variable from start.S file sparc: leon3: Clear GD_FLAG_SERIAL_READY flag on AMBA failure sparc: leon3: Updated serial driver to use CONFIG_CONS_INDEX sparc: Fix whitespace in cpu/leon2/cpu_init.c sparc: Initial ground work for generic board initialization sparc: leon3: Move snoop detection from startup.S to arch_cpu_init() sparc: leon3: Move ambapp_bus_init() call to arch_cpu_init() function sparc: leon3: Updates for generic board initialization sparc: leon2: Updates for generic board initialization sparc: Update cpu_init.c to use generic timer infrastructure sparc: Update PROM initialization code for generic board sparc: Add CONFIG_DISPLAY_BOARDINFO variable to all LEON boards sparc: Use microseconds instead of ticks for timeout sparc: Remove non-generic board init files: board.c, time.c
arch/Kconfig | 1 + arch/sparc/Kconfig | 9 + arch/sparc/cpu/leon2/cpu.c | 14 +- arch/sparc/cpu/leon2/cpu_init.c | 94 +++------ arch/sparc/cpu/leon2/interrupts.c | 14 -- arch/sparc/cpu/leon2/prom.c | 2 + arch/sparc/cpu/leon2/serial.c | 2 +- arch/sparc/cpu/leon2/start.S | 213 +++++++++++-------- arch/sparc/cpu/leon3/ambapp.c | 2 +- arch/sparc/cpu/leon3/cpu.c | 60 +++++- arch/sparc/cpu/leon3/cpu_init.c | 175 ++++++++------- arch/sparc/cpu/leon3/interrupts.c | 11 - arch/sparc/cpu/leon3/prom.c | 2 + arch/sparc/cpu/leon3/serial.c | 23 +- arch/sparc/cpu/leon3/start.S | 303 +++++++++++++------------- arch/sparc/cpu/leon3/usb_uhci.c | 7 +- arch/sparc/include/asm/config.h | 8 +- arch/sparc/include/asm/global_data.h | 9 +- arch/sparc/include/asm/irq.h | 3 + arch/sparc/include/asm/leon3.h | 13 ++ arch/sparc/include/asm/u-boot.h | 36 +--- arch/sparc/lib/Makefile | 4 +- arch/sparc/lib/board.c | 398 ----------------------------------- arch/sparc/lib/bootm.c | 8 - arch/sparc/lib/interrupts.c | 42 +--- arch/sparc/lib/time.c | 62 ------ common/board_f.c | 20 +- common/board_r.c | 10 +- drivers/net/greth.c | 2 +- include/configs/gr_cpci_ax2000.h | 8 +- include/configs/gr_ep2s60.h | 8 +- include/configs/gr_xc3s_1500.h | 8 +- include/configs/grsim.h | 8 +- include/configs/grsim_leon2.h | 12 +- 34 files changed, 602 insertions(+), 989 deletions(-) delete mode 100644 arch/sparc/lib/board.c delete mode 100644 arch/sparc/lib/time.c

Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 04dc08f..1d1347b 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 2031149..1566010 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 5bbf1aa..67538d0 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 b55ca77..387596d 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 d086b69..5fb800b 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 e1f7dc3..932f330 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 83fd7fa..83022e8 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 */

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 fgretief@spaceteq.co.za ---
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 974de76..fa1534f 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 <asm/psr.h> #include <asm/stack.h> #include <asm/leon.h> -#include <version.h>
/* 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 1566010..fe4795c 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 <asm/psr.h> #include <asm/stack.h> #include <asm/leon.h> -#include <version.h> #include <ambapp.h>
/* 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 2faf7a0..5d0f756 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 b7c3993..b8f2efb 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;

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 fgretief@spaceteq.co.za ---
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 66b3773..15d0226 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 603364e..460abd1 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 15d0226..5348a78 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 0680a56..71820f0 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 <asm-generic/global_data.h>

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 fgretief@spaceteq.co.za ---
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 5348a78..bc6e7a1 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) {

Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 6e07fe6..695ee02 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 }

Initial ground work in preperation for generic board initialization code for the SPARC architecture.
Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 25dcf4a..6489cc9 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 380c397..22e63e3 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 695ee02..581f057 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 8ab3150..d57bf2f 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 b140da3..a0526cd 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 fd0b551..c884b25 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 5f12e58..4c4b5f2 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 <asm-generic/u-boot.h> +#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 e69b9ba..6bddd4c 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 f7118e8..a5690ad 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -805,7 +805,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

Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 a0526cd..421859e 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 fe4795c..1988ee1 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 1be84c6..242b83f 100644 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ b/arch/sparc/cpu/leon3/usb_uhci.c @@ -85,10 +85,11 @@ #include <usb.h> #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 71820f0..8c6557a 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 <asm-generic/global_data.h>

Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 b8ac05f..47769cf 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 421859e..20a6a25 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 20a6a25..0ce2f89 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) {

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 fgretief@spaceteq.co.za ---
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 0ce2f89..9c76657 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 1988ee1..52e82b5 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 + +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
-/* un relocated end address of monitor */ -#define DATA_END __init_end +!-------------------------------------------------------------------------------
+/* 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 + +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
- 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 +dead: + mov 1, %g1 ! For GRMON2 to exit normally. + ta 0 ! if call returns.. (unlikely) + nop + b dead ! infinte loop + nop
-dead: ta 0 ! if call returns... - 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 67538d0..a16f59a 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 387596d..f472179 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 5fb800b..8598ac1 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 932f330..e280dee 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)

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 fgretief@spaceteq.co.za ---
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 581f057..5630b09 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 fa1534f..7362ae1 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 83022e8..2f7a562 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)

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 fgretief@spaceteq.co.za ---
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 5630b09..b4d91e5 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -10,6 +10,7 @@ #include <common.h> #include <asm/asi.h> #include <asm/leon.h> +#include <asm/io.h>
#include <config.h>
@@ -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 9c76657..88f82c9 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -10,6 +10,7 @@ #include <common.h> #include <asm/asi.h> #include <asm/leon.h> +#include <asm/io.h> #include <ambapp.h> #include <grlib/irqmp.h> #include <grlib/gptimer.h> @@ -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 c884b25..455fbc1 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 8c6557a..af38d17 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 b8f2efb..fab26c6 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 b035c90..2dd10b9 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

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 fgretief@spaceteq.co.za ---
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 cd2571f..7829e7a 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 7362ae1..1b404da 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 - -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 + /* + * 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
-#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 c391be7..1f185b7 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 52e82b5..1527d72 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 - -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 + /* + * 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
-#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 2dd10b9..8325dc3 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 a5690ad..be8a603 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) @@ -926,6 +930,9 @@ init_fnc_t init_sequence_r[] = { #ifdef CONFIG_PS2KBD initr_kbd, #endif +#if defined(CONFIG_SPARC) + prom_init, +#endif run_main_loop, };

Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 22e63e3..d044c3a 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 d57bf2f..7034be6 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 a16f59a..c3b1729 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 f472179..45163ed 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 8598ac1..f675b75 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 e280dee..47c3573 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 2f7a562..0a5292e 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 */

We now use the generic delay method which specifies the timeout as microseconds instead of ticks.
Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 0624eb8..088cb22 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 9e2b784..927a351 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 7034be6..149e5c6 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -13,15 +13,59 @@
#include <asm/io.h> #include <asm/processor.h> +#include <ambapp.h>
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 6ee1ea8..a9f32b9 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: Daniel Hellstrom daniel@gaisler.com
Signed-off-by: Daniel Hellstrom daniel@gaisler.com Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 88f82c9..9e294bf 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,6 +11,7 @@ #include <asm/asi.h> #include <asm/leon.h> #include <asm/io.h> +#include <asm/irq.h> #include <ambapp.h> #include <grlib/irqmp.h> #include <grlib/gptimer.h> @@ -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)

Remove the board.c and time.c files and all associated non-generic board initialization code.
Signed-off-by: Francois Retief fgretief@spaceteq.co.za ---
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 b4d91e5..9dfb99c 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -14,9 +14,6 @@
#include <config.h>
-#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 - * - */ -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. +/* initiate and setup timer0 to configured HZ. Base clock is 1MHz. */ -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 f78ec8a..602e4a6 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 9e294bf..f25388c 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,7 +11,6 @@ #include <asm/asi.h> #include <asm/leon.h> #include <asm/io.h> -#include <asm/irq.h> #include <ambapp.h> #include <grlib/irqmp.h> #include <grlib/gptimer.h> @@ -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 2312b58..00c3288 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 4c4b5f2..9b9a71d 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 <asm-generic/u-boot.h> -#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 <asm-generic/u-boot.h>
/* 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 6bddd4c..6b7ad6d 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 10475d1..0000000 --- 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 <common.h> -#include <command.h> -#include <console.h> -#include <malloc.h> -#include <stdio_dev.h> -#include <config.h> -#if defined(CONFIG_CMD_IDE) -#include <ide.h> -#endif -#ifdef CONFIG_STATUS_LED -#include <status_led.h> -#endif -#include <net.h> -#include <serial.h> -#include <version.h> -#if defined(CONFIG_POST) -#include <post.h> -#endif -#ifdef CONFIG_PS2KBD -#include <keyboard.h> -#endif -#ifdef CONFIG_CMD_AMBAPP -#include <ambapp.h> -#endif - -#ifdef CONFIG_BITBANGMII -#include <miiphy.h> -#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 <environment.h> - -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 fab26c6..cb73d17 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 50a09ad..0000000 --- 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 <common.h> - -/* 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); -} - -/* ------------------------------------------------------------------------- */
participants (1)
-
Francois Retief