diff options
Diffstat (limited to 'arch')
90 files changed, 3011 insertions, 131 deletions
| diff --git a/arch/arm/config.mk b/arch/arm/config.mk index fd3e5fb66..cfa42094c 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -17,7 +17,8 @@ endif  LDFLAGS_FINAL += --gc-sections  PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ -		     -fno-common -ffixed-r9 -msoft-float +		     -fno-common -ffixed-r9 +PLATFORM_RELFLAGS += $(call cc-option, -msoft-float)  # Support generic board on ARM  __HAVE_ARCH_GENERIC_BOARD := y @@ -105,4 +106,8 @@ PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations)  endif  # limit ourselves to the sections we want in the .bin. -OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rel.dyn +ifdef CONFIG_ARM64 +OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn +else +OBJCFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn +endif diff --git a/arch/arm/cpu/armv7/exynos/config.mk b/arch/arm/cpu/armv7/exynos/config.mk new file mode 100644 index 000000000..ee0d2dab7 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/config.mk @@ -0,0 +1,7 @@ +# +# Copyright (C) Albert ARIBAUD <albert.u.boot@aribaud.net> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +SPL_OBJCFLAGS += -j .machine_param diff --git a/arch/arm/cpu/armv7/lowlevel_init.S b/arch/arm/cpu/armv7/lowlevel_init.S index 69e3053a4..f1aea05c9 100644 --- a/arch/arm/cpu/armv7/lowlevel_init.S +++ b/arch/arm/cpu/armv7/lowlevel_init.S @@ -24,7 +24,7 @@ ENTRY(lowlevel_init)  #ifdef CONFIG_SPL_BUILD  	ldr	r9, =gdata  #else -	sub	sp, #GD_SIZE +	sub	sp, sp, #GD_SIZE  	bic	sp, sp, #7  	mov	r9, sp  #endif diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index 717ec65ae..b4c11c324 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -101,6 +101,12 @@ void zynq_slcr_devcfg_enable(void)  	zynq_slcr_lock();  } +u32 zynq_slcr_get_boot_mode(void) +{ +	/* Get the bootmode register value */ +	return readl(&slcr_base->boot_mode); +} +  u32 zynq_slcr_get_idcode(void)  {  	return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c index 636322a8e..2be253c2c 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -107,8 +107,7 @@ void __udelay(unsigned long usec)  	if (usec == 0)  		return; -	countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) / -								1000000); +	countticks = lldiv(TIMER_TICK_HZ * usec, 1000000);  	/* decrementing timer */  	timeend = readl(&timer_base->counter) - countticks; diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile new file mode 100644 index 000000000..b6eb6de5e --- /dev/null +++ b/arch/arm/cpu/armv8/Makefile @@ -0,0 +1,17 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y	:= start.o + +obj-y	+= cpu.o +obj-y	+= generic_timer.o +obj-y	+= cache_v8.o +obj-y	+= exceptions.o +obj-y	+= cache.o +obj-y	+= tlb.o +obj-y	+= gic.o +obj-y	+= transition.o diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S new file mode 100644 index 000000000..546a83e8f --- /dev/null +++ b/arch/arm/cpu/armv8/cache.S @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * This file is based on sample code from ARMv8 ARM. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <asm/macro.h> +#include <linux/linkage.h> + +/* + * void __asm_flush_dcache_level(level) + * + * clean and invalidate one level cache. + * + * x0: cache level + * x1~x9: clobbered + */ +ENTRY(__asm_flush_dcache_level) +	lsl	x1, x0, #1 +	msr	csselr_el1, x1		/* select cache level */ +	isb				/* sync change of cssidr_el1 */ +	mrs	x6, ccsidr_el1		/* read the new cssidr_el1 */ +	and	x2, x6, #7		/* x2 <- log2(cache line size)-4 */ +	add	x2, x2, #4		/* x2 <- log2(cache line size) */ +	mov	x3, #0x3ff +	and	x3, x3, x6, lsr #3	/* x3 <- max number of #ways */ +	add	w4, w3, w3 +	sub	w4, w4, 1		/* round up log2(#ways + 1) */ +	clz	w5, w4			/* bit position of #ways */ +	mov	x4, #0x7fff +	and	x4, x4, x6, lsr #13	/* x4 <- max number of #sets */ +	/* x1 <- cache level << 1 */ +	/* x2 <- line length offset */ +	/* x3 <- number of cache ways - 1 */ +	/* x4 <- number of cache sets - 1 */ +	/* x5 <- bit position of #ways */ + +loop_set: +	mov	x6, x3			/* x6 <- working copy of #ways */ +loop_way: +	lsl	x7, x6, x5 +	orr	x9, x1, x7		/* map way and level to cisw value */ +	lsl	x7, x4, x2 +	orr	x9, x9, x7		/* map set number to cisw value */ +	dc	cisw, x9		/* clean & invalidate by set/way */ +	subs	x6, x6, #1		/* decrement the way */ +	b.ge	loop_way +	subs	x4, x4, #1		/* decrement the set */ +	b.ge	loop_set + +	ret +ENDPROC(__asm_flush_dcache_level) + +/* + * void __asm_flush_dcache_all(void) + * + * clean and invalidate all data cache by SET/WAY. + */ +ENTRY(__asm_flush_dcache_all) +	dsb	sy +	mrs	x10, clidr_el1		/* read clidr_el1 */ +	lsr	x11, x10, #24 +	and	x11, x11, #0x7		/* x11 <- loc */ +	cbz	x11, finished		/* if loc is 0, exit */ +	mov	x15, lr +	mov	x0, #0			/* start flush at cache level 0 */ +	/* x0  <- cache level */ +	/* x10 <- clidr_el1 */ +	/* x11 <- loc */ +	/* x15 <- return address */ + +loop_level: +	lsl	x1, x0, #1 +	add	x1, x1, x0		/* x0 <- tripled cache level */ +	lsr	x1, x10, x1 +	and	x1, x1, #7		/* x1 <- cache type */ +	cmp	x1, #2 +	b.lt	skip			/* skip if no cache or icache */ +	bl	__asm_flush_dcache_level +skip: +	add	x0, x0, #1		/* increment cache level */ +	cmp	x11, x0 +	b.gt	loop_level + +	mov	x0, #0 +	msr	csselr_el1, x0		/* resotre csselr_el1 */ +	dsb	sy +	isb +	mov	lr, x15 + +finished: +	ret +ENDPROC(__asm_flush_dcache_all) + +/* + * void __asm_flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +ENTRY(__asm_flush_dcache_range) +	mrs	x3, ctr_el0 +	lsr	x3, x3, #16 +	and	x3, x3, #0xf +	mov	x2, #4 +	lsl	x2, x2, x3		/* cache line size */ + +	/* x2 <- minimal cache line size in cache system */ +	sub	x3, x2, #1 +	bic	x0, x0, x3 +1:	dc	civac, x0	/* clean & invalidate data or unified cache */ +	add	x0, x0, x2 +	cmp	x0, x1 +	b.lo	1b +	dsb	sy +	ret +ENDPROC(__asm_flush_dcache_range) + +/* + * void __asm_invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__asm_invalidate_icache_all) +	ic	ialluis +	isb	sy +	ret +ENDPROC(__asm_invalidate_icache_all) diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c new file mode 100644 index 000000000..131fdaba3 --- /dev/null +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -0,0 +1,219 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/system.h> +#include <asm/armv8/mmu.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_DCACHE_OFF + +static void set_pgtable_section(u64 section, u64 memory_type) +{ +	u64 *page_table = (u64 *)gd->arch.tlb_addr; +	u64 value; + +	value = (section << SECTION_SHIFT) | PMD_TYPE_SECT | PMD_SECT_AF; +	value |= PMD_ATTRINDX(memory_type); +	page_table[section] = value; +} + +/* to activate the MMU we need to set up virtual memory */ +static void mmu_setup(void) +{ +	int i, j, el; +	bd_t *bd = gd->bd; + +	/* Setup an identity-mapping for all spaces */ +	for (i = 0; i < (PGTABLE_SIZE >> 3); i++) +		set_pgtable_section(i, MT_DEVICE_NGNRNE); + +	/* Setup an identity-mapping for all RAM space */ +	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { +		ulong start = bd->bi_dram[i].start; +		ulong end = bd->bi_dram[i].start + bd->bi_dram[i].size; +		for (j = start >> SECTION_SHIFT; +		     j < end >> SECTION_SHIFT; j++) { +			set_pgtable_section(j, MT_NORMAL); +		} +	} + +	/* load TTBR0 */ +	el = current_el(); +	if (el == 1) +		asm volatile("msr ttbr0_el1, %0" +			     : : "r" (gd->arch.tlb_addr) : "memory"); +	else if (el == 2) +		asm volatile("msr ttbr0_el2, %0" +			     : : "r" (gd->arch.tlb_addr) : "memory"); +	else +		asm volatile("msr ttbr0_el3, %0" +			     : : "r" (gd->arch.tlb_addr) : "memory"); + +	/* enable the mmu */ +	set_sctlr(get_sctlr() | CR_M); +} + +/* + * Performs a invalidation of the entire data cache at all levels + */ +void invalidate_dcache_all(void) +{ +	__asm_flush_dcache_all(); +} + +/* + * Performs a clean & invalidation of the entire data cache at all levels + */ +void flush_dcache_all(void) +{ +	__asm_flush_dcache_all(); +} + +/* + * Invalidates range in all levels of D-cache/unified cache + */ +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +	__asm_flush_dcache_range(start, stop); +} + +/* + * Flush range(clean & invalidate) from all levels of D-cache/unified cache + */ +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +	__asm_flush_dcache_range(start, stop); +} + +void dcache_enable(void) +{ +	/* The data cache is not active unless the mmu is enabled */ +	if (!(get_sctlr() & CR_M)) { +		invalidate_dcache_all(); +		__asm_invalidate_tlb_all(); +		mmu_setup(); +	} + +	set_sctlr(get_sctlr() | CR_C); +} + +void dcache_disable(void) +{ +	uint32_t sctlr; + +	sctlr = get_sctlr(); + +	/* if cache isn't enabled no need to disable */ +	if (!(sctlr & CR_C)) +		return; + +	set_sctlr(sctlr & ~(CR_C|CR_M)); + +	flush_dcache_all(); +	__asm_invalidate_tlb_all(); +} + +int dcache_status(void) +{ +	return (get_sctlr() & CR_C) != 0; +} + +#else	/* CONFIG_SYS_DCACHE_OFF */ + +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void dcache_enable(void) +{ +} + +void dcache_disable(void) +{ +} + +int dcache_status(void) +{ +	return 0; +} + +#endif	/* CONFIG_SYS_DCACHE_OFF */ + +#ifndef CONFIG_SYS_ICACHE_OFF + +void icache_enable(void) +{ +	set_sctlr(get_sctlr() | CR_I); +} + +void icache_disable(void) +{ +	set_sctlr(get_sctlr() & ~CR_I); +} + +int icache_status(void) +{ +	return (get_sctlr() & CR_I) != 0; +} + +void invalidate_icache_all(void) +{ +	__asm_invalidate_icache_all(); +} + +#else	/* CONFIG_SYS_ICACHE_OFF */ + +void icache_enable(void) +{ +} + +void icache_disable(void) +{ +} + +int icache_status(void) +{ +	return 0; +} + +void invalidate_icache_all(void) +{ +} + +#endif	/* CONFIG_SYS_ICACHE_OFF */ + +/* + * Enable dCache & iCache, whether cache is actually enabled + * depend on CONFIG_SYS_DCACHE_OFF and CONFIG_SYS_ICACHE_OFF + */ +void enable_caches(void) +{ +	icache_enable(); +	dcache_enable(); +} + +/* + * Flush range from all levels of d-cache/unified-cache + */ +void flush_cache(unsigned long start, unsigned long size) +{ +	flush_dcache_range(start, start + size); +} diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk new file mode 100644 index 000000000..027a68ca5 --- /dev/null +++ b/arch/arm/cpu/armv8/config.mk @@ -0,0 +1,15 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# SPDX-License-Identifier:	GPL-2.0+ +# +PLATFORM_RELFLAGS += -fno-common -ffixed-x18 + +# SEE README.arm-unaligned-accesses +PF_NO_UNALIGNED := $(call cc-option, -mstrict-align) +PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED) + +PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8) +PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED) diff --git a/arch/arm/cpu/armv8/cpu.c b/arch/arm/cpu/armv8/cpu.c new file mode 100644 index 000000000..e06c3cc04 --- /dev/null +++ b/arch/arm/cpu/armv8/cpu.c @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <linux/compiler.h> + +int cleanup_before_linux(void) +{ +	/* +	 * this function is called just before we call linux +	 * it prepares the processor for linux +	 * +	 * disable interrupt and turn off caches etc ... +	 */ +	disable_interrupts(); + +	/* +	 * Turn off I-cache and invalidate it +	 */ +	icache_disable(); +	invalidate_icache_all(); + +	/* +	 * turn off D-cache +	 * dcache_disable() in turn flushes the d-cache and disables MMU +	 */ +	dcache_disable(); +	invalidate_dcache_all(); + +	return 0; +} diff --git a/arch/arm/cpu/armv8/exceptions.S b/arch/arm/cpu/armv8/exceptions.S new file mode 100644 index 000000000..b91a1b662 --- /dev/null +++ b/arch/arm/cpu/armv8/exceptions.S @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <asm/ptrace.h> +#include <asm/macro.h> +#include <linux/linkage.h> + +/* + * Enter Exception. + * This will save the processor state that is ELR/X0~X30 + * to the stack frame. + */ +.macro	exception_entry +	stp	x29, x30, [sp, #-16]! +	stp	x27, x28, [sp, #-16]! +	stp	x25, x26, [sp, #-16]! +	stp	x23, x24, [sp, #-16]! +	stp	x21, x22, [sp, #-16]! +	stp	x19, x20, [sp, #-16]! +	stp	x17, x18, [sp, #-16]! +	stp	x15, x16, [sp, #-16]! +	stp	x13, x14, [sp, #-16]! +	stp	x11, x12, [sp, #-16]! +	stp	x9, x10, [sp, #-16]! +	stp	x7, x8, [sp, #-16]! +	stp	x5, x6, [sp, #-16]! +	stp	x3, x4, [sp, #-16]! +	stp	x1, x2, [sp, #-16]! + +	/* Could be running at EL3/EL2/EL1 */ +	switch_el x11, 3f, 2f, 1f +3:	mrs	x1, esr_el3 +	mrs	x2, elr_el3 +	b	0f +2:	mrs	x1, esr_el2 +	mrs	x2, elr_el2 +	b	0f +1:	mrs	x1, esr_el1 +	mrs	x2, elr_el1 +0: +	stp	x2, x0, [sp, #-16]! +	mov	x0, sp +.endm + +/* + * Exception vectors. + */ +	.align	11 +	.globl	vectors +vectors: +	.align	7 +	b	_do_bad_sync	/* Current EL Synchronous Thread */ + +	.align	7 +	b	_do_bad_irq	/* Current EL IRQ Thread */ + +	.align	7 +	b	_do_bad_fiq	/* Current EL FIQ Thread */ + +	.align	7 +	b	_do_bad_error	/* Current EL Error Thread */ + +	.align	7 +	b	_do_sync	/* Current EL Synchronous Handler */ + +	.align	7 +	b	_do_irq		/* Current EL IRQ Handler */ + +	.align	7 +	b	_do_fiq		/* Current EL FIQ Handler */ + +	.align	7 +	b	_do_error	/* Current EL Error Handler */ + + +_do_bad_sync: +	exception_entry +	bl	do_bad_sync + +_do_bad_irq: +	exception_entry +	bl	do_bad_irq + +_do_bad_fiq: +	exception_entry +	bl	do_bad_fiq + +_do_bad_error: +	exception_entry +	bl	do_bad_error + +_do_sync: +	exception_entry +	bl	do_sync + +_do_irq: +	exception_entry +	bl	do_irq + +_do_fiq: +	exception_entry +	bl	do_fiq + +_do_error: +	exception_entry +	bl	do_error diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c new file mode 100644 index 000000000..223b95e21 --- /dev/null +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +/* + * Generic timer implementation of get_tbclk() + */ +unsigned long get_tbclk(void) +{ +	unsigned long cntfrq; +	asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq)); +	return cntfrq; +} + +/* + * Generic timer implementation of timer_read_counter() + */ +unsigned long timer_read_counter(void) +{ +	unsigned long cntpct; +	isb(); +	asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); +	return cntpct; +} diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S new file mode 100644 index 000000000..599aa8f2b --- /dev/null +++ b/arch/arm/cpu/armv8/gic.S @@ -0,0 +1,106 @@ +/* + * GIC Initialization Routines. + * + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> +#include <asm/macro.h> +#include <asm/gic.h> + + +/************************************************************************* + * + * void gic_init(void) __attribute__((weak)); + * + * Currently, this routine only initialize secure copy of GIC + * with Security Extensions at EL3. + * + *************************************************************************/ +WEAK(gic_init) +	branch_if_slave	x0, 2f + +	/* Initialize Distributor and SPIs */ +	ldr	x1, =GICD_BASE +	mov	w0, #0x3		/* EnableGrp0 | EnableGrp1 */ +	str	w0, [x1, GICD_CTLR]	/* Secure GICD_CTLR */ +	ldr	w0, [x1, GICD_TYPER] +	and	w2, w0, #0x1f		/* ITLinesNumber */ +	cbz	w2, 2f			/* No SPIs */ +	add	x1, x1, (GICD_IGROUPRn + 4) +	mov	w0, #~0			/* Config SPIs as Grp1 */ +1:	str	w0, [x1], #0x4 +	sub	w2, w2, #0x1 +	cbnz	w2, 1b + +	/* Initialize SGIs and PPIs */ +2:	ldr	x1, =GICD_BASE +	mov	w0, #~0			/* Config SGIs and PPIs as Grp1 */ +	str	w0, [x1, GICD_IGROUPRn]	/* GICD_IGROUPR0 */ +	mov	w0, #0x1		/* Enable SGI 0 */ +	str	w0, [x1, GICD_ISENABLERn] + +	/* Initialize Cpu Interface */ +	ldr	x1, =GICC_BASE +	mov	w0, #0x1e7		/* Disable IRQ/FIQ Bypass & */ +					/* Enable Ack Group1 Interrupt & */ +					/* EnableGrp0 & EnableGrp1 */ +	str	w0, [x1, GICC_CTLR]	/* Secure GICC_CTLR */ + +	mov	w0, #0x1 << 7		/* Non-Secure access to GICC_PMR */ +	str	w0, [x1, GICC_PMR] + +	ret +ENDPROC(gic_init) + + +/************************************************************************* + * + * void gic_send_sgi(u64 sgi) __attribute__((weak)); + * + *************************************************************************/ +WEAK(gic_send_sgi) +	ldr	x1, =GICD_BASE +	mov	w2, #0x8000 +	movk	w2, #0x100, lsl #16 +	orr	w2, w2, w0 +	str	w2, [x1, GICD_SGIR] +	ret +ENDPROC(gic_send_sgi) + + +/************************************************************************* + * + * void wait_for_wakeup(void) __attribute__((weak)); + * + * Wait for SGI 0 from master. + * + *************************************************************************/ +WEAK(wait_for_wakeup) +	ldr	x1, =GICC_BASE +0:	wfi +	ldr	w0, [x1, GICC_AIAR] +	str	w0, [x1, GICC_AEOIR] +	cbnz	w0, 0b +	ret +ENDPROC(wait_for_wakeup) + + +/************************************************************************* + * + * void smp_kick_all_cpus(void) __attribute__((weak)); + * + *************************************************************************/ +WEAK(smp_kick_all_cpus) +	/* Kick secondary cpus up by SGI 0 interrupt */ +	mov	x0, xzr			/* SGI 0 */ +	mov	x29, lr			/* Save LR */ +	bl	gic_send_sgi +	mov	lr, x29			/* Restore LR */ +	ret +ENDPROC(smp_kick_all_cpus) diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S new file mode 100644 index 000000000..bcc260309 --- /dev/null +++ b/arch/arm/cpu/armv8/start.S @@ -0,0 +1,164 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> +#include <asm/macro.h> +#include <asm/armv8/mmu.h> + +/************************************************************************* + * + * Startup Code (reset vector) + * + *************************************************************************/ + +.globl	_start +_start: +	b	reset + +	.align 3 + +.globl	_TEXT_BASE +_TEXT_BASE: +	.quad	CONFIG_SYS_TEXT_BASE + +/* + * These are defined in the linker script. + */ +.globl	_end_ofs +_end_ofs: +	.quad	_end - _start + +.globl	_bss_start_ofs +_bss_start_ofs: +	.quad	__bss_start - _start + +.globl	_bss_end_ofs +_bss_end_ofs: +	.quad	__bss_end - _start + +reset: +	/* +	 * Could be EL3/EL2/EL1, Initial State: +	 * Little Endian, MMU Disabled, i/dCache Disabled +	 */ +	adr	x0, vectors +	switch_el x1, 3f, 2f, 1f +3:	msr	vbar_el3, x0 +	msr	cptr_el3, xzr			/* Enable FP/SIMD */ +	ldr	x0, =COUNTER_FREQUENCY +	msr	cntfrq_el0, x0			/* Initialize CNTFRQ */ +	b	0f +2:	msr	vbar_el2, x0 +	mov	x0, #0x33ff +	msr	cptr_el2, x0			/* Enable FP/SIMD */ +	b	0f +1:	msr	vbar_el1, x0 +	mov	x0, #3 << 20 +	msr	cpacr_el1, x0			/* Enable FP/SIMD */ +0: + +	/* Cache/BPB/TLB Invalidate */ +	bl	__asm_flush_dcache_all		/* dCache clean&invalidate */ +	bl	__asm_invalidate_icache_all	/* iCache invalidate */ +	bl	__asm_invalidate_tlb_all	/* invalidate TLBs */ + +	/* Processor specific initialization */ +	bl	lowlevel_init + +	branch_if_master x0, x1, master_cpu + +	/* +	 * Slave CPUs +	 */ +slave_cpu: +	wfe +	ldr	x1, =CPU_RELEASE_ADDR +	ldr	x0, [x1] +	cbz	x0, slave_cpu +	br	x0			/* branch to the given address */ + +	/* +	 * Master CPU +	 */ +master_cpu: +	bl	_main + +/*-----------------------------------------------------------------------*/ + +WEAK(lowlevel_init) +	/* Initialize GIC Secure Bank Status */ +	mov	x29, lr			/* Save LR */ +	bl	gic_init + +	branch_if_master x0, x1, 1f + +	/* +	 * Slave should wait for master clearing spin table. +	 * This sync prevent salves observing incorrect +	 * value of spin table and jumping to wrong place. +	 */ +	bl	wait_for_wakeup + +	/* +	 * All processors will enter EL2 and optionally EL1. +	 */ +	bl	armv8_switch_to_el2 +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 +	bl	armv8_switch_to_el1 +#endif + +1: +	mov	lr, x29			/* Restore LR */ +	ret +ENDPROC(lowlevel_init) + +/*-----------------------------------------------------------------------*/ + +ENTRY(c_runtime_cpu_setup) +	/* If I-cache is enabled invalidate it */ +#ifndef CONFIG_SYS_ICACHE_OFF +	ic	iallu			/* I+BTB cache invalidate */ +	isb	sy +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +	/* +	 * Setup MAIR and TCR. +	 */ +	ldr	x0, =MEMORY_ATTRIBUTES +	ldr	x1, =TCR_FLAGS + +	switch_el x2, 3f, 2f, 1f +3:	orr	x1, x1, TCR_EL3_IPS_BITS +	msr	mair_el3, x0 +	msr	tcr_el3, x1 +	b	0f +2:	orr	x1, x1, TCR_EL2_IPS_BITS +	msr	mair_el2, x0 +	msr	tcr_el2, x1 +	b	0f +1:	orr	x1, x1, TCR_EL1_IPS_BITS +	msr	mair_el1, x0 +	msr	tcr_el1, x1 +0: +#endif + +	/* Relocate vBAR */ +	adr	x0, vectors +	switch_el x1, 3f, 2f, 1f +3:	msr	vbar_el3, x0 +	b	0f +2:	msr	vbar_el2, x0 +	b	0f +1:	msr	vbar_el1, x0 +0: + +	ret +ENDPROC(c_runtime_cpu_setup) diff --git a/arch/arm/cpu/armv8/tlb.S b/arch/arm/cpu/armv8/tlb.S new file mode 100644 index 000000000..f840b04df --- /dev/null +++ b/arch/arm/cpu/armv8/tlb.S @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> +#include <asm/macro.h> + +/* + * void __asm_invalidate_tlb_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__asm_invalidate_tlb_all) +	switch_el x9, 3f, 2f, 1f +3:	tlbi	alle3 +	dsb	sy +	isb +	b	0f +2:	tlbi	alle2 +	dsb	sy +	isb +	b	0f +1:	tlbi	vmalle1 +	dsb	sy +	isb +0: +	ret +ENDPROC(__asm_invalidate_tlb_all) diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S new file mode 100644 index 000000000..e0a594600 --- /dev/null +++ b/arch/arm/cpu/armv8/transition.S @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> +#include <asm/macro.h> + +ENTRY(armv8_switch_to_el2) +	switch_el x0, 1f, 0f, 0f +0:	ret +1: +	mov	x0, #0x5b1	/* Non-secure EL0/EL1 | HVC | 64bit EL2 */ +	msr	scr_el3, x0 +	msr	cptr_el3, xzr	/* Disable coprocessor traps to EL3 */ +	mov	x0, #0x33ff +	msr	cptr_el2, x0	/* Disable coprocessor traps to EL2 */ + +	/* Initialize SCTLR_EL2 */ +	msr	sctlr_el2, xzr + +	/* Return to the EL2_SP2 mode from EL3 */ +	mov	x0, sp +	msr	sp_el2, x0	/* Migrate SP */ +	mrs	x0, vbar_el3 +	msr	vbar_el2, x0	/* Migrate VBAR */ +	mov	x0, #0x3c9 +	msr	spsr_el3, x0	/* EL2_SP2 | D | A | I | F */ +	msr	elr_el3, lr +	eret +ENDPROC(armv8_switch_to_el2) + +ENTRY(armv8_switch_to_el1) +	switch_el x0, 0f, 1f, 0f +0:	ret +1: +	/* Initialize Generic Timers */ +	mrs	x0, cnthctl_el2 +	orr	x0, x0, #0x3		/* Enable EL1 access to timers */ +	msr	cnthctl_el2, x0 +	msr	cntvoff_el2, x0 +	mrs	x0, cntkctl_el1 +	orr	x0, x0, #0x3		/* Enable EL0 access to timers */ +	msr	cntkctl_el1, x0 + +	/* Initilize MPID/MPIDR registers */ +	mrs	x0, midr_el1 +	mrs	x1, mpidr_el1 +	msr	vpidr_el2, x0 +	msr	vmpidr_el2, x1 + +	/* Disable coprocessor traps */ +	mov	x0, #0x33ff +	msr	cptr_el2, x0		/* Disable coprocessor traps to EL2 */ +	msr	hstr_el2, xzr		/* Disable coprocessor traps to EL2 */ +	mov	x0, #3 << 20 +	msr	cpacr_el1, x0		/* Enable FP/SIMD at EL1 */ + +	/* Initialize HCR_EL2 */ +	mov	x0, #(1 << 31)		/* 64bit EL1 */ +	orr	x0, x0, #(1 << 29)	/* Disable HVC */ +	msr	hcr_el2, x0 + +	/* SCTLR_EL1 initialization */ +	mov	x0, #0x0800 +	movk	x0, #0x30d0, lsl #16 +	msr	sctlr_el1, x0 + +	/* Return to the EL1_SP1 mode from EL2 */ +	mov	x0, sp +	msr	sp_el1, x0		/* Migrate SP */ +	mrs	x0, vbar_el2 +	msr	vbar_el1, x0		/* Migrate VBAR */ +	mov	x0, #0x3c5 +	msr	spsr_el2, x0		/* EL1_SP1 | D | A | I | F */ +	msr	elr_el2, lr +	eret +ENDPROC(armv8_switch_to_el1) diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds new file mode 100644 index 000000000..4c1222237 --- /dev/null +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ +	. = 0x00000000; + +	. = ALIGN(8); +	.text : +	{ +		*(.__image_copy_start) +		CPUDIR/start.o (.text*) +		*(.text*) +	} + +	. = ALIGN(8); +	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + +	. = ALIGN(8); +	.data : { +		*(.data*) +	} + +	. = ALIGN(8); + +	. = .; + +	. = ALIGN(8); +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} + +	. = ALIGN(8); + +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	. = ALIGN(8); + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	} + +	.rela.dyn : { +		*(.rela*) +	} + +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end) +	} + +	_end = .; + +	. = ALIGN(8); + +	.bss_start : { +		KEEP(*(.__bss_start)); +	} + +	.bss : { +		*(.bss*) +		 . = ALIGN(8); +	} + +	.bss_end : { +		KEEP(*(.__bss_end)); +	} + +	/DISCARD/ : { *(.dynsym) } +	/DISCARD/ : { *(.dynstr*) } +	/DISCARD/ : { *(.dynamic*) } +	/DISCARD/ : { *(.plt*) } +	/DISCARD/ : { *(.interp*) } +	/DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm/cpu/pxa/config.mk b/arch/arm/cpu/pxa/config.mk index d8d263d40..f2befbe51 100644 --- a/arch/arm/cpu/pxa/config.mk +++ b/arch/arm/cpu/pxa/config.mk @@ -14,3 +14,16 @@ PLATFORM_CPPFLAGS += -mcpu=xscale  # ========================================================================  PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))  PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT) + +# +# !WARNING! +# The PXA's OneNAND SPL uses .text.0 and .text.1 segments to allow booting from +# really small OneNAND memories where the mmap'd window is only 1KiB big. The +# .text.0 contains only the bare minimum needed to load the real SPL into SRAM. +# Add .text.0 and .text.1 into OBJFLAGS, so when the SPL is being objcopy'd, +# they are not discarded. +# + +#ifdef CONFIG_SPL_BUILD +OBJCFLAGS += -j .text.0 -j .text.1 +#endif diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index 78d9f3274..c4717de6a 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -28,12 +28,12 @@ DECLARE_GLOBAL_DATA_PTR;  static unsigned long long tick_to_time(unsigned long long tick)  { -	return tick * CONFIG_SYS_HZ / TIMER_FREQ_HZ; +	return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ);  }  static unsigned long long us_to_tick(unsigned long long us)  { -	return (us * TIMER_FREQ_HZ) / 1000000; +	return lldiv(us * TIMER_FREQ_HZ, 1000000);  }  int timer_init(void) diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 9463a33dc..4da5d246e 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -92,8 +92,6 @@ SECTIONS  	}  	.dynsym _end : { *(.dynsym) } -	.hash : { *(.hash) } -	.got.plt : { *(.got.plt) }  	.dynbss : { *(.dynbss) }  	.dynstr : { *(.dynstr*) }  	.dynamic : { *(.dynamic*) } @@ -101,4 +99,5 @@ SECTIONS  	.interp : { *(.interp*) }  	.gnu : { *(.gnu*) }  	.ARM.exidx : { *(.ARM.exidx*) } +	.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }  } diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi new file mode 100644 index 000000000..f20b8bd60 --- /dev/null +++ b/arch/arm/dts/zynq-7000.dtsi @@ -0,0 +1,13 @@ +/* + * Xilinx Zynq 7000 DTSI + * Describes the hardware common to all Zynq 7000-based boards. + * + * Copyright (C) 2013 Xilinx, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +/include/ "skeleton.dtsi" + +/ { +	compatible = "xlnx,zynq-7000"; +}; diff --git a/arch/arm/include/asm/arch-exynos/ehci.h b/arch/arm/include/asm/arch-exynos/ehci.h index d79f25c0c..d2d70bd82 100644 --- a/arch/arm/include/asm/arch-exynos/ehci.h +++ b/arch/arm/include/asm/arch-exynos/ehci.h @@ -29,6 +29,20 @@  #define EHCICTRL_ENAINCR8			(1 << 27)  #define EHCICTRL_ENAINCR16			(1 << 26) +#define HSIC_CTRL_REFCLKSEL                     (0x2) +#define HSIC_CTRL_REFCLKSEL_MASK                (0x3) +#define HSIC_CTRL_REFCLKSEL_SHIFT               (23) + +#define HSIC_CTRL_REFCLKDIV_12                  (0x24) +#define HSIC_CTRL_REFCLKDIV_MASK                (0x7f) +#define HSIC_CTRL_REFCLKDIV_SHIFT               (16) + +#define HSIC_CTRL_SIDDQ                         (0x1 << 6) +#define HSIC_CTRL_FORCESLEEP                    (0x1 << 5) +#define HSIC_CTRL_FORCESUSPEND                  (0x1 << 4) +#define HSIC_CTRL_UTMISWRST                     (0x1 << 2) +#define HSIC_CTRL_PHYSWRST                      (0x1 << 0) +  /* Register map for PHY control */  struct exynos_usb_phy {  	unsigned int usbphyctrl0; diff --git a/arch/arm/include/asm/arch-rmobile/r8a7790.h b/arch/arm/include/asm/arch-rmobile/r8a7790.h index 42d65d356..d9ea71fa1 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7790.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7790.h @@ -19,6 +19,7 @@  #define DBSC3_1_BASE		0xE67A0000  #define TMU_BASE		0xE61E0000  #define	GPIO5_BASE		0xE6055000 +#define SH_QSPI_BASE	0xE6B10000  #define S3C_BASE		0xE6784000  #define S3C_INT_BASE		0xE6784A00 diff --git a/arch/arm/include/asm/arch-rmobile/r8a7791.h b/arch/arm/include/asm/arch-rmobile/r8a7791.h index 2afda0a62..ff3018059 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7791.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7791.h @@ -19,6 +19,7 @@  #define DBSC3_1_BASE	0xE67A0000  #define TMU_BASE	0xE61E0000  #define	GPIO5_BASE	0xE6055000 +#define SH_QSPI_BASE	0xE6B10000  #define S3C_BASE	0xE6784000  #define S3C_INT_BASE	0xE6784A00 diff --git a/arch/arm/include/asm/arch-socfpga/dwmmc.h b/arch/arm/include/asm/arch-socfpga/dwmmc.h new file mode 100644 index 000000000..945eb646c --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/dwmmc.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef	_SOCFPGA_DWMMC_H_ +#define	_SOCFPGA_DWMMC_H_ + +extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index); + +#endif /* _SOCFPGA_SDMMC_H_ */ diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index d965d25ef..838d21053 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -19,4 +19,69 @@ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM];  #define CONFIG_SYSMGR_PINMUXGRP_OFFSET	(0x400) +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)	\ +	((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) + +struct socfpga_system_manager { +	u32	siliconid1; +	u32	siliconid2; +	u32	_pad_0x8_0xf[2]; +	u32	wddbg; +	u32	bootinfo; +	u32	hpsinfo; +	u32	parityinj; +	u32	fpgaintfgrp_gbl; +	u32	fpgaintfgrp_indiv; +	u32	fpgaintfgrp_module; +	u32	_pad_0x2c_0x2f; +	u32	scanmgrgrp_ctrl; +	u32	_pad_0x34_0x3f[3]; +	u32	frzctrl_vioctrl; +	u32	_pad_0x44_0x4f[3]; +	u32	frzctrl_hioctrl; +	u32	frzctrl_src; +	u32	frzctrl_hwctrl; +	u32	_pad_0x5c_0x5f; +	u32	emacgrp_ctrl; +	u32	emacgrp_l3master; +	u32	_pad_0x68_0x6f[2]; +	u32	dmagrp_ctrl; +	u32	dmagrp_persecurity; +	u32	_pad_0x78_0x7f[2]; +	u32	iswgrp_handoff[8]; +	u32	_pad_0xa0_0xbf[8]; +	u32	romcodegrp_ctrl; +	u32	romcodegrp_cpu1startaddr; +	u32	romcodegrp_initswstate; +	u32	romcodegrp_initswlastld; +	u32	romcodegrp_bootromswstate; +	u32	__pad_0xd4_0xdf[3]; +	u32	romcodegrp_warmramgrp_enable; +	u32	romcodegrp_warmramgrp_datastart; +	u32	romcodegrp_warmramgrp_length; +	u32	romcodegrp_warmramgrp_execution; +	u32	romcodegrp_warmramgrp_crc; +	u32	__pad_0xf4_0xff[3]; +	u32	romhwgrp_ctrl; +	u32	_pad_0x104_0x107; +	u32	sdmmcgrp_ctrl; +	u32	sdmmcgrp_l3master; +	u32	nandgrp_bootstrap; +	u32	nandgrp_l3master; +	u32	usbgrp_l3master; +	u32	_pad_0x11c_0x13f[9]; +	u32	eccgrp_l2; +	u32	eccgrp_ocram; +	u32	eccgrp_usb0; +	u32	eccgrp_usb1; +	u32	eccgrp_emac0; +	u32	eccgrp_emac1; +	u32	eccgrp_dma; +	u32	eccgrp_can0; +	u32	eccgrp_can1; +	u32	eccgrp_nand; +	u32	eccgrp_qspi; +	u32	eccgrp_sdmmc; +}; +  #endif /* _SYSTEM_MANAGER_H_ */ diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h new file mode 100644 index 000000000..2dbba756d --- /dev/null +++ b/arch/arm/include/asm/arch-zynq/gpio.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 Xilinx, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _ZYNQ_GPIO_H +#define _ZYNQ_GPIO_H + +inline int gpio_get_value(unsigned gpio) +{ +	return 0; +} + +inline int gpio_set_value(unsigned gpio, int val) +{ +	return 0; +} + +inline int gpio_request(unsigned gpio, const char *label) +{ +	return 0; +} + +#endif /* _ZYNQ_GPIO_H */ diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 110de9092..8f925af8a 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -13,6 +13,7 @@ extern void zynq_slcr_cpu_reset(void);  extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);  extern void zynq_slcr_devcfg_disable(void);  extern void zynq_slcr_devcfg_enable(void); +extern u32 zynq_slcr_get_boot_mode(void);  extern u32 zynq_slcr_get_idcode(void);  extern void zynq_ddrc_init(void); diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h new file mode 100644 index 000000000..1193e76a8 --- /dev/null +++ b/arch/arm/include/asm/armv8/mmu.h @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _ASM_ARMV8_MMU_H_ +#define _ASM_ARMV8_MMU_H_ + +#ifdef __ASSEMBLY__ +#define _AC(X, Y)	X +#else +#define _AC(X, Y)	(X##Y) +#endif + +#define UL(x)		_AC(x, UL) + +/***************************************************************/ +/* + * The following definitions are related each other, shoud be + * calculated specifically. + */ +#define VA_BITS			(42)	/* 42 bits virtual address */ + +/* PAGE_SHIFT determines the page size */ +#undef  PAGE_SIZE +#define PAGE_SHIFT		16 +#define PAGE_SIZE		(1 << PAGE_SHIFT) +#define PAGE_MASK		(~(PAGE_SIZE-1)) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT		29 +#define SECTION_SIZE		(UL(1) << SECTION_SHIFT) +#define SECTION_MASK		(~(SECTION_SIZE-1)) +/***************************************************************/ + +/* + * Memory types + */ +#define MT_DEVICE_NGNRNE	0 +#define MT_DEVICE_NGNRE		1 +#define MT_DEVICE_GRE		2 +#define MT_NORMAL_NC		3 +#define MT_NORMAL		4 + +#define MEMORY_ATTRIBUTES	((0x00 << (MT_DEVICE_NGNRNE*8)) |	\ +				(0x04 << (MT_DEVICE_NGNRE*8)) |		\ +				(0x0c << (MT_DEVICE_GRE*8)) |		\ +				(0x44 << (MT_NORMAL_NC*8)) |		\ +				(UL(0xff) << (MT_NORMAL*8))) + +/* + * Hardware page table definitions. + * + * Level 2 descriptor (PMD). + */ +#define PMD_TYPE_MASK		(3 << 0) +#define PMD_TYPE_FAULT		(0 << 0) +#define PMD_TYPE_TABLE		(3 << 0) +#define PMD_TYPE_SECT		(1 << 0) + +/* + * Section + */ +#define PMD_SECT_S		(3 << 8) +#define PMD_SECT_AF		(1 << 10) +#define PMD_SECT_NG		(1 << 11) +#define PMD_SECT_PXN		(UL(1) << 53) +#define PMD_SECT_UXN		(UL(1) << 54) + +/* + * AttrIndx[2:0] + */ +#define PMD_ATTRINDX(t)		((t) << 2) +#define PMD_ATTRINDX_MASK	(7 << 2) + +/* + * TCR flags. + */ +#define TCR_T0SZ(x)		((64 - (x)) << 0) +#define TCR_IRGN_NC		(0 << 8) +#define TCR_IRGN_WBWA		(1 << 8) +#define TCR_IRGN_WT		(2 << 8) +#define TCR_IRGN_WBNWA		(3 << 8) +#define TCR_IRGN_MASK		(3 << 8) +#define TCR_ORGN_NC		(0 << 10) +#define TCR_ORGN_WBWA		(1 << 10) +#define TCR_ORGN_WT		(2 << 10) +#define TCR_ORGN_WBNWA		(3 << 10) +#define TCR_ORGN_MASK		(3 << 10) +#define TCR_SHARED_NON		(0 << 12) +#define TCR_SHARED_OUTER	(1 << 12) +#define TCR_SHARED_INNER	(2 << 12) +#define TCR_TG0_4K		(0 << 14) +#define TCR_TG0_64K		(1 << 14) +#define TCR_TG0_16K		(2 << 14) +#define TCR_EL1_IPS_BITS	(UL(3) << 32)	/* 42 bits physical address */ +#define TCR_EL2_IPS_BITS	(3 << 16)	/* 42 bits physical address */ +#define TCR_EL3_IPS_BITS	(3 << 16)	/* 42 bits physical address */ + +/* PTWs cacheable, inner/outer WBWA and non-shareable */ +#define TCR_FLAGS		(TCR_TG0_64K |		\ +				TCR_SHARED_NON |	\ +				TCR_ORGN_WBWA |		\ +				TCR_IRGN_WBWA |		\ +				TCR_T0SZ(VA_BITS)) + +#endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h index c3489f1e1..20cce7657 100644 --- a/arch/arm/include/asm/byteorder.h +++ b/arch/arm/include/asm/byteorder.h @@ -23,7 +23,7 @@  #  define __SWAB_64_THRU_32__  #endif -#ifdef __ARMEB__ +#if defined(__ARMEB__) || defined(__AARCH64EB__)  #include <linux/byteorder/big_endian.h>  #else  #include <linux/byteorder/little_endian.h> diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 6d60a4a6d..ddebbc8fc 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -11,6 +11,8 @@  #include <asm/system.h> +#ifndef CONFIG_ARM64 +  /*   * Invalidate L2 Cache using co-proc instruction   */ @@ -28,6 +30,9 @@ void l2_cache_disable(void);  void set_section_dcache(int section, enum dcache_option option);  void dram_bank_mmu_setup(int bank); + +#endif +  /*   * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We   * use that value for aligning DMA buffers unless the board config has specified diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 99b703e1e..abf79e5c9 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -9,4 +9,10 @@  #define CONFIG_LMB  #define CONFIG_SYS_BOOT_RAMDISK_HIGH + +#ifdef CONFIG_ARM64 +#define CONFIG_PHYS_64BIT +#define CONFIG_STATIC_RELA +#endif +  #endif diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h index a0891cc09..ac2b2bfbe 100644 --- a/arch/arm/include/asm/gic.h +++ b/arch/arm/include/asm/gic.h @@ -1,19 +1,54 @@ -#ifndef __GIC_V2_H__ -#define __GIC_V2_H__ +#ifndef __GIC_H__ +#define __GIC_H__ -/* register offsets for the ARM generic interrupt controller (GIC) */ +/* Register offsets for the ARM generic interrupt controller (GIC) */  #define GIC_DIST_OFFSET		0x1000 +#define GIC_CPU_OFFSET_A9	0x0100 +#define GIC_CPU_OFFSET_A15	0x2000 + +/* Distributor Registers */  #define GICD_CTLR		0x0000  #define GICD_TYPER		0x0004 +#define GICD_IIDR		0x0008 +#define GICD_STATUSR		0x0010 +#define GICD_SETSPI_NSR		0x0040 +#define GICD_CLRSPI_NSR		0x0048 +#define GICD_SETSPI_SR		0x0050 +#define GICD_CLRSPI_SR		0x0058 +#define GICD_SEIR		0x0068  #define GICD_IGROUPRn		0x0080 -#define GICD_SGIR		0x0F00 +#define GICD_ISENABLERn		0x0100 +#define GICD_ICENABLERn		0x0180 +#define GICD_ISPENDRn		0x0200 +#define GICD_ICPENDRn		0x0280 +#define GICD_ISACTIVERn		0x0300 +#define GICD_ICACTIVERn		0x0380 +#define GICD_IPRIORITYRn	0x0400 +#define GICD_ITARGETSRn		0x0800 +#define GICD_ICFGR		0x0c00 +#define GICD_IGROUPMODRn	0x0d00 +#define GICD_NSACRn		0x0e00 +#define GICD_SGIR		0x0f00 +#define GICD_CPENDSGIRn		0x0f10 +#define GICD_SPENDSGIRn		0x0f20 +#define GICD_IROUTERn		0x6000 -#define GIC_CPU_OFFSET_A9	0x0100 -#define GIC_CPU_OFFSET_A15	0x2000 +/* Cpu Interface Memory Mapped Registers */  #define GICC_CTLR		0x0000  #define GICC_PMR		0x0004 +#define GICC_BPR		0x0008  #define GICC_IAR		0x000C  #define GICC_EOIR		0x0010 +#define GICC_RPR		0x0014 +#define GICC_HPPIR		0x0018 +#define GICC_ABPR		0x001c +#define GICC_AIAR		0x0020 +#define GICC_AEOIR		0x0024 +#define GICC_AHPPIR		0x0028 +#define GICC_APRn		0x00d0 +#define GICC_NSAPRn		0x00e0 +#define GICC_IIDR		0x00fc +#define GICC_DIR		0x1000 -#endif +#endif /* __GIC_H__ */ diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index e12643609..60e872637 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -47,6 +47,10 @@ struct arch_global_data {  #include <asm-generic/global_data.h> -#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r9") +#ifdef CONFIG_ARM64 +#define DECLARE_GLOBAL_DATA_PTR		register volatile gd_t *gd asm ("x18") +#else +#define DECLARE_GLOBAL_DATA_PTR		register volatile gd_t *gd asm ("r9") +#endif  #endif /* __ASM_GBL_DATA_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 1fbc531a0..6a1f05ac3 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -75,42 +75,45 @@ static inline phys_addr_t virt_to_phys(void * vaddr)  #define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))  #define __arch_putl(v,a)		(*(volatile unsigned int *)(a) = (v)) -extern inline void __raw_writesb(unsigned int addr, const void *data, int bytelen) +extern inline void __raw_writesb(unsigned long addr, const void *data, +				 int bytelen)  {  	uint8_t *buf = (uint8_t *)data;  	while(bytelen--)  		__arch_putb(*buf++, addr);  } -extern inline void __raw_writesw(unsigned int addr, const void *data, int wordlen) +extern inline void __raw_writesw(unsigned long addr, const void *data, +				 int wordlen)  {  	uint16_t *buf = (uint16_t *)data;  	while(wordlen--)  		__arch_putw(*buf++, addr);  } -extern inline void __raw_writesl(unsigned int addr, const void *data, int longlen) +extern inline void __raw_writesl(unsigned long addr, const void *data, +				 int longlen)  {  	uint32_t *buf = (uint32_t *)data;  	while(longlen--)  		__arch_putl(*buf++, addr);  } -extern inline void __raw_readsb(unsigned int addr, void *data, int bytelen) +extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen)  {  	uint8_t *buf = (uint8_t *)data;  	while(bytelen--)  		*buf++ = __arch_getb(addr);  } -extern inline void __raw_readsw(unsigned int addr, void *data, int wordlen) +extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen)  {  	uint16_t *buf = (uint16_t *)data;  	while(wordlen--)  		*buf++ = __arch_getw(addr);  } -extern inline void __raw_readsl(unsigned int addr, void *data, int longlen) +extern inline void __raw_readsl(unsigned long addr, void *data, int longlen)  {  	uint32_t *buf = (uint32_t *)data;  	while(longlen--) diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index ff13f36ba..f77e4b880 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -54,5 +54,58 @@  	bcs	1b  .endm +#ifdef CONFIG_ARM64 +/* + * Register aliases. + */ +lr	.req	x30 + +/* + * Branch according to exception level + */ +.macro	switch_el, xreg, el3_label, el2_label, el1_label +	mrs	\xreg, CurrentEL +	cmp	\xreg, 0xc +	b.eq	\el3_label +	cmp	\xreg, 0x8 +	b.eq	\el2_label +	cmp	\xreg, 0x4 +	b.eq	\el1_label +.endm + +/* + * Branch if current processor is a slave, + * choose processor with all zero affinity value as the master. + */ +.macro	branch_if_slave, xreg, slave_label +	mrs	\xreg, mpidr_el1 +	tst	\xreg, #0xff		/* Test Affinity 0 */ +	b.ne	\slave_label +	lsr	\xreg, \xreg, #8 +	tst	\xreg, #0xff		/* Test Affinity 1 */ +	b.ne	\slave_label +	lsr	\xreg, \xreg, #8 +	tst	\xreg, #0xff		/* Test Affinity 2 */ +	b.ne	\slave_label +	lsr	\xreg, \xreg, #16 +	tst	\xreg, #0xff		/* Test Affinity 3 */ +	b.ne	\slave_label +.endm + +/* + * Branch if current processor is a master, + * choose processor with all zero affinity value as the master. + */ +.macro	branch_if_master, xreg1, xreg2, master_label +	mrs	\xreg1, mpidr_el1 +	lsr	\xreg2, \xreg1, #32 +	lsl	\xreg1, \xreg1, #40 +	lsr	\xreg1, \xreg1, #40 +	orr	\xreg1, \xreg1, \xreg2 +	cbz	\xreg1, \master_label +.endm + +#endif /* CONFIG_ARM64 */ +  #endif /* __ASSEMBLY__ */  #endif /* __ASM_ARM_MACRO_H__ */ diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h index c412486db..d254b95b2 100644 --- a/arch/arm/include/asm/posix_types.h +++ b/arch/arm/include/asm/posix_types.h @@ -28,9 +28,17 @@ typedef int			__kernel_pid_t;  typedef unsigned short		__kernel_ipc_pid_t;  typedef unsigned short		__kernel_uid_t;  typedef unsigned short		__kernel_gid_t; + +#ifdef	__aarch64__ +typedef unsigned long		__kernel_size_t; +typedef long			__kernel_ssize_t; +typedef long			__kernel_ptrdiff_t; +#else  typedef unsigned int		__kernel_size_t;  typedef int			__kernel_ssize_t;  typedef int			__kernel_ptrdiff_t; +#endif +  typedef long			__kernel_time_t;  typedef long			__kernel_suseconds_t;  typedef long			__kernel_clock_t; diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h index a060ee67e..21aef58b7 100644 --- a/arch/arm/include/asm/proc-armv/ptrace.h +++ b/arch/arm/include/asm/proc-armv/ptrace.h @@ -10,6 +10,25 @@  #ifndef __ASM_PROC_PTRACE_H  #define __ASM_PROC_PTRACE_H +#ifdef CONFIG_ARM64 + +#define PCMASK		0 + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored + * on the stack during an exception. + */ +struct pt_regs { +	unsigned long elr; +	unsigned long regs[31]; +}; + +#endif	/* __ASSEMBLY__ */ + +#else	/* CONFIG_ARM64 */ +  #define USR26_MODE	0x00  #define FIQ26_MODE	0x01  #define IRQ26_MODE	0x02 @@ -104,4 +123,6 @@ static inline int valid_user_regs(struct pt_regs *regs)  #endif	/* __ASSEMBLY__ */ +#endif	/* CONFIG_ARM64 */ +  #endif diff --git a/arch/arm/include/asm/proc-armv/system.h b/arch/arm/include/asm/proc-armv/system.h index cda8976b6..693d1f492 100644 --- a/arch/arm/include/asm/proc-armv/system.h +++ b/arch/arm/include/asm/proc-armv/system.h @@ -13,6 +13,60 @@  /*   * Save the current interrupt enable state & disable IRQs   */ +#ifdef CONFIG_ARM64 + +/* + * Save the current interrupt enable state + * and disable IRQs/FIQs + */ +#define local_irq_save(flags)					\ +	({							\ +	asm volatile(						\ +	"mrs	%0, daif"					\ +	"msr	daifset, #3"					\ +	: "=r" (flags)						\ +	:							\ +	: "memory");						\ +	}) + +/* + * restore saved IRQ & FIQ state + */ +#define local_irq_restore(flags)				\ +	({							\ +	asm volatile(						\ +	"msr	daif, %0"					\ +	:							\ +	: "r" (flags)						\ +	: "memory");						\ +	}) + +/* + * Enable IRQs/FIQs + */ +#define local_irq_enable()					\ +	({							\ +	asm volatile(						\ +	"msr	daifclr, #3"					\ +	:							\ +	:							\ +	: "memory");						\ +	}) + +/* + * Disable IRQs/FIQs + */ +#define local_irq_disable()					\ +	({							\ +	asm volatile(						\ +	"msr	daifset, #3"					\ +	:							\ +	:							\ +	: "memory");						\ +	}) + +#else	/* CONFIG_ARM64 */ +  #define local_irq_save(x)					\  	({							\  		unsigned long temp;				\ @@ -107,7 +161,10 @@  	: "r" (x)						\  	: "memory") -#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +#endif	/* CONFIG_ARM64 */ + +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) || \ +	defined(CONFIG_ARM64)  /*   * On the StrongARM, "swp" is terminally broken since it bypasses the   * cache totally.  This means that the cache becomes inconsistent, and, diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 760345f84..4178f8cf7 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -1,6 +1,86 @@  #ifndef __ASM_ARM_SYSTEM_H  #define __ASM_ARM_SYSTEM_H +#ifdef CONFIG_ARM64 + +/* + * SCTLR_EL1/SCTLR_EL2/SCTLR_EL3 bits definitions + */ +#define CR_M		(1 << 0)	/* MMU enable			*/ +#define CR_A		(1 << 1)	/* Alignment abort enable	*/ +#define CR_C		(1 << 2)	/* Dcache enable		*/ +#define CR_SA		(1 << 3)	/* Stack Alignment Check Enable	*/ +#define CR_I		(1 << 12)	/* Icache enable		*/ +#define CR_WXN		(1 << 19)	/* Write Permision Imply XN	*/ +#define CR_EE		(1 << 25)	/* Exception (Big) Endian	*/ + +#define PGTABLE_SIZE	(0x10000) + +#ifndef __ASSEMBLY__ + +#define isb()				\ +	({asm volatile(			\ +	"isb" : : : "memory");		\ +	}) + +#define wfi()				\ +	({asm volatile(			\ +	"wfi" : : : "memory");		\ +	}) + +static inline unsigned int current_el(void) +{ +	unsigned int el; +	asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc"); +	return el >> 2; +} + +static inline unsigned int get_sctlr(void) +{ +	unsigned int el, val; + +	el = current_el(); +	if (el == 1) +		asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc"); +	else if (el == 2) +		asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); +	else +		asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc"); + +	return val; +} + +static inline void set_sctlr(unsigned int val) +{ +	unsigned int el; + +	el = current_el(); +	if (el == 1) +		asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc"); +	else if (el == 2) +		asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc"); +	else +		asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc"); + +	asm volatile("isb"); +} + +void __asm_flush_dcache_all(void); +void __asm_flush_dcache_range(u64 start, u64 end); +void __asm_invalidate_tlb_all(void); +void __asm_invalidate_icache_all(void); + +void armv8_switch_to_el2(void); +void armv8_switch_to_el1(void); +void gic_init(void); +void gic_send_sgi(unsigned long sgino); +void wait_for_wakeup(void); +void smp_kick_all_cpus(void); + +#endif	/* __ASSEMBLY__ */ + +#else /* CONFIG_ARM64 */ +  #ifdef __KERNEL__  #define CPU_ARCH_UNKNOWN	0 @@ -45,6 +125,8 @@  #define CR_AFE	(1 << 29)	/* Access flag enable			*/  #define CR_TE	(1 << 30)	/* Thumb exception enable		*/ +#define PGTABLE_SIZE		(4096 * 4) +  /*   * This is used to ensure the compiler did actually allocate the register we   * asked it for some inline assembly sequences.  Apparently we can't trust @@ -132,4 +214,6 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);  #endif /* __KERNEL__ */ +#endif /* CONFIG_ARM64 */ +  #endif diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h index 71dc049da..2326420a7 100644 --- a/arch/arm/include/asm/types.h +++ b/arch/arm/include/asm/types.h @@ -39,7 +39,11 @@ typedef unsigned int u32;  typedef signed long long s64;  typedef unsigned long long u64; +#ifdef	CONFIG_ARM64 +#define BITS_PER_LONG 64 +#else	/* CONFIG_ARM64 */  #define BITS_PER_LONG 32 +#endif	/* CONFIG_ARM64 */  /* Dma addresses are 32-bits wide.  */ diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h index 2b5fce86a..cb81232b8 100644 --- a/arch/arm/include/asm/u-boot.h +++ b/arch/arm/include/asm/u-boot.h @@ -44,6 +44,10 @@ typedef struct bd_info {  #endif /* !CONFIG_SYS_GENERIC_BOARD */  /* For image.h:image_check_target_arch() */ +#ifndef CONFIG_ARM64  #define IH_ARCH_DEFAULT IH_ARCH_ARM +#else +#define IH_ARCH_DEFAULT IH_ARCH_ARM64 +#endif  #endif	/* _U_BOOT_H_ */ diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h index 44593a894..0a228fb8e 100644 --- a/arch/arm/include/asm/unaligned.h +++ b/arch/arm/include/asm/unaligned.h @@ -8,7 +8,7 @@  /*   * Select endianness   */ -#ifndef __ARMEB__ +#if __BYTE_ORDER == __LITTLE_ENDIAN  #define get_unaligned	__get_unaligned_le  #define put_unaligned	__put_unaligned_le  #else diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 679f19a23..321997c33 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -17,14 +17,22 @@ lib-y	+= _umodsi3.o  lib-y	+= div0.o  endif -obj-y += crt0.o +ifdef CONFIG_ARM64 +obj-y	+= crt0_64.o +else +obj-y	+= crt0.o +endif  ifndef CONFIG_SPL_BUILD -obj-y += relocate.o +ifdef CONFIG_ARM64 +obj-y	+= relocate_64.o +else +obj-y	+= relocate.o +endif  ifndef CONFIG_SYS_GENERIC_BOARD  obj-y	+= board.o  endif -obj-y += sections.o +obj-y	+= sections.o  obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o  obj-$(CONFIG_CMD_BOOTM) += bootm.o @@ -35,11 +43,17 @@ else  obj-$(CONFIG_SPL_FRAMEWORK) += spl.o  endif +ifdef CONFIG_ARM64 +obj-y	+= interrupts_64.o +else  obj-y	+= interrupts.o +endif  obj-y	+= reset.o  obj-y	+= cache.o +ifndef CONFIG_ARM64  obj-y	+= cache-cp15.o +endif  # For EABI conformant tool chains, provide eabi_compat()  ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 9c72a5353..b770e25d8 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -344,7 +344,7 @@ void board_init_f(ulong bootflag)  #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))  	/* reserve TLB table */ -	gd->arch.tlb_size = 4096 * 4; +	gd->arch.tlb_size = PGTABLE_SIZE;  	addr -= gd->arch.tlb_size;  	/* round down to next 64 kB limit */ @@ -419,6 +419,7 @@ void board_init_f(ulong bootflag)  	}  #endif +#ifndef CONFIG_ARM64  	/* setup stackpointer for exeptions */  	gd->irq_sp = addr_sp;  #ifdef CONFIG_USE_IRQ @@ -431,6 +432,10 @@ void board_init_f(ulong bootflag)  	/* 8-byte alignment for ABI compliance */  	addr_sp &= ~0x07; +#else	/* CONFIG_ARM64 */ +	/* 16-byte alignment for ABI compliance */ +	addr_sp &= ~0x0f; +#endif	/* CONFIG_ARM64 */  #else  	addr_sp += 128;	/* leave 32 words for abort-stack   */  	gd->irq_sp = addr_sp; diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index f476a8970..a8295bf1f 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -196,6 +196,14 @@ static void do_nonsec_virt_switch(void)  		debug("entered non-secure state\n");  #endif  #endif + +#ifdef CONFIG_ARM64 +	smp_kick_all_cpus(); +	armv8_switch_to_el2(); +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 +	armv8_switch_to_el1(); +#endif +#endif  }  /* Subcommand: PREP */ @@ -240,6 +248,21 @@ static void boot_prep_linux(bootm_headers_t *images)  /* Subcommand: GO */  static void boot_jump_linux(bootm_headers_t *images, int flag)  { +#ifdef CONFIG_ARM64 +	void (*kernel_entry)(void *fdt_addr); +	int fake = (flag & BOOTM_STATE_OS_FAKE_GO); + +	kernel_entry = (void (*)(void *fdt_addr))images->ep; + +	debug("## Transferring control to Linux (at address %lx)...\n", +		(ulong) kernel_entry); +	bootstage_mark(BOOTSTAGE_ID_RUN_OS); + +	announce_and_cleanup(fake); + +	if (!fake) +		kernel_entry(images->ft_addr); +#else  	unsigned long machid = gd->bd->bi_arch_number;  	char *s;  	void (*kernel_entry)(int zero, int arch, uint params); @@ -266,6 +289,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)  	if (!fake)  		kernel_entry(0, machid, r2); +#endif  }  /* Main Entry point for arm bootm implementation @@ -326,3 +350,26 @@ int bootz_setup(ulong image, ulong *start, ulong *end)  }  #endif	/* CONFIG_CMD_BOOTZ */ + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) +	int off; + +	if (images->ft_addr) { +		off = fdt_path_offset(images->ft_addr, "/memory"); +		if (off < 0) { +			if (arch_fixup_memory_node(images->ft_addr)) +				puts("## WARNING: fixup memory failed!\n"); +		} +	} +#endif +	cleanup_before_linux(); +} +void boot_jump_vxworks(bootm_headers_t *images) +{ +	/* ARM VxWorks requires device tree physical address to be passed */ +	((void (*)(void *))images->ep)(images->ft_addr); +} +#endif diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index ac54b9359..dfc2de9a6 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -67,7 +67,7 @@ ENTRY(_main)  	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)  #endif  	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */ -	sub	sp, #GD_SIZE	/* allocate one GD above SP */ +	sub	sp, sp, #GD_SIZE	/* allocate one GD above SP */  	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */  	mov	r9, sp		/* GD is above SP */  	mov	r0, #0 diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S new file mode 100644 index 000000000..77563967e --- /dev/null +++ b/arch/arm/lib/crt0_64.S @@ -0,0 +1,113 @@ +/* + * crt0 - C-runtime startup Code for AArch64 U-Boot + * + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * (C) Copyright 2012 + * Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include <asm-offsets.h> +#include <asm/macro.h> +#include <linux/linkage.h> + +/* + * This file handles the target-independent stages of the U-Boot + * start-up where a C runtime environment is needed. Its entry point + * is _main and is branched into from the target's start.S file. + * + * _main execution sequence is: + * + * 1. Set up initial environment for calling board_init_f(). + *    This environment only provides a stack and a place to store + *    the GD ('global data') structure, both located in some readily + *    available RAM (SRAM, locked cache...). In this context, VARIABLE + *    global data, initialized or not (BSS), are UNAVAILABLE; only + *    CONSTANT initialized data are available. + * + * 2. Call board_init_f(). This function prepares the hardware for + *    execution from system RAM (DRAM, DDR...) As system RAM may not + *    be available yet, , board_init_f() must use the current GD to + *    store any data which must be passed on to later stages. These + *    data include the relocation destination, the future stack, and + *    the future GD location. + * + * (the following applies only to non-SPL builds) + * + * 3. Set up intermediate environment where the stack and GD are the + *    ones allocated by board_init_f() in system RAM, but BSS and + *    initialized non-const data are still not available. + * + * 4. Call relocate_code(). This function relocates U-Boot from its + *    current location into the relocation destination computed by + *    board_init_f(). + * + * 5. Set up final environment for calling board_init_r(). This + *    environment has BSS (initialized to 0), initialized non-const + *    data (initialized to their intended value), and stack in system + *    RAM. GD has retained values set by board_init_f(). Some CPUs + *    have some work left to do at this point regarding memory, so + *    call c_runtime_cpu_setup. + * + * 6. Branch to board_init_r(). + */ + +ENTRY(_main) + +/* + * Set up initial C runtime environment and call board_init_f(0). + */ +	ldr	x0, =(CONFIG_SYS_INIT_SP_ADDR) +	sub	x0, x0, #GD_SIZE	/* allocate one GD above SP */ +	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance */ +	mov	x18, sp			/* GD is above SP */ +	mov	x0, #0 +	bl	board_init_f + +/* + * Set up intermediate environment (new sp and gd) and call + * relocate_code(addr_moni). Trick here is that we'll return + * 'here' but relocated. + */ +	ldr	x0, [x18, #GD_START_ADDR_SP]	/* x0 <- gd->start_addr_sp */ +	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance */ +	ldr	x18, [x18, #GD_BD]		/* x18 <- gd->bd */ +	sub	x18, x18, #GD_SIZE		/* new GD is below bd */ + +	adr	lr, relocation_return +	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */ +	add	lr, lr, x9	/* new return address after relocation */ +	ldr	x0, [x18, #GD_RELOCADDR]	/* x0 <- gd->relocaddr */ +	b	relocate_code + +relocation_return: + +/* + * Set up final (full) environment + */ +	bl	c_runtime_cpu_setup		/* still call old routine */ + +/* + * Clear BSS section + */ +	ldr	x0, =__bss_start		/* this is auto-relocated! */ +	ldr	x1, =__bss_end			/* this is auto-relocated! */ +	mov	x2, #0 +clear_loop: +	str	x2, [x0] +	add	x0, x0, #8 +	cmp	x0, x1 +	b.lo	clear_loop + +	/* call board_init_r(gd_t *id, ulong dest_addr) */ +	mov	x0, x18				/* gd_t */ +	ldr	x1, [x18, #GD_RELOCADDR]	/* dest_addr */ +	b	board_init_r			/* PC relative jump */ + +	/* NOTREACHED - board_init_r() does not return */ + +ENDPROC(_main) diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c new file mode 100644 index 000000000..b47672255 --- /dev/null +++ b/arch/arm/lib/interrupts_64.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <linux/compiler.h> + + +int interrupt_init(void) +{ +	return 0; +} + +void enable_interrupts(void) +{ +	return; +} + +int disable_interrupts(void) +{ +	return 0; +} + +void show_regs(struct pt_regs *regs) +{ +	int i; + +	printf("ELR:     %lx\n", regs->elr); +	printf("LR:      %lx\n", regs->regs[30]); +	for (i = 0; i < 29; i += 2) +		printf("x%-2d: %016lx x%-2d: %016lx\n", +		       i, regs->regs[i], i+1, regs->regs[i+1]); +	printf("\n"); +} + +/* + * do_bad_sync handles the impossible case in the Synchronous Abort vector. + */ +void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_bad_irq handles the impossible case in the Irq vector. + */ +void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_bad_fiq handles the impossible case in the Fiq vector. + */ +void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_bad_error handles the impossible case in the Error vector. + */ +void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_sync handles the Synchronous Abort exception. + */ +void do_sync(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_irq handles the Irq exception. + */ +void do_irq(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("\"Irq\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_fiq handles the Fiq exception. + */ +void do_fiq(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("\"Fiq\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} + +/* + * do_error handles the Error exception. + * Errors are more likely to be processor specific, + * it is defined with weak attribute and can be redefined + * in processor specific code. + */ +void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) +{ +	printf("\"Error\" handler, esr 0x%08x\n", esr); +	show_regs(pt_regs); +	panic("Resetting CPU ...\n"); +} diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S new file mode 100644 index 000000000..7fba9e278 --- /dev/null +++ b/arch/arm/lib/relocate_64.S @@ -0,0 +1,58 @@ +/* + * relocate - common relocation function for AArch64 U-Boot + * + * (C) Copyright 2013 + * Albert ARIBAUD <albert.u.boot@aribaud.net> + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> + +/* + * void relocate_code (addr_moni) + * + * This function relocates the monitor code. + * x0 holds the destination address. + */ +ENTRY(relocate_code) +	/* +	 * Copy u-boot from flash to RAM +	 */ +	ldr	x1, =__image_copy_start	/* x1 <- SRC &__image_copy_start */ +	subs	x9, x0, x1		/* x9 <- relocation offset */ +	b.eq	relocate_done		/* skip relocation */ +	ldr	x2, =__image_copy_end	/* x2 <- SRC &__image_copy_end */ + +copy_loop: +	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */ +	stp	x10, x11, [x0], #16	/* copy to   target address [x0] */ +	cmp	x1, x2			/* until source end address [x2] */ +	b.lo	copy_loop + +	/* +	 * Fix .rela.dyn relocations +	 */ +	ldr	x2, =__rel_dyn_start	/* x2 <- SRC &__rel_dyn_start */ +	ldr	x3, =__rel_dyn_end	/* x3 <- SRC &__rel_dyn_end */ +fixloop: +	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */ +	ldr	x4, [x2], #8		/* x4 <- addend */ +	and	x1, x1, #0xffffffff +	cmp	x1, #1027		/* relative fixup? */ +	bne	fixnext + +	/* relative fix: store addend plus offset at dest location */ +	add	x0, x0, x9 +	add	x4, x4, x9 +	str	x4, [x0] +fixnext: +	cmp	x2, x3 +	b.lo	fixloop + +relocate_done: +	ret +ENDPROC(relocate_code) diff --git a/arch/blackfin/config.mk b/arch/blackfin/config.mk index 35f871662..73fa79855 100644 --- a/arch/blackfin/config.mk +++ b/arch/blackfin/config.mk @@ -14,9 +14,9 @@ CONFIG_BFIN_CPU := \  	$(shell awk '$$2 == "CONFIG_BFIN_CPU" { print $$3 }' \  		$(src)include/configs/$(BOARD).h)  else -CONFIG_BFIN_CPU := $(strip $(subst ",,$(CONFIG_BFIN_CPU))) +CONFIG_BFIN_CPU := $(strip $(CONFIG_BFIN_CPU:"%"=%))  endif -CONFIG_BFIN_BOOT_MODE := $(strip $(subst ",,$(CONFIG_BFIN_BOOT_MODE))) +CONFIG_BFIN_BOOT_MODE := $(strip $(CONFIG_BFIN_BOOT_MODE:"%"=%))  PLATFORM_RELFLAGS += -ffixed-P3 -fomit-frame-pointer -mno-fdpic  PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index ffaf1017d..2e640afc4 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -18,8 +18,6 @@  #include <asm/mach-common/bits/core.h>  #include <asm/serial.h> -#define BUG() while (1) asm volatile("emuexcpt;"); -  #ifndef __ADSPBF60x__  #include <asm/mach-common/bits/ebiu.h>  #include <asm/mach-common/bits/pll.h> @@ -147,8 +145,6 @@ static struct ddr_config ddr_config_table[] = {  __attribute__((always_inline))  static inline void serial_init(void)  { -	uint32_t uart_base = UART_BASE; -  #if defined(__ADSPBF54x__) || defined(__ADSPBF60x__)  # ifdef BFIN_BOOT_UART_USE_RTS  #  define BFIN_UART_USE_RTS 1 @@ -156,6 +152,7 @@ static inline void serial_init(void)  #  define BFIN_UART_USE_RTS 0  # endif  	if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { +		uint32_t uart_base = UART_BASE;  		size_t i;  		/* force RTS rather than relying on auto RTS */ @@ -195,8 +192,8 @@ static inline void serial_init(void)  #if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS  	if (BFIN_DEBUG_EARLY_SERIAL) { -		serial_early_init(uart_base); -		serial_early_set_baud(uart_base, CONFIG_BAUDRATE); +		serial_early_init(UART_BASE); +		serial_early_set_baud(UART_BASE, CONFIG_BAUDRATE);  	}  #endif  } @@ -547,7 +544,7 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)  __attribute__((always_inline)) static inline u16  program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)  { -	u16 vr_ctl; +	u16 vr_ctl = 0;  	serial_putc('a'); @@ -731,6 +728,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB)  	serial_putc('a'); +	if (BFIN_DEBUG_EARLY_SERIAL || +		CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {  #ifdef __ADSPBF60x__  	sdivR = bfin_read_CGU_DIV();  	sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7); @@ -744,6 +743,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB)  	divisor = vcoB * sdivR;  	quotient = early_division(dividend, divisor);  	serial_early_put_div(quotient - ANOMALY_05000230); +	} +  	serial_putc('c');  } @@ -913,7 +914,8 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs)  			continue;  		serial_putc('z'); -		uint32_t *hibernate_magic = bfin_read32(DPM0_RESTORE4); +		uint32_t *hibernate_magic = +			(uint32_t *)bfin_read32(DPM0_RESTORE4);  		SSYNC(); /* make sure memory controller is done */  		if (hibernate_magic[0] == 0xDEADBEEF) {  			serial_putc('c'); diff --git a/arch/blackfin/include/asm/blackfin_local.h b/arch/blackfin/include/asm/blackfin_local.h index 8ea8cde69..4d6eeab0e 100644 --- a/arch/blackfin/include/asm/blackfin_local.h +++ b/arch/blackfin/include/asm/blackfin_local.h @@ -81,6 +81,8 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);  # define NOP_PAD_ANOMALY_05000198  #endif +#define BFIN_BUG() while (1) asm volatile("emuexcpt;"); +  #define _bfin_readX(addr, size, asm_size, asm_ext) ({ \  	u32 __v; \  	__asm__ __volatile__( \ @@ -111,7 +113,7 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);  	sizeof(*(addr)) == 1 ? bfin_read8(addr)  : \  	sizeof(*(addr)) == 2 ? bfin_read16(addr) : \  	sizeof(*(addr)) == 4 ? bfin_read32(addr) : \ -	({ BUG(); 0; }); \ +	({ BFIN_BUG(); 0; }); \  })  #define bfin_write(addr, val) \  do { \ @@ -119,7 +121,8 @@ do { \  	case 1: bfin_write8(addr, val);  break; \  	case 2: bfin_write16(addr, val); break; \  	case 4: bfin_write32(addr, val); break; \ -	default: BUG(); \ +	default: \ +		BFIN_BUG(); \  	} \  } while (0) diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 17d1f468d..392d72d23 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -19,6 +19,7 @@  #include <net.h>  #include <status_led.h>  #include <version.h> +#include <watchdog.h>  #include <asm/cplb.h>  #include <asm/mach-common/bits/mpu.h> diff --git a/arch/blackfin/lib/clocks.c b/arch/blackfin/lib/clocks.c index 97795e11a..7ed56a727 100644 --- a/arch/blackfin/lib/clocks.c +++ b/arch/blackfin/lib/clocks.c @@ -36,7 +36,10 @@ u_long get_vco(void)  u_long get_cclk(void)  {  	static u_long cached_cclk_pll_div, cached_cclk; -	u_long div, csel, ssel; +	u_long div, csel; +#ifndef CGU_DIV +	u_long ssel; +#endif  	if (pll_is_bypassed())  		return CONFIG_CLKIN_HZ; diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk index e6bb93572..f75c3bf18 100644 --- a/arch/powerpc/config.mk +++ b/arch/powerpc/config.mk @@ -9,8 +9,9 @@ CROSS_COMPILE ?= ppc_8xx-  CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000  LDFLAGS_FINAL += --gc-sections -PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections -PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ +PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections \ +								-meabi +PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ -ffixed-r2  PLATFORM_LDFLAGS  += -n  # Support generic board on PPC diff --git a/arch/powerpc/cpu/74xx_7xx/config.mk b/arch/powerpc/cpu/74xx_7xx/config.mk index 905319160..96812a02d 100644 --- a/arch/powerpc/cpu/74xx_7xx/config.mk +++ b/arch/powerpc/cpu/74xx_7xx/config.mk @@ -5,6 +5,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -ffixed-r2 -mstring +PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -mstring diff --git a/arch/powerpc/cpu/Makefile b/arch/powerpc/cpu/Makefile index d630abe1d..88b5298be 100644 --- a/arch/powerpc/cpu/Makefile +++ b/arch/powerpc/cpu/Makefile @@ -1,3 +1,3 @@ -ifneq ($(filter mpc83xx mpc85xx mpc86xx,$(CPU)),) -obj-y += mpc8xxx/ -endif +obj-$(CONFIG_MPC83xx) += mpc8xxx/ +obj-$(CONFIG_MPC85xx) += mpc8xxx/ +obj-$(CONFIG_MPC86xx) += mpc8xxx/ diff --git a/arch/powerpc/cpu/mpc512x/config.mk b/arch/powerpc/cpu/mpc512x/config.mk index 04717a485..03759e662 100644 --- a/arch/powerpc/cpu/mpc512x/config.mk +++ b/arch/powerpc/cpu/mpc512x/config.mk @@ -4,7 +4,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \ -			-ffixed-r2 -msoft-float -mcpu=603e +PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 -msoft-float -mcpu=603e diff --git a/arch/powerpc/cpu/mpc5xx/config.mk b/arch/powerpc/cpu/mpc5xx/config.mk index b33f17a1b..31e2dc987 100644 --- a/arch/powerpc/cpu/mpc5xx/config.mk +++ b/arch/powerpc/cpu/mpc5xx/config.mk @@ -5,6 +5,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS +=	-meabi - -PLATFORM_CPPFLAGS +=	-DCONFIG_5xx -ffixed-r2 -mpowerpc -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_5xx -mpowerpc -msoft-float diff --git a/arch/powerpc/cpu/mpc5xxx/config.mk b/arch/powerpc/cpu/mpc5xxx/config.mk index 57bdd2d25..3384f6ffc 100644 --- a/arch/powerpc/cpu/mpc5xxx/config.mk +++ b/arch/powerpc/cpu/mpc5xxx/config.mk @@ -5,7 +5,5 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 \ +PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx \  		     -mstring -mcpu=603e -mmultiple diff --git a/arch/powerpc/cpu/mpc824x/config.mk b/arch/powerpc/cpu/mpc824x/config.mk index ef605f079..a224bc8e7 100644 --- a/arch/powerpc/cpu/mpc824x/config.mk +++ b/arch/powerpc/cpu/mpc824x/config.mk @@ -5,6 +5,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -mstring -mcpu=603e -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -mstring -mcpu=603e -msoft-float diff --git a/arch/powerpc/cpu/mpc8260/config.mk b/arch/powerpc/cpu/mpc8260/config.mk index 91b0497cc..dfac710e6 100644 --- a/arch/powerpc/cpu/mpc8260/config.mk +++ b/arch/powerpc/cpu/mpc8260/config.mk @@ -5,7 +5,5 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 -ffixed-r2 \ +PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 \  		     -mstring -mcpu=603e -mmultiple diff --git a/arch/powerpc/cpu/mpc83xx/config.mk b/arch/powerpc/cpu/mpc83xx/config.mk index c16a00376..dfce4d53b 100644 --- a/arch/powerpc/cpu/mpc83xx/config.mk +++ b/arch/powerpc/cpu/mpc83xx/config.mk @@ -4,7 +4,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 \ -			-ffixed-r2 -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 -msoft-float diff --git a/arch/powerpc/cpu/mpc85xx/config.mk b/arch/powerpc/cpu/mpc85xx/config.mk index 9eef539e5..72c964cd1 100644 --- a/arch/powerpc/cpu/mpc85xx/config.mk +++ b/arch/powerpc/cpu/mpc85xx/config.mk @@ -5,13 +5,10 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -ffixed-r2 -Wa,-me500 -msoft-float -mno-string +PLATFORM_CPPFLAGS += -Wa,-me500 -msoft-float -mno-string  # -mspe=yes is needed to have -mno-spe accepted by a buggy GCC;  # see "[PATCH,rs6000] make -mno-spe work as expected" on  # http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00311.html -PF_CPPFLAGS_SPE := $(call cc-option,-mspe=yes) \ +PLATFORM_CPPFLAGS += $(call cc-option,-mspe=yes) \  		   $(call cc-option,-mno-spe) -PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_SPE) diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 46ae80c4d..35867dffd 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -74,12 +74,33 @@ void get_sys_info(sys_info_t *sys_info)  	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];  	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;  	uint mem_pll_rat; +#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK +	uint single_src; +#endif  	sys_info->freq_systembus = sysclk; +#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK +	/* +	 * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS +	 * are driven by separate DDR Refclock or single source +	 * differential clock. +	 */ +	single_src = (in_be32(&gur->rcwsr[5]) >> +		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) & +		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK; +	/* +	 * For single source clocking, both ddrclock and syclock +	 * are driven by differential sysclock. +	 */ +	if (single_src == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK) { +		printf("Single Source Clock Configuration\n"); +		sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ; +	} else +#endif  #ifdef CONFIG_DDR_CLK_FREQ -	sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; +		sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;  #else -	sys_info->freq_ddrbus = sysclk; +		sys_info->freq_ddrbus = sysclk;  #endif  	sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; @@ -229,6 +250,9 @@ void get_sys_info(sys_info_t *sys_info)  	case 4:  		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4;  		break; +	case 5: +		sys_info->freq_fman[1] = sys_info->freq_systembus; +		break;  	case 6:  		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2;  		break; diff --git a/arch/powerpc/cpu/mpc86xx/config.mk b/arch/powerpc/cpu/mpc86xx/config.mk index 5dbf6a847..69a0b96ea 100644 --- a/arch/powerpc/cpu/mpc86xx/config.mk +++ b/arch/powerpc/cpu/mpc86xx/config.mk @@ -5,7 +5,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -ffixed-r2 -mstring -PLATFORM_CPPFLAGS += -maltivec -mabi=altivec -msoft-float +PLATFORM_CPPFLAGS += -mstring -maltivec -mabi=altivec -msoft-float diff --git a/arch/powerpc/cpu/mpc8xx/config.mk b/arch/powerpc/cpu/mpc8xx/config.mk index c04e7338c..ee2c88366 100644 --- a/arch/powerpc/cpu/mpc8xx/config.mk +++ b/arch/powerpc/cpu/mpc8xx/config.mk @@ -5,6 +5,4 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_8xx -ffixed-r2 -mstring -mcpu=860 -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_8xx -mstring -mcpu=860 -msoft-float diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile index f66ee2e42..e95539e0a 100644 --- a/arch/powerpc/cpu/mpc8xxx/Makefile +++ b/arch/powerpc/cpu/mpc8xxx/Makefile @@ -19,10 +19,8 @@ ifdef MINIMAL  obj-$(CONFIG_FSL_LAW) += law.o  else - -ifneq ($(CPU),mpc83xx) -obj-y	+= cpu.o -endif +obj-$(CONFIG_MPC85xx) += cpu.o +obj-$(CONFIG_MPC86xx) += cpu.o  obj-$(CONFIG_OF_LIBFDT) += fdt.o  obj-$(CONFIG_FSL_LBC) += fsl_lbc.o diff --git a/arch/powerpc/cpu/ppc4xx/config.mk b/arch/powerpc/cpu/ppc4xx/config.mk index c2b0f9aab..71c2a6c72 100644 --- a/arch/powerpc/cpu/ppc4xx/config.mk +++ b/arch/powerpc/cpu/ppc4xx/config.mk @@ -5,8 +5,7 @@  # SPDX-License-Identifier:	GPL-2.0+  # -PLATFORM_RELFLAGS += -meabi -PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -mstring -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_4xx -mstring -msoft-float  cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/')  is440:=$(shell grep CONFIG_440 $(TOPDIR)/include/$(cfg)) diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 99e16bdf6..54ce2f053 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -711,7 +711,8 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)  #define CONFIG_FM_PLAT_CLK_DIV	1  #define CONFIG_SYS_FM1_CLK		CONFIG_FM_PLAT_CLK_DIV  #define CONFIG_SYS_FM_MURAM_SIZE	0x30000 -#define CONFIG_SYS_FSL_TBCLK_DIV	32 +#define CONFIG_SYS_FSL_SINGLE_SOURCE_CLK +#define CONFIG_SYS_FSL_TBCLK_DIV	16  #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.4"  #define CONFIG_SYS_FSL_USB1_PHY_ENABLE  #define CONFIG_SYS_FSL_USB2_PHY_ENABLE @@ -745,7 +746,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)  #define CONFIG_SYS_NUM_FM1_DTSEC	6  #define CONFIG_SYS_NUM_FM1_10GEC	2  #endif -#define CONFIG_SYS_FSL_NUM_USB_CTRLS	2 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2  #define CONFIG_NUM_DDR_CONTROLLERS	1  #define CONFIG_PME_PLAT_CLK_DIV		1  #define CONFIG_SYS_PME_CLK		CONFIG_PME_PLAT_CLK_DIV diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 672e8c665..68c3c8245 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1774,6 +1774,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)  #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S3_PLL2	0x00040000  #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL1	0x00020000  #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL2	0x00010000 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT 4 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK	0x00000011 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK	1  #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */  #define FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT	17 diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e7153b048..41fc8f7ff 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;  extern ulong get_effective_memsize(void);  static ulong get_sp (void); +extern void ft_fixup_num_cores(void *blob);  static void set_clocks_in_mhz (bd_t *kbd);  #ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE @@ -277,3 +278,58 @@ static void set_clocks_in_mhz (bd_t *kbd)  #endif /* CONFIG_MPC5xxx */  	}  } + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) +	int off; +	u64 base, size; + +	if (!images->ft_addr) +		return; + +	base = (u64)gd->bd->bi_memstart; +	size = (u64)gd->bd->bi_memsize; + +	off = fdt_path_offset(images->ft_addr, "/memory"); +	if (off < 0) +		fdt_fixup_memory(images->ft_addr, base, size); + +#if defined(CONFIG_MP) +#if defined(CONFIG_MPC85xx) +	ft_fixup_cpu(images->ft_addr, base + size); +	ft_fixup_num_cores(images->ft_addr); +#elif defined(CONFIG_MPC86xx) +	off = fdt_add_mem_rsv(images->ft_addr, +			determine_mp_bootpg(NULL), (u64)4096); +	if (off < 0) +		printf("## WARNING %s: %s\n", __func__, fdt_strerror(off)); +	ft_fixup_num_cores(images->ft_addr); +#endif +	flush_cache((unsigned long)images->ft_addr, images->ft_len); +#endif +#endif +} + +void boot_jump_vxworks(bootm_headers_t *images) +{ +	/* PowerPC VxWorks boot interface conforms to the ePAPR standard +	 * general purpuse registers: +	 * +	 *	r3: Effective address of the device tree image +	 *	r4: 0 +	 *	r5: 0 +	 *	r6: ePAPR magic value +	 *	r7: shall be the size of the boot IMA in bytes +	 *	r8: 0 +	 *	r9: 0 +	 *	TCR: WRC = 0, no watchdog timer reset will occur +	 */ +	WATCHDOG_RESET(); + +	((void (*)(void *, ulong, ulong, ulong, +		ulong, ulong, ulong))images->ep)(images->ft_addr, +		0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0); +} +#endif diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index cfc1fda1e..38019e0b4 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -5,13 +5,23 @@  #include <common.h>  #include <os.h> +#include <asm/state.h>  DECLARE_GLOBAL_DATA_PTR; -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +void reset_cpu(ulong ignored)  { +	if (state_uninit()) +		os_exit(2); +  	/* This is considered normal termination for now */  	os_exit(0); +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	reset_cpu(0); +  	return 0;  } @@ -28,7 +38,14 @@ unsigned long __attribute__((no_instrument_function)) timer_get_us(void)  int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)  { -	return -1; +	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { +		bootstage_mark(BOOTSTAGE_ID_RUN_OS); +		printf("## Transferring control to Linux (at address %08lx)...\n", +		       images->ep); +		reset_cpu(0); +	} + +	return 0;  }  int cleanup_before_linux(void) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 26f44cb59..725b50517 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -27,6 +27,10 @@  /* Operating System Interface */ +struct os_mem_hdr { +	size_t length;		/* number of bytes in the block */ +}; +  ssize_t os_read(int fd, void *buf, size_t count)  {  	return read(fd, buf, count); @@ -128,8 +132,45 @@ void os_tty_raw(int fd)  void *os_malloc(size_t length)  { -	return mmap(NULL, length, PROT_READ | PROT_WRITE, -			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +	struct os_mem_hdr *hdr; + +	hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE, +		   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +	if (hdr == MAP_FAILED) +		return NULL; +	hdr->length = length; + +	return hdr + 1; +} + +void *os_free(void *ptr) +{ +	struct os_mem_hdr *hdr = ptr; + +	hdr--; +	if (ptr) +		munmap(hdr, hdr->length + sizeof(*hdr)); +} + +void *os_realloc(void *ptr, size_t length) +{ +	struct os_mem_hdr *hdr = ptr; +	void *buf = NULL; + +	hdr--; +	if (length != 0) { +		buf = os_malloc(length); +		if (!buf) +			return buf; +		if (ptr) { +			if (length > hdr->length) +				length = hdr->length; +			memcpy(buf, ptr, length); +		} +	} +	os_free(ptr); + +	return buf;  }  void os_usleep(unsigned long usec) @@ -347,3 +388,53 @@ ssize_t os_get_filesize(const char *fname)  		return ret;  	return buf.st_size;  } + +void os_putc(int ch) +{ +	putchar(ch); +} + +void os_puts(const char *str) +{ +	while (*str) +		os_putc(*str++); +} + +int os_write_ram_buf(const char *fname) +{ +	struct sandbox_state *state = state_get_current(); +	int fd, ret; + +	fd = open(fname, O_CREAT | O_WRONLY, 0777); +	if (fd < 0) +		return -ENOENT; +	ret = write(fd, state->ram_buf, state->ram_size); +	close(fd); +	if (ret != state->ram_size) +		return -EIO; + +	return 0; +} + +int os_read_ram_buf(const char *fname) +{ +	struct sandbox_state *state = state_get_current(); +	int fd, ret; +	int size; + +	size = os_get_filesize(fname); +	if (size < 0) +		return -ENOENT; +	if (size != state->ram_size) +		return -ENOSPC; +	fd = open(fname, O_RDONLY); +	if (fd < 0) +		return -ENOENT; + +	ret = read(fd, state->ram_buf, state->ram_size); +	close(fd); +	if (ret != state->ram_size) +		return -EIO; + +	return 0; +} diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 1b1545478..1df21d49f 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -4,11 +4,12 @@   */  #include <common.h> +#include <os.h>  #include <asm/getopt.h>  #include <asm/sections.h>  #include <asm/state.h> -#include <os.h> +DECLARE_GLOBAL_DATA_PTR;  int sandbox_early_getopt_check(void)  { @@ -50,9 +51,9 @@ int sandbox_early_getopt_check(void)  		/* then the long flag */  		if (opt->has_arg) -			printf("--%-*s", max_noarg_len, opt->flag); -		else  			printf("--%-*s <arg> ", max_arg_len, opt->flag); +		else +			printf("--%-*s", max_noarg_len, opt->flag);  		/* finally the help text */  		printf("  %s\n", opt->help); @@ -75,7 +76,8 @@ int sandbox_main_loop_init(void)  	/* Execute command if required */  	if (state->cmd) {  		run_command_list(state->cmd, -1, 0); -		os_exit(state->exit_type); +		if (!state->interactive) +			os_exit(state->exit_type);  	}  	return 0; @@ -96,25 +98,93 @@ static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)  }  SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); -int main(int argc, char *argv[]) +static int sandbox_cmdline_cb_interactive(struct sandbox_state *state, +					  const char *arg) +{ +	state->interactive = true; +	return 0; +} + +SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode"); + +static int sandbox_cmdline_cb_memory(struct sandbox_state *state, +				     const char *arg)  { -	struct sandbox_state *state;  	int err; -	err = state_init(); -	if (err) +	/* For now assume we always want to write it */ +	state->write_ram_buf = true; +	state->ram_buf_fname = arg; + +	if (os_read_ram_buf(arg)) { +		printf("Failed to read RAM buffer\n");  		return err; +	} + +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1, +			  "Read/write ram_buf memory contents from file"); + +static int sandbox_cmdline_cb_state(struct sandbox_state *state, +				    const char *arg) +{ +	state->state_fname = arg; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT"); + +static int sandbox_cmdline_cb_read(struct sandbox_state *state, +				   const char *arg) +{ +	state->read_state = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup"); + +static int sandbox_cmdline_cb_write(struct sandbox_state *state, +				    const char *arg) +{ +	state->write_state = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit"); + +static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state, +					     const char *arg) +{ +	state->ignore_missing_state_on_read = true; +	return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0, +			  "Ignore missing state on read"); + +int main(int argc, char *argv[]) +{ +	struct sandbox_state *state; +	int ret; + +	ret = state_init(); +	if (ret) +		goto err;  	state = state_get_current();  	if (os_parse_args(state, argc, argv))  		return 1; -	/* -	 * Do pre- and post-relocation init, then start up U-Boot. This will -	 * never return. -	 */ +	ret = sandbox_read_state(state, state->state_fname); +	if (ret) +		goto err; + +	/* Do pre- and post-relocation init */  	board_init_f(0); -	/* NOTREACHED - board_init_f() does not return */ +	board_init_r(gd->new_gd, 0); + +	/* NOTREACHED - board_init_r() does not return */  	return 0; + +err: +	printf("Error %d\n", ret); +	return 1;  } diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 56d504141..a145808a5 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -4,6 +4,9 @@   */  #include <common.h> +#include <errno.h> +#include <fdtdec.h> +#include <os.h>  #include <asm/state.h>  /* Main state record for the sandbox */ @@ -15,6 +18,324 @@ void state_record_exit(enum exit_type_id exit_type)  	state->exit_type = exit_type;  } +static int state_ensure_space(int extra_size) +{ +	void *blob = state->state_fdt; +	int used, size, free; +	void *buf; +	int ret; + +	used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob); +	size = fdt_totalsize(blob); +	free = size - used; +	if (free > extra_size) +		return 0; + +	size = used + extra_size; +	buf = os_malloc(size); +	if (!buf) +		return -ENOMEM; + +	ret = fdt_open_into(blob, buf, size); +	if (ret) { +		os_free(buf); +		return -EIO; +	} + +	os_free(blob); +	state->state_fdt = buf; +	return 0; +} + +static int state_read_file(struct sandbox_state *state, const char *fname) +{ +	int size; +	int ret; +	int fd; + +	size = os_get_filesize(fname); +	if (size < 0) { +		printf("Cannot find sandbox state file '%s'\n", fname); +		return -ENOENT; +	} +	state->state_fdt = os_malloc(size); +	if (!state->state_fdt) { +		puts("No memory to read sandbox state\n"); +		return -ENOMEM; +	} +	fd = os_open(fname, OS_O_RDONLY); +	if (fd < 0) { +		printf("Cannot open sandbox state file '%s'\n", fname); +		ret = -EPERM; +		goto err_open; +	} +	if (os_read(fd, state->state_fdt, size) != size) { +		printf("Cannot read sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_read; +	} +	os_close(fd); + +	return 0; +err_read: +	os_close(fd); +err_open: +	os_free(state->state_fdt); +	state->state_fdt = NULL; + +	return ret; +} + +/*** + * sandbox_read_state_nodes() - Read state associated with a driver + * + * This looks through all compatible nodes and calls the read function on + * each one, to read in the state. + * + * If nothing is found, it still calls the read function once, to set up a + * single global state for that driver. + * + * @state: Sandbox state + * @io: Method to use for reading state + * @blob: FDT containing state + * @return 0 if OK, -EINVAL if the read function returned failure + */ +int sandbox_read_state_nodes(struct sandbox_state *state, +			     struct sandbox_state_io *io, const void *blob) +{ +	int count; +	int node; +	int ret; + +	debug("   - read %s\n", io->name); +	if (!io->read) +		return 0; + +	node = -1; +	count = 0; +	while (blob) { +		node = fdt_node_offset_by_compatible(blob, node, io->compat); +		if (node < 0) +			return 0;	/* No more */ +		debug("   - read node '%s'\n", fdt_get_name(blob, node, NULL)); +		ret = io->read(blob, node); +		if (ret) { +			printf("Unable to read state for '%s'\n", io->compat); +			return -EINVAL; +		} +		count++; +	} + +	/* +	 * If we got no saved state, call the read function once without a +	 * node, to set up the global state. +	 */ +	if (count == 0) { +		debug("   - read global\n"); +		ret = io->read(NULL, -1); +		if (ret) { +			printf("Unable to read global state for '%s'\n", +			       io->name); +			return -EINVAL; +		} +	} + +	return 0; +} + +int sandbox_read_state(struct sandbox_state *state, const char *fname) +{ +	struct sandbox_state_io *io; +	const void *blob; +	bool got_err; +	int ret; + +	if (state->read_state && fname) { +		ret = state_read_file(state, fname); +		if (ret == -ENOENT && state->ignore_missing_state_on_read) +			ret = 0; +		if (ret) +			return ret; +	} + +	/* Call all the state read funtcions */ +	got_err = false; +	blob = state->state_fdt; +	io = ll_entry_start(struct sandbox_state_io, state_io); +	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { +		ret = sandbox_read_state_nodes(state, io, blob); +		if (ret < 0) +			got_err = true; +	} + +	if (state->read_state && fname) { +		debug("Read sandbox state from '%s'%s\n", fname, +		      got_err ? " (with errors)" : ""); +	} + +	return got_err ? -1 : 0; +} + +/*** + * sandbox_write_state_node() - Write state associated with a driver + * + * This calls the write function to write out global state for that driver. + * + * TODO(sjg@chromium.org): Support writing out state from multiple drivers + * of the same time. We don't need this yet,and it will be much easier to + * do when driver model is available. + * + * @state: Sandbox state + * @io: Method to use for writing state + * @return 0 if OK, -EIO if there is a fatal error (such as out of space + * for adding the data), -EINVAL if the write function failed. + */ +int sandbox_write_state_node(struct sandbox_state *state, +			     struct sandbox_state_io *io) +{ +	void *blob; +	int node; +	int ret; + +	if (!io->write) +		return 0; + +	ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE); +	if (ret) { +		printf("Failed to add more space for state\n"); +		return -EIO; +	} + +	/* The blob location can change when the size increases */ +	blob = state->state_fdt; +	node = fdt_node_offset_by_compatible(blob, -1, io->compat); +	if (node == -FDT_ERR_NOTFOUND) { +		node = fdt_add_subnode(blob, 0, io->name); +		if (node < 0) { +			printf("Cannot create node '%s': %s\n", io->name, +			       fdt_strerror(node)); +			return -EIO; +		} + +		if (fdt_setprop_string(blob, node, "compatible", io->compat)) { +			puts("Cannot set compatible\n"); +			return -EIO; +		} +	} else if (node < 0) { +		printf("Cannot access node '%s': %s\n", io->name, +		       fdt_strerror(node)); +		return -EIO; +	} +	debug("Write state for '%s' to node %d\n", io->compat, node); +	ret = io->write(blob, node); +	if (ret) { +		printf("Unable to write state for '%s'\n", io->compat); +		return -EINVAL; +	} + +	return 0; +} + +int sandbox_write_state(struct sandbox_state *state, const char *fname) +{ +	struct sandbox_state_io *io; +	bool got_err; +	int size; +	int ret; +	int fd; + +	/* Create a state FDT if we don't have one */ +	if (!state->state_fdt) { +		size = 0x4000; +		state->state_fdt = os_malloc(size); +		if (!state->state_fdt) { +			puts("No memory to create FDT\n"); +			return -ENOMEM; +		} +		ret = fdt_create_empty_tree(state->state_fdt, size); +		if (ret < 0) { +			printf("Cannot create empty state FDT: %s\n", +			       fdt_strerror(ret)); +			ret = -EIO; +			goto err_create; +		} +	} + +	/* Call all the state write funtcions */ +	got_err = false; +	io = ll_entry_start(struct sandbox_state_io, state_io); +	ret = 0; +	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { +		ret = sandbox_write_state_node(state, io); +		if (ret == -EIO) +			break; +		else if (ret) +			got_err = true; +	} + +	if (ret == -EIO) { +		printf("Could not write sandbox state\n"); +		goto err_create; +	} + +	ret = fdt_pack(state->state_fdt); +	if (ret < 0) { +		printf("Cannot pack state FDT: %s\n", fdt_strerror(ret)); +		ret = -EINVAL; +		goto err_create; +	} +	size = fdt_totalsize(state->state_fdt); +	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT); +	if (fd < 0) { +		printf("Cannot open sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_create; +	} +	if (os_write(fd, state->state_fdt, size) != size) { +		printf("Cannot write sandbox state file '%s'\n", fname); +		ret = -EIO; +		goto err_write; +	} +	os_close(fd); + +	debug("Wrote sandbox state to '%s'%s\n", fname, +	      got_err ? " (with errors)" : ""); + +	return 0; +err_write: +	os_close(fd); +err_create: +	os_free(state->state_fdt); + +	return ret; +} + +int state_setprop(int node, const char *prop_name, const void *data, int size) +{ +	void *blob; +	int len; +	int ret; + +	fdt_getprop(state->state_fdt, node, prop_name, &len); + +	/* Add space for the new property, its name and some overhead */ +	ret = state_ensure_space(size - len + strlen(prop_name) + 32); +	if (ret) +		return ret; + +	/* This should succeed, barring a mutiny */ +	blob = state->state_fdt; +	ret = fdt_setprop(blob, node, prop_name, data, size); +	if (ret) { +		printf("%s: Unable to set property '%s' in node '%s': %s\n", +		       __func__, prop_name, fdt_get_name(blob, node, NULL), +			fdt_strerror(ret)); +		return -ENOSPC; +	} + +	return 0; +} +  struct sandbox_state *state_get_current(void)  {  	assert(state); @@ -25,6 +346,10 @@ int state_init(void)  {  	state = &main_state; +	state->ram_size = CONFIG_SYS_SDRAM_SIZE; +	state->ram_buf = os_malloc(state->ram_size); +	assert(state->ram_buf); +  	/*  	 * Example of how to use GPIOs:  	 * @@ -33,3 +358,31 @@ int state_init(void)  	 */  	return 0;  } + +int state_uninit(void) +{ +	int err; + +	state = &main_state; + +	if (state->write_ram_buf) { +		err = os_write_ram_buf(state->ram_buf_fname); +		if (err) { +			printf("Failed to write RAM buffer\n"); +			return err; +		} +	} + +	if (state->write_state) { +		if (sandbox_write_state(state, state->state_fname)) { +			printf("Failed to write sandbox state\n"); +			return -1; +		} +	} + +	if (state->state_fdt) +		os_free(state->state_fdt); +	memset(state, '\0', sizeof(*state)); + +	return 0; +} diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index d70532aa4..b2e9b488f 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -12,7 +12,7 @@  /* Architecture-specific global data */  struct arch_global_data { -	u8		*ram_buf;	/* emulated RAM buffer */ +	uint8_t		*ram_buf;	/* emulated RAM buffer */  };  #include <asm-generic/global_data.h> diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index a38820bde..e8e4fea1b 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -7,6 +7,8 @@  #define __SANDBOX_STATE_H  #include <config.h> +#include <stdbool.h> +#include <linux/stringify.h>  /* How we exited U-Boot */  enum exit_type_id { @@ -23,17 +25,92 @@ struct sandbox_spi_info {  /* The complete state of the test system */  struct sandbox_state {  	const char *cmd;		/* Command to execute */ +	bool interactive;		/* Enable cmdline after execute */  	const char *fdt_fname;		/* Filename of FDT binary */  	enum exit_type_id exit_type;	/* How we exited U-Boot */  	const char *parse_err;		/* Error to report from parsing */  	int argc;			/* Program arguments */  	char **argv; +	uint8_t *ram_buf;		/* Emulated RAM buffer */ +	unsigned int ram_size;		/* Size of RAM buffer */ +	const char *ram_buf_fname;	/* Filename to use for RAM buffer */ +	bool write_ram_buf;		/* Write RAM buffer on exit */ +	const char *state_fname;	/* File containing sandbox state */ +	void *state_fdt;		/* Holds saved state for sandbox */ +	bool read_state;		/* Read sandbox state on startup */ +	bool write_state;		/* Write sandbox state on exit */ +	bool ignore_missing_state_on_read;	/* No error if state missing */  	/* Pointer to information for each SPI bus/cs */  	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]  					[CONFIG_SANDBOX_SPI_MAX_CS];  }; +/* Minimum space we guarantee in the state FDT when calling read/write*/ +#define SANDBOX_STATE_MIN_SPACE		0x1000 + +/** + * struct sandbox_state_io - methods to saved/restore sandbox state + * @name: Name of of the device tree node, also the name of the variable + *	holding this data so it should be an identifier (use underscore + *	instead of minus) + * @compat: Compatible string for the node containing this state + * + * @read: Function to read state from FDT + *	If data is available, then blob and node will provide access to it. If + *	not (blob == NULL and node == -1) this function should set up an empty + *	data set for start-of-day. + *	@param blob: Pointer to device tree blob, or NULL if no data to read + *	@param node: Node offset to read from + *	@return 0 if OK, -ve on error + * + * @write: Function to write state to FDT + *	The caller will ensure that there is a node ready for the state. The + *	node may already contain the old state, in which case it should be + *	overridden. There is guaranteed to be SANDBOX_STATE_MIN_SPACE bytes + *	of free space, so error checking is not required for fdt_setprop...() + *	calls which add up to less than this much space. + * + *	For adding larger properties, use state_setprop(). + * + * @param blob: Device tree blob holding state + * @param node: Node to write our state into + * + * Note that it is possible to save data as large blobs or as individual + * hierarchical properties. However, unless you intend to keep state files + * around for a long time and be able to run an old state file on a new + * sandbox, it might not be worth using individual properties for everything. + * This is certainly supported, it is just a matter of the effort you wish + * to put into the state read/write feature. + */ +struct sandbox_state_io { +	const char *name; +	const char *compat; +	int (*write)(void *blob, int node); +	int (*read)(const void *blob, int node); +}; + +/** + * SANDBOX_STATE_IO - Declare sandbox state to read/write + * + * Sandbox permits saving state from one run and restoring it in another. This + * allows the test system to retain state between runs and thus better + * emulate a real system. Examples of state that might be useful to save are + * the emulated GPIOs pin settings, flash memory contents and TPM private + * data. U-Boot memory contents is dealth with separately since it is large + * and it is not normally useful to save it (since a normal system does not + * preserve DRAM between runs). See the '-m' option for this. + * + * See struct sandbox_state_io above for member documentation. + */ +#define SANDBOX_STATE_IO(_name, _compat, _read, _write) \ +	ll_entry_declare(struct sandbox_state_io, _name, state_io) = { \ +		.name = __stringify(_name), \ +		.read = _read, \ +		.write = _write, \ +		.compat = _compat, \ +	} +  /**   * Record the exit type to be reported by the test program.   * @@ -49,8 +126,59 @@ void state_record_exit(enum exit_type_id exit_type);  struct sandbox_state *state_get_current(void);  /** + * Read the sandbox state from the supplied device tree file + * + * This calls all registered state handlers to read in the sandbox state + * from a previous test run. + * + * @param state		Sandbox state to update + * @param fname		Filename of device tree file to read from + * @return 0 if OK, -ve on error + */ +int sandbox_read_state(struct sandbox_state *state, const char *fname); + +/** + * Write the sandbox state to the supplied device tree file + * + * This calls all registered state handlers to write out the sandbox state + * so that it can be preserved for a future test run. + * + * If the file exists it is overwritten. + * + * @param state		Sandbox state to update + * @param fname		Filename of device tree file to write to + * @return 0 if OK, -ve on error + */ +int sandbox_write_state(struct sandbox_state *state, const char *fname); + +/** + * Add a property to a sandbox state node + * + * This is equivalent to fdt_setprop except that it automatically enlarges + * the device tree if necessary. That means it is safe to write any amount + * of data here. + * + * This function can only be called from within struct sandbox_state_io's + * ->write method, i.e. within state I/O drivers. + * + * @param node		Device tree node to write to + * @param prop_name	Property to write + * @param data		Data to write into property + * @param size		Size of data to write into property + */ +int state_setprop(int node, const char *prop_name, const void *data, int size); + +/**   * Initialize the test system state   */  int state_init(void); +/** + * Uninitialize the test system state, writing out state if configured to + * do so. + * + * @return 0 if OK, -ve on error + */ +int state_uninit(void); +  #endif diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index bed720cf8..5707c2710 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -23,4 +23,6 @@ int dram_init(void);  int sandbox_early_getopt_check(void);  int sandbox_main_loop_init(void); +int cleanup_before_linux(void); +  #endif	/* _U_BOOT_SANDBOX_H_ */ diff --git a/arch/sh/cpu/sh2/config.mk b/arch/sh/cpu/sh2/config.mk index 8a0de9671..69273b4f3 100644 --- a/arch/sh/cpu/sh2/config.mk +++ b/arch/sh/cpu/sh2/config.mk @@ -12,7 +12,7 @@ PLATFORM_CPPFLAGS += -m2a -m2a-nofpu -mb -ffreestanding  else # SH2  PLATFORM_CPPFLAGS += -m3e -mb  endif -PLATFORM_CPPFLAGS += $(call cc-option,-mno-fdpic) +PLATFORM_CPPFLAGS += -DCONFIG_SH2 $(call cc-option,-mno-fdpic)  PLATFORM_RELFLAGS += -ffixed-r13  PLATFORM_LDFLAGS += $(ENDIANNESS) diff --git a/arch/sh/cpu/sh2/cpu.c b/arch/sh/cpu/sh2/cpu.c index 18479a4c4..a2f856f45 100644 --- a/arch/sh/cpu/sh2/cpu.c +++ b/arch/sh/cpu/sh2/cpu.c @@ -23,11 +23,7 @@  int checkcpu(void)  { -#if defined(CONFIG_SH2A) -	puts("CPU: SH2A\n"); -#else  	puts("CPU: SH2\n"); -#endif  	return 0;  } diff --git a/arch/sh/cpu/sh3/config.mk b/arch/sh/cpu/sh3/config.mk index 5c77e5c32..abd4b8d2b 100644 --- a/arch/sh/cpu/sh3/config.mk +++ b/arch/sh/cpu/sh3/config.mk @@ -11,5 +11,5 @@  # SPDX-License-Identifier:	GPL-2.0+  #  # -PLATFORM_CPPFLAGS += -m3 +PLATFORM_CPPFLAGS += -DCONFIG_SH3 -m3  PLATFORM_RELFLAGS += -ffixed-r13 diff --git a/arch/sh/cpu/sh4/config.mk b/arch/sh/cpu/sh4/config.mk index c3575570e..753580beb 100644 --- a/arch/sh/cpu/sh4/config.mk +++ b/arch/sh/cpu/sh4/config.mk @@ -8,5 +8,5 @@  # SPDX-License-Identifier:	GPL-2.0+  #  # -PLATFORM_CPPFLAGS += -m4-nofpu +PLATFORM_CPPFLAGS += -DCONFIG_SH4 -m4-nofpu  PLATFORM_RELFLAGS += -ffixed-r13 diff --git a/arch/sh/cpu/sh4/cpu.c b/arch/sh/cpu/sh4/cpu.c index 91133a38a..e8ee0a45a 100644 --- a/arch/sh/cpu/sh4/cpu.c +++ b/arch/sh/cpu/sh4/cpu.c @@ -13,11 +13,7 @@  int checkcpu(void)  { -#ifdef CONFIG_SH4A -	puts("CPU: SH-4A\n"); -#else  	puts("CPU: SH4\n"); -#endif  	return 0;  } diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h index b21dc4422..0698a3775 100644 --- a/arch/sh/include/asm/cache.h +++ b/arch/sh/include/asm/cache.h @@ -1,7 +1,7 @@  #ifndef __ASM_SH_CACHE_H  #define __ASM_SH_CACHE_H -#if defined(CONFIG_SH4) || defined(CONFIG_SH4A) +#if defined(CONFIG_SH4)  int cache_control(unsigned int cmd); @@ -18,7 +18,7 @@ struct __large_struct { unsigned long buf[100]; };   */  #define ARCH_DMA_MINALIGN	32 -#endif /* CONFIG_SH4 || CONFIG_SH4A */ +#endif /* CONFIG_SH4 */  /*   * Use the L1 data cache line size value for the minimum DMA buffer alignment diff --git a/arch/sh/include/asm/cpu_sh4.h b/arch/sh/include/asm/cpu_sh4.h index 9181d59a9..9f48e4fe0 100644 --- a/arch/sh/include/asm/cpu_sh4.h +++ b/arch/sh/include/asm/cpu_sh4.h @@ -37,6 +37,8 @@  # include <asm/cpu_sh7734.h>  #elif defined (CONFIG_CPU_SH7752)  # include <asm/cpu_sh7752.h> +#elif defined (CONFIG_CPU_SH7753) +# include <asm/cpu_sh7753.h>  #elif defined (CONFIG_CPU_SH7757)  # include <asm/cpu_sh7757.h>  #elif defined (CONFIG_CPU_SH7763) diff --git a/arch/sh/include/asm/cpu_sh7753.h b/arch/sh/include/asm/cpu_sh7753.h new file mode 100644 index 000000000..cd0e0bba6 --- /dev/null +++ b/arch/sh/include/asm/cpu_sh7753.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2012  Renesas Solutions Corp. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _ASM_CPU_SH7753_H_ +#define _ASM_CPU_SH7753_H_ + +#define CCR		0xFF00001C +#define WTCNT		0xFFCC0000 +#define CCR_CACHE_INIT	0x0000090b +#define CACHE_OC_NUM_WAYS	1 + +#ifndef __ASSEMBLY__		/* put C only stuff in this section */ +/* MMU */ +struct mmu_regs { +	unsigned int	reserved[4]; +	unsigned int	mmucr; +}; +#define MMU_BASE	((struct mmu_regs *)0xff000000) + +/* Watchdog */ +#define WTCSR0		0xffcc0002 +#define WRSTCSR_R	0xffcc0003 +#define WRSTCSR_W	0xffcc0002 +#define WTCSR_PREFIX		0xa500 +#define WRSTCSR_PREFIX		0x6900 +#define WRSTCSR_WOVF_PREFIX	0x9600 + +/* SCIF */ +#define SCIF0_BASE	0xfe4b0000	/* The real name is SCIF2 */ +#define SCIF1_BASE	0xfe4c0000	/* The real name is SCIF3 */ +#define SCIF2_BASE	0xfe4d0000	/* The real name is SCIF4 */ + +/* TMU0 */ +#define TMU_BASE	 0xFE430000 + +/* ETHER, GETHER MAC address */ +struct ether_mac_regs { +	unsigned int	reserved[114]; +	unsigned int	mahr; +	unsigned int	reserved2; +	unsigned int	malr; +}; +#define GETHER0_MAC_BASE	((struct ether_mac_regs *)0xfee0400) +#define GETHER1_MAC_BASE	((struct ether_mac_regs *)0xfee0c00) +#define ETHER0_MAC_BASE		((struct ether_mac_regs *)0xfef0000) +#define ETHER1_MAC_BASE		((struct ether_mac_regs *)0xfef0800) + +/* GETHER */ +struct gether_control_regs { +	unsigned int	gbecont; +}; +#define GETHER_CONTROL_BASE	((struct gether_control_regs *)0xffc10100) +#define GBECONT_RMII1		0x00020000 +#define GBECONT_RMII0		0x00010000 + +/* SerMux */ +struct sermux_regs { +	unsigned char	smr0; +	unsigned char	smr1; +	unsigned char	smr2; +	unsigned char	smr3; +	unsigned char	smr4; +	unsigned char	smr5; +}; +#define SERMUX_BASE	((struct sermux_regs *)0xfe470000) + + +/* USB0/1 */ +struct usb_common_regs { +	unsigned short	reserved[129]; +	unsigned short	suspmode; +}; +#define USB0_COMMON_BASE	((struct usb_common_regs *)0xfe450000) +#define USB1_COMMON_BASE	((struct usb_common_regs *)0xfe4f0000) + +struct usb0_phy_regs { +	unsigned short	reset; +	unsigned short	reserved[4]; +	unsigned short	portsel; +}; +#define USB0_PHY_BASE		((struct usb0_phy_regs *)0xfe5f0000) + +struct usb1_port_regs { +	unsigned int	port1sel; +	unsigned int	reserved; +	unsigned int	usb1intsts; +}; +#define USB1_PORT_BASE		((struct usb1_port_regs *)0xfe4f2000) + +struct usb1_alignment_regs { +	unsigned int	ehcidatac;	/* 0xfe4fe018 */ +	unsigned int	reserved[63]; +	unsigned int	ohcidatac; +}; +#define USB1_ALIGNMENT_BASE	((struct usb1_alignment_regs *)0xfe4fe018) + +/* GPIO */ +struct gpio_regs { +	unsigned short	pacr; +	unsigned short	pbcr; +	unsigned short	pccr; +	unsigned short	pdcr; +	unsigned short	pecr; +	unsigned short	pfcr; +	unsigned short	pgcr; +	unsigned short	phcr; +	unsigned short	picr; +	unsigned short	pjcr; +	unsigned short	pkcr; +	unsigned short	plcr; +	unsigned short	pmcr; +	unsigned short	pncr; +	unsigned short	pocr; +	unsigned short	reserved; +	unsigned short	pqcr; +	unsigned short	prcr; +	unsigned short	pscr; +	unsigned short	ptcr; +	unsigned short	pucr; +	unsigned short	pvcr; +	unsigned short	pwcr; +	unsigned short	pxcr; +	unsigned short	pycr; +	unsigned short	pzcr; +	unsigned char	padr; +	unsigned char	reserved_a; +	unsigned char	pbdr; +	unsigned char	reserved_b; +	unsigned char	pcdr; +	unsigned char	reserved_c; +	unsigned char	pddr; +	unsigned char	reserved_d; +	unsigned char	pedr; +	unsigned char	reserved_e; +	unsigned char	pfdr; +	unsigned char	reserved_f; +	unsigned char	pgdr; +	unsigned char	reserved_g; +	unsigned char	phdr; +	unsigned char	reserved_h; +	unsigned char	pidr; +	unsigned char	reserved_i; +	unsigned char	pjdr; +	unsigned char	reserved_j; +	unsigned char	pkdr; +	unsigned char	reserved_k; +	unsigned char	pldr; +	unsigned char	reserved_l; +	unsigned char	pmdr; +	unsigned char	reserved_m; +	unsigned char	pndr; +	unsigned char	reserved_n; +	unsigned char	podr; +	unsigned char	reserved_o; +	unsigned char	ppdr; +	unsigned char	reserved_p; +	unsigned char	pqdr; +	unsigned char	reserved_q; +	unsigned char	prdr; +	unsigned char	reserved_r; +	unsigned char	psdr; +	unsigned char	reserved_s; +	unsigned char	ptdr; +	unsigned char	reserved_t; +	unsigned char	pudr; +	unsigned char	reserved_u; +	unsigned char	pvdr; +	unsigned char	reserved_v; +	unsigned char	pwdr; +	unsigned char	reserved_w; +	unsigned char	pxdr; +	unsigned char	reserved_x; +	unsigned char	pydr; +	unsigned char	reserved_y; +	unsigned char	pzdr; +	unsigned char	reserved_z; +	unsigned short	ncer; +	unsigned short	ncmcr; +	unsigned short	nccsr; +	unsigned char	reserved2[2]; +	unsigned short	psel0;		/* +0x70 */ +	unsigned short	psel1; +	unsigned short	psel2; +	unsigned short	psel3; +	unsigned short	psel4; +	unsigned short	psel5; +	unsigned short	psel6; +	unsigned short	reserved3[2]; +	unsigned short	psel7; +}; +#define GPIO_BASE	((struct gpio_regs *)0xffec0000) + +#endif	/* ifndef __ASSEMBLY__ */ +#endif	/* _ASM_CPU_SH7753_H_ */ diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 938a89cff..b8677da95 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -1,12 +1,10 @@  #ifndef _ASM_SH_PROCESSOR_H_  #define _ASM_SH_PROCESSOR_H_ -#if defined(CONFIG_SH2) || \ -	defined (CONFIG_SH2A) +#if defined(CONFIG_SH2)  # include <asm/cpu_sh2.h> -#elif defined (CONFIG_SH3) +#elif defined(CONFIG_SH3)  # include <asm/cpu_sh3.h> -#elif defined (CONFIG_SH4) || \ -	defined (CONFIG_SH4A) +#elif defined(CONFIG_SH4)  # include <asm/cpu_sh4.h>  #endif  #endif diff --git a/arch/sh/lib/time_sh2.c b/arch/sh/lib/time_sh2.c index be3896c3e..4b1f47b6a 100644 --- a/arch/sh/lib/time_sh2.c +++ b/arch/sh/lib/time_sh2.c @@ -84,5 +84,5 @@ void __udelay(unsigned long usec)  unsigned long get_tbclk(void)  { -	return CONFIG_SYS_HZ; +	return CONFIG_SH_CMT_CLK_FREQ;  } |