diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/arch/powerpc/cpu/74xx_7xx | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/powerpc/cpu/74xx_7xx')
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/Makefile | 13 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/cache.S | 404 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/config.mk | 8 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu.c | 300 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu_init.c | 47 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/interrupts.c | 88 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/io.S | 112 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/kgdb.S | 61 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/speed.c | 165 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/start.S | 840 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/traps.c | 218 | ||||
| -rw-r--r-- | roms/u-boot/arch/powerpc/cpu/74xx_7xx/u-boot.lds | 78 | 
12 files changed, 2334 insertions, 0 deletions
diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/Makefile b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/Makefile new file mode 100644 index 00000000..f31fe756 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2001 +# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y	= start.o +obj-y	= cache.o kgdb.o io.o +obj-y	+= traps.o cpu.o cpu_init.o speed.o interrupts.o diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cache.S b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cache.S new file mode 100644 index 00000000..66c72983 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cache.S @@ -0,0 +1,404 @@ +#include <config.h> +#include <74xx_7xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#ifndef CACHE_LINE_SIZE +# define CACHE_LINE_SIZE L1_CACHE_BYTES +#endif + +#if CACHE_LINE_SIZE == 128 +#define LG_CACHE_LINE_SIZE 7 +#elif CACHE_LINE_SIZE == 32 +#define LG_CACHE_LINE_SIZE 5 +#elif CACHE_LINE_SIZE == 16 +#define LG_CACHE_LINE_SIZE 4 +#elif CACHE_LINE_SIZE == 8 +#define LG_CACHE_LINE_SIZE 3 +#else +# error "Invalid cache line size!" +#endif + +/* + * Invalidate L1 instruction cache. + */ +_GLOBAL(invalidate_l1_instruction_cache) +	mfspr	r3,PVR +	rlwinm	r3,r3,16,16,31 +	cmpi	0,r3,1 +	beqlr			/* for 601, do nothing */ +	/* 603/604 processor - use invalidate-all bit in HID0 */ +	mfspr	r3,HID0 +	ori	r3,r3,HID0_ICFI +	mtspr	HID0,r3 +	isync +	blr + +/* + * Invalidate L1 data cache. + */ +_GLOBAL(invalidate_l1_data_cache) +	mfspr	r3,HID0 +	ori	r3,r3,HID0_DCFI +	mtspr	HID0,r3 +	isync +	blr + +/* + * Flush data cache. + */ +_GLOBAL(flush_dcache) +	lis	r3,0 +	lis	r5,CACHE_LINE_SIZE +flush: +	cmp	0,1,r3,r5 +	bge	done +	lwz	r5,0(r3) +	lis	r5,CACHE_LINE_SIZE +	addi	r3,r3,0x4 +	b	flush +done: +	blr +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * This is a no-op on the 601. + * + * flush_icache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_icache_range) +	mfspr	r5,PVR +	rlwinm	r5,r5,16,16,31 +	cmpi	0,r5,1 +	beqlr				/* for 601, do nothing */ +	li	r5,CACHE_LINE_SIZE-1 +	andc	r3,r3,r5 +	subf	r4,r3,r4 +	add	r4,r4,r5 +	srwi.	r4,r4,LG_CACHE_LINE_SIZE +	beqlr +	mtctr	r4 +	mr	r6,r3 +1:	dcbst	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	sync				/* wait for dcbst's to get to ram */ +	mtctr	r4 +2:	icbi	0,r6 +	addi	r6,r6,CACHE_LINE_SIZE +	bdnz	2b +	sync				/* additional sync needed on g4 */ +	isync +	blr +/* + * Write any modified data cache blocks out to memory. + * Does not invalidate the corresponding cache lines (especially for + * any corresponding instruction cache). + * + * clean_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(clean_dcache_range) +	li	r5,CACHE_LINE_SIZE-1 +	andc	r3,r3,r5	/* align r3 down to cache line */ +	subf	r4,r3,r4	/* r4 = offset of stop from start of cache line */ +	add	r4,r4,r5	/* r4 += cache_line_size-1 */ +	srwi.	r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */ +	beqlr				  /* if r4 == 0 return */ +	mtctr	r4			  /* ctr = r4 */ + +	sync +1:	dcbst	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	sync				/* wait for dcbst's to get to ram */ +	blr + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_dcache_range) +	li	r5,CACHE_LINE_SIZE-1 +	andc	r3,r3,r5 +	subf	r4,r3,r4 +	add	r4,r4,r5 +	srwi.	r4,r4,LG_CACHE_LINE_SIZE +	beqlr +	mtctr	r4 + +	sync +1:	dcbf	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	sync				/* wait for dcbf's to get to ram */ +	blr + +/* + * Like above, but invalidate the D-cache.  This is used by the 8xx + * to invalidate the cache so the PPC core doesn't get stale data + * from the CPM (no cache snooping here :-). + * + * invalidate_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(invalidate_dcache_range) +	li	r5,CACHE_LINE_SIZE-1 +	andc	r3,r3,r5 +	subf	r4,r3,r4 +	add	r4,r4,r5 +	srwi.	r4,r4,LG_CACHE_LINE_SIZE +	beqlr +	mtctr	r4 + +	sync +1:	dcbi	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	sync				/* wait for dcbi's to get to ram */ +	blr + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * This is a no-op on the 601 which has a unified cache. + * + *	void __flush_page_to_ram(void *page) + */ +_GLOBAL(__flush_page_to_ram) +	mfspr	r5,PVR +	rlwinm	r5,r5,16,16,31 +	cmpi	0,r5,1 +	beqlr				/* for 601, do nothing */ +	rlwinm	r3,r3,0,0,19		/* Get page base address */ +	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */ +	mtctr	r4 +	mr	r6,r3 +0:	dcbst	0,r3			/* Write line to ram */ +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	0b +	sync +	mtctr	r4 +1:	icbi	0,r6 +	addi	r6,r6,CACHE_LINE_SIZE +	bdnz	1b +	sync +	isync +	blr + +/* + * Flush a particular page from the instruction cache. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * This is a no-op on the 601 which has a unified cache. + * + *	void __flush_icache_page(void *page) + */ +_GLOBAL(__flush_icache_page) +	mfspr	r5,PVR +	rlwinm	r5,r5,16,16,31 +	cmpi	0,r5,1 +	beqlr				/* for 601, do nothing */ +	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */ +	mtctr	r4 +1:	icbi	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	sync +	isync +	blr + +/* + * Clear a page using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced).  This only works on cacheable memory. + */ +_GLOBAL(clear_page) +	li	r0,4096/CACHE_LINE_SIZE +	mtctr	r0 +1:	dcbz	0,r3 +	addi	r3,r3,CACHE_LINE_SIZE +	bdnz	1b +	blr + +/* + * Enable L1 Instruction cache + */ +_GLOBAL(icache_enable) +	mfspr	r3, HID0 +	li	r5, HID0_ICFI|HID0_ILOCK +	andc	r3, r3, r5 +	ori	r3, r3, HID0_ICE +	ori	r5, r3, HID0_ICFI +	mtspr	HID0, r5 +	mtspr	HID0, r3 +	isync +	blr + +/* + * Disable L1 Instruction cache + */ +_GLOBAL(icache_disable) +	mflr	r4 +	bl	invalidate_l1_instruction_cache		/* uses r3 */ +	sync +	mtlr	r4 +	mfspr	r3, HID0 +	li	r5, 0 +	ori	r5, r5, HID0_ICE +	andc	r3, r3, r5 +	mtspr	HID0, r3 +	isync +	blr + +/* + * Is instruction cache enabled? + */ +_GLOBAL(icache_status) +	mfspr	r3, HID0 +	andi.	r3, r3, HID0_ICE +	blr + + +_GLOBAL(l1dcache_enable) +	mfspr	r3, HID0 +	li	r5, HID0_DCFI|HID0_DLOCK +	andc	r3, r3, r5 +	mtspr	HID0, r3		/* no invalidate, unlock */ +	ori	r3, r3, HID0_DCE +	ori	r5, r3, HID0_DCFI +	mtspr	HID0, r5		/* enable + invalidate */ +	mtspr	HID0, r3		/* enable */ +	sync +	blr + +/* + * Enable data cache(s) - L1 and optionally L2 + * Calls l2cache_enable. LR saved in r5 + */ +_GLOBAL(dcache_enable) +	mfspr	r3, HID0 +	li	r5, HID0_DCFI|HID0_DLOCK +	andc	r3, r3, r5 +	mtspr	HID0, r3		/* no invalidate, unlock */ +	ori	r3, r3, HID0_DCE +	ori	r5, r3, HID0_DCFI +	mtspr	HID0, r5		/* enable + invalidate */ +	mtspr	HID0, r3		/* enable */ +	sync +#ifdef CONFIG_SYS_L2 +	mflr	r5 +	bl	l2cache_enable		/* uses r3 and r4 */ +	sync +	mtlr	r5 +#endif +	blr + + +/* + * Disable data cache(s) - L1 and optionally L2 + * Calls flush_dcache and l2cache_disable_no_flush. + * LR saved in r4 + */ +_GLOBAL(dcache_disable) +	mflr	r4			/* save link register */ +	bl	flush_dcache	/* uses r3 and r5 */ +	sync +	mfspr	r3, HID0 +	li	r5, HID0_DCFI|HID0_DLOCK +	andc	r3, r3, r5 +	mtspr	HID0, r3		/* no invalidate, unlock */ +	li	r5, HID0_DCE|HID0_DCFI +	andc	r3, r3, r5		/* no enable, no invalidate */ +	mtspr	HID0, r3 +	sync +#ifdef CONFIG_SYS_L2 +	bl	l2cache_disable_no_flush /* uses r3 */ +#endif +	mtlr	r4			/* restore link register */ +	blr + +/* + * Is data cache enabled? + */ +_GLOBAL(dcache_status) +	mfspr	r3, HID0 +	andi.	r3, r3, HID0_DCE +	blr + +/* + * Invalidate L2 cache using L2I and polling L2IP or L2I + */ +_GLOBAL(l2cache_invalidate) +	sync +	mfspr r3, l2cr +	oris	r3, r3, L2CR_L2I@h +	sync +	mtspr	l2cr, r3 +	sync +	mfspr r3, PVR +	sync +	rlwinm r3, r3, 16,16,31 +	cmpli 0,r3,0x8000  /* 7451, 7441 */ +	beq 0,inv_7450 +	cmpli 0,r3,0x8001  /* 7455, 7445 */ +	beq 0,inv_7450 +	cmpli 0,r3,0x8002  /* 7457, 7447 */ +	beq 0,inv_7450 +	cmpli 0,r3,0x8003  /* 7447A */ +	beq 0,inv_7450 +	cmpli 0,r3,0x8004  /* 7448 */ +	beq 0,inv_7450 +invl2: +	mfspr	r3, l2cr +	andi.	r3, r3, L2CR_L2IP +	bne	invl2 +	/* turn off the global invalidate bit */ +	mfspr	r3, l2cr +	rlwinm	r3, r3, 0, 11, 9 +	sync +	mtspr	l2cr, r3 +	sync +	blr +inv_7450: +	mfspr	r3, l2cr +	andis. r3, r3, L2CR_L2I@h +	bne inv_7450 +	blr + +/* + * Enable L2 cache + * Calls l2cache_invalidate. LR is saved in r4 + */ +_GLOBAL(l2cache_enable) +	mflr	r4			/* save link register */ +	bl	l2cache_invalidate	/* uses r3 */ +	sync +	lis	r3, L2_ENABLE@h +	ori	r3, r3, L2_ENABLE@l +	mtspr	l2cr, r3 +	isync +	mtlr	r4			/* restore link register */ +	blr + +/* + * Disable L2 cache + * Calls flush_dcache. LR is saved in r4 + */ +_GLOBAL(l2cache_disable) +	mflr	r4			/* save link register */ +	bl	flush_dcache		/* uses r3 and r5 */ +	sync +	mtlr	r4			/* restore link register */ +l2cache_disable_no_flush:		/* provide way to disable L2 w/o flushing */ +	lis	r3, L2_INIT@h +	ori	r3, r3, L2_INIT@l +	mtspr	l2cr, r3 +	isync +	blr diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/config.mk b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/config.mk new file mode 100644 index 00000000..96812a02 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/config.mk @@ -0,0 +1,8 @@ +# +# (C) Copyright 2001 +# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -mstring diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu.c b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu.c new file mode 100644 index 00000000..6cd54bf9 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu.c @@ -0,0 +1,300 @@ +/* + * (C) Copyright 2001 + * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * cpu.c + * + * CPU specific code + * + * written or collected and sometimes rewritten by + * Magnus Damm <damm@bitsmart.com> + * + * minor modifications by + * Wolfgang Denk <wd@denx.de> + * + * more modifications by + * Josh Huber <huber@mclx.com> + * added support for the 74xx series of cpus + * added support for the 7xx series of cpus + * made the code a little less hard-coded, and more auto-detectish + */ + +#include <common.h> +#include <command.h> +#include <74xx_7xx.h> +#include <asm/cache.h> + +#if defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#include <fdt_support.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +cpu_t +get_cpu_type(void) +{ +	uint pvr = get_pvr(); +	cpu_t type; + +	type = CPU_UNKNOWN; + +	switch (PVR_VER(pvr)) { +	case 0x000c: +		type = CPU_7400; +		break; +	case 0x0008: +		type = CPU_750; + +		if (((pvr >> 8) & 0xff) == 0x01) { +			type = CPU_750CX;	/* old CX (80100 and 8010x?)*/ +		} else if (((pvr >> 8) & 0xff) == 0x22) { +			type = CPU_750CX;	/* CX (82201,82202) and CXe (82214) */ +		} else if (((pvr >> 8) & 0xff) == 0x33) { +			type = CPU_750CX;	/* CXe (83311) */ +		} else if (((pvr >> 12) & 0xF) == 0x3) { +			type = CPU_755; +		} +		break; + +	case 0x7000: +		type = CPU_750FX; +		break; + +	case 0x7002: +		type = CPU_750GX; +		break; + +	case 0x800C: +		type = CPU_7410; +		break; + +	case 0x8000: +		type = CPU_7450; +		break; + +	case 0x8001: +		type = CPU_7455; +		break; + +	case 0x8002: +		type = CPU_7457; +		break; + +	case 0x8003: +		type = CPU_7447A; +		break; + +	case 0x8004: +		type = CPU_7448; +		break; + +	default: +		break; +	} + +	return type; +} + +/* ------------------------------------------------------------------------- */ + +#if !defined(CONFIG_BAB7xx) +int checkcpu (void) +{ +	uint type   = get_cpu_type(); +	uint pvr    = get_pvr(); +	ulong clock = gd->cpu_clk; +	char buf[32]; +	char *str; + +	puts ("CPU:   "); + +	switch (type) { +	case CPU_750CX: +		printf ("750CX%s v%d.%d", (pvr&0xf0)?"e":"", +			(pvr>>8) & 0xf, +			pvr & 0xf); +		goto	PR_CLK; + +	case CPU_750: +		str = "750"; +		break; + +	case CPU_750FX: +		str = "750FX"; +		break; + +	case CPU_750GX: +		str = "750GX"; +		break; + +	case CPU_755: +		str = "755"; +		break; + +	case CPU_7400: +		str = "MPC7400"; +		break; + +	case CPU_7410: +		str = "MPC7410"; +		break; + +	case CPU_7447A: +		str = "MPC7447A"; +		break; + +	case CPU_7448: +		str = "MPC7448"; +		break; + +	case CPU_7450: +		str = "MPC7450"; +		break; + +	case CPU_7455: +		str = "MPC7455"; +		break; + +	case CPU_7457: +		str = "MPC7457"; +		break; + +	default: +		printf("Unknown CPU -- PVR: 0x%08x\n", pvr); +		return -1; +	} + +	printf ("%s v%d.%d", str, (pvr >> 8) & 0xFF, pvr & 0xFF); +PR_CLK: +	printf (" @ %s MHz\n", strmhz(buf, clock)); + +	return (0); +} +#endif +/* these two functions are unimplemented currently [josh] */ + +/* -------------------------------------------------------------------- */ +/* L1 i-cache								*/ + +int +checkicache(void) +{ +	return 0; /* XXX */ +} + +/* -------------------------------------------------------------------- */ +/* L1 d-cache								*/ + +int +checkdcache(void) +{ +	return 0; /* XXX */ +} + +/* -------------------------------------------------------------------- */ + +static inline void +soft_restart(unsigned long addr) +{ +	/* SRR0 has system reset vector, SRR1 has default MSR value */ +	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + +	__asm__ __volatile__ ("mtspr	26, %0"		:: "r" (addr)); +	__asm__ __volatile__ ("li	4, (1 << 6)"	::: "r4"); +	__asm__ __volatile__ ("mtspr	27, 4"); +	__asm__ __volatile__ ("rfi"); + +	while(1);	/* not reached */ +} + + +#if !defined(CONFIG_BAB7xx)  && \ +    !defined(CONFIG_ELPPC)   && \ +    !defined(CONFIG_PPMC7XX) +/* no generic way to do board reset. simply call soft_reset. */ +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	ulong addr; +	/* flush and disable I/D cache */ +	__asm__ __volatile__ ("mfspr	3, 1008"	::: "r3"); +	__asm__ __volatile__ ("ori	5, 5, 0xcc00"	::: "r5"); +	__asm__ __volatile__ ("ori	4, 3, 0xc00"	::: "r4"); +	__asm__ __volatile__ ("andc	5, 3, 5"	::: "r5"); +	__asm__ __volatile__ ("sync"); +	__asm__ __volatile__ ("mtspr	1008, 4"); +	__asm__ __volatile__ ("isync"); +	__asm__ __volatile__ ("sync"); +	__asm__ __volatile__ ("mtspr	1008, 5"); +	__asm__ __volatile__ ("isync"); +	__asm__ __volatile__ ("sync"); + +#ifdef CONFIG_SYS_RESET_ADDRESS +	addr = CONFIG_SYS_RESET_ADDRESS; +#else +	/* +	 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, +	 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid +	 * address. Better pick an address known to be invalid on your +	 * system and assign it to CONFIG_SYS_RESET_ADDRESS. +	 */ +	addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); +#endif +	soft_restart(addr); + +	/* not reached */ +	while(1) +		; + +	return 1; +} +#endif + +/* ------------------------------------------------------------------------- */ + +/* + * For the 7400 the TB clock runs at 1/4 the cpu bus speed. + */ +#ifndef CONFIG_SYS_BUS_CLK +#define	CONFIG_SYS_BUS_CLK gd->bus_clk +#endif + +unsigned long get_tbclk(void) +{ +	return CONFIG_SYS_BUS_CLK / 4; +} + +/* ------------------------------------------------------------------------- */ + +#if defined(CONFIG_WATCHDOG) +#if !defined(CONFIG_BAB7xx) +void +watchdog_reset(void) +{ + +} +#endif  /* !CONFIG_BAB7xx */ +#endif	/* CONFIG_WATCHDOG */ + +/* ------------------------------------------------------------------------- */ + +#ifdef CONFIG_OF_LIBFDT +void ft_cpu_setup(void *blob, bd_t *bd) +{ +	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, +			     "timebase-frequency", bd->bi_busfreq / 4, 1); +	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, +			     "bus-frequency", bd->bi_busfreq, 1); +	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, +			     "clock-frequency", bd->bi_intfreq, 1); + +	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); + +	fdt_fixup_ethernet(blob); +} +#endif +/* ------------------------------------------------------------------------- */ diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu_init.c b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu_init.c new file mode 100644 index 00000000..a6a87884 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/cpu_init.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2001 + * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * cpu_init.c - low level cpu init + * + * there's really nothing going on here yet.  future work area? + */ + +#include <common.h> +#include <74xx_7xx.h> + +/* + * Breath some life into the CPU... + * + * there's basically nothing to do here since the memory controller + * isn't on the CPU in this case. + */ +void +cpu_init_f (void) +{ +	switch (get_cpu_type()) { +	case CPU_7450: +	case CPU_7455: +	case CPU_7457: +	case CPU_7447A: +	case CPU_7448: +		/* enable the timebase bit in HID0 */ +		set_hid0(get_hid0() | 0x4000000); +		break; +	default: +		/* do nothing */ +		break; +	} +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r (void) +{ +	return (0); +} diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/interrupts.c b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/interrupts.c new file mode 100644 index 00000000..a9062435 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/interrupts.c @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2001 + * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * interrupts.c - just enough support for the decrementer/timer + */ + +#include <common.h> +#include <mpc8xx.h> +#include <mpc8xx_irq.h> +#include <asm/processor.h> +#include <commproc.h> +#include <command.h> + +int interrupt_init_cpu (unsigned *decrementer_count) +{ +	debug("interrupt_init: GT main cause reg: %08x:%08x\n", +	       GTREGREAD(LOW_INTERRUPT_CAUSE_REGISTER), +	       GTREGREAD(HIGH_INTERRUPT_CAUSE_REGISTER)); +	debug("interrupt_init: ethernet cause regs: %08x %08x %08x\n", +	       GTREGREAD(ETHERNET0_INTERRUPT_CAUSE_REGISTER), +	       GTREGREAD(ETHERNET1_INTERRUPT_CAUSE_REGISTER), +	       GTREGREAD(ETHERNET2_INTERRUPT_CAUSE_REGISTER)); +	debug("interrupt_init: ethernet mask regs:  %08x %08x %08x\n", +	       GTREGREAD(ETHERNET0_INTERRUPT_MASK_REGISTER), +	       GTREGREAD(ETHERNET1_INTERRUPT_MASK_REGISTER), +	       GTREGREAD(ETHERNET2_INTERRUPT_MASK_REGISTER)); +	debug("interrupt_init: setting decrementer_count\n"); + +	*decrementer_count = get_tbclk() / CONFIG_SYS_HZ; + +	return (0); +} + +/****************************************************************************/ + +/* + * Handle external interrupts + */ +void +external_interrupt(struct pt_regs *regs) +{ +	puts("external_interrupt (oops!)\n"); +} + +volatile ulong timestamp = 0; + +/* + * timer_interrupt - gets called when the decrementer overflows, + * with interrupts disabled. + * Trivial implementation - no need to be really accurate. + */ +void +timer_interrupt_cpu (struct pt_regs *regs) +{ +	/* nothing to do here */ +	return; +} + +/****************************************************************************/ + +/* + * Install and free a interrupt handler. + */ + +void +irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) +{ + +} + +void +irq_free_handler(int vec) +{ + +} + +/****************************************************************************/ + +void +do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char * const argv[]) +{ +	puts("IRQ related functions are unimplemented currently.\n"); +} diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/io.S b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/io.S new file mode 100644 index 00000000..3b4b08a8 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/io.S @@ -0,0 +1,112 @@ +/* + *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net> + *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + *  Copyright (C) 2001	Sysgo Real-Time Solutions, GmbH <www.elinos.com> + *			Andreas Heppel <aheppel@sysgo.de> + *  Copyright (C) 2002	Wolfgang Denk <wd@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include <ppc_asm.tmpl> + +/* ------------------------------------------------------------------------------- */ +/*  Function:     in8 */ +/*  Description:  Input 8 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  in8 +in8: +	lbz     r3,0(r3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     in16 */ +/*  Description:  Input 16 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  in16 +in16: +	lhz     r3,0(r3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     in16r */ +/*  Description:  Input 16 bits and byte reverse */ +/* ------------------------------------------------------------------------------- */ +	.globl  in16r +in16r: +	lhbrx   r3,0,r3 +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     in32 */ +/*  Description:  Input 32 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  in32 +in32: +	lwz     3,0(3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     in32r */ +/*  Description:  Input 32 bits and byte reverse */ +/* ------------------------------------------------------------------------------- */ +    .globl  in32r +in32r: +	lwbrx   r3,0,r3 +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     out8 */ +/*  Description:  Output 8 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  out8 +out8: +	stb     r4,0(r3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     out16 */ +/*  Description:  Output 16 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  out16 +out16: +	sth     r4,0(r3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     out16r */ +/*  Description:  Byte reverse and output 16 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  out16r +out16r: +	sthbrx  r4,0,r3 +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     out32 */ +/*  Description:  Output 32 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  out32 +out32: +	stw     r4,0(r3) +	sync +	blr + +/* ------------------------------------------------------------------------------- */ +/*  Function:     out32r */ +/*  Description:  Byte reverse and output 32 bits */ +/* ------------------------------------------------------------------------------- */ +	.globl  out32r +out32r: +	stwbrx  r4,0,r3 +	sync +	blr diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/kgdb.S b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/kgdb.S new file mode 100644 index 00000000..42b3a760 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/kgdb.S @@ -0,0 +1,61 @@ +/* + *  Copyright (C) 2000	Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include <command.h> +#include <74xx_7xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#if defined(CONFIG_CMD_KGDB) + + /* + * cache flushing routines for kgdb + */ + +	.globl	kgdb_flush_cache_all +kgdb_flush_cache_all: +	lis	r3,0 +	addis	r4,r0,0x0040 +kgdb_flush_loop: +	lwz	r5,0(r3) +	addi	r3,r3,CONFIG_SYS_CACHELINE_SIZE +	cmp	0,0,r3,r4 +	bne	kgdb_flush_loop +	SYNC +	mfspr	r3,1008 +	ori	r3,r3,0x8800 +	mtspr	1008,r3 +	sync +	blr + +	.globl	kgdb_flush_cache_range +kgdb_flush_cache_range: +	li	r5,CONFIG_SYS_CACHELINE_SIZE-1 +	andc	r3,r3,r5 +	subf	r4,r3,r4 +	add	r4,r4,r5 +	srwi.	r4,r4,CONFIG_SYS_CACHELINE_SHIFT +	beqlr +	mtctr	r4 +	mr	r6,r3 +1:	dcbst	0,r3 +	addi	r3,r3,CONFIG_SYS_CACHELINE_SIZE +	bdnz	1b +	sync				/* wait for dcbst's to get to ram */ +	mtctr	r4 +2:	icbi	0,r6 +	addi	r6,r6,CONFIG_SYS_CACHELINE_SIZE +	bdnz	2b +	SYNC +	blr + +#endif diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/speed.c b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/speed.c new file mode 100644 index 00000000..5ffa41cf --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/speed.c @@ -0,0 +1,165 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <74xx_7xx.h> +#include <asm/processor.h> + +DECLARE_GLOBAL_DATA_PTR; + +extern unsigned long get_board_bus_clk (void); + +static const int hid1_multipliers_x_10[] = { +	25,	/* 0000 - 2.5x */ +	75,	/* 0001 - 7.5x */ +	70,	/* 0010 - 7x */ +	10,	/* 0011 - bypass */ +	20,	/* 0100 - 2x */ +	65,	/* 0101 - 6.5x */ +	100,	/* 0110 - 10x */ +	45,	/* 0111 - 4.5x */ +	30,	/* 1000 - 3x */ +	55,	/* 1001 - 5.5x */ +	40,	/* 1010 - 4x */ +	50,	/* 1011 - 5x */ +	80,	/* 1100 - 8x */ +	60,	/* 1101 - 6x */ +	35,	/* 1110 - 3.5x */ +	0	/* 1111 - off */ +}; + +/* PLL_CFG[0:4] table for cpu 7448/7447A/7455/7457 */ +static const int hid1_74xx_multipliers_x_10[] = { +	115,	/* 00000 - 11.5x  */ +	170,	/* 00001 - 17x    */ +	75,	/* 00010 -  7.5x  */ +	150,	/* 00011 - 15x    */ +	70,	/* 00100 -  7x    */ +	180,	/* 00101 - 18x    */ +	10,	/* 00110 - bypass */ +	200,	/* 00111 - 20x    */ +	20,	/* 01000 -  2x    */ +	210,	/* 01001 - 21x    */ +	65,	/* 01010 -  6.5x  */ +	130,	/* 01011 - 13x    */ +	85,	/* 01100 -  8.5x  */ +	240,	/* 01101 - 24x    */ +	95,	/* 01110 -  9.5x  */ +	90,	/* 01111 -  9x    */ +	30,	/* 10000 -  3x    */ +	105,	/* 10001 - 10.5x  */ +	55,	/* 10010 -  5.5x  */ +	110,	/* 10011 - 11x    */ +	40,	/* 10100 -  4x    */ +	100,	/* 10101 - 10x    */ +	50,	/* 10110 -  5x    */ +	120,	/* 10111 - 12x    */ +	80,	/* 11000 -  8x    */ +	140,	/* 11001 - 14x    */ +	60,	/* 11010 -  6x    */ +	160,	/* 11011 - 16x    */ +	135,	/* 11100 - 13.5x  */ +	280,	/* 11101 - 28x    */ +	0,	/* 11110 - off    */ +	125	/* 11111 - 12.5x  */ +}; + +static const int hid1_fx_multipliers_x_10[] = { +	00,	/* 0000 - off */ +	00,	/* 0001 - off */ +	10,	/* 0010 - bypass */ +	10,	/* 0011 - bypass */ +	20,	/* 0100 - 2x */ +	25,	/* 0101 - 2.5x */ +	30,	/* 0110 - 3x */ +	35,	/* 0111 - 3.5x */ +	40,	/* 1000 - 4x */ +	45,	/* 1001 - 4.5x */ +	50,	/* 1010 - 5x */ +	55,	/* 1011 - 5.5x */ +	60,	/* 1100 - 6x */ +	65,	/* 1101 - 6.5x */ +	70,	/* 1110 - 7x */ +	75,	/* 1111 - 7.5 */ +	80,	/* 10000 - 8x */ +	85,	/* 10001 - 8.5x */ +	90,	/* 10010 - 9x */ +	95,	/* 10011 - 9.5x */ +	100,	/* 10100 - 10x */ +	110,	/* 10101 - 11x */ +	120,	/* 10110 - 12x */ +}; + + +/* ------------------------------------------------------------------------- */ + +/* + * Measure CPU clock speed (core clock GCLK1, GCLK2) + * + * (Approx. GCLK frequency in Hz) + */ + +int get_clocks (void) +{ +	ulong clock = 0; + +#ifdef CONFIG_SYS_BUS_CLK +	gd->bus_clk = CONFIG_SYS_BUS_CLK;	/* bus clock is a fixed frequency */ +#else +	gd->bus_clk = get_board_bus_clk ();	/* bus clock is configurable */ +#endif + +	/* calculate the clock frequency based upon the CPU type */ +	switch (get_cpu_type()) { +	case CPU_7447A: +	case CPU_7448: +	case CPU_7455: +	case CPU_7457: +		/* +		 * Make sure division is done before multiplication to prevent 32-bit +		 * arithmetic overflows which will cause a negative number +		 */ +		clock = (gd->bus_clk / 10) * +			hid1_74xx_multipliers_x_10[(get_hid1 () >> 12) & 0x1F]; +		break; + +	case CPU_750GX: +	case CPU_750FX: +		clock = (gd->bus_clk / 10) * +			hid1_fx_multipliers_x_10[get_hid1 () >> 27]; +		break; + +	case CPU_7450: +	case CPU_740: +	case CPU_740P: +	case CPU_745: +	case CPU_750CX: +	case CPU_750: +	case CPU_750P: +	case CPU_755: +	case CPU_7400: +	case CPU_7410: +		/* +		 * Make sure division is done before multiplication to prevent 32-bit +		 * arithmetic overflows which will cause a negative number +		 */ +		clock = (gd->bus_clk / 10) * +			hid1_multipliers_x_10[get_hid1 () >> 28]; +		break; + +	case CPU_UNKNOWN: +	       printf ("get_gclk_freq(): unknown CPU type\n"); +	       clock = 0; +	       return (1); +	} + +	gd->cpu_clk = clock; + +	return (0); +} + +/* ------------------------------------------------------------------------- */ diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/start.S b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/start.S new file mode 100644 index 00000000..b0e102c6 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/start.S @@ -0,0 +1,840 @@ +/* + *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net> + *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de> + *  Copyright (C) 2001  Josh Huber <huber@mclx.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*  U-Boot - Startup Code for PowerPC based Embedded Boards + * + * + *  The processor starts at 0xfff00100 and the code is executed + *  from flash. The code is organized to be at an other address + *  in memory, but as long we don't jump around before relocating. + *  board_init lies at a quite high address and when the cpu has + *  jumped there, everything is ok. + */ +#include <asm-offsets.h> +#include <config.h> +#include <74xx_7xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> +#include <asm/u-boot.h> + +#if !defined(CONFIG_DB64360) && \ +    !defined(CONFIG_DB64460) && \ +    !defined(CONFIG_CPCI750) && \ +    !defined(CONFIG_P3Mx) +#include <galileo/gt64260R.h> +#endif + +/* We don't want the  MMU yet. +*/ +#undef	MSR_KERNEL +/* Machine Check and Recoverable Interr. */ +#define MSR_KERNEL ( MSR_ME | MSR_RI ) + +/* + * Set up GOT: Global Offset Table + * + * Use r12 to access the GOT + */ +	START_GOT +	GOT_ENTRY(_GOT2_TABLE_) +	GOT_ENTRY(_FIXUP_TABLE_) + +	GOT_ENTRY(_start) +	GOT_ENTRY(_start_of_vectors) +	GOT_ENTRY(_end_of_vectors) +	GOT_ENTRY(transfer_to_handler) + +	GOT_ENTRY(__init_end) +	GOT_ENTRY(__bss_end) +	GOT_ENTRY(__bss_start) +	END_GOT + +/* + * r3 - 1st arg to board_init(): IMMP pointer + * r4 - 2nd arg to board_init(): boot flag + */ +	.text +	.long	0x27051956		/* U-Boot Magic Number		*/ +	.globl	version_string +version_string: +	.ascii U_BOOT_VERSION_STRING, "\0" + +	. = EXC_OFF_SYS_RESET +	.globl	_start +_start: +	b	boot_cold + +	/* the boot code is located below the exception table */ + +	.globl	_start_of_vectors +_start_of_vectors: + +/* Machine check */ +	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) + +/* Data Storage exception.  "Never" generated on the 860. */ +	STD_EXCEPTION(0x300, DataStorage, UnknownException) + +/* Instruction Storage exception.  "Never" generated on the 860. */ +	STD_EXCEPTION(0x400, InstStorage, UnknownException) + +/* External Interrupt exception. */ +	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) + +/* Alignment exception. */ +	. = 0x600 +Alignment: +	EXCEPTION_PROLOG(SRR0, SRR1) +	mfspr	r4,DAR +	stw	r4,_DAR(r21) +	mfspr	r5,DSISR +	stw	r5,_DSISR(r21) +	addi	r3,r1,STACK_FRAME_OVERHEAD +	EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) + +/* Program check exception */ +	. = 0x700 +ProgramCheck: +	EXCEPTION_PROLOG(SRR0, SRR1) +	addi	r3,r1,STACK_FRAME_OVERHEAD +	EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, +		MSR_KERNEL, COPY_EE) + +	/* No FPU on MPC8xx.  This exception is not supposed to happen. +	*/ +	STD_EXCEPTION(0x800, FPUnavailable, UnknownException) + +	/* I guess we could implement decrementer, and may have +	 * to someday for timekeeping. +	 */ +	STD_EXCEPTION(0x900, Decrementer, timer_interrupt) +	STD_EXCEPTION(0xa00, Trap_0a, UnknownException) +	STD_EXCEPTION(0xb00, Trap_0b, UnknownException) +	STD_EXCEPTION(0xc00, SystemCall, UnknownException) +	STD_EXCEPTION(0xd00, SingleStep, UnknownException) + +	STD_EXCEPTION(0xe00, Trap_0e, UnknownException) +	STD_EXCEPTION(0xf00, Trap_0f, UnknownException) + +	/* +	 * On the MPC8xx, this is a software emulation interrupt. It +	 * occurs for all unimplemented and illegal instructions. +	 */ +	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) + +	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) +	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) +	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) +	STD_EXCEPTION(0x1400, DataTLBError, UnknownException) + +	STD_EXCEPTION(0x1500, Reserved5, UnknownException) +	STD_EXCEPTION(0x1600, Reserved6, UnknownException) +	STD_EXCEPTION(0x1700, Reserved7, UnknownException) +	STD_EXCEPTION(0x1800, Reserved8, UnknownException) +	STD_EXCEPTION(0x1900, Reserved9, UnknownException) +	STD_EXCEPTION(0x1a00, ReservedA, UnknownException) +	STD_EXCEPTION(0x1b00, ReservedB, UnknownException) + +	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) +	STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException) +	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) +	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) + +	.globl	_end_of_vectors +_end_of_vectors: + +	. = 0x2000 + +boot_cold: +	/* disable everything */ +	li	r0, 0 +	mtspr	HID0, r0 +	sync +	mtmsr	0 +	bl	invalidate_bats +	sync + +#ifdef CONFIG_SYS_L2 +	/* init the L2 cache */ +	addis	r3, r0, L2_INIT@h +	ori	r3, r3, L2_INIT@l +	sync +	mtspr	l2cr, r3 +#endif +#if defined(CONFIG_ALTIVEC) && defined(CONFIG_74xx) +	.long	0x7e00066c +		/* +		 * dssall instruction, gas doesn't have it yet +		 * ...for altivec, data stream stop all this probably +		 * isn't needed unless we warm (software) reboot U-Boot +		 */ +#endif + +#ifdef CONFIG_SYS_L2 +	/* invalidate the L2 cache */ +	bl	l2cache_invalidate +	sync +#endif +#ifdef CONFIG_SYS_BOARD_ASM_INIT +	/* do early init */ +	bl	board_asm_init +#endif + +	/* +	 * Calculate absolute address in FLASH and jump there +	 *------------------------------------------------------*/ +	lis	r3, CONFIG_SYS_MONITOR_BASE@h +	ori	r3, r3, CONFIG_SYS_MONITOR_BASE@l +	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET +	mtlr	r3 +	blr + +in_flash: +	/* let the C-code set up the rest			*/ +	/*							*/ +	/* Be careful to keep code relocatable !		*/ +	/*------------------------------------------------------*/ + +	/* perform low-level init */ +	/* sdram init, galileo init, etc */ +	/* r3:	NHR bit from HID0 */ + +	/* setup the bats */ +	bl	setup_bats +	sync + +	/* +	 * Cache must be enabled here for stack-in-cache trick. +	 * This means we need to enable the BATS. +	 * This means: +	 *   1) for the EVB, original gt regs need to be mapped +	 *   2) need to have an IBAT for the 0xf region, +	 *      we are running there! +	 * Cache should be turned on after BATs, since by default +	 * everything is write-through. +	 * The init-mem BAT can be reused after reloc. The old +	 * gt-regs BAT can be reused after board_init_f calls +	 * board_early_init_f (EVB only). +	 */ +#if !defined(CONFIG_BAB7xx) && !defined(CONFIG_ELPPC) && !defined(CONFIG_P3Mx) +	/* enable address translation */ +	bl	enable_addr_trans +	sync + +	/* enable and invalidate the data cache */ +	bl	l1dcache_enable +	sync +#endif +#ifdef CONFIG_SYS_INIT_RAM_LOCK +	bl	lock_ram_in_cache +	sync +#endif + +	/* set up the stack pointer in our newly created +	 * cache-ram (r1) */ +	lis	r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h +	ori	r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l + +	li	r0, 0		/* Make room for stack frame header and	*/ +	stwu	r0, -4(r1)	/* clear final stack frame so that	*/ +	stwu	r0, -4(r1)	/* stack backtraces terminate cleanly	*/ + +	GET_GOT			/* initialize GOT access	*/ + +	/* run low-level CPU init code     (from Flash)	*/ +	bl	cpu_init_f +	sync + +	/* run 1st part of board init code (from Flash)   */ +	bl	board_init_f +	sync + +	/* NOTREACHED - board_init_f() does not return */ + +	.globl	invalidate_bats +invalidate_bats: +	/* invalidate BATs */ +	mtspr	IBAT0U, r0 +	mtspr	IBAT1U, r0 +	mtspr	IBAT2U, r0 +	mtspr	IBAT3U, r0 +#ifdef CONFIG_HIGH_BATS +	mtspr   IBAT4U, r0 +	mtspr   IBAT5U, r0 +	mtspr   IBAT6U, r0 +	mtspr   IBAT7U, r0 +#endif +	isync +	mtspr	DBAT0U, r0 +	mtspr	DBAT1U, r0 +	mtspr	DBAT2U, r0 +	mtspr	DBAT3U, r0 +#ifdef CONFIG_HIGH_BATS +	mtspr   DBAT4U, r0 +	mtspr   DBAT5U, r0 +	mtspr   DBAT6U, r0 +	mtspr   DBAT7U, r0 +#endif +	isync +	sync +	blr + +	/* setup_bats - set them up to some initial state */ +	.globl	setup_bats +setup_bats: +	addis	r0, r0, 0x0000 + +	/* IBAT 0 */ +	addis	r4, r0, CONFIG_SYS_IBAT0L@h +	ori	r4, r4, CONFIG_SYS_IBAT0L@l +	addis	r3, r0, CONFIG_SYS_IBAT0U@h +	ori	r3, r3, CONFIG_SYS_IBAT0U@l +	mtspr	IBAT0L, r4 +	mtspr	IBAT0U, r3 +	isync + +	/* DBAT 0 */ +	addis	r4, r0, CONFIG_SYS_DBAT0L@h +	ori	r4, r4, CONFIG_SYS_DBAT0L@l +	addis	r3, r0, CONFIG_SYS_DBAT0U@h +	ori	r3, r3, CONFIG_SYS_DBAT0U@l +	mtspr	DBAT0L, r4 +	mtspr	DBAT0U, r3 +	isync + +	/* IBAT 1 */ +	addis	r4, r0, CONFIG_SYS_IBAT1L@h +	ori	r4, r4, CONFIG_SYS_IBAT1L@l +	addis	r3, r0, CONFIG_SYS_IBAT1U@h +	ori	r3, r3, CONFIG_SYS_IBAT1U@l +	mtspr	IBAT1L, r4 +	mtspr	IBAT1U, r3 +	isync + +	/* DBAT 1 */ +	addis	r4, r0, CONFIG_SYS_DBAT1L@h +	ori	r4, r4, CONFIG_SYS_DBAT1L@l +	addis	r3, r0, CONFIG_SYS_DBAT1U@h +	ori	r3, r3, CONFIG_SYS_DBAT1U@l +	mtspr	DBAT1L, r4 +	mtspr	DBAT1U, r3 +	isync + +	/* IBAT 2 */ +	addis	r4, r0, CONFIG_SYS_IBAT2L@h +	ori	r4, r4, CONFIG_SYS_IBAT2L@l +	addis	r3, r0, CONFIG_SYS_IBAT2U@h +	ori	r3, r3, CONFIG_SYS_IBAT2U@l +	mtspr	IBAT2L, r4 +	mtspr	IBAT2U, r3 +	isync + +	/* DBAT 2 */ +	addis	r4, r0, CONFIG_SYS_DBAT2L@h +	ori	r4, r4, CONFIG_SYS_DBAT2L@l +	addis	r3, r0, CONFIG_SYS_DBAT2U@h +	ori	r3, r3, CONFIG_SYS_DBAT2U@l +	mtspr	DBAT2L, r4 +	mtspr	DBAT2U, r3 +	isync + +	/* IBAT 3 */ +	addis	r4, r0, CONFIG_SYS_IBAT3L@h +	ori	r4, r4, CONFIG_SYS_IBAT3L@l +	addis	r3, r0, CONFIG_SYS_IBAT3U@h +	ori	r3, r3, CONFIG_SYS_IBAT3U@l +	mtspr	IBAT3L, r4 +	mtspr	IBAT3U, r3 +	isync + +	/* DBAT 3 */ +	addis	r4, r0, CONFIG_SYS_DBAT3L@h +	ori	r4, r4, CONFIG_SYS_DBAT3L@l +	addis	r3, r0, CONFIG_SYS_DBAT3U@h +	ori	r3, r3, CONFIG_SYS_DBAT3U@l +	mtspr	DBAT3L, r4 +	mtspr	DBAT3U, r3 +	isync + +#ifdef CONFIG_HIGH_BATS +	/* IBAT 4 */ +	addis   r4, r0, CONFIG_SYS_IBAT4L@h +	ori     r4, r4, CONFIG_SYS_IBAT4L@l +	addis   r3, r0, CONFIG_SYS_IBAT4U@h +	ori     r3, r3, CONFIG_SYS_IBAT4U@l +	mtspr   IBAT4L, r4 +	mtspr   IBAT4U, r3 +	isync + +	/* DBAT 4 */ +	addis   r4, r0, CONFIG_SYS_DBAT4L@h +	ori     r4, r4, CONFIG_SYS_DBAT4L@l +	addis   r3, r0, CONFIG_SYS_DBAT4U@h +	ori     r3, r3, CONFIG_SYS_DBAT4U@l +	mtspr   DBAT4L, r4 +	mtspr   DBAT4U, r3 +	isync + +	/* IBAT 5 */ +	addis   r4, r0, CONFIG_SYS_IBAT5L@h +	ori     r4, r4, CONFIG_SYS_IBAT5L@l +	addis   r3, r0, CONFIG_SYS_IBAT5U@h +	ori     r3, r3, CONFIG_SYS_IBAT5U@l +	mtspr   IBAT5L, r4 +	mtspr   IBAT5U, r3 +	isync + +	/* DBAT 5 */ +	addis   r4, r0, CONFIG_SYS_DBAT5L@h +	ori     r4, r4, CONFIG_SYS_DBAT5L@l +	addis   r3, r0, CONFIG_SYS_DBAT5U@h +	ori     r3, r3, CONFIG_SYS_DBAT5U@l +	mtspr   DBAT5L, r4 +	mtspr   DBAT5U, r3 +	isync + +	/* IBAT 6 */ +	addis   r4, r0, CONFIG_SYS_IBAT6L@h +	ori     r4, r4, CONFIG_SYS_IBAT6L@l +	addis   r3, r0, CONFIG_SYS_IBAT6U@h +	ori     r3, r3, CONFIG_SYS_IBAT6U@l +	mtspr   IBAT6L, r4 +	mtspr   IBAT6U, r3 +	isync + +	/* DBAT 6 */ +	addis   r4, r0, CONFIG_SYS_DBAT6L@h +	ori     r4, r4, CONFIG_SYS_DBAT6L@l +	addis   r3, r0, CONFIG_SYS_DBAT6U@h +	ori     r3, r3, CONFIG_SYS_DBAT6U@l +	mtspr   DBAT6L, r4 +	mtspr   DBAT6U, r3 +	isync + +	/* IBAT 7 */ +	addis   r4, r0, CONFIG_SYS_IBAT7L@h +	ori     r4, r4, CONFIG_SYS_IBAT7L@l +	addis   r3, r0, CONFIG_SYS_IBAT7U@h +	ori     r3, r3, CONFIG_SYS_IBAT7U@l +	mtspr   IBAT7L, r4 +	mtspr   IBAT7U, r3 +	isync + +	/* DBAT 7 */ +	addis   r4, r0, CONFIG_SYS_DBAT7L@h +	ori     r4, r4, CONFIG_SYS_DBAT7L@l +	addis   r3, r0, CONFIG_SYS_DBAT7U@h +	ori     r3, r3, CONFIG_SYS_DBAT7U@l +	mtspr   DBAT7L, r4 +	mtspr   DBAT7U, r3 +	isync +#endif + +	/* bats are done, now invalidate the TLBs */ + +	addis	r3, 0, 0x0000 +	addis	r5, 0, 0x4    /* upper bound of 0x00040000 for 7400/750 */ + +	isync + +tlblp: +	tlbie	r3 +	sync +	addi	r3, r3, 0x1000 +	cmp	0, 0, r3, r5 +	blt tlblp + +	blr + +	.globl enable_addr_trans +enable_addr_trans: +	/* enable address translation */ +	mfmsr	r5 +	ori	r5, r5, (MSR_IR | MSR_DR) +	mtmsr	r5 +	isync +	blr + +	.globl disable_addr_trans +disable_addr_trans: +	/* disable address translation */ +	mflr	r4 +	mfmsr	r3 +	andi.	r0, r3, (MSR_IR | MSR_DR) +	beqlr +	andc	r3, r3, r0 +	mtspr	SRR0, r4 +	mtspr	SRR1, r3 +	rfi + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception. + * Register r21 is pointer into trap frame, r1 has new stack pointer. + */ +	.globl	transfer_to_handler +transfer_to_handler: +	stw	r22,_NIP(r21) +	lis	r22,MSR_POW@h +	andc	r23,r23,r22 +	stw	r23,_MSR(r21) +	SAVE_GPR(7, r21) +	SAVE_4GPRS(8, r21) +	SAVE_8GPRS(12, r21) +	SAVE_8GPRS(24, r21) +	mflr	r23 +	andi.	r24,r23,0x3f00		/* get vector offset */ +	stw	r24,TRAP(r21) +	li	r22,0 +	stw	r22,RESULT(r21) +	mtspr	SPRG2,r22		/* r1 is now kernel sp */ +	lwz	r24,0(r23)		/* virtual address of handler */ +	lwz	r23,4(r23)		/* where to go when done */ +	mtspr	SRR0,r24 +	mtspr	SRR1,r20 +	mtlr	r23 +	SYNC +	rfi				/* jump to handler, enable MMU */ + +int_return: +	mfmsr	r28		/* Disable interrupts */ +	li	r4,0 +	ori	r4,r4,MSR_EE +	andc	r28,r28,r4 +	SYNC			/* Some chip revs need this... */ +	mtmsr	r28 +	SYNC +	lwz	r2,_CTR(r1) +	lwz	r0,_LINK(r1) +	mtctr	r2 +	mtlr	r0 +	lwz	r2,_XER(r1) +	lwz	r0,_CCR(r1) +	mtspr	XER,r2 +	mtcrf	0xFF,r0 +	REST_10GPRS(3, r1) +	REST_10GPRS(13, r1) +	REST_8GPRS(23, r1) +	REST_GPR(31, r1) +	lwz	r2,_NIP(r1)	/* Restore environment */ +	lwz	r0,_MSR(r1) +	mtspr	SRR0,r2 +	mtspr	SRR1,r0 +	lwz	r0,GPR0(r1) +	lwz	r2,GPR2(r1) +	lwz	r1,GPR1(r1) +	SYNC +	rfi + +	.globl	dc_read +dc_read: +	blr + +	.globl get_pvr +get_pvr: +	mfspr	r3, PVR +	blr + +/*-----------------------------------------------------------------------*/ +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ +	.globl	relocate_code +relocate_code: +	mr	r1,  r3		/* Set new stack pointer		*/ +	mr	r9,  r4		/* Save copy of Global Data pointer	*/ +	mr	r10, r5		/* Save copy of Destination Address	*/ + +	GET_GOT +	mr	r3,  r5				/* Destination Address	*/ +	lis	r4, CONFIG_SYS_MONITOR_BASE@h		/* Source      Address	*/ +	ori	r4, r4, CONFIG_SYS_MONITOR_BASE@l +	lwz	r5, GOT(__init_end) +	sub	r5, r5, r4 +	li	r6, CONFIG_SYS_CACHELINE_SIZE		/* Cache Line Size	*/ + +	/* +	 * Fix GOT pointer: +	 * +	 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address +	 * +	 * Offset: +	 */ +	sub	r15, r10, r4 + +	/* First our own GOT */ +	add	r12, r12, r15 +	/* then the one used by the C code */ +	add	r30, r30, r15 + +	/* +	 * Now relocate code +	 */ +#ifdef CONFIG_ECC +	bl	board_relocate_rom +	sync +	mr	r3, r10				/* Destination Address	*/ +	lis	r4, CONFIG_SYS_MONITOR_BASE@h		/* Source      Address	*/ +	ori	r4, r4, CONFIG_SYS_MONITOR_BASE@l +	lwz	r5, GOT(__init_end) +	sub	r5, r5, r4 +	li	r6, CONFIG_SYS_CACHELINE_SIZE		/* Cache Line Size	*/ +#else +	cmplw	cr1,r3,r4 +	addi	r0,r5,3 +	srwi.	r0,r0,2 +	beq	cr1,4f		/* In place copy is not necessary	*/ +	beq	7f		/* Protect against 0 count		*/ +	mtctr	r0 +	bge	cr1,2f + +	la	r8,-4(r4) +	la	r7,-4(r3) +1:	lwzu	r0,4(r8) +	stwu	r0,4(r7) +	bdnz	1b +	b	4f + +2:	slwi	r0,r0,2 +	add	r8,r4,r0 +	add	r7,r3,r0 +3:	lwzu	r0,-4(r8) +	stwu	r0,-4(r7) +	bdnz	3b +#endif +/* + * Now flush the cache: note that we must start from a cache aligned + * address. Otherwise we might miss one cache line. + */ +4:	cmpwi	r6,0 +	add	r5,r3,r5 +	beq	7f		/* Always flush prefetch queue in any case */ +	subi	r0,r6,1 +	andc	r3,r3,r0 +	mr	r4,r3 +5:	dcbst	0,r4 +	add	r4,r4,r6 +	cmplw	r4,r5 +	blt	5b +	sync			/* Wait for all dcbst to complete on bus */ +	mr	r4,r3 +6:	icbi	0,r4 +	add	r4,r4,r6 +	cmplw	r4,r5 +	blt	6b +7:	sync			/* Wait for all icbi to complete on bus	*/ +	isync + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ +	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET +	mtlr	r0 +	blr + +in_ram: +#ifdef CONFIG_ECC +	bl	board_init_ecc +#endif +	/* +	 * Relocation Function, r12 point to got2+0x8000 +	 * +	 * Adjust got2 pointers, no need to check for 0, this code +	 * already puts a few entries in the table. +	 */ +	li	r0,__got2_entries@sectoff@l +	la	r3,GOT(_GOT2_TABLE_) +	lwz	r11,GOT(_GOT2_TABLE_) +	mtctr	r0 +	sub	r11,r3,r11 +	addi	r3,r3,-4 +1:	lwzu	r0,4(r3) +	cmpwi	r0,0 +	beq-	2f +	add	r0,r0,r11 +	stw	r0,0(r3) +2:	bdnz	1b + +	/* +	 * Now adjust the fixups and the pointers to the fixups +	 * in case we need to move ourselves again. +	 */ +	li	r0,__fixup_entries@sectoff@l +	lwz	r3,GOT(_FIXUP_TABLE_) +	cmpwi	r0,0 +	mtctr	r0 +	addi	r3,r3,-4 +	beq	4f +3:	lwzu	r4,4(r3) +	lwzux	r0,r4,r11 +	cmpwi	r0,0 +	add	r0,r0,r11 +	stw	r4,0(r3) +	beq-	5f +	stw	r0,0(r4) +5:	bdnz	3b +4: +/* clear_bss: */ +	/* +	 * Now clear BSS segment +	 */ +	lwz	r3,GOT(__bss_start) +	lwz	r4,GOT(__bss_end) + +	cmplw	0, r3, r4 +	beq	6f + +	li	r0, 0 +5: +	stw	r0, 0(r3) +	addi	r3, r3, 4 +	cmplw	0, r3, r4 +	bne	5b +6: +	mr	r3, r10		/* Destination Address		*/ +#if defined(CONFIG_DB64360)	|| \ +    defined(CONFIG_DB64460)     || \ +    defined(CONFIG_CPCI750)	|| \ +    defined(CONFIG_PPMC7XX)     || \ +    defined(CONFIG_P3Mx) +	mr	r4, r9		/* Use RAM copy of the global data */ +#endif +	bl	after_reloc + +	/* not reached - end relocate_code */ +/*-----------------------------------------------------------------------*/ + +	/* +	 * Copy exception vector code to low memory +	 * +	 * r3: dest_addr +	 * r7: source address, r8: end address, r9: target address +	 */ +	.globl	trap_init +trap_init: +	mflr	r4			/* save link register		*/ +	GET_GOT +	lwz	r7, GOT(_start) +	lwz	r8, GOT(_end_of_vectors) + +	li	r9, 0x100		/* reset vector always at 0x100 */ + +	cmplw	0, r7, r8 +	bgelr				/* return if r7>=r8 - just in case */ +1: +	lwz	r0, 0(r7) +	stw	r0, 0(r9) +	addi	r7, r7, 4 +	addi	r9, r9, 4 +	cmplw	0, r7, r8 +	bne	1b + +	/* +	 * relocate `hdlr' and `int_return' entries +	 */ +	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET +	li	r8, Alignment - _start + EXC_OFF_SYS_RESET +2: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	2b + +	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET +	bl	trap_reloc + +	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET +	bl	trap_reloc + +	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET +	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET +3: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	3b + +	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET +	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET +4: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	4b + +	/* enable execptions from RAM vectors */ +	mfmsr	r7 +	li	r8,MSR_IP +	andc	r7,r7,r8 +	mtmsr	r7 + +	mtlr	r4			/* restore link register	*/ +	blr + +#ifdef CONFIG_SYS_INIT_RAM_LOCK +lock_ram_in_cache: +	/* Allocate Initial RAM in data cache. +	 */ +	lis	r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h +	ori	r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l +	li	r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \ +		     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 +	mtctr	r4 +1: +	dcbz	r0, r3 +	addi	r3, r3, 32 +	bdnz	1b + +	/* Lock the data cache */ +	mfspr	r0, HID0 +	ori	r0, r0, 0x1000 +	sync +	mtspr	HID0, r0 +	sync +	blr + +.globl unlock_ram_in_cache +unlock_ram_in_cache: +	/* invalidate the INIT_RAM section */ +	lis	r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h +	ori	r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l +	li	r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \ +		     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 +	mtctr	r4 +1:	icbi	r0, r3 +	addi	r3, r3, 32 +	bdnz	1b +	sync			/* Wait for all icbi to complete on bus	*/ +	isync + +	/* Unlock the data cache and invalidate it */ +	mfspr   r0, HID0 +	li      r3,0x1000 +	andc    r0,r0,r3 +	li	r3,0x0400 +	or	r0,r0,r3 +	sync +	mtspr   HID0, r0 +	sync +	blr +#endif diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/traps.c b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/traps.c new file mode 100644 index 00000000..111c86cc --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/traps.c @@ -0,0 +1,218 @@ +/* + * linux/arch/powerpc/kernel/traps.c + * + * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org) + * + * Modified by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras (paulus@cs.anu.edu.au) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include <common.h> +#include <command.h> +#include <kgdb.h> +#include <asm/processor.h> + +/* Returns 0 if exception not found and fixup otherwise.  */ +extern unsigned long search_exception_table(unsigned long); + +/* THIS NEEDS CHANGING to use the board info structure. +*/ +#define END_OF_MEM	0x02000000 + +/* + * Trap & Exception support + */ + +static void print_backtrace(unsigned long *sp) +{ +	int cnt = 0; +	unsigned long i; + +	printf("Call backtrace: "); +	while (sp) { +		if ((uint)sp > END_OF_MEM) +			break; + +		i = sp[1]; +		if (cnt++ % 7 == 0) +			printf("\n"); +		printf("%08lX ", i); +		if (cnt > 32) break; +		sp = (unsigned long *)*sp; +	} +	printf("\n"); +} + +void show_regs(struct pt_regs *regs) +{ +	int i; + +	printf("NIP: %08lX XER: %08lX LR: %08lX REGS:" +	       " %p TRAP: %04lx DAR: %08lX\n", +	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); +	printf("MSR: %08lx EE: %01x PR: %01x FP:" +	       " %01x ME: %01x IR/DR: %01x%01x\n", +	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, +	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, +	       regs->msr&MSR_IR ? 1 : 0, +	       regs->msr&MSR_DR ? 1 : 0); + +	printf("\n"); +	for (i = 0;  i < 32;  i++) { +		if ((i % 8) == 0) +		{ +			printf("GPR%02d: ", i); +		} + +		printf("%08lX ", regs->gpr[i]); +		if ((i % 8) == 7) +		{ +			printf("\n"); +		} +	} +} + + +static void _exception(int signr, struct pt_regs *regs) +{ +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Exception in kernel pc %lx signal %d",regs->nip,signr); +} + +void MachineCheckException(struct pt_regs *regs) +{ +	unsigned long fixup; + +	/* Probing PCI using config cycles cause this exception +	 * when a device is not present.  Catch it and return to +	 * the PCI exception handler. +	 */ +	if ((fixup = search_exception_table(regs->nip)) != 0) { +		regs->nip = fixup; +		return; +	} + +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif + +	printf("Machine check in kernel mode.\n"); +	printf("Caused by (from msr): "); +	printf("regs %p ",regs); +	switch( regs->msr & 0x000F0000) { +	case (0x80000000>>12): +		printf("Machine check signal - probably due to mm fault\n" +			"with mmu off\n"); +		break; +	case (0x80000000>>13): +		printf("Transfer error ack signal\n"); +		break; +	case (0x80000000>>14): +		printf("Data parity signal\n"); +		break; +	case (0x80000000>>15): +		printf("Address parity signal\n"); +		break; +	default: +		printf("Unknown values in msr\n"); +	} +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("machine check"); +} + +void AlignmentException(struct pt_regs *regs) +{ +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Alignment Exception"); +} + +void ProgramCheckException(struct pt_regs *regs) +{ +	unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL; +	int i, j; + +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); + +	p = (unsigned char *) ((unsigned long)p & 0xFFFFFFE0); +	p -= 32; +	for (i = 0; i < 256; i+=16) { +		printf("%08x: ", (unsigned int)p+i); +		for (j = 0; j < 16; j++) { +			printf("%02x ", p[i+j]); +		} +		printf("\n"); +	} + +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Program Check Exception"); +} + +void SoftEmuException(struct pt_regs *regs) +{ +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Software Emulation Exception"); +} + +void UnknownException(struct pt_regs *regs) +{ +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", +	       regs->nip, regs->msr, regs->trap); +	_exception(0, regs); +} + +/* Probe an address by reading.  If not present, return -1, otherwise + * return 0. + */ +int addr_probe(uint *addr) +{ +#if 0 +	int	retval; + +	__asm__ __volatile__(			\ +		"1:	lwz %0,0(%1)\n"		\ +		"	eieio\n"		\ +		"	li %0,0\n"		\ +		"2:\n"				\ +		".section .fixup,\"ax\"\n"	\ +		"3:	li %0,-1\n"		\ +		"	b 2b\n"			\ +		".section __ex_table,\"a\"\n"	\ +		"	.align 2\n"		\ +		"	.long 1b,3b\n"		\ +		".text"				\ +		: "=r" (retval) : "r"(addr)); + +	return (retval); +#endif +	return 0; +} diff --git a/roms/u-boot/arch/powerpc/cpu/74xx_7xx/u-boot.lds b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/u-boot.lds new file mode 100644 index 00000000..c0998490 --- /dev/null +++ b/roms/u-boot/arch/powerpc/cpu/74xx_7xx/u-boot.lds @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2010 Wolfgang Denk <wd@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) + +SECTIONS +{ +  .text      : +  { +    arch/powerpc/cpu/74xx_7xx/start.o	(.text*) + +    *(.text*) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) +  } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x00FF) & 0xFFFFFF00; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    _GOT2_TABLE_ = .; +    KEEP(*(.got2)) +    KEEP(*(.got)) +    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4); +    _FIXUP_TABLE_ = .; +    KEEP(*(.fixup)) +  } +  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data*) +    *(.sdata*) +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  . = .; + +  . = ALIGN(4); +  .u_boot_list : { +	KEEP(*(SORT(.u_boot_list*))); +  } + + +  . = .; +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(256); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(256); +  __init_end = .; + +  __bss_start = .; +  .bss (NOLOAD)       : +  { +   *(.bss*) +   *(.sbss*) +   *(COMMON) +   . = ALIGN(4); +  } +  __bss_end = . ; +  PROVIDE (end = .); +}  | 
