瀏覽代碼

Merge branch 'master' of http://git.denx.de/u-boot-sparc

Tom Rini 9 年之前
父節點
當前提交
9eed48c8be

+ 1 - 0
arch/Kconfig

@@ -97,6 +97,7 @@ config SH
 
 config SPARC
 	bool "SPARC architecture"
+	select HAVE_GENERIC_BOARD
 	select CREATE_ARCH_SYMLINK
 
 config X86

+ 9 - 0
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

+ 12 - 2
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+
  */
@@ -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)

+ 29 - 65
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+
  */
@@ -10,22 +10,12 @@
 #include <common.h>
 #include <asm/asi.h>
 #include <asm/leon.h>
+#include <asm/io.h>
 
 #include <config.h>
 
-#define TIMER_BASE_CLK 1000000
-#define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
-
 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...
  *
@@ -50,82 +40,56 @@ 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
+
+	/* disable timers */
+	leon2->Timer_Control_1 = leon2->Timer_Control_2 = 0;
 }
 
-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
+ * 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
- * 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)
+int timer_init(void)
 {
-	unsigned long start = get_timer(0);
-	while (get_timer(start) < ticks) ;
-}
+	LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS;
 
-/* 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;
+	/* 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 = (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;
-}
-
-ulong get_tbclk(void)
-{
-	return TIMER_BASE_CLK;
-}
+	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;
 
-/*
- * 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;
+	CONFIG_SYS_TIMER_COUNTER = (void *)&leon2->Timer_Counter_1;
+	return 0;
 }

+ 0 - 14
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.
  */

+ 2 - 0
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

+ 1 - 1
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);
 }

+ 121 - 92
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
@@ -318,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
@@ -356,91 +380,93 @@ 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
 
 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
+
+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)
+! %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
@@ -469,7 +495,11 @@ _irq_entry:
 
 	RESTORE_ALL
 
-!Window overflow trap handler.
+!------------------------------------------------------------------------------
+
+/*
+ * Window overflow trap handler.
+ */
 	.global _window_overflow
 
 _window_overflow:
@@ -477,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];
@@ -506,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:
@@ -541,7 +570,7 @@ _window_underflow:
 	jmp	%l1			! Re-execute restore.
 	rett	%l2
 
-	retl
+!------------------------------------------------------------------------------
 
 _nmi_trap:
 	nop

+ 1 - 1
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,

+ 57 - 3
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+
  */
@@ -13,18 +13,72 @@
 
 #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;
 }
 
+#ifdef CONFIG_DISPLAY_CPUINFO
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   LEON3\n");
+	return 0;
+}
+
+#endif
+
 /* ------------------------------------------------------------------------- */
 
 void cpu_reset(void)

+ 86 - 89
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,23 +23,14 @@
 #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
 #endif
 
-#define TIMER_BASE_CLK 1000000
-#define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
+/* Select which TIMER that will become the time base */
+#ifndef CONFIG_SYS_GRLIB_GPTIMER_INDEX
+#define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0
+#endif
 
 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...
@@ -56,19 +48,62 @@ 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.
+ */
+static unsigned int snoop_detect(void)
 {
+	unsigned int result;
+	asm("lda [%%g0] 2, %0" : "=r"(result));
+	return result & 0x00800000;
+}
+
+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;
+
+	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);
+
+	/* 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;
 }
 
 /*
@@ -77,9 +112,7 @@ void cpu_init_f2(void)
 int cpu_init_r(void)
 {
 	ambapp_apbdev apbdev;
-	int index, cpu;
-	ambapp_dev_gptimer *timer = NULL;
-	unsigned int bus_freq;
+	int cpu;
 
 	/*
 	 * Find AMBA APB IRQMP Controller,
@@ -102,77 +135,41 @@ 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;
-
-		index++;
-	}
-	if (!gptimer) {
-		printf("%s: gptimer not found!\n", __func__);
-		return 1;
-	}
 	return 0;
 }
 
-/* Uses Timer 0 to get accurate
- * pauses. Max 2 raised to 32 ticks
- *
- */
-void cpu_wait_ticks(unsigned long ticks)
+			;
+int timer_init(void)
 {
-	unsigned long start = get_timer(0);
-	while (get_timer(start) < ticks) ;
-}
+	ambapp_dev_gptimer_element *tmr;
+	ambapp_dev_gptimer *gptimer;
+	ambapp_apbdev apbdev;
+	unsigned bus_freq;
 
