GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
menu "mpc86xx CPU"
|
||||
depends on MPC86xx
|
||||
|
||||
config SYS_CPU
|
||||
default "mpc86xx"
|
||||
|
||||
choice
|
||||
prompt "Target select"
|
||||
optional
|
||||
|
||||
config TARGET_SBC8641D
|
||||
bool "Support sbc8641d"
|
||||
select ARCH_MPC8641
|
||||
select BOARD_EARLY_INIT_F
|
||||
|
||||
config TARGET_MPC8610HPCD
|
||||
bool "Support MPC8610HPCD"
|
||||
select ARCH_MPC8610
|
||||
select BOARD_EARLY_INIT_F
|
||||
|
||||
config TARGET_MPC8641HPCN
|
||||
bool "Support MPC8641HPCN"
|
||||
select ARCH_MPC8641
|
||||
select FSL_DDR_INTERACTIVE
|
||||
imply SCSI
|
||||
|
||||
config TARGET_XPEDITE517X
|
||||
bool "Support xpedite517x"
|
||||
select ARCH_MPC8641
|
||||
|
||||
endchoice
|
||||
|
||||
config ARCH_MPC8610
|
||||
bool
|
||||
select FSL_LAW
|
||||
select SYS_FSL_HAS_DDR1
|
||||
select SYS_FSL_HAS_DDR2
|
||||
|
||||
config ARCH_MPC8641
|
||||
bool
|
||||
select FSL_LAW
|
||||
select SYS_FSL_HAS_DDR1
|
||||
select SYS_FSL_HAS_DDR2
|
||||
|
||||
config FSL_LAW
|
||||
bool
|
||||
help
|
||||
Use Freescale common code for Local Access Window
|
||||
|
||||
config SYS_CCSRBAR_DEFAULT
|
||||
hex "Default CCSRBAR address"
|
||||
default 0xff700000 if ARCH_MPC8610 || ARCH_MPC8641
|
||||
help
|
||||
Default value of CCSRBAR comes from power-on-reset. It
|
||||
is fixed on each SoC. Some SoCs can have different value
|
||||
if changed by pre-boot regime. The value here must match
|
||||
the current value in SoC. If not sure, do not change.
|
||||
config SYS_FSL_NUM_LAWS
|
||||
int "Number of local access windows"
|
||||
default 10 if ARCH_MPC8610 || ARCH_MPC8641
|
||||
help
|
||||
Number of local access windows. This is fixed per SoC.
|
||||
If not sure, do not change.
|
||||
|
||||
source "board/freescale/mpc8610hpcd/Kconfig"
|
||||
source "board/freescale/mpc8641hpcn/Kconfig"
|
||||
source "board/sbc8641d/Kconfig"
|
||||
source "board/xes/xpedite517x/Kconfig"
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright 2007 Freescale Semiconductor, Inc.
|
||||
# (C) Copyright 2002,2003 Motorola Inc.
|
||||
# Xianghua Xiao,X.Xiao@motorola.com
|
||||
#
|
||||
# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port)
|
||||
# Jeff Brown
|
||||
#
|
||||
|
||||
extra-y = start.o
|
||||
extra-y += traps.o
|
||||
|
||||
obj-y += cache.o
|
||||
obj-$(CONFIG_MP) += release.o
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-y += cpu_init.o
|
||||
obj-$(CONFIG_OF_LIBFDT) += fdt.o
|
||||
obj-y += interrupts.o
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
obj-$(CONFIG_ARCH_MPC8610) += mpc8610_serdes.o
|
||||
obj-$(CONFIG_ARCH_MPC8641) += mpc8641_serdes.o
|
||||
obj-y += speed.o
|
||||
@@ -0,0 +1,332 @@
|
||||
#include <config.h>
|
||||
#include <mpc86xx.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
|
||||
|
||||
/*
|
||||
* Most of this code is taken from 74xx_7xx/cache.S
|
||||
* and then cleaned up a bit
|
||||
*/
|
||||
|
||||
/*
|
||||
* Invalidate L1 instruction cache.
|
||||
*/
|
||||
_GLOBAL(invalidate_l1_instruction_cache)
|
||||
/* 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)
|
||||
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
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* void __flush_page_to_ram(void *page)
|
||||
*/
|
||||
_GLOBAL(__flush_page_to_ram)
|
||||
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.
|
||||
*
|
||||
* void __flush_icache_page(void *page)
|
||||
*/
|
||||
_GLOBAL(__flush_icache_page)
|
||||
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, assume L2 is enabled
|
||||
*/
|
||||
_GLOBAL(l2cache_invalidate)
|
||||
mfspr r3, l2cr
|
||||
rlwinm. r3, r3, 0, 0, 0
|
||||
beq 1f
|
||||
|
||||
mfspr r3, l2cr
|
||||
rlwinm r3, r3, 0, 1, 31
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
dssall
|
||||
#endif
|
||||
sync
|
||||
mtspr l2cr, r3
|
||||
sync
|
||||
1: mfspr r3, l2cr
|
||||
oris r3, r3, L2CR_L2I@h
|
||||
mtspr l2cr, r3
|
||||
|
||||
invl2:
|
||||
mfspr r3, l2cr
|
||||
andis. r3, r3, L2CR_L2I@h
|
||||
bne invl2
|
||||
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
|
||||
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2004 Freescale Semiconductor.
|
||||
# Jeff Brown
|
||||
|
||||
PLATFORM_CPPFLAGS += -mcpu=7400 -mstring -maltivec -mabi=altivec -msoft-float
|
||||
@@ -0,0 +1,204 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2006,2009-2010 Freescale Semiconductor, Inc.
|
||||
* Jeff Brown
|
||||
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <vsprintf.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <mpc86xx.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <asm/ppc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Default board reset function
|
||||
*/
|
||||
static void
|
||||
__board_reset(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
void board_reset(void) __attribute__((weak, alias("__board_reset")));
|
||||
|
||||
|
||||
int
|
||||
checkcpu(void)
|
||||
{
|
||||
sys_info_t sysinfo;
|
||||
uint pvr, svr;
|
||||
uint major, minor;
|
||||
char buf1[32], buf2[32];
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
struct cpu_type *cpu;
|
||||
uint msscr0 = mfspr(MSSCR0);
|
||||
|
||||
svr = get_svr();
|
||||
major = SVR_MAJ(svr);
|
||||
minor = SVR_MIN(svr);
|
||||
|
||||
if (cpu_numcores() > 1) {
|
||||
#ifndef CONFIG_MP
|
||||
puts("Unicore software on multiprocessor system!!\n"
|
||||
"To enable mutlticore build define CONFIG_MP\n");
|
||||
#endif
|
||||
}
|
||||
puts("CPU: ");
|
||||
|
||||
cpu = gd->arch.cpu;
|
||||
|
||||
puts(cpu->name);
|
||||
|
||||
printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
|
||||
puts("Core: ");
|
||||
|
||||
pvr = get_pvr();
|
||||
major = PVR_E600_MAJ(pvr);
|
||||
minor = PVR_E600_MIN(pvr);
|
||||
|
||||
printf("e600 Core %d", (msscr0 & 0x20) ? 1 : 0);
|
||||
if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
|
||||
puts("\n Core1Translation Enabled");
|
||||
debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
|
||||
|
||||
printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
|
||||
|
||||
get_sys_info(&sysinfo);
|
||||
|
||||
puts("Clock Configuration:\n");
|
||||
printf(" CPU:%-4s MHz, ", strmhz(buf1, sysinfo.freq_processor));
|
||||
printf("MPX:%-4s MHz\n", strmhz(buf1, sysinfo.freq_systembus));
|
||||
printf(" DDR:%-4s MHz (%s MT/s data rate), ",
|
||||
strmhz(buf1, sysinfo.freq_systembus / 2),
|
||||
strmhz(buf2, sysinfo.freq_systembus));
|
||||
|
||||
if (sysinfo.freq_localbus > LCRR_CLKDIV) {
|
||||
printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
|
||||
} else {
|
||||
printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n",
|
||||
sysinfo.freq_localbus);
|
||||
}
|
||||
|
||||
puts("L1: D-cache 32 KiB enabled\n");
|
||||
puts(" I-cache 32 KiB enabled\n");
|
||||
|
||||
puts("L2: ");
|
||||
if (get_l2cr() & 0x80000000) {
|
||||
#if defined(CONFIG_ARCH_MPC8610)
|
||||
puts("256");
|
||||
#elif defined(CONFIG_ARCH_MPC8641)
|
||||
puts("512");
|
||||
#endif
|
||||
puts(" KiB enabled\n");
|
||||
} else {
|
||||
puts("Disabled\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
|
||||
/* Attempt board-specific reset */
|
||||
board_reset();
|
||||
|
||||
/* Next try asserting HRESET_REQ */
|
||||
out_be32(&gur->rstcr, MPC86xx_RSTCR_HRST_REQ);
|
||||
|
||||
while (1)
|
||||
;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get timebase clock frequency
|
||||
*/
|
||||
unsigned long
|
||||
get_tbclk(void)
|
||||
{
|
||||
sys_info_t sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
return (sys_info.freq_systembus + 3L) / 4L;
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
void
|
||||
watchdog_reset(void)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_MPC8610)
|
||||
/*
|
||||
* This actually feed the hard enabled watchdog.
|
||||
*/
|
||||
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile ccsr_wdt_t *wdt = &immap->im_wdt;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
u32 tmp = gur->pordevsr;
|
||||
|
||||
if (tmp & 0x4000) {
|
||||
wdt->swsrr = 0x556c;
|
||||
wdt->swsrr = 0xaa39;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
|
||||
/*
|
||||
* Print out the state of various machine registers.
|
||||
* Currently prints out LAWs, BR0/OR0, and BATs
|
||||
*/
|
||||
void print_reginfo(void)
|
||||
{
|
||||
print_bats();
|
||||
print_laws();
|
||||
print_lbc_regs();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the DDR BATs to reflect the actual size of DDR.
|
||||
*
|
||||
* dram_size is the actual size of DDR, in bytes
|
||||
*
|
||||
* Note: we assume that CONFIG_MAX_MEM_MAPPED is 2G or smaller as we only
|
||||
* are using a single BAT to cover DDR.
|
||||
*
|
||||
* If this is not true, (e.g. CONFIG_MAX_MEM_MAPPED is 2GB but HID0_XBSEN
|
||||
* is not defined) then we might have a situation where U-Boot will attempt
|
||||
* to relocated itself outside of the region mapped by DBAT0.
|
||||
* This will cause a machine check.
|
||||
*
|
||||
* Currently we are limited to power of two sized DDR since we only use a
|
||||
* single bat. If a non-power of two size is used that is less than
|
||||
* CONFIG_MAX_MEM_MAPPED u-boot will crash.
|
||||
*
|
||||
*/
|
||||
void setup_ddr_bat(phys_addr_t dram_size)
|
||||
{
|
||||
unsigned long batu, bl;
|
||||
|
||||
bl = TO_BATU_BL(min(dram_size, CONFIG_MAX_MEM_MAPPED));
|
||||
|
||||
if (BATU_SIZE(bl) != dram_size) {
|
||||
u64 sz = (u64)dram_size - BATU_SIZE(bl);
|
||||
print_size(sz, " left unmapped\n");
|
||||
}
|
||||
|
||||
batu = bl | BATU_VS | BATU_VP;
|
||||
write_bat(DBAT0, batu, CONFIG_SYS_DBAT0L);
|
||||
write_bat(IBAT0, batu, CONFIG_SYS_IBAT0L);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2004,2009-2011 Freescale Semiconductor, Inc.
|
||||
* Jeff Brown
|
||||
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
|
||||
*/
|
||||
|
||||
/*
|
||||
* cpu_init.c - low level cpu init
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <mpc86xx.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
#include <asm/mp.h>
|
||||
|
||||
extern void srio_init(void);
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Breathe some life into the CPU...
|
||||
*
|
||||
* Set up the memory map
|
||||
* initialize a bunch of registers
|
||||
*/
|
||||
|
||||
void cpu_init_f(void)
|
||||
{
|
||||
/* Pointer is writable since we allocated a register for it */
|
||||
gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
|
||||
|
||||
/* Clear initial global data */
|
||||
memset ((void *) gd, 0, sizeof (gd_t));
|
||||
|
||||
#ifdef CONFIG_FSL_LAW
|
||||
init_laws();
|
||||
#endif
|
||||
|
||||
setup_bats();
|
||||
|
||||
init_early_memctl_regs();
|
||||
|
||||
#if defined(CONFIG_FSL_DMA)
|
||||
dma_init();
|
||||
#endif
|
||||
|
||||
/* enable the timebase bit in HID0 */
|
||||
set_hid0(get_hid0() | 0x4000000);
|
||||
|
||||
/* enable EMCP, SYNCBE | ABE bits in HID1 */
|
||||
set_hid1(get_hid1() | 0x80000C00);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize higher level parts of CPU like timers
|
||||
*/
|
||||
int cpu_init_r(void)
|
||||
{
|
||||
/* needs to be in ram since code uses global static vars */
|
||||
fsl_serdes_init();
|
||||
|
||||
#ifdef CONFIG_SYS_SRIO
|
||||
srio_init();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MP)
|
||||
setup_mp();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ADDR_MAP
|
||||
/* Initialize address mapping array */
|
||||
void init_addr_map(void)
|
||||
{
|
||||
int i;
|
||||
ppc_bat_t bat = DBAT0;
|
||||
phys_size_t size;
|
||||
unsigned long upper, lower;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++, bat++) {
|
||||
if (read_bat(bat, &upper, &lower) != -1) {
|
||||
if (!BATU_VALID(upper))
|
||||
size = 0;
|
||||
else
|
||||
size = BATU_SIZE(upper);
|
||||
addrmap_set_entry(BATU_VADDR(upper), BATL_PADDR(lower),
|
||||
size, i);
|
||||
}
|
||||
#ifdef CONFIG_HIGH_BATS
|
||||
/* High bats are not contiguous with low BAT numbers */
|
||||
if (bat == DBAT3)
|
||||
bat = DBAT4 - 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2008, 2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/mp.h>
|
||||
|
||||
extern void ft_fixup_num_cores(void *blob);
|
||||
extern void ft_srio_setup(void *blob);
|
||||
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
#ifdef CONFIG_MP
|
||||
int off;
|
||||
u32 bootpg = determine_mp_bootpg(NULL);
|
||||
#endif
|
||||
|
||||
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);
|
||||
do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
|
||||
"bus-frequency", bd->bi_busfreq, 1);
|
||||
|
||||
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
|
||||
|
||||
#ifdef CONFIG_SYS_NS16550
|
||||
do_fixup_by_compat_u32(blob, "ns16550",
|
||||
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MP
|
||||
/* Reserve the boot page so OSes dont use it */
|
||||
off = fdt_add_mem_rsv(blob, bootpg, (u64)4096);
|
||||
if (off < 0)
|
||||
printf("%s: %s\n", __FUNCTION__, fdt_strerror(off));
|
||||
|
||||
ft_fixup_num_cores(blob);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_SRIO
|
||||
ft_srio_setup(blob);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2000-2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2002 (440 port)
|
||||
* Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
|
||||
*
|
||||
* (C) Copyright 2003 Motorola Inc. (MPC85xx port)
|
||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||
*
|
||||
* (C) Copyright 2004, 2007 Freescale Semiconductor. (MPC86xx Port)
|
||||
* Jeff Brown
|
||||
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <irq_func.h>
|
||||
#include <mpc86xx.h>
|
||||
#include <command.h>
|
||||
#include <asm/processor.h>
|
||||
#ifdef CONFIG_POST
|
||||
#include <post.h>
|
||||
#endif
|
||||
|
||||
void interrupt_init_cpu(unsigned *decrementer_count)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile ccsr_pic_t *pic = &immr->im_pic;
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
/*
|
||||
* The POST word is stored in the PIC's TFRR register which gets
|
||||
* cleared when the PIC is reset. Save it off so we can restore it
|
||||
* later.
|
||||
*/
|
||||
ulong post_word = post_word_load();
|
||||
#endif
|
||||
|
||||
pic->gcr = MPC86xx_PICGCR_RST;
|
||||
while (pic->gcr & MPC86xx_PICGCR_RST)
|
||||
;
|
||||
pic->gcr = MPC86xx_PICGCR_MODE;
|
||||
|
||||
*decrementer_count = get_tbclk() / CONFIG_SYS_HZ;
|
||||
debug("interrupt init: tbclk() = %ld MHz, decrementer_count = %d\n",
|
||||
(get_tbclk() / 1000000),
|
||||
*decrementer_count);
|
||||
|
||||
#ifdef CONFIG_INTERRUPTS
|
||||
|
||||
pic->iivpr1 = 0x810001; /* 50220 enable mcm interrupts */
|
||||
debug("iivpr1@%p = %x\n", &pic->iivpr1, pic->iivpr1);
|
||||
|
||||
pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */
|
||||
debug("iivpr2@%p = %x\n", &pic->iivpr2, pic->iivpr2);
|
||||
|
||||
pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */
|
||||
debug("iivpr3@%p = %x\n", &pic->iivpr3, pic->iivpr3);
|
||||
|
||||
#if defined(CONFIG_PCI1) || defined(CONFIG_PCIE1)
|
||||
pic->iivpr8 = 0x810008; /* enable pcie1 interrupts */
|
||||
debug("iivpr8@%p = %x\n", &pic->iivpr8, pic->iivpr8);
|
||||
#endif
|
||||
#if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2)
|
||||
pic->iivpr9 = 0x810009; /* enable pcie2 interrupts */
|
||||
debug("iivpr9@%p = %x\n", &pic->iivpr9, pic->iivpr9);
|
||||
#endif
|
||||
|
||||
pic->ctpr = 0; /* 40080 clear current task priority register */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
post_word_store(post_word);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Install and free a interrupt handler. Not implemented yet.
|
||||
*/
|
||||
void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
|
||||
{
|
||||
}
|
||||
|
||||
void irq_free_handler(int vec)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* irqinfo - print information about PCI devices,not implemented.
|
||||
*/
|
||||
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle external interrupts
|
||||
*/
|
||||
void external_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
puts("external_interrupt(oops!)\n");
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2008-2010 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <ioports.h>
|
||||
#include <lmb.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mp.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int cpu_reset(u32 nr)
|
||||
{
|
||||
/* dummy function so common/cmd_mp.c will build
|
||||
* should be implemented in the future, when cpu_release()
|
||||
* is supported. Be aware there may be a similiar bug
|
||||
* as exists on MPC85xx w/its PIC having a timing window
|
||||
* associated to resetting the core */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cpu_status(u32 nr)
|
||||
{
|
||||
/* dummy function so common/cmd_mp.c will build */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_disable(u32 nr)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
|
||||
switch (nr) {
|
||||
case 0:
|
||||
setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU0);
|
||||
break;
|
||||
case 1:
|
||||
setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU1);
|
||||
break;
|
||||
default:
|
||||
printf("Invalid cpu number for disable %d\n", nr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_core_disabled(int nr) {
|
||||
immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
|
||||
ccsr_gur_t *gur = &immap->im_gur;
|
||||
u32 devdisr = in_be32(&gur->devdisr);
|
||||
|
||||
switch (nr) {
|
||||
case 0:
|
||||
return (devdisr & MPC86xx_DEVDISR_CPU0);
|
||||
case 1:
|
||||
return (devdisr & MPC86xx_DEVDISR_CPU1);
|
||||
default:
|
||||
printf("Invalid cpu number for disable %d\n", nr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_release(u32 nr, int argc, char * const argv[])
|
||||
{
|
||||
/* dummy function so common/cmd_mp.c will build
|
||||
* should be implemented in the future */
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 determine_mp_bootpg(unsigned int *pagesize)
|
||||
{
|
||||
if (pagesize)
|
||||
*pagesize = 4096;
|
||||
|
||||
/* if we have 4G or more of memory, put the boot page at 4Gb-1M */
|
||||
if ((u64)gd->ram_size > 0xfffff000)
|
||||
return (0xfff00000);
|
||||
|
||||
return (gd->ram_size - (1024 * 1024));
|
||||
}
|
||||
|
||||
void cpu_mp_lmb_reserve(struct lmb *lmb)
|
||||
{
|
||||
u32 bootpg = determine_mp_bootpg(NULL);
|
||||
|
||||
/* tell u-boot we stole a page */
|
||||
lmb_reserve(lmb, bootpg, 4096);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the code for other cpus to execute into an
|
||||
* aligned location accessible via BPTR
|
||||
*/
|
||||
void setup_mp(void)
|
||||
{
|
||||
extern ulong __secondary_start_page;
|
||||
ulong fixup = (ulong)&__secondary_start_page;
|
||||
u32 bootpg = determine_mp_bootpg(NULL);
|
||||
u32 bootpg_va;
|
||||
|
||||
if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) {
|
||||
/* We're not covered by the DDR mapping, set up BAT */
|
||||
write_bat(DBAT7, CONFIG_SYS_SCRATCH_VA | BATU_BL_128K |
|
||||
BATU_VS | BATU_VP,
|
||||
bootpg | BATL_PP_RW | BATL_MEMCOHERENCE);
|
||||
bootpg_va = CONFIG_SYS_SCRATCH_VA;
|
||||
} else {
|
||||
bootpg_va = bootpg;
|
||||
}
|
||||
|
||||
memcpy((void *)bootpg_va, (void *)fixup, 4096);
|
||||
flush_cache(bootpg_va, 4096);
|
||||
|
||||
/* remove the temporary BAT mapping */
|
||||
if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE)
|
||||
write_bat(DBAT7, 0, 0);
|
||||
|
||||
/* If the physical location of bootpg is not at fff00000, set BPTR */
|
||||
if (bootpg != 0xfff00000)
|
||||
out_be32((uint *)(CONFIG_SYS_CCSRBAR + 0x20), 0x80000000 |
|
||||
(bootpg >> 12));
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2010 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/immap_86xx.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
|
||||
#define SRDS1_MAX_LANES 4
|
||||
#define SRDS2_MAX_LANES 4
|
||||
|
||||
static u32 serdes1_prtcl_map, serdes2_prtcl_map;
|
||||
|
||||
static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
|
||||
[0x1] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x4] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x7] = {NONE, NONE, NONE, NONE},
|
||||
};
|
||||
|
||||
static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
|
||||
[0x0] = {PCIE2, PCIE2, PCIE2, PCIE2},
|
||||
[0x4] = {PCIE2, PCIE2, PCIE2, PCIE2},
|
||||
[0x7] = {NONE, NONE, NONE, NONE},
|
||||
};
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(serdes1_prtcl_map & (1 << NONE)))
|
||||
fsl_serdes_init();
|
||||
|
||||
ret = (1 << device) & serdes1_prtcl_map;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(serdes2_prtcl_map & (1 << NONE)))
|
||||
fsl_serdes_init();
|
||||
|
||||
return (1 << device) & serdes2_prtcl_map;
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
|
||||
ccsr_gur_t *gur = &immap->im_gur;
|
||||
u32 pordevsr = in_be32(&gur->pordevsr);
|
||||
u32 srds_cfg = (pordevsr & MPC8610_PORDEVSR_IO_SEL) >>
|
||||
MPC8610_PORDEVSR_IO_SEL_SHIFT;
|
||||
int lane;
|
||||
|
||||
if (serdes1_prtcl_map & (1 << NONE) &&
|
||||
serdes2_prtcl_map & (1 << NONE))
|
||||
return;
|
||||
|
||||
debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
|
||||
|
||||
if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
|
||||
printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
|
||||
return;
|
||||
}
|
||||
for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
|
||||
serdes1_prtcl_map |= (1 << lane_prtcl);
|
||||
}
|
||||
|
||||
/* Set the first bit to indicate serdes has been initialized */
|
||||
serdes1_prtcl_map |= (1 << NONE);
|
||||
|
||||
if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
|
||||
printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (lane = 0; lane < SRDS2_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
|
||||
serdes2_prtcl_map |= (1 << lane_prtcl);
|
||||
}
|
||||
|
||||
/* Set the first bit to indicate serdes has been initialized */
|
||||
serdes2_prtcl_map |= (1 << NONE);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2010 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/immap_86xx.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
|
||||
#define SRDS1_MAX_LANES 4
|
||||
#define SRDS2_MAX_LANES 4
|
||||
|
||||
static u32 serdes1_prtcl_map, serdes2_prtcl_map;
|
||||
|
||||
static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
|
||||
[0x2] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x3] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x5] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x6] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0x7] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
[0xf] = {PCIE1, PCIE1, PCIE1, PCIE1},
|
||||
};
|
||||
|
||||
static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
|
||||
[0x3] = {PCIE2, PCIE2, PCIE2, PCIE2},
|
||||
[0x5] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0x6] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0x7] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0x9] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0xa] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0xb] = {SRIO1, SRIO1, SRIO1, SRIO1},
|
||||
[0xe] = {PCIE2, PCIE2, PCIE2, PCIE2},
|
||||
[0xf] = {PCIE2, PCIE2, PCIE2, PCIE2},
|
||||
};
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(serdes1_prtcl_map & (1 << NONE)))
|
||||
fsl_serdes_init();
|
||||
|
||||
ret = (1 << device) & serdes1_prtcl_map;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(serdes2_prtcl_map & (1 << NONE)))
|
||||
fsl_serdes_init();
|
||||
|
||||
return (1 << device) & serdes2_prtcl_map;
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
|
||||
ccsr_gur_t *gur = &immap->im_gur;
|
||||
u32 pordevsr = in_be32(&gur->pordevsr);
|
||||
u32 srds_cfg = (pordevsr & MPC8641_PORDEVSR_IO_SEL) >>
|
||||
MPC8641_PORDEVSR_IO_SEL_SHIFT;
|
||||
int lane;
|
||||
|
||||
if (serdes1_prtcl_map & (1 << NONE) &&
|
||||
serdes2_prtcl_map & (1 << NONE))
|
||||
return;
|
||||
|
||||
debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
|
||||
|
||||
if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
|
||||
printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
|
||||
return;
|
||||
}
|
||||
for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
|
||||
serdes1_prtcl_map |= (1 << lane_prtcl);
|
||||
}
|
||||
|
||||
/* Set the first bit to indicate serdes has been initialized */
|
||||
serdes1_prtcl_map |= (1 << NONE);
|
||||
|
||||
if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
|
||||
printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (lane = 0; lane < SRDS2_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
|
||||
serdes2_prtcl_map |= (1 << lane_prtcl);
|
||||
}
|
||||
|
||||
/* Set the first bit to indicate serdes has been initialized */
|
||||
serdes2_prtcl_map |= (1 << NONE);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2004, 2007, 2008 Freescale Semiconductor.
|
||||
* Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <mpc86xx.h>
|
||||
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
/* If this is a multi-cpu system then we need to handle the
|
||||
* 2nd cpu. The assumption is that the 2nd cpu is being
|
||||
* held in boot holdoff mode until the 1st cpu unlocks it
|
||||
* from Linux. We'll do some basic cpu init and then pass
|
||||
* it to the Linux Reset Vector.
|
||||
* Sri: Much of this initialization is not required. Linux
|
||||
* rewrites the bats, and the sprs and also enables the L1 cache.
|
||||
*
|
||||
* Core 0 must copy this to a 1M aligned region and set BPTR
|
||||
* to point to it.
|
||||
*/
|
||||
.align 12
|
||||
.globl __secondary_start_page
|
||||
__secondary_start_page:
|
||||
.space 0x100 /* space over to reset vector loc */
|
||||
mfspr r0, MSSCR0
|
||||
andi. r0, r0, 0x0020
|
||||
rlwinm r0,r0,27,31,31
|
||||
mtspr PIR, r0
|
||||
|
||||
/* Invalidate BATs */
|
||||
li r0, 0
|
||||
mtspr IBAT0U, r0
|
||||
mtspr IBAT1U, r0
|
||||
mtspr IBAT2U, r0
|
||||
mtspr IBAT3U, r0
|
||||
mtspr IBAT4U, r0
|
||||
mtspr IBAT5U, r0
|
||||
mtspr IBAT6U, r0
|
||||
mtspr IBAT7U, r0
|
||||
isync
|
||||
mtspr DBAT0U, r0
|
||||
mtspr DBAT1U, r0
|
||||
mtspr DBAT2U, r0
|
||||
mtspr DBAT3U, r0
|
||||
mtspr DBAT4U, r0
|
||||
mtspr DBAT5U, r0
|
||||
mtspr DBAT6U, r0
|
||||
mtspr DBAT7U, r0
|
||||
isync
|
||||
sync
|
||||
|
||||
/* enable extended addressing */
|
||||
mfspr r0, HID0
|
||||
lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
|
||||
ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
|
||||
mtspr HID0, r0
|
||||
sync
|
||||
isync
|
||||
|
||||
#ifdef CONFIG_SYS_L2
|
||||
/* init the L2 cache */
|
||||
addis r3, r0, L2_INIT@h
|
||||
ori r3, r3, L2_INIT@l
|
||||
sync
|
||||
mtspr l2cr, r3
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
dssall
|
||||
#endif
|
||||
/* invalidate the L2 cache */
|
||||
mfspr r3, l2cr
|
||||
rlwinm. r3, r3, 0, 0, 0
|
||||
beq 1f
|
||||
|
||||
mfspr r3, l2cr
|
||||
rlwinm r3, r3, 0, 1, 31
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
dssall
|
||||
#endif
|
||||
sync
|
||||
mtspr l2cr, r3
|
||||
sync
|
||||
1: mfspr r3, l2cr
|
||||
oris r3, r3, L2CR_L2I@h
|
||||
mtspr l2cr, r3
|
||||
|
||||
invl2:
|
||||
mfspr r3, l2cr
|
||||
andis. r3, r3, L2CR_L2I@h
|
||||
bne invl2
|
||||
sync
|
||||
#endif
|
||||
|
||||
/* enable and invalidate the data cache */
|
||||
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
|
||||
sync
|
||||
lis r3, L2_ENABLE@h
|
||||
ori r3, r3, L2_ENABLE@l
|
||||
mtspr l2cr, r3
|
||||
isync
|
||||
sync
|
||||
#endif
|
||||
|
||||
/* enable and invalidate the instruction cache*/
|
||||
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
|
||||
sync
|
||||
|
||||
/* TBEN in HID0 */
|
||||
mfspr r4, HID0
|
||||
oris r4, r4, 0x0400
|
||||
mtspr HID0, r4
|
||||
sync
|
||||
isync
|
||||
|
||||
/* MCP|SYNCBE|ABE in HID1 */
|
||||
mfspr r4, HID1
|
||||
oris r4, r4, 0x8000
|
||||
ori r4, r4, 0x0C00
|
||||
mtspr HID1, r4
|
||||
sync
|
||||
isync
|
||||
|
||||
lis r3, CONFIG_LINUX_RESET_VEC@h
|
||||
ori r3, r3, CONFIG_LINUX_RESET_VEC@l
|
||||
mtlr r3
|
||||
blr
|
||||
|
||||
/* Never Returns, Running in Linux Now */
|
||||
@@ -0,0 +1,132 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2004 Freescale Semiconductor.
|
||||
* Jeff Brown
|
||||
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
|
||||
*
|
||||
* (C) Copyright 2000-2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc86xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* used in some defintiions of CONFIG_SYS_CLK_FREQ */
|
||||
extern unsigned long get_board_sys_clk(unsigned long dummy);
|
||||
|
||||
void get_sys_info(sys_info_t *sys_info)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile ccsr_gur_t *gur = &immap->im_gur;
|
||||
uint plat_ratio, e600_ratio;
|
||||
|
||||
plat_ratio = (gur->porpllsr) & 0x0000003e;
|
||||
plat_ratio >>= 1;
|
||||
|
||||
switch (plat_ratio) {
|
||||
case 0x0:
|
||||
sys_info->freq_systembus = 16 * CONFIG_SYS_CLK_FREQ;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0c:
|
||||
case 0x10:
|
||||
sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ;
|
||||
break;
|
||||
default:
|
||||
sys_info->freq_systembus = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
e600_ratio = (gur->porpllsr) & 0x003f0000;
|
||||
e600_ratio >>= 16;
|
||||
|
||||
switch (e600_ratio) {
|
||||
case 0x10:
|
||||
sys_info->freq_processor = 2 * sys_info->freq_systembus;
|
||||
break;
|
||||
case 0x19:
|
||||
sys_info->freq_processor = 5 * sys_info->freq_systembus / 2;
|
||||
break;
|
||||
case 0x20:
|
||||
sys_info->freq_processor = 3 * sys_info->freq_systembus;
|
||||
break;
|
||||
case 0x39:
|
||||
sys_info->freq_processor = 7 * sys_info->freq_systembus / 2;
|
||||
break;
|
||||
case 0x28:
|
||||
sys_info->freq_processor = 4 * sys_info->freq_systembus;
|
||||
break;
|
||||
case 0x1d:
|
||||
sys_info->freq_processor = 9 * sys_info->freq_systembus / 2;
|
||||
break;
|
||||
default:
|
||||
sys_info->freq_processor = e600_ratio +
|
||||
sys_info->freq_systembus;
|
||||
break;
|
||||
}
|
||||
|
||||
sys_info->freq_localbus = sys_info->freq_systembus;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Measure CPU clock speed (core clock GCLK1, GCLK2)
|
||||
* (Approx. GCLK frequency in Hz)
|
||||
*/
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
sys_info_t sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
gd->cpu_clk = sys_info.freq_processor;
|
||||
gd->bus_clk = sys_info.freq_systembus;
|
||||
gd->arch.lbc_clk = sys_info.freq_localbus;
|
||||
|
||||
/*
|
||||
* The base clock for I2C depends on the actual SOC. Unfortunately,
|
||||
* there is no pattern that can be used to determine the frequency, so
|
||||
* the only choice is to look up the actual SOC number and use the value
|
||||
* for that SOC. This information is taken from application note
|
||||
* AN2919.
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_MPC8610
|
||||
gd->arch.i2c1_clk = sys_info.freq_systembus;
|
||||
#else
|
||||
gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
|
||||
#endif
|
||||
gd->arch.i2c2_clk = gd->arch.i2c1_clk;
|
||||
|
||||
if (gd->cpu_clk != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_bus_freq
|
||||
* Return system bus freq in Hz
|
||||
*/
|
||||
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
ulong val;
|
||||
sys_info_t sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
val = sys_info.freq_systembus;
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,982 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2004, 2007, 2011 Freescale Semiconductor.
|
||||
* Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
|
||||
*/
|
||||
|
||||
/* U-Boot - Startup Code for 86xx 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 <mpc86xx.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>
|
||||
|
||||
/*
|
||||
* Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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. */
|
||||
STD_EXCEPTION(0x300, DataStorage, UnknownException)
|
||||
|
||||
/* Instruction Storage exception. */
|
||||
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)
|
||||
|
||||
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)
|
||||
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:
|
||||
/*
|
||||
* NOTE: Only Cpu 0 will ever come here. Other cores go to an
|
||||
* address specified by the BPTR
|
||||
*/
|
||||
1:
|
||||
#ifdef CONFIG_SYS_RAMBOOT
|
||||
/* disable everything */
|
||||
li r0, 0
|
||||
mtspr HID0, r0
|
||||
sync
|
||||
mtmsr 0
|
||||
#endif
|
||||
|
||||
/* Invalidate BATs */
|
||||
bl invalidate_bats
|
||||
sync
|
||||
/* Invalidate all of TLB before MMU turn on */
|
||||
bl clear_tlbs
|
||||
sync
|
||||
|
||||
#ifdef CONFIG_SYS_L2
|
||||
/* init the L2 cache */
|
||||
lis r3, L2_INIT@h
|
||||
ori r3, r3, L2_INIT@l
|
||||
mtspr l2cr, r3
|
||||
/* invalidate the L2 cache */
|
||||
bl l2cache_invalidate
|
||||
sync
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate absolute address in FLASH and jump there
|
||||
*------------------------------------------------------*/
|
||||
lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
|
||||
ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@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 */
|
||||
|
||||
/* enable extended addressing */
|
||||
bl enable_ext_addr
|
||||
|
||||
/* setup the bats */
|
||||
bl early_bats
|
||||
|
||||
/*
|
||||
* Cache must be enabled here for stack-in-cache trick.
|
||||
* This means we need to enable the BATS.
|
||||
* Cache should be turned on after BATs, since by default
|
||||
* everything is write-through.
|
||||
*/
|
||||
|
||||
/* enable address translation */
|
||||
mfmsr r5
|
||||
ori r5, r5, (MSR_IR | MSR_DR)
|
||||
lis r3,addr_trans_enabled@h
|
||||
ori r3, r3, addr_trans_enabled@l
|
||||
mtspr SPRN_SRR0,r3
|
||||
mtspr SPRN_SRR1,r5
|
||||
rfi
|
||||
|
||||
addr_trans_enabled:
|
||||
/* enable and invalidate the data cache */
|
||||
/* bl l1dcache_enable */
|
||||
bl dcache_enable
|
||||
sync
|
||||
|
||||
#if 1
|
||||
bl icache_enable
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_INIT_RAM_LOCK
|
||||
bl lock_ram_in_cache
|
||||
sync
|
||||
#endif
|
||||
|
||||
#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
|
||||
bl setup_ccsrbar
|
||||
#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
|
||||
|
||||
#ifdef RUN_DIAG
|
||||
|
||||
/* Load PX_AUX register address in r4 */
|
||||
lis r4, PIXIS_BASE@h
|
||||
ori r4, r4, 0x6
|
||||
/* Load contents of PX_AUX in r3 bits 24 to 31*/
|
||||
lbz r3, 0(r4)
|
||||
|
||||
/* Mask and obtain the bit in r3 */
|
||||
rlwinm. r3, r3, 0, 24, 24
|
||||
/* If not zero, jump and continue with u-boot */
|
||||
bne diag_done
|
||||
|
||||
/* Load back contents of PX_AUX in r3 bits 24 to 31 */
|
||||
lbz r3, 0(r4)
|
||||
/* Set the MSB of the register value */
|
||||
ori r3, r3, 0x80
|
||||
/* Write value in r3 back to PX_AUX */
|
||||
stb r3, 0(r4)
|
||||
|
||||
/* Get the address to jump to in r3*/
|
||||
lis r3, CONFIG_SYS_DIAG_ADDR@h
|
||||
ori r3, r3, CONFIG_SYS_DIAG_ADDR@l
|
||||
|
||||
/* Load the LR with the branch address */
|
||||
mtlr r3
|
||||
|
||||
/* Branch to diagnostic */
|
||||
blr
|
||||
|
||||
diag_done:
|
||||
#endif
|
||||
|
||||
/* bl l2cache_enable */
|
||||
|
||||
/* run 1st part of board init code (from Flash) */
|
||||
li r3, 0 /* clear boot_flag for calling board_init_f */
|
||||
bl board_init_f
|
||||
sync
|
||||
|
||||
/* NOTREACHED - board_init_f() does not return */
|
||||
|
||||
.globl invalidate_bats
|
||||
invalidate_bats:
|
||||
|
||||
li r0, 0
|
||||
/* invalidate BATs */
|
||||
mtspr IBAT0U, r0
|
||||
mtspr IBAT1U, r0
|
||||
mtspr IBAT2U, r0
|
||||
mtspr IBAT3U, r0
|
||||
mtspr IBAT4U, r0
|
||||
mtspr IBAT5U, r0
|
||||
mtspr IBAT6U, r0
|
||||
mtspr IBAT7U, r0
|
||||
|
||||
isync
|
||||
mtspr DBAT0U, r0
|
||||
mtspr DBAT1U, r0
|
||||
mtspr DBAT2U, r0
|
||||
mtspr DBAT3U, r0
|
||||
mtspr DBAT4U, r0
|
||||
mtspr DBAT5U, r0
|
||||
mtspr DBAT6U, r0
|
||||
mtspr DBAT7U, r0
|
||||
|
||||
isync
|
||||
sync
|
||||
blr
|
||||
|
||||
#define CONFIG_BAT_PAIR(n) \
|
||||
lis r4, CONFIG_SYS_IBAT##n##L@h; \
|
||||
ori r4, r4, CONFIG_SYS_IBAT##n##L@l; \
|
||||
lis r3, CONFIG_SYS_IBAT##n##U@h; \
|
||||
ori r3, r3, CONFIG_SYS_IBAT##n##U@l; \
|
||||
mtspr IBAT##n##L, r4; \
|
||||
mtspr IBAT##n##U, r3; \
|
||||
lis r4, CONFIG_SYS_DBAT##n##L@h; \
|
||||
ori r4, r4, CONFIG_SYS_DBAT##n##L@l; \
|
||||
lis r3, CONFIG_SYS_DBAT##n##U@h; \
|
||||
ori r3, r3, CONFIG_SYS_DBAT##n##U@l; \
|
||||
mtspr DBAT##n##L, r4; \
|
||||
mtspr DBAT##n##U, r3;
|
||||
|
||||
/*
|
||||
* setup_bats:
|
||||
*
|
||||
* Set up the final BAT registers now that setup is done.
|
||||
*
|
||||
* Assumes that:
|
||||
* 1) Address translation is enabled upon entry
|
||||
* 2) The boot rom is still accessible via 1:1 translation
|
||||
*/
|
||||
.globl setup_bats
|
||||
setup_bats:
|
||||
mflr r5
|
||||
sync
|
||||
|
||||
/*
|
||||
* When we disable address translation, we will get 1:1 (VA==PA)
|
||||
* translation. The only place we know for sure is safe for that is
|
||||
* the bootrom where we originally started out. Pop back into there.
|
||||
*/
|
||||
lis r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
|
||||
ori r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
|
||||
addi r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
|
||||
|
||||
/* disable address translation */
|
||||
mfmsr r3
|
||||
rlwinm r3, r3, 0, 28, 25
|
||||
mtspr SRR0, r4
|
||||
mtspr SRR1, r3
|
||||
rfi
|
||||
|
||||
trans_disabled:
|
||||
#if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
|
||||
&& defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
|
||||
CONFIG_BAT_PAIR(0)
|
||||
#endif
|
||||
CONFIG_BAT_PAIR(1)
|
||||
CONFIG_BAT_PAIR(2)
|
||||
CONFIG_BAT_PAIR(3)
|
||||
CONFIG_BAT_PAIR(4)
|
||||
CONFIG_BAT_PAIR(5)
|
||||
CONFIG_BAT_PAIR(6)
|
||||
CONFIG_BAT_PAIR(7)
|
||||
|
||||
sync
|
||||
isync
|
||||
|
||||
/* Turn translation back on and return */
|
||||
mfmsr r3
|
||||
ori r3, r3, (MSR_IR | MSR_DR)
|
||||
mtspr SPRN_SRR0,r5
|
||||
mtspr SPRN_SRR1,r3
|
||||
rfi
|
||||
|
||||
/*
|
||||
* early_bats:
|
||||
*
|
||||
* Set up bats needed early on - this is usually the BAT for the
|
||||
* stack-in-cache, the Flash, and CCSR space
|
||||
*/
|
||||
.globl early_bats
|
||||
early_bats:
|
||||
/* IBAT 3 */
|
||||
lis r4, CONFIG_SYS_IBAT3L@h
|
||||
ori r4, r4, CONFIG_SYS_IBAT3L@l
|
||||
lis r3, CONFIG_SYS_IBAT3U@h
|
||||
ori r3, r3, CONFIG_SYS_IBAT3U@l
|
||||
mtspr IBAT3L, r4
|
||||
mtspr IBAT3U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 3 */
|
||||
lis r4, CONFIG_SYS_DBAT3L@h
|
||||
ori r4, r4, CONFIG_SYS_DBAT3L@l
|
||||
lis r3, CONFIG_SYS_DBAT3U@h
|
||||
ori r3, r3, CONFIG_SYS_DBAT3U@l
|
||||
mtspr DBAT3L, r4
|
||||
mtspr DBAT3U, r3
|
||||
isync
|
||||
|
||||
/* IBAT 5 */
|
||||
lis r4, CONFIG_SYS_IBAT5L@h
|
||||
ori r4, r4, CONFIG_SYS_IBAT5L@l
|
||||
lis r3, CONFIG_SYS_IBAT5U@h
|
||||
ori r3, r3, CONFIG_SYS_IBAT5U@l
|
||||
mtspr IBAT5L, r4
|
||||
mtspr IBAT5U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 5 */
|
||||
lis r4, CONFIG_SYS_DBAT5L@h
|
||||
ori r4, r4, CONFIG_SYS_DBAT5L@l
|
||||
lis r3, CONFIG_SYS_DBAT5U@h
|
||||
ori r3, r3, CONFIG_SYS_DBAT5U@l
|
||||
mtspr DBAT5L, r4
|
||||
mtspr DBAT5U, r3
|
||||
isync
|
||||
|
||||
/* IBAT 6 */
|
||||
lis r4, CONFIG_SYS_IBAT6L_EARLY@h
|
||||
ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
|
||||
lis r3, CONFIG_SYS_IBAT6U_EARLY@h
|
||||
ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
|
||||
mtspr IBAT6L, r4
|
||||
mtspr IBAT6U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 6 */
|
||||
lis r4, CONFIG_SYS_DBAT6L_EARLY@h
|
||||
ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
|
||||
lis r3, CONFIG_SYS_DBAT6U_EARLY@h
|
||||
ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
|
||||
mtspr DBAT6L, r4
|
||||
mtspr DBAT6U, r3
|
||||
isync
|
||||
|
||||
#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
|
||||
/* IBAT 7 */
|
||||
lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
|
||||
ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
|
||||
lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
|
||||
ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
|
||||
mtspr IBAT7L, r4
|
||||
mtspr IBAT7U, r3
|
||||
isync
|
||||
|
||||
/* DBAT 7 */
|
||||
lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
|
||||
ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
|
||||
lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
|
||||
ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
|
||||
mtspr DBAT7L, r4
|
||||
mtspr DBAT7U, r3
|
||||
isync
|
||||
#endif
|
||||
blr
|
||||
|
||||
.globl clear_tlbs
|
||||
clear_tlbs:
|
||||
addis r3, 0, 0x0000
|
||||
addis r5, 0, 0x4
|
||||
isync
|
||||
tlblp:
|
||||
tlbie r3
|
||||
sync
|
||||
addi r3, r3, 0x1000
|
||||
cmp 0, 0, r3, r5
|
||||
blt tlblp
|
||||
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
|
||||
|
||||
|
||||
/*
|
||||
* Function: in8
|
||||
* Description: Input 8 bits
|
||||
*/
|
||||
.globl in8
|
||||
in8:
|
||||
lbz r3,0x0000(r3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: out8
|
||||
* Description: Output 8 bits
|
||||
*/
|
||||
.globl out8
|
||||
out8:
|
||||
stb r4,0x0000(r3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: out16
|
||||
* Description: Output 16 bits
|
||||
*/
|
||||
.globl out16
|
||||
out16:
|
||||
sth r4,0x0000(r3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: out16r
|
||||
* Description: Byte reverse and output 16 bits
|
||||
*/
|
||||
.globl out16r
|
||||
out16r:
|
||||
sthbrx r4,r0,r3
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: out32
|
||||
* Description: Output 32 bits
|
||||
*/
|
||||
.globl out32
|
||||
out32:
|
||||
stw r4,0x0000(r3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: out32r
|
||||
* Description: Byte reverse and output 32 bits
|
||||
*/
|
||||
.globl out32r
|
||||
out32r:
|
||||
stwbrx r4,r0,r3
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: in16
|
||||
* Description: Input 16 bits
|
||||
*/
|
||||
.globl in16
|
||||
in16:
|
||||
lhz r3,0x0000(r3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: in16r
|
||||
* Description: Input 16 bits and byte reverse
|
||||
*/
|
||||
.globl in16r
|
||||
in16r:
|
||||
lhbrx r3,r0,r3
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: in32
|
||||
* Description: Input 32 bits
|
||||
*/
|
||||
.globl in32
|
||||
in32:
|
||||
lwz 3,0x0000(3)
|
||||
blr
|
||||
|
||||
/*
|
||||
* Function: in32r
|
||||
* Description: Input 32 bits and byte reverse
|
||||
*/
|
||||
.globl in32r
|
||||
in32r:
|
||||
lwbrx r3,r0,r3
|
||||
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
|
||||
*/
|
||||
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
|
||||
/*
|
||||
* 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:
|
||||
/*
|
||||
* 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, r9 /* Init Date pointer */
|
||||
mr r4, r10 /* Destination Address */
|
||||
bl board_init_r
|
||||
|
||||
/* 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
|
||||
ori r7,r7,MSR_ME /* Enable Machine Check */
|
||||
mtmsr r7
|
||||
|
||||
mtlr r4 /* restore link register */
|
||||
blr
|
||||
|
||||
.globl enable_ext_addr
|
||||
enable_ext_addr:
|
||||
mfspr r0, HID0
|
||||
lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
|
||||
ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
|
||||
mtspr HID0, r0
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
|
||||
.globl setup_ccsrbar
|
||||
setup_ccsrbar:
|
||||
/* Special sequence needed to update CCSRBAR itself */
|
||||
lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
|
||||
ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
|
||||
|
||||
lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
|
||||
ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
|
||||
srwi r5,r5,12
|
||||
li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
|
||||
rlwimi r5,r6,20,8,11
|
||||
stw r5, 0(r4) /* Store physical value of CCSR */
|
||||
isync
|
||||
|
||||
lis r5, CONFIG_SYS_TEXT_BASE@h
|
||||
ori r5,r5,CONFIG_SYS_TEXT_BASE@l
|
||||
lwz r5, 0(r5)
|
||||
isync
|
||||
|
||||
/* Use VA of CCSR to do read */
|
||||
lis r3, CONFIG_SYS_CCSRBAR@h
|
||||
lwz r5, CONFIG_SYS_CCSRBAR@l(r3)
|
||||
isync
|
||||
|
||||
blr
|
||||
#endif
|
||||
|
||||
#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
|
||||
#if 1
|
||||
/* Lock the data cache */
|
||||
mfspr r0, HID0
|
||||
ori r0, r0, 0x1000
|
||||
sync
|
||||
mtspr HID0, r0
|
||||
sync
|
||||
blr
|
||||
#endif
|
||||
#if 0
|
||||
/* Lock the first way of the data cache */
|
||||
mfspr r0, LDSTCR
|
||||
ori r0, r0, 0x0080
|
||||
#if defined(CONFIG_ALTIVEC)
|
||||
dssall
|
||||
#endif
|
||||
sync
|
||||
mtspr LDSTCR, r0
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
#endif
|
||||
|
||||
.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
|
||||
#if 1
|
||||
/* 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
|
||||
#if 0
|
||||
/* Unlock the first way of the data cache */
|
||||
mfspr r0, LDSTCR
|
||||
li r3,0x0080
|
||||
andc r0,r0,r3
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
dssall
|
||||
#endif
|
||||
sync
|
||||
mtspr LDSTCR, r0
|
||||
sync
|
||||
isync
|
||||
li r3,0x0400
|
||||
or r0,r0,r3
|
||||
sync
|
||||
mtspr HID0, r0
|
||||
sync
|
||||
blr
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of hardware exceptions
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <kgdb.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* Returns 0 if exception not found and fixup otherwise. */
|
||||
extern unsigned long search_exception_table(unsigned long);
|
||||
|
||||
/*
|
||||
* End of addressable memory. This may be less than the actual
|
||||
* amount of memory on the system if we're unable to keep all
|
||||
* the memory mapped in.
|
||||
*/
|
||||
#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize())
|
||||
|
||||
/*
|
||||
* 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 & 0x001F0000) {
|
||||
case (0x80000000>>11):
|
||||
printf("MSS error. MSSSR0: %08x\n", mfspr(SPRN_MSSSR0));
|
||||
break;
|
||||
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("UnknownException regs@%lx\n", (ulong)regs);
|
||||
printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
|
||||
regs->nip, regs->msr, regs->trap);
|
||||
_exception(0, regs);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2006, 2007 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.text :
|
||||
{
|
||||
arch/powerpc/cpu/mpc86xx/start.o (.text*)
|
||||
arch/powerpc/cpu/mpc86xx/traps.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))
|
||||
_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 = .);
|
||||
}
|
||||
Reference in New Issue
Block a user