-/* 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;
-}
+	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;
+	}
 
-ulong get_tbclk(void)
-{
-	return TIMER_BASE_CLK;
-}
+	gptimer = (ambapp_dev_gptimer *) apbdev.address;
 
-/*
- * 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;
-}
+	/* 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);
 
-unsigned long cpu_ticks2usec(unsigned long ticks)
-{
-	return ticks * US_PER_TICK;
+	/* 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;
 }

+ 0 - 11
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.
  */

+ 2 - 0
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

+ 20 - 3
arch/sparc/cpu/leon3/serial.c

@@ -17,8 +17,18 @@ 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)
+{
+	return (((apbuart_freq * 10) / (baud * 8)) - 5) / 10;
+}
 
 static int leon3_serial_init(void)
 {
@@ -29,6 +39,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 */
 	}
@@ -36,8 +47,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) */
@@ -122,7 +136,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);
 }
@@ -155,7 +172,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;
 }
 

+ 162 - 141
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 */
@@ -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; \
@@ -203,15 +208,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
-	.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
@@ -261,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)
 
@@ -302,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
@@ -335,106 +363,97 @@ 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
 
 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
+
+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)
+! %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
 
-/* 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)
-	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
@@ -463,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
@@ -533,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

+ 4 - 3
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 */

+ 7 - 1
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,9 +8,14 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
+#define CONFIG_SYS_GENERIC_GLOBAL_DATA
 #define CONFIG_NEEDS_MANUAL_RELOC
 
 #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

+ 7 - 2
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+
  */
@@ -15,7 +15,12 @@
 
 /* Architecture-specific global data */
 struct arch_global_data {
+	void *timer;
 	void *uart;
+	unsigned int uart_freq;
+#ifdef CONFIG_LEON3
+	unsigned int snooping_available;
+#endif
 };
 
 #include <asm-generic/global_data.h>

+ 3 - 0
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

+ 13 - 0
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

+ 5 - 31
arch/sparc/include/asm/u-boot.h

@@ -2,49 +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__
 
-/*
- * 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__ */
+#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

+ 2 - 2
arch/sparc/lib/Makefile

@@ -1,9 +1,9 @@
 #
-# (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
 obj-$(CONFIG_CMD_BOOTM) += bootm.o

+ 0 - 398
arch/sparc/lib/board.c

@@ -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();
-	}
-
-}
-
-/************************************************************************/

+ 0 - 8
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.
 	 */

+ 7 - 35
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;
@@ -59,38 +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++;
-}
-
-ulong get_timer(ulong base)
-{
-	return (timestamp - base);
-}
-
-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);
-}

+ 0 - 62
arch/sparc/lib/time.c

@@ -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);
-}
-
-/* ------------------------------------------------------------------------- */

+ 19 - 1
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)
 {
@@ -808,7 +822,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
@@ -908,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

+ 9 - 1
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)
@@ -813,7 +817,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
@@ -932,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,
 };

+ 1 - 1
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

+ 4 - 4
include/configs/gr_cpci_ax2000.h

@@ -14,6 +14,9 @@
 #ifndef __CONFIG_H__
 #define __CONFIG_H__
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO
+
 /*
  * High Level Configuration Options
  * (easy to change)
@@ -42,9 +45,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
  */
@@ -344,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"

+ 4 - 4
include/configs/gr_ep2s60.h

@@ -15,6 +15,9 @@
 #ifndef __CONFIG_H__
 #define __CONFIG_H__
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO
+
 /*
  * High Level Configuration Options
  * (easy to change)
@@ -26,9 +29,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
  */
@@ -314,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"

+ 4 - 4
include/configs/gr_xc3s_1500.h

@@ -13,6 +13,9 @@
 #ifndef __CONFIG_H__
 #define __CONFIG_H__
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO
+
 /*
  * High Level Configuration Options
  * (easy to change)
@@ -23,9 +26,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
  */
@@ -276,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"

+ 4 - 4
include/configs/grsim.h

@@ -13,6 +13,9 @@
 #ifndef __CONFIG_H__
 #define __CONFIG_H__
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO
+
 /*
  * High Level Configuration Options
  * (easy to change)
@@ -34,9 +37,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
  */
@@ -295,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

+ 6 - 6
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,9 @@
 #ifndef __CONFIG_H__
 #define __CONFIG_H__
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO
+
 /*
  * High Level Configuration Options
  * (easy to change)
@@ -29,9 +32,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
  */
@@ -291,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 */