avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
89
u-boot/arch/powerpc/cpu/mpc5xxx/Kconfig
Normal file
89
u-boot/arch/powerpc/cpu/mpc5xxx/Kconfig
Normal file
@@ -0,0 +1,89 @@
|
||||
menu "mpc5xxx CPU"
|
||||
depends on MPC5xxx
|
||||
|
||||
config SYS_CPU
|
||||
default "mpc5xxx"
|
||||
|
||||
choice
|
||||
prompt "Target select"
|
||||
optional
|
||||
|
||||
config TARGET_A3M071
|
||||
bool "Support a3m071"
|
||||
select SUPPORT_SPL
|
||||
|
||||
config TARGET_A4M072
|
||||
bool "Support a4m072"
|
||||
|
||||
config TARGET_CANMB
|
||||
bool "Support canmb"
|
||||
|
||||
config TARGET_CM5200
|
||||
bool "Support cm5200"
|
||||
|
||||
config TARGET_INKA4X0
|
||||
bool "Support inka4x0"
|
||||
|
||||
config TARGET_IPEK01
|
||||
bool "Support ipek01"
|
||||
|
||||
config TARGET_JUPITER
|
||||
bool "Support jupiter"
|
||||
|
||||
config TARGET_MOTIONPRO
|
||||
bool "Support motionpro"
|
||||
|
||||
config TARGET_MUNICES
|
||||
bool "Support munices"
|
||||
|
||||
config TARGET_V38B
|
||||
bool "Support v38b"
|
||||
|
||||
config TARGET_O2D
|
||||
bool "Support O2D"
|
||||
|
||||
config TARGET_O2D300
|
||||
bool "Support O2D300"
|
||||
|
||||
config TARGET_O2DNT2
|
||||
bool "Support O2DNT2"
|
||||
|
||||
config TARGET_O2I
|
||||
bool "Support O2I"
|
||||
|
||||
config TARGET_O2MNT
|
||||
bool "Support O2MNT"
|
||||
|
||||
config TARGET_O3DNT
|
||||
bool "Support O3DNT"
|
||||
|
||||
config TARGET_DIGSY_MTC
|
||||
bool "Support digsy_mtc"
|
||||
|
||||
config TARGET_PCM030
|
||||
bool "Support pcm030"
|
||||
|
||||
config TARGET_CHARON
|
||||
bool "Support charon"
|
||||
|
||||
config TARGET_TQM5200
|
||||
bool "Support TQM5200"
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/a3m071/Kconfig"
|
||||
source "board/a4m072/Kconfig"
|
||||
source "board/canmb/Kconfig"
|
||||
source "board/cm5200/Kconfig"
|
||||
source "board/ifm/o2dnt2/Kconfig"
|
||||
source "board/inka4x0/Kconfig"
|
||||
source "board/intercontrol/digsy_mtc/Kconfig"
|
||||
source "board/ipek01/Kconfig"
|
||||
source "board/jupiter/Kconfig"
|
||||
source "board/motionpro/Kconfig"
|
||||
source "board/munices/Kconfig"
|
||||
source "board/phytec/pcm030/Kconfig"
|
||||
source "board/tqc/tqm5200/Kconfig"
|
||||
source "board/v38b/Kconfig"
|
||||
|
||||
endmenu
|
||||
26
u-boot/arch/powerpc/cpu/mpc5xxx/Makefile
Normal file
26
u-boot/arch/powerpc/cpu/mpc5xxx/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# (C) Copyright 2003-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
extra-y = start.o
|
||||
extra-y += traps.o
|
||||
obj-y += io.o
|
||||
obj-y += firmware_sc_task_bestcomm.impl.o
|
||||
obj-y += i2c.o
|
||||
obj-y += cpu.o
|
||||
obj-y += cpu_init.o
|
||||
obj-y += ide.o
|
||||
obj-y += interrupts.o
|
||||
obj-y += loadtask.o
|
||||
obj-y += pci_mpc5200.o
|
||||
obj-y += serial.o
|
||||
obj-y += speed.o
|
||||
obj-$(CONFIG_CMD_USB) += usb_ohci.o
|
||||
obj-$(CONFIG_CMD_USB) += usb.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl_boot.o
|
||||
endif
|
||||
8
u-boot/arch/powerpc/cpu/mpc5xxx/config.mk
Normal file
8
u-boot/arch/powerpc/cpu/mpc5xxx/config.mk
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# (C) Copyright 2003-2010
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
PLATFORM_CPPFLAGS += -mstring -mcpu=603e -mmultiple
|
||||
168
u-boot/arch/powerpc/cpu/mpc5xxx/cpu.c
Normal file
168
u-boot/arch/powerpc/cpu/mpc5xxx/cpu.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2010
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPU specific code for the MPC5xxx CPUs
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <net.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <netdev.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT)
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF_IDE_FIXUP)
|
||||
#include <ide.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int checkcpu (void)
|
||||
{
|
||||
ulong clock = gd->cpu_clk;
|
||||
char buf[32];
|
||||
uint svr, pvr;
|
||||
|
||||
puts ("CPU: ");
|
||||
|
||||
svr = get_svr();
|
||||
pvr = get_pvr();
|
||||
|
||||
switch (pvr) {
|
||||
case PVR_5200:
|
||||
printf("MPC5200");
|
||||
break;
|
||||
case PVR_5200B:
|
||||
printf("MPC5200B");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown MPC5xxx");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" v%d.%d, Core v%d.%d", SVR_MJREV (svr), SVR_MNREV (svr),
|
||||
PVR_MAJ(pvr), PVR_MIN(pvr));
|
||||
printf (" at %s MHz\n", strmhz (buf, clock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
ulong msr;
|
||||
/* Interrupts and MMU off */
|
||||
__asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
|
||||
|
||||
msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
|
||||
__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
|
||||
|
||||
/* Charge the watchdog timer */
|
||||
*(vu_long *)(MPC5XXX_GPT0_COUNTER) = 0x0001000f;
|
||||
*(vu_long *)(MPC5XXX_GPT0_ENABLE) = 0x9004; /* wden|ce|timer_ms */
|
||||
while(1);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Get timebase clock frequency (like cpu_clk in Hz)
|
||||
*
|
||||
*/
|
||||
unsigned long get_tbclk (void)
|
||||
{
|
||||
ulong tbclk;
|
||||
|
||||
tbclk = (gd->bus_clk + 3L) / 4L;
|
||||
|
||||
return (tbclk);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
int div = in_8((void*)CONFIG_SYS_MBAR + 0x204) & 0x0020 ? 8 : 4;
|
||||
char * cpu_path = "/cpus/" OF_CPU;
|
||||
#ifdef CONFIG_MPC5xxx_FEC
|
||||
uchar enetaddr[6];
|
||||
char * eth_path = "/" OF_SOC "/ethernet@3000";
|
||||
#endif
|
||||
|
||||
do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
|
||||
do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
|
||||
do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
|
||||
do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1);
|
||||
do_fixup_by_path_u32(blob, "/" OF_SOC, "system-frequency",
|
||||
bd->bi_busfreq*div, 1);
|
||||
#ifdef CONFIG_MPC5xxx_FEC
|
||||
eth_getenv_enetaddr("ethaddr", enetaddr);
|
||||
do_fixup_by_path(blob, eth_path, "mac-address", enetaddr, 6, 0);
|
||||
do_fixup_by_path(blob, eth_path, "local-mac-address", enetaddr, 6, 0);
|
||||
#endif
|
||||
#ifdef CONFIG_OF_IDE_FIXUP
|
||||
if (!ide_device_present(0)) {
|
||||
/* NO CF card detected -> delete ata node in DTS */
|
||||
int nodeoffset = 0;
|
||||
char nodename[] = "/soc5200@f0000000/ata@3a00";
|
||||
|
||||
nodeoffset = fdt_path_offset(blob, nodename);
|
||||
if (nodeoffset >= 0) {
|
||||
fdt_del_node(blob, nodeoffset);
|
||||
} else {
|
||||
printf("%s: cannot find %s node err:%s\n",
|
||||
__func__, nodename, fdt_strerror(nodeoffset));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OF_IDE_FIXUP */
|
||||
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
|
||||
}
|
||||
#endif /* CONFIG_OF_BOARD_SETUP */
|
||||
|
||||
#ifdef CONFIG_MPC5xxx_FEC
|
||||
/* Default initializations for FEC controllers. To override,
|
||||
* create a board-specific function called:
|
||||
* int board_eth_init(bd_t *bis)
|
||||
*/
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
return mpc5xxx_fec_initialize(bis);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
void watchdog_reset(void)
|
||||
{
|
||||
int re_enable = disable_interrupts();
|
||||
reset_5xxx_watchdog();
|
||||
if (re_enable) enable_interrupts();
|
||||
}
|
||||
|
||||
void reset_5xxx_watchdog(void)
|
||||
{
|
||||
volatile struct mpc5xxx_gpt *gpt0 =
|
||||
(struct mpc5xxx_gpt *) MPC5XXX_GPT;
|
||||
|
||||
/* Trigger TIMER_0 by writing A5 to OCPW */
|
||||
clrsetbits_be32(&gpt0->emsr, 0xff000000, 0xa5000000);
|
||||
}
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
231
u-boot/arch/powerpc/cpu/mpc5xxx/cpu_init.c
Normal file
231
u-boot/arch/powerpc/cpu/mpc5xxx/cpu_init.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2010
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <asm/io.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Breath some life into the CPU...
|
||||
*
|
||||
* Set up the memory map,
|
||||
* initialize a bunch of registers.
|
||||
*/
|
||||
void cpu_init_f (void)
|
||||
{
|
||||
volatile struct mpc5xxx_mmap_ctl *mm =
|
||||
(struct mpc5xxx_mmap_ctl *) CONFIG_SYS_MBAR;
|
||||
volatile struct mpc5xxx_lpb *lpb =
|
||||
(struct mpc5xxx_lpb *) MPC5XXX_LPB;
|
||||
volatile struct mpc5xxx_gpio *gpio =
|
||||
(struct mpc5xxx_gpio *) MPC5XXX_GPIO;
|
||||
volatile struct mpc5xxx_xlb *xlb =
|
||||
(struct mpc5xxx_xlb *) MPC5XXX_XLBARB;
|
||||
#if defined(CONFIG_SYS_IPBCLK_EQUALS_XLBCLK)
|
||||
volatile struct mpc5xxx_cdm *cdm =
|
||||
(struct mpc5xxx_cdm *) MPC5XXX_CDM;
|
||||
#endif /* CONFIG_SYS_IPBCLK_EQUALS_XLBCLK */
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
volatile struct mpc5xxx_gpt *gpt0 =
|
||||
(struct mpc5xxx_gpt *) MPC5XXX_GPT;
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
unsigned long addecr = (1 << 25); /* Boot_CS */
|
||||
/* 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));
|
||||
|
||||
/*
|
||||
* Memory Controller: configure chip selects and enable them
|
||||
*/
|
||||
#if defined(CONFIG_SYS_BOOTCS_START) && defined(CONFIG_SYS_BOOTCS_SIZE)
|
||||
out_be32(&mm->boot_start, START_REG(CONFIG_SYS_BOOTCS_START));
|
||||
out_be32(&mm->boot_stop, STOP_REG(CONFIG_SYS_BOOTCS_START,
|
||||
CONFIG_SYS_BOOTCS_SIZE));
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_BOOTCS_CFG)
|
||||
out_be32(&lpb->cs0_cfg, CONFIG_SYS_BOOTCS_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS0_START) && defined(CONFIG_SYS_CS0_SIZE)
|
||||
out_be32(&mm->cs0_start, START_REG(CONFIG_SYS_CS0_START));
|
||||
out_be32(&mm->cs0_stop, STOP_REG(CONFIG_SYS_CS0_START,
|
||||
CONFIG_SYS_CS0_SIZE));
|
||||
/* CS0 and BOOT_CS cannot be enabled at once. */
|
||||
/* addecr |= (1 << 16); */
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS0_CFG)
|
||||
out_be32(&lpb->cs0_cfg, CONFIG_SYS_CS0_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS1_START) && defined(CONFIG_SYS_CS1_SIZE)
|
||||
out_be32(&mm->cs1_start, START_REG(CONFIG_SYS_CS1_START));
|
||||
out_be32(&mm->cs1_stop, STOP_REG(CONFIG_SYS_CS1_START,
|
||||
CONFIG_SYS_CS1_SIZE));
|
||||
addecr |= (1 << 17);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS1_CFG)
|
||||
out_be32(&lpb->cs1_cfg, CONFIG_SYS_CS1_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS2_START) && defined(CONFIG_SYS_CS2_SIZE)
|
||||
out_be32(&mm->cs2_start, START_REG(CONFIG_SYS_CS2_START));
|
||||
out_be32(&mm->cs2_stop, STOP_REG(CONFIG_SYS_CS2_START,
|
||||
CONFIG_SYS_CS2_SIZE));
|
||||
addecr |= (1 << 18);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS2_CFG)
|
||||
out_be32(&lpb->cs2_cfg, CONFIG_SYS_CS2_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS3_START) && defined(CONFIG_SYS_CS3_SIZE)
|
||||
out_be32(&mm->cs3_start, START_REG(CONFIG_SYS_CS3_START));
|
||||
out_be32(&mm->cs3_stop, STOP_REG(CONFIG_SYS_CS3_START,
|
||||
CONFIG_SYS_CS3_SIZE));
|
||||
addecr |= (1 << 19);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS3_CFG)
|
||||
out_be32(&lpb->cs3_cfg, CONFIG_SYS_CS3_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS4_START) && defined(CONFIG_SYS_CS4_SIZE)
|
||||
out_be32(&mm->cs4_start, START_REG(CONFIG_SYS_CS4_START));
|
||||
out_be32(&mm->cs4_stop, STOP_REG(CONFIG_SYS_CS4_START,
|
||||
CONFIG_SYS_CS4_SIZE));
|
||||
addecr |= (1 << 20);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS4_CFG)
|
||||
out_be32(&lpb->cs4_cfg, CONFIG_SYS_CS4_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS5_START) && defined(CONFIG_SYS_CS5_SIZE)
|
||||
out_be32(&mm->cs5_start, START_REG(CONFIG_SYS_CS5_START));
|
||||
out_be32(&mm->cs5_stop, STOP_REG(CONFIG_SYS_CS5_START,
|
||||
CONFIG_SYS_CS5_SIZE));
|
||||
addecr |= (1 << 21);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS5_CFG)
|
||||
out_be32(&lpb->cs5_cfg, CONFIG_SYS_CS5_CFG);
|
||||
#endif
|
||||
|
||||
addecr |= 1;
|
||||
#if defined(CONFIG_SYS_CS6_START) && defined(CONFIG_SYS_CS6_SIZE)
|
||||
out_be32(&mm->cs6_start, START_REG(CONFIG_SYS_CS6_START));
|
||||
out_be32(&mm->cs6_stop, STOP_REG(CONFIG_SYS_CS6_START,
|
||||
CONFIG_SYS_CS6_SIZE));
|
||||
addecr |= (1 << 26);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS6_CFG)
|
||||
out_be32(&lpb->cs6_cfg, CONFIG_SYS_CS6_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS7_START) && defined(CONFIG_SYS_CS7_SIZE)
|
||||
out_be32(&mm->cs7_start, START_REG(CONFIG_SYS_CS7_START));
|
||||
out_be32(&mm->cs7_stop, STOP_REG(CONFIG_SYS_CS7_START,
|
||||
CONFIG_SYS_CS7_SIZE));
|
||||
addecr |= (1 << 27);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS7_CFG)
|
||||
out_be32(&lpb->cs7_cfg, CONFIG_SYS_CS7_CFG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_CS_BURST)
|
||||
out_be32(&lpb->cs_burst, CONFIG_SYS_CS_BURST);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_CS_DEADCYCLE)
|
||||
out_be32(&lpb->cs_deadcycle, CONFIG_SYS_CS_DEADCYCLE);
|
||||
#endif
|
||||
|
||||
/* Enable chip selects */
|
||||
out_be32(&mm->ipbi_ws_ctrl, addecr);
|
||||
out_be32(&lpb->cs_ctrl, (1 << 24));
|
||||
|
||||
/* Setup pin multiplexing */
|
||||
#if defined(CONFIG_SYS_GPS_PORT_CONFIG)
|
||||
out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG);
|
||||
#endif
|
||||
|
||||
/* Setup gpios */
|
||||
#if defined(CONFIG_SYS_GPIO_DATADIR)
|
||||
out_be32(&gpio->simple_ddr, CONFIG_SYS_GPIO_DATADIR);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_GPIO_OPENDRAIN)
|
||||
out_be32(&gpio->simple_ode, CONFIG_SYS_GPIO_OPENDRAIN);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_GPIO_DATAVALUE)
|
||||
out_be32(&gpio->simple_dvo, CONFIG_SYS_GPIO_DATAVALUE);
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_GPIO_ENABLE)
|
||||
out_be32(&gpio->simple_gpioe, CONFIG_SYS_GPIO_ENABLE);
|
||||
#endif
|
||||
|
||||
/* enable timebase */
|
||||
setbits_be32(&xlb->config, (1 << 13));
|
||||
|
||||
/* Enable snooping for RAM */
|
||||
setbits_be32(&xlb->config, (1 << 15));
|
||||
out_be32(&xlb->snoop_window, CONFIG_SYS_SDRAM_BASE | 0x1d);
|
||||
|
||||
#if defined(CONFIG_SYS_IPBCLK_EQUALS_XLBCLK)
|
||||
/* Motorola reports IPB should better run at 133 MHz. */
|
||||
setbits_be32(&mm->ipbi_ws_ctrl, 1);
|
||||
/* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */
|
||||
addecr = in_be32(&cdm->cfg);
|
||||
addecr &= ~0x103;
|
||||
# if defined(CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2)
|
||||
/* pci_clk_sel = 0x01 -> IPB_CLK/2 */
|
||||
addecr |= 0x01;
|
||||
# else
|
||||
/* pci_clk_sel = 0x02 -> XLB_CLK/4 = IPB_CLK/4 */
|
||||
addecr |= 0x02;
|
||||
# endif /* CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2 */
|
||||
out_be32(&cdm->cfg, addecr);
|
||||
#endif /* CONFIG_SYS_IPBCLK_EQUALS_XLBCLK */
|
||||
/* Configure the XLB Arbiter */
|
||||
out_be32(&xlb->master_pri_enable, 0xff);
|
||||
out_be32(&xlb->master_priority, 0x11111111);
|
||||
|
||||
#if defined(CONFIG_SYS_XLB_PIPELINING)
|
||||
/* Enable piplining */
|
||||
clrbits_be32(&xlb->config, (1 << 31));
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
/* Charge the watchdog timer - prescaler = 64k, count = 64k*/
|
||||
out_be32(&gpt0->cir, 0x0000ffff);
|
||||
out_be32(&gpt0->emsr, 0x9004); /* wden|ce|timer_ms */
|
||||
|
||||
reset_5xxx_watchdog();
|
||||
#endif /* CONFIG_WATCHDOG */
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize higher level parts of CPU like time base and timers
|
||||
*/
|
||||
int cpu_init_r (void)
|
||||
{
|
||||
volatile struct mpc5xxx_intr *intr =
|
||||
(struct mpc5xxx_intr *) MPC5XXX_ICTL;
|
||||
|
||||
/* mask all interrupts */
|
||||
out_be32(&intr->per_mask, 0xffffff00);
|
||||
setbits_be32(&intr->main_mask, 0x0001ffff);
|
||||
clrbits_be32(&intr->ctrl, 0x00000f00);
|
||||
/* route critical ints to normal ints */
|
||||
setbits_be32(&intr->ctrl, 0x00000001);
|
||||
|
||||
#if defined(CONFIG_CMD_NET) && defined(CONFIG_MPC5xxx_FEC)
|
||||
/* load FEC microcode */
|
||||
loadtask(0, 2);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
359
u-boot/arch/powerpc/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
Normal file
359
u-boot/arch/powerpc/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (C) 2001, Software Center, Motorola China.
|
||||
*
|
||||
* This file contains microcode for the FEC controller of the MPC5200 CPU.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* sas/sccg, gas target */
|
||||
.section smartdmaInitData,"aw",@progbits /* Initialized data for task variables */
|
||||
.section smartdmaTaskTable,"aw",@progbits /* Task tables */
|
||||
.align 9
|
||||
.globl taskTable
|
||||
taskTable:
|
||||
.globl scEthernetRecv_Entry
|
||||
scEthernetRecv_Entry: /* Task 0 */
|
||||
.long scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */
|
||||
.long scEthernetRecv_TDT - taskTable + 0x000000a4
|
||||
.long scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */
|
||||
.long scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function Descriptor Table & Flags */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */
|
||||
.long CONFIG_SYS_MBAR
|
||||
.globl scEthernetXmit_Entry
|
||||
scEthernetXmit_Entry: /* Task 1 */
|
||||
.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
|
||||
.long scEthernetXmit_TDT - taskTable + 0x000000d0
|
||||
.long scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */
|
||||
.long scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function Descriptor Table & Flags */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */
|
||||
.long CONFIG_SYS_MBAR
|
||||
|
||||
|
||||
.globl scEthernetRecv_TDT
|
||||
scEthernetRecv_TDT: /* Task 0 Descriptor Table */
|
||||
.long 0xc4c50000 /* 0000: LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */
|
||||
.long 0x84c5e000 /* 0004: LCD: idx1 = var9 + var11; ; idx1 += inc0 */
|
||||
.long 0x10001f08 /* 0008: DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x10000380 /* 000C: DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x00000f88 /* 0010: DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
|
||||
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x010cf04c /* 0020: DRD2B1: var4 = EU3(); EU3(var1,var12) */
|
||||
.long 0x82180349 /* 0024: LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */
|
||||
.long 0x81c68004 /* 0028: LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x70000000 /* 002C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x018cf04e /* 0030: DRD2B1: var6 = EU3(); EU3(var1,var14) */
|
||||
.long 0x70000000 /* 0034: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x020cf04f /* 0038: DRD2B1: var8 = EU3(); EU3(var1,var15) */
|
||||
.long 0x00000b88 /* 003C: DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x8000d184 /* 0040: LCDEXT: idx1 = 0xf0003184; ; */
|
||||
.long 0xc6990452 /* 0044: LCDEXT: idx2 = var13; idx2 < var17; idx2 += inc2 */
|
||||
.long 0x81486010 /* 0048: LCD: idx3 = var2 + var16; ; idx3 += inc2 */
|
||||
.long 0x006acf88 /* 004C: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
|
||||
.long 0x8000d184 /* 0050: LCDEXT: idx1 = 0xf0003184; ; */
|
||||
.long 0x86810492 /* 0054: LCD: idx2 = var13, idx3 = var2; idx2 < var18; idx2 += inc2, idx3 += inc2 */
|
||||
.long 0x006acf88 /* 0058: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
|
||||
.long 0x8000d184 /* 005C: LCDEXT: idx1 = 0xf0003184; ; */
|
||||
.long 0x868184d2 /* 0060: LCD: idx2 = var13, idx3 = var3; idx2 < var19; idx2 += inc2, idx3 += inc2 */
|
||||
.long 0x000acf88 /* 0064: DRD1A: *idx3 = *idx1; FN=0 init=0 WS=1 RS=1 */
|
||||
.long 0xc318839b /* 0068: LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc3 */
|
||||
.long 0x80190000 /* 006C: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x04008468 /* 0070: DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */
|
||||
.long 0xc4038358 /* 0074: LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc3, idx2 += inc0 */
|
||||
.long 0x81c50000 /* 0078: LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */
|
||||
.long 0x1000cb18 /* 007C: DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x00000f18 /* 0080: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0xc4188364 /* 0084: LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc4 */
|
||||
.long 0x83990000 /* 0088: LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x10000c00 /* 008C: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x0000c800 /* 0090: DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x81988000 /* 0094: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x10000788 /* 0098: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x60000000 /* 009C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x080cf04c /* 00A0: DRD2B1: idx0 = EU3(); EU3(var1,var12) */
|
||||
.long 0x000001f8 /* 00A4(:0): NOP */
|
||||
|
||||
|
||||
.globl scEthernetXmit_TDT
|
||||
scEthernetXmit_TDT: /* Task 1 Descriptor Table */
|
||||
.long 0x80024800 /* 0000: LCDEXT: idx0 = 0xf0008800; ; */
|
||||
.long 0x85c60004 /* 0004: LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x10002308 /* 0008: DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x10000f88 /* 000C: DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x00000380 /* 0010: DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
|
||||
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x024cf04d /* 0020: DRD2B1: var9 = EU3(); EU3(var1,var13) */
|
||||
.long 0x84980309 /* 0024: LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */
|
||||
.long 0xc0004003 /* 0028: LCDEXT: idx1 = 0x00000003; ; */
|
||||
.long 0x81c60004 /* 002C: LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x70000000 /* 0030: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x010cf04e /* 0034: DRD2B1: var4 = EU3(); EU3(var1,var14) */
|
||||
.long 0x70000000 /* 0038: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x014cf04f /* 003C: DRD2B1: var5 = EU3(); EU3(var1,var15) */
|
||||
.long 0x70000000 /* 0040: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x028cf050 /* 0044: DRD2B1: var10 = EU3(); EU3(var1,var16) */
|
||||
.long 0x70000000 /* 0048: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
|
||||
.long 0x018cf051 /* 004C: DRD2B1: var6 = EU3(); EU3(var1,var17) */
|
||||
.long 0x10000b90 /* 0050: DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x60000000 /* 0054: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x01ccf0a1 /* 0058: DRD2B1: var7 = EU3(); EU3(var2,idx1) */
|
||||
.long 0xc2988312 /* 005C: LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */
|
||||
.long 0x83490000 /* 0060: LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x00001b10 /* 0064: DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x8000d1a4 /* 0068: LCDEXT: idx1 = 0xf00031a4; ; */
|
||||
.long 0x8301031c /* 006C: LCD: idx2 = var6, idx3 = var2; idx2 > var12; idx2 += inc3, idx3 += inc4 */
|
||||
.long 0x008ac798 /* 0070: DRD1A: *idx1 = *idx3; FN=0 init=4 WS=1 RS=1 */
|
||||
.long 0x8000d1a4 /* 0074: LCDEXT: idx1 = 0xf00031a4; ; */
|
||||
.long 0xc1430000 /* 0078: LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x82998312 /* 007C: LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */
|
||||
.long 0x088ac790 /* 0080: DRD1A: *idx1 = *idx2; FN=0 TFD init=4 WS=1 RS=1 */
|
||||
.long 0x81988000 /* 0084: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x60000001 /* 0088: DRD2A: EU0=0 EU1=0 EU2=0 EU3=1 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x0c4cfc4d /* 008C: DRD2B1: *idx1 = EU3(); EU3(*idx1,var13) */
|
||||
.long 0xc21883ad /* 0090: LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */
|
||||
.long 0x80190000 /* 0094: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
|
||||
.long 0x04008460 /* 0098: DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */
|
||||
.long 0xc4052305 /* 009C: LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */
|
||||
.long 0x81c98000 /* 00A0: LCD: idx3 = var3 + var19; idx3 once var0; idx3 += inc0 */
|
||||
.long 0x1000c718 /* 00A4: DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x00000f18 /* 00A8: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0xc4188000 /* 00AC: LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x85190312 /* 00B0: LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */
|
||||
.long 0x10000c00 /* 00B4: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x1000c400 /* 00B8: DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x00008860 /* 00BC: DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */
|
||||
.long 0x81988000 /* 00C0: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
|
||||
.long 0x10000788 /* 00C4: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
|
||||
.long 0x60000000 /* 00C8: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
|
||||
.long 0x080cf04d /* 00CC: DRD2B1: idx0 = EU3(); EU3(var1,var13) */
|
||||
.long 0x000001f8 /* 00D0(:0): NOP */
|
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetRecv_VarTab
|
||||
scEthernetRecv_VarTab: /* Task 0 Variable Table */
|
||||
.long 0x00000000 /* var[0] */
|
||||
.long 0x00000000 /* var[1] */
|
||||
.long 0x00000000 /* var[2] */
|
||||
.long 0x00000000 /* var[3] */
|
||||
.long 0x00000000 /* var[4] */
|
||||
.long 0x00000000 /* var[5] */
|
||||
.long 0x00000000 /* var[6] */
|
||||
.long 0x00000000 /* var[7] */
|
||||
.long 0x00000000 /* var[8] */
|
||||
.long (CONFIG_SYS_MBAR + 0x8800) /* var[9] */
|
||||
.long 0x00000008 /* var[10] */
|
||||
.long 0x0000000c /* var[11] */
|
||||
.long 0x80000000 /* var[12] */
|
||||
.long 0x00000000 /* var[13] */
|
||||
.long 0x10000000 /* var[14] */
|
||||
.long 0x20000000 /* var[15] */
|
||||
.long 0x000005e4 /* var[16] */
|
||||
.long 0x0000000e /* var[17] */
|
||||
.long 0x000005e0 /* var[18] */
|
||||
.long 0x00000004 /* var[19] */
|
||||
.long 0x00000000 /* var[20] */
|
||||
.long 0x00000000 /* var[21] */
|
||||
.long 0x00000000 /* var[22] */
|
||||
.long 0x00000000 /* var[23] */
|
||||
.long 0x00000000 /* inc[0] */
|
||||
.long 0x60000000 /* inc[1] */
|
||||
.long 0x20000001 /* inc[2] */
|
||||
.long 0x80000000 /* inc[3] */
|
||||
.long 0x40000000 /* inc[4] */
|
||||
.long 0x00000000 /* inc[5] */
|
||||
.long 0x00000000 /* inc[6] */
|
||||
.long 0x00000000 /* inc[7] */
|
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetXmit_VarTab
|
||||
scEthernetXmit_VarTab: /* Task 1 Variable Table */
|
||||
.long 0x00000000 /* var[0] */
|
||||
.long 0x00000000 /* var[1] */
|
||||
.long 0x00000000 /* var[2] */
|
||||
.long 0x00000000 /* var[3] */
|
||||
.long 0x00000000 /* var[4] */
|
||||
.long 0x00000000 /* var[5] */
|
||||
.long 0x00000000 /* var[6] */
|
||||
.long 0x00000000 /* var[7] */
|
||||
.long 0x00000000 /* var[8] */
|
||||
.long 0x00000000 /* var[9] */
|
||||
.long 0x00000000 /* var[10] */
|
||||
.long (CONFIG_SYS_MBAR + 0x8800) /* var[11] */
|
||||
.long 0x00000000 /* var[12] */
|
||||
.long 0x80000000 /* var[13] */
|
||||
.long 0x10000000 /* var[14] */
|
||||
.long 0x08000000 /* var[15] */
|
||||
.long 0x20000000 /* var[16] */
|
||||
.long 0x0000ffff /* var[17] */
|
||||
.long 0xffffffff /* var[18] */
|
||||
.long 0x00000008 /* var[19] */
|
||||
.long 0x00000000 /* var[20] */
|
||||
.long 0x00000000 /* var[21] */
|
||||
.long 0x00000000 /* var[22] */
|
||||
.long 0x00000000 /* var[23] */
|
||||
.long 0x00000000 /* inc[0] */
|
||||
.long 0x60000000 /* inc[1] */
|
||||
.long 0x40000000 /* inc[2] */
|
||||
.long 0x4000ffff /* inc[3] */
|
||||
.long 0xe0000001 /* inc[4] */
|
||||
.long 0x80000000 /* inc[5] */
|
||||
.long 0x00000000 /* inc[6] */
|
||||
.long 0x00000000 /* inc[7] */
|
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetRecv_FDT
|
||||
scEthernetRecv_FDT: /* Task 0 Function Descriptor Table */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x21800000 /* and(), EU# 3 */
|
||||
.long 0x21400000 /* andn(), EU# 3 */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetXmit_FDT
|
||||
scEthernetXmit_FDT: /* Task 1 Function Descriptor Table */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x21800000 /* and(), EU# 3 */
|
||||
.long 0x21400000 /* andn(), EU# 3 */
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
||||
|
||||
.globl scEthernetRecv_CSave
|
||||
scEthernetRecv_CSave: /* Task 0 context save space */
|
||||
.space 128, 0x0
|
||||
|
||||
|
||||
.globl scEthernetXmit_CSave
|
||||
scEthernetXmit_CSave: /* Task 1 context save space */
|
||||
.space 128, 0x0
|
||||
456
u-boot/arch/powerpc/cpu/mpc5xxx/i2c.c
Normal file
456
u-boot/arch/powerpc/cpu/mpc5xxx/i2c.c
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_HARD_I2C
|
||||
|
||||
#include <mpc5xxx.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if !defined(CONFIG_I2C_MULTI_BUS)
|
||||
#if (CONFIG_SYS_I2C_MODULE == 2)
|
||||
#define I2C_BASE MPC5XXX_I2C2
|
||||
#elif (CONFIG_SYS_I2C_MODULE == 1)
|
||||
#define I2C_BASE MPC5XXX_I2C1
|
||||
#else
|
||||
#error CONFIG_SYS_I2C_MODULE is not properly configured
|
||||
#endif
|
||||
#else
|
||||
static unsigned int i2c_bus_num __attribute__ ((section (".data"))) =
|
||||
CONFIG_SYS_SPD_BUS_NUM;
|
||||
static unsigned int i2c_bus_speed[2] = {CONFIG_SYS_I2C_SPEED,
|
||||
CONFIG_SYS_I2C_SPEED};
|
||||
|
||||
static const unsigned long i2c_dev[2] = {
|
||||
MPC5XXX_I2C1,
|
||||
MPC5XXX_I2C2,
|
||||
};
|
||||
|
||||
#define I2C_BASE ((struct mpc5xxx_i2c *)i2c_dev[i2c_bus_num])
|
||||
#endif
|
||||
|
||||
#define I2C_TIMEOUT 6667
|
||||
#define I2C_RETRIES 3
|
||||
|
||||
struct mpc5xxx_i2c_tap {
|
||||
int scl2tap;
|
||||
int tap2tap;
|
||||
};
|
||||
|
||||
static int mpc_reg_in (volatile u32 *reg);
|
||||
static void mpc_reg_out (volatile u32 *reg, int val, int mask);
|
||||
static int wait_for_bb (void);
|
||||
static int wait_for_pin (int *status);
|
||||
static int do_address (uchar chip, char rdwr_flag);
|
||||
static int send_bytes (uchar chip, char *buf, int len);
|
||||
static int receive_bytes (uchar chip, char *buf, int len);
|
||||
static int mpc_get_fdr (int);
|
||||
|
||||
static int mpc_reg_in(volatile u32 *reg)
|
||||
{
|
||||
int ret = *reg >> 24;
|
||||
__asm__ __volatile__ ("eieio");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mpc_reg_out(volatile u32 *reg, int val, int mask)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (!mask) {
|
||||
*reg = val << 24;
|
||||
} else {
|
||||
tmp = mpc_reg_in(reg);
|
||||
*reg = ((tmp & ~mask) | (val & mask)) << 24;
|
||||
}
|
||||
__asm__ __volatile__ ("eieio");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int wait_for_bb(void)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int timeout = I2C_TIMEOUT;
|
||||
int status;
|
||||
|
||||
status = mpc_reg_in(®s->msr);
|
||||
|
||||
while (timeout-- && (status & I2C_BB)) {
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
(void)mpc_reg_in(®s->mdr);
|
||||
mpc_reg_out(®s->mcr, 0, I2C_STA);
|
||||
mpc_reg_out(®s->mcr, 0, 0);
|
||||
mpc_reg_out(®s->mcr, I2C_EN, 0);
|
||||
udelay(15);
|
||||
status = mpc_reg_in(®s->msr);
|
||||
}
|
||||
|
||||
return (status & I2C_BB);
|
||||
}
|
||||
|
||||
static int wait_for_pin(int *status)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int timeout = I2C_TIMEOUT;
|
||||
|
||||
*status = mpc_reg_in(®s->msr);
|
||||
|
||||
while (timeout-- && !(*status & I2C_IF)) {
|
||||
udelay(15);
|
||||
*status = mpc_reg_in(®s->msr);
|
||||
}
|
||||
|
||||
if (!(*status & I2C_IF)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->msr, 0, I2C_IF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_address(uchar chip, char rdwr_flag)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int status;
|
||||
|
||||
chip <<= 1;
|
||||
|
||||
if (rdwr_flag) {
|
||||
chip |= 1;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_TX, I2C_TX);
|
||||
mpc_reg_out(®s->mdr, chip, 0);
|
||||
|
||||
if (wait_for_pin(&status)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (status & I2C_RXAK) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int send_bytes(uchar chip, char *buf, int len)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int wrcount;
|
||||
int status;
|
||||
|
||||
for (wrcount = 0; wrcount < len; ++wrcount) {
|
||||
|
||||
mpc_reg_out(®s->mdr, buf[wrcount], 0);
|
||||
|
||||
if (wait_for_pin(&status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (status & I2C_RXAK) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return !(wrcount == len);
|
||||
}
|
||||
|
||||
static int receive_bytes(uchar chip, char *buf, int len)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int dummy = 1;
|
||||
int rdcount = 0;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
mpc_reg_out(®s->mcr, 0, I2C_TX);
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
buf[rdcount] = mpc_reg_in(®s->mdr);
|
||||
|
||||
if (dummy) {
|
||||
dummy = 0;
|
||||
} else {
|
||||
rdcount++;
|
||||
}
|
||||
|
||||
|
||||
if (wait_for_pin(&status)) {
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_TXAK, I2C_TXAK);
|
||||
buf[rdcount++] = mpc_reg_in(®s->mdr);
|
||||
|
||||
if (wait_for_pin(&status)) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, 0, I2C_TXAK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX)
|
||||
|
||||
#define FDR510(x) (u8) (((x & 0x20) >> 3) | (x & 0x3))
|
||||
#define FDR432(x) (u8) ((x & 0x1C) >> 2)
|
||||
/*
|
||||
* Reset any i2c devices that may have been interrupted during a system reset.
|
||||
* Normally this would be accomplished by clocking the line until SCL and SDA
|
||||
* are released and then sending a start condtiion (From an Atmel datasheet).
|
||||
* There is no direct access to the i2c pins so instead create start commands
|
||||
* through the i2c interface. Send a start command then delay for the SDA Hold
|
||||
* time, repeat this by disabling/enabling the bus a total of 9 times.
|
||||
*/
|
||||
static void send_reset(void)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int i;
|
||||
u32 delay;
|
||||
u8 fdr;
|
||||
int SDA_Tap[] = { 3, 3, 4, 4, 1, 1, 2, 2};
|
||||
struct mpc5xxx_i2c_tap scltap[] = {
|
||||
{4, 1},
|
||||
{4, 2},
|
||||
{6, 4},
|
||||
{6, 8},
|
||||
{14, 16},
|
||||
{30, 32},
|
||||
{62, 64},
|
||||
{126, 128}
|
||||
};
|
||||
|
||||
fdr = (u8)mpc_reg_in(®s->mfdr);
|
||||
|
||||
delay = scltap[FDR432(fdr)].scl2tap + ((SDA_Tap[FDR510(fdr)] - 1) * \
|
||||
scltap[FDR432(fdr)].tap2tap) + 3;
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
mpc_reg_out(®s->mcr, I2C_EN|I2C_STA|I2C_TX, I2C_INIT_MASK);
|
||||
udelay(delay);
|
||||
mpc_reg_out(®s->mcr, 0, I2C_INIT_MASK);
|
||||
udelay(delay);
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK);
|
||||
}
|
||||
#endif /* CONFIG_SYS_I2c_INIT_MPC5XXX */
|
||||
|
||||
/**************** I2C API ****************/
|
||||
|
||||
void i2c_init(int speed, int saddr)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
|
||||
mpc_reg_out(®s->mcr, 0, 0);
|
||||
mpc_reg_out(®s->madr, saddr << 1, 0);
|
||||
|
||||
/* Set clock
|
||||
*/
|
||||
mpc_reg_out(®s->mfdr, mpc_get_fdr(speed), 0);
|
||||
|
||||
/* Enable module
|
||||
*/
|
||||
mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK);
|
||||
mpc_reg_out(®s->msr, 0, I2C_IF);
|
||||
|
||||
#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX)
|
||||
send_reset();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static int mpc_get_fdr(int speed)
|
||||
{
|
||||
static int fdr = -1;
|
||||
|
||||
if (fdr == -1) {
|
||||
ulong best_speed = 0;
|
||||
ulong divider;
|
||||
ulong ipb, scl;
|
||||
ulong bestmatch = 0xffffffffUL;
|
||||
int best_i = 0, best_j = 0, i, j;
|
||||
int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
|
||||
struct mpc5xxx_i2c_tap scltap[] = {
|
||||
{4, 1},
|
||||
{4, 2},
|
||||
{6, 4},
|
||||
{6, 8},
|
||||
{14, 16},
|
||||
{30, 32},
|
||||
{62, 64},
|
||||
{126, 128}
|
||||
};
|
||||
|
||||
ipb = gd->arch.ipb_clk;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
for (j = 7; j >= 0; j--) {
|
||||
scl = 2 * (scltap[j].scl2tap +
|
||||
(SCL_Tap[i] - 1) * scltap[j].tap2tap + 2);
|
||||
if (ipb <= speed*scl) {
|
||||
if ((speed*scl - ipb) < bestmatch) {
|
||||
bestmatch = speed*scl - ipb;
|
||||
best_i = i;
|
||||
best_j = j;
|
||||
best_speed = ipb/scl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
|
||||
if (gd->flags & GD_FLG_RELOC) {
|
||||
fdr = divider;
|
||||
} else {
|
||||
printf("%ld kHz, ", best_speed / 1000);
|
||||
return divider;
|
||||
}
|
||||
}
|
||||
|
||||
return fdr;
|
||||
}
|
||||
|
||||
int i2c_probe(uchar chip)
|
||||
{
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < I2C_RETRIES; i++) {
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
|
||||
if (! do_address(chip, 0)) {
|
||||
mpc_reg_out(®s->mcr, 0, I2C_STA);
|
||||
udelay(500);
|
||||
break;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, 0, I2C_STA);
|
||||
udelay(500);
|
||||
}
|
||||
|
||||
return (i == I2C_RETRIES);
|
||||
}
|
||||
|
||||
int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
{
|
||||
char xaddr[4];
|
||||
struct mpc5xxx_i2c * regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int ret = -1;
|
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF;
|
||||
xaddr[1] = (addr >> 16) & 0xFF;
|
||||
xaddr[2] = (addr >> 8) & 0xFF;
|
||||
xaddr[3] = addr & 0xFF;
|
||||
|
||||
if (wait_for_bb()) {
|
||||
printf("i2c_read: bus is busy\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
if (do_address(chip, 0)) {
|
||||
printf("i2c_read: failed to address chip\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (send_bytes(chip, &xaddr[4-alen], alen)) {
|
||||
printf("i2c_read: send_bytes failed\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_RSTA, I2C_RSTA);
|
||||
if (do_address(chip, 1)) {
|
||||
printf("i2c_read: failed to address chip\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (receive_bytes(chip, (char *)buf, len)) {
|
||||
printf("i2c_read: receive_bytes failed\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
Done:
|
||||
mpc_reg_out(®s->mcr, 0, I2C_STA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
{
|
||||
char xaddr[4];
|
||||
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
|
||||
int ret = -1;
|
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF;
|
||||
xaddr[1] = (addr >> 16) & 0xFF;
|
||||
xaddr[2] = (addr >> 8) & 0xFF;
|
||||
xaddr[3] = addr & 0xFF;
|
||||
|
||||
if (wait_for_bb()) {
|
||||
printf("i2c_write: bus is busy\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
mpc_reg_out(®s->mcr, I2C_STA, I2C_STA);
|
||||
if (do_address(chip, 0)) {
|
||||
printf("i2c_write: failed to address chip\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (send_bytes(chip, &xaddr[4-alen], alen)) {
|
||||
printf("i2c_write: send_bytes failed\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (send_bytes(chip, (char *)buf, len)) {
|
||||
printf("i2c_write: send_bytes failed\n");
|
||||
goto Done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
Done:
|
||||
mpc_reg_out(®s->mcr, 0, I2C_STA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_I2C_MULTI_BUS)
|
||||
int i2c_set_bus_num(unsigned int bus)
|
||||
{
|
||||
if (bus > 1)
|
||||
return -1;
|
||||
|
||||
i2c_bus_num = bus;
|
||||
i2c_init(i2c_bus_speed[bus], CONFIG_SYS_I2C_SLAVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_set_bus_speed(unsigned int speed)
|
||||
{
|
||||
i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int i2c_get_bus_num(void)
|
||||
{
|
||||
return i2c_bus_num;
|
||||
}
|
||||
|
||||
unsigned int i2c_get_bus_speed(void)
|
||||
{
|
||||
return i2c_bus_speed[i2c_bus_num];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
75
u-boot/arch/powerpc/cpu/mpc5xxx/ide.c
Normal file
75
u-boot/arch/powerpc/cpu/mpc5xxx/ide.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* (C) Copyright 2004
|
||||
* Pierre AUBERT, Staubli Faverges, <p.aubert@staubli.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Init is derived from Linux code.
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
#if defined(CONFIG_CMD_IDE)
|
||||
#include <mpc5xxx.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CALC_TIMING(t) (t + period - 1) / period
|
||||
|
||||
#ifdef CONFIG_IDE_RESET
|
||||
extern void init_ide_reset (void);
|
||||
#endif
|
||||
|
||||
int ide_preinit (void)
|
||||
{
|
||||
long period, t0, t1, t2_8, t2_16, t4, ta;
|
||||
vu_long reg;
|
||||
struct mpc5xxx_sdma *psdma = (struct mpc5xxx_sdma *) MPC5XXX_SDMA;
|
||||
|
||||
reg = *(vu_long *) MPC5XXX_GPS_PORT_CONFIG;
|
||||
#if defined(CONFIG_SYS_ATA_CS_ON_I2C2)
|
||||
/* ATA cs0/1 on i2c2 clk/io */
|
||||
reg = (reg & ~0x03000000ul) | 0x02000000ul;
|
||||
#elif defined(CONFIG_SYS_ATA_CS_ON_TIMER01)
|
||||
/* ATA cs0/1 on Timer 0/1 */
|
||||
reg = (reg & ~0x03000000ul) | 0x03000000ul;
|
||||
#else
|
||||
/* ATA cs0/1 on Local Plus cs4/5 */
|
||||
reg = (reg & ~0x03000000ul) | 0x01000000ul;
|
||||
#endif /* CONFIG_TOTAL5200 */
|
||||
*(vu_long *) MPC5XXX_GPS_PORT_CONFIG = reg;
|
||||
|
||||
/* All sample codes do that... */
|
||||
*(vu_long *) MPC5XXX_ATA_SHARE_COUNT = 0;
|
||||
|
||||
/* Configure and reset host */
|
||||
*(vu_long *) MPC5XXX_ATA_HOST_CONFIG = MPC5xxx_ATA_HOSTCONF_IORDY |
|
||||
MPC5xxx_ATA_HOSTCONF_SMR | MPC5xxx_ATA_HOSTCONF_FR;
|
||||
udelay (10);
|
||||
*(vu_long *) MPC5XXX_ATA_HOST_CONFIG = MPC5xxx_ATA_HOSTCONF_IORDY;
|
||||
|
||||
/* Disable prefetch on Commbus */
|
||||
psdma->PtdCntrl |= 1;
|
||||
|
||||
/* Init timings : we use PIO mode 0 timings */
|
||||
period = 1000000000 / gd->arch.ipb_clk; /* period in ns */
|
||||
|
||||
t0 = CALC_TIMING (600);
|
||||
t2_8 = CALC_TIMING (290);
|
||||
t2_16 = CALC_TIMING (165);
|
||||
reg = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8);
|
||||
*(vu_long *) MPC5XXX_ATA_PIO1 = reg;
|
||||
|
||||
t4 = CALC_TIMING (30);
|
||||
t1 = CALC_TIMING (70);
|
||||
ta = CALC_TIMING (35);
|
||||
reg = (t4 << 24) | (t1 << 16) | (ta << 8);
|
||||
|
||||
*(vu_long *) MPC5XXX_ATA_PIO2 = reg;
|
||||
|
||||
#ifdef CONFIG_IDE_RESET
|
||||
init_ide_reset ();
|
||||
#endif /* CONFIG_IDE_RESET */
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
330
u-boot/arch/powerpc/cpu/mpc5xxx/interrupts.c
Normal file
330
u-boot/arch/powerpc/cpu/mpc5xxx/interrupts.c
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* (C) Copyright 2006
|
||||
* Detlev Zundel, DENX Software Engineering, dzu@denx.de
|
||||
*
|
||||
* (C) Copyright -2003
|
||||
* 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+
|
||||
*/
|
||||
|
||||
/* this section was ripped out of arch/powerpc/syslib/mpc52xx_pic.c in the
|
||||
* Linux 2.6 source with the following copyright.
|
||||
*
|
||||
* Based on (well, mostly copied from) the code from the 2.4 kernel by
|
||||
* Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
|
||||
*
|
||||
* Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
* Copyright (C) 2003 Montavista Software, Inc
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
#include <command.h>
|
||||
|
||||
struct irq_action {
|
||||
interrupt_handler_t *handler;
|
||||
void *arg;
|
||||
ulong count;
|
||||
};
|
||||
|
||||
static struct irq_action irq_handlers[NR_IRQS];
|
||||
|
||||
static struct mpc5xxx_intr *intr;
|
||||
static struct mpc5xxx_sdma *sdma;
|
||||
|
||||
static void mpc5xxx_ic_disable(unsigned int irq)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (irq == MPC5XXX_IRQ0) {
|
||||
val = in_be32(&intr->ctrl);
|
||||
val &= ~(1 << 11);
|
||||
out_be32(&intr->ctrl, val);
|
||||
} else if (irq < MPC5XXX_IRQ1) {
|
||||
BUG();
|
||||
} else if (irq <= MPC5XXX_IRQ3) {
|
||||
val = in_be32(&intr->ctrl);
|
||||
val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
|
||||
out_be32(&intr->ctrl, val);
|
||||
} else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
|
||||
val = in_be32(&intr->main_mask);
|
||||
val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
|
||||
out_be32(&intr->main_mask, val);
|
||||
} else if (irq < MPC5XXX_PERP_IRQ_BASE) {
|
||||
val = in_be32(&sdma->IntMask);
|
||||
val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
|
||||
out_be32(&sdma->IntMask, val);
|
||||
} else {
|
||||
val = in_be32(&intr->per_mask);
|
||||
val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
|
||||
out_be32(&intr->per_mask, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc5xxx_ic_enable(unsigned int irq)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (irq == MPC5XXX_IRQ0) {
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 1 << 11;
|
||||
out_be32(&intr->ctrl, val);
|
||||
} else if (irq < MPC5XXX_IRQ1) {
|
||||
BUG();
|
||||
} else if (irq <= MPC5XXX_IRQ3) {
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
|
||||
out_be32(&intr->ctrl, val);
|
||||
} else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
|
||||
val = in_be32(&intr->main_mask);
|
||||
val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
|
||||
out_be32(&intr->main_mask, val);
|
||||
} else if (irq < MPC5XXX_PERP_IRQ_BASE) {
|
||||
val = in_be32(&sdma->IntMask);
|
||||
val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
|
||||
out_be32(&sdma->IntMask, val);
|
||||
} else {
|
||||
val = in_be32(&intr->per_mask);
|
||||
val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
|
||||
out_be32(&intr->per_mask, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc5xxx_ic_ack(unsigned int irq)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Only some irqs are reset here, others in interrupting hardware.
|
||||
*/
|
||||
|
||||
switch (irq) {
|
||||
case MPC5XXX_IRQ0:
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 0x08000000;
|
||||
out_be32(&intr->ctrl, val);
|
||||
break;
|
||||
case MPC5XXX_CCS_IRQ:
|
||||
val = in_be32(&intr->enc_status);
|
||||
val |= 0x00000400;
|
||||
out_be32(&intr->enc_status, val);
|
||||
break;
|
||||
case MPC5XXX_IRQ1:
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 0x04000000;
|
||||
out_be32(&intr->ctrl, val);
|
||||
break;
|
||||
case MPC5XXX_IRQ2:
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 0x02000000;
|
||||
out_be32(&intr->ctrl, val);
|
||||
break;
|
||||
case MPC5XXX_IRQ3:
|
||||
val = in_be32(&intr->ctrl);
|
||||
val |= 0x01000000;
|
||||
out_be32(&intr->ctrl, val);
|
||||
break;
|
||||
default:
|
||||
if (irq >= MPC5XXX_SDMA_IRQ_BASE
|
||||
&& irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
|
||||
out_be32(&sdma->IntPend,
|
||||
1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
|
||||
{
|
||||
mpc5xxx_ic_disable(irq);
|
||||
mpc5xxx_ic_ack(irq);
|
||||
}
|
||||
|
||||
static void mpc5xxx_ic_end(unsigned int irq)
|
||||
{
|
||||
mpc5xxx_ic_enable(irq);
|
||||
}
|
||||
|
||||
void mpc5xxx_init_irq(void)
|
||||
{
|
||||
u32 intr_ctrl;
|
||||
|
||||
/* Remap the necessary zones */
|
||||
intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
|
||||
sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
|
||||
|
||||
/* Disable all interrupt sources. */
|
||||
out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
|
||||
out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
|
||||
out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
|
||||
out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
|
||||
intr_ctrl = in_be32(&intr->ctrl);
|
||||
intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
|
||||
0x00ff0000 | /* IRQ 0-3 level sensitive low active */
|
||||
0x00001000 | /* MEE master external enable */
|
||||
0x00000000 | /* 0 means disable IRQ 0-3 */
|
||||
0x00000001; /* CEb route critical normally */
|
||||
out_be32(&intr->ctrl, intr_ctrl);
|
||||
|
||||
/* Zero a bunch of the priority settings. */
|
||||
out_be32(&intr->per_pri1, 0);
|
||||
out_be32(&intr->per_pri2, 0);
|
||||
out_be32(&intr->per_pri3, 0);
|
||||
out_be32(&intr->main_pri1, 0);
|
||||
out_be32(&intr->main_pri2, 0);
|
||||
}
|
||||
|
||||
int mpc5xxx_get_irq(struct pt_regs *regs)
|
||||
{
|
||||
u32 status;
|
||||
int irq = -1;
|
||||
|
||||
status = in_be32(&intr->enc_status);
|
||||
|
||||
if (status & 0x00000400) { /* critical */
|
||||
irq = (status >> 8) & 0x3;
|
||||
if (irq == 2) /* high priority peripheral */
|
||||
goto peripheral;
|
||||
irq += MPC5XXX_CRIT_IRQ_BASE;
|
||||
} else if (status & 0x00200000) { /* main */
|
||||
irq = (status >> 16) & 0x1f;
|
||||
if (irq == 4) /* low priority peripheral */
|
||||
goto peripheral;
|
||||
irq += MPC5XXX_MAIN_IRQ_BASE;
|
||||
} else if (status & 0x20000000) { /* peripheral */
|
||||
peripheral:
|
||||
irq = (status >> 24) & 0x1f;
|
||||
if (irq == 0) { /* bestcomm */
|
||||
status = in_be32(&sdma->IntPend);
|
||||
irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
|
||||
} else
|
||||
irq += MPC5XXX_PERP_IRQ_BASE;
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
int interrupt_init_cpu(ulong * decrementer_count)
|
||||
{
|
||||
*decrementer_count = get_tbclk() / CONFIG_SYS_HZ;
|
||||
|
||||
mpc5xxx_init_irq();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Handle external interrupts
|
||||
*/
|
||||
void external_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
int irq, unmask = 1;
|
||||
|
||||
irq = mpc5xxx_get_irq(regs);
|
||||
|
||||
mpc5xxx_ic_disable_and_ack(irq);
|
||||
|
||||
enable_interrupts();
|
||||
|
||||
if (irq_handlers[irq].handler != NULL)
|
||||
(*irq_handlers[irq].handler) (irq_handlers[irq].arg);
|
||||
else {
|
||||
printf("\nBogus External Interrupt IRQ %d\n", irq);
|
||||
/*
|
||||
* turn off the bogus interrupt, otherwise it
|
||||
* might repeat forever
|
||||
*/
|
||||
unmask = 0;
|
||||
}
|
||||
|
||||
if (unmask)
|
||||
mpc5xxx_ic_end(irq);
|
||||
}
|
||||
|
||||
void timer_interrupt_cpu(struct pt_regs *regs)
|
||||
{
|
||||
/* nothing to do here */
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Install and free a interrupt handler.
|
||||
*/
|
||||
|
||||
void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
|
||||
{
|
||||
if (irq < 0 || irq >= NR_IRQS) {
|
||||
printf("irq_install_handler: bad irq number %d\n", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irq_handlers[irq].handler != NULL)
|
||||
printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
|
||||
(ulong) handler, (ulong) irq_handlers[irq].handler);
|
||||
|
||||
irq_handlers[irq].handler = handler;
|
||||
irq_handlers[irq].arg = arg;
|
||||
|
||||
mpc5xxx_ic_enable(irq);
|
||||
}
|
||||
|
||||
void irq_free_handler(int irq)
|
||||
{
|
||||
if (irq < 0 || irq >= NR_IRQS) {
|
||||
printf("irq_free_handler: bad irq number %d\n", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
mpc5xxx_ic_disable(irq);
|
||||
|
||||
irq_handlers[irq].handler = NULL;
|
||||
irq_handlers[irq].arg = NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_CMD_IRQ)
|
||||
void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int irq, re_enable;
|
||||
u32 intr_ctrl;
|
||||
char *irq_config[] = { "level sensitive, active high",
|
||||
"edge sensitive, rising active edge",
|
||||
"edge sensitive, falling active edge",
|
||||
"level sensitive, active low"
|
||||
};
|
||||
|
||||
re_enable = disable_interrupts();
|
||||
|
||||
intr_ctrl = in_be32(&intr->ctrl);
|
||||
printf("Interrupt configuration:\n");
|
||||
|
||||
for (irq = 0; irq <= 3; irq++) {
|
||||
printf("IRQ%d: %s\n", irq,
|
||||
irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
|
||||
}
|
||||
|
||||
puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
|
||||
|
||||
for (irq = 0; irq < NR_IRQS; irq++)
|
||||
if (irq_handlers[irq].handler != NULL)
|
||||
printf("%02d %08lx %08lx %ld\n", irq,
|
||||
(ulong) irq_handlers[irq].handler,
|
||||
(ulong) irq_handlers[irq].arg,
|
||||
irq_handlers[irq].count);
|
||||
|
||||
if (re_enable)
|
||||
enable_interrupts();
|
||||
}
|
||||
#endif
|
||||
112
u-boot/arch/powerpc/cpu/mpc5xxx/io.S
Normal file
112
u-boot/arch/powerpc/cpu/mpc5xxx/io.S
Normal file
@@ -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) 2003 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
|
||||
76
u-boot/arch/powerpc/cpu/mpc5xxx/loadtask.c
Normal file
76
u-boot/arch/powerpc/cpu/mpc5xxx/loadtask.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* This file is based on code
|
||||
* (C) Copyright Motorola, Inc., 2000
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
|
||||
/* BestComm/SmartComm microcode */
|
||||
extern int taskTable;
|
||||
|
||||
void loadtask(int basetask, int tasks)
|
||||
{
|
||||
int *sram = (int *)MPC5XXX_SRAM;
|
||||
int *task_org = &taskTable;
|
||||
unsigned int start, offset, end;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("basetask = %d, tasks = %d\n", basetask, tasks);
|
||||
printf("task_org = 0x%08x\n", (unsigned int)task_org);
|
||||
#endif
|
||||
|
||||
/* setup TaskBAR register */
|
||||
*(vu_long *)MPC5XXX_SDMA = MPC5XXX_SRAM;
|
||||
|
||||
/* relocate task table entries */
|
||||
offset = (unsigned int)sram;
|
||||
for (i = basetask; i < basetask + tasks; i++) {
|
||||
sram[i * 8 + 0] = task_org[i * 8 + 0] + offset;
|
||||
sram[i * 8 + 1] = task_org[i * 8 + 1] + offset;
|
||||
sram[i * 8 + 2] = task_org[i * 8 + 2] + offset;
|
||||
sram[i * 8 + 3] = task_org[i * 8 + 3] + offset;
|
||||
sram[i * 8 + 4] = task_org[i * 8 + 4];
|
||||
sram[i * 8 + 5] = task_org[i * 8 + 5];
|
||||
sram[i * 8 + 6] = task_org[i * 8 + 6] + offset;
|
||||
sram[i * 8 + 7] = task_org[i * 8 + 7];
|
||||
}
|
||||
|
||||
/* relocate task descriptors */
|
||||
start = (sram[basetask * 8] - (unsigned int)sram);
|
||||
end = (sram[(basetask + tasks - 1) * 8 + 1] - (unsigned int)sram);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("TDT start = 0x%08x, end = 0x%08x\n", start, end);
|
||||
#endif
|
||||
|
||||
start /= 4;
|
||||
end /= 4;
|
||||
for (i = start; i <= end; i++) {
|
||||
sram[i] = task_org[i];
|
||||
}
|
||||
|
||||
/* relocate variables */
|
||||
start = (sram[basetask * 8 + 2] - (unsigned int)sram);
|
||||
end = (sram[(basetask + tasks - 1) * 8 + 2] + 256 - (unsigned int)sram);
|
||||
start /= 4;
|
||||
end /= 4;
|
||||
for (i = start; i < end; i++) {
|
||||
sram[i] = task_org[i];
|
||||
}
|
||||
|
||||
/* relocate function decriptors */
|
||||
start = ((sram[basetask * 8 + 3] & 0xfffffffc) - (unsigned int)sram);
|
||||
end = ((sram[(basetask + tasks - 1) * 8 + 3] & 0xfffffffc) + 256 - (unsigned int)sram);
|
||||
start /= 4;
|
||||
end /= 4;
|
||||
for (i = start; i < end; i++) {
|
||||
sram[i] = task_org[i];
|
||||
}
|
||||
|
||||
asm volatile ("sync");
|
||||
}
|
||||
157
u-boot/arch/powerpc/cpu/mpc5xxx/pci_mpc5200.c
Normal file
157
u-boot/arch/powerpc/cpu/mpc5xxx/pci_mpc5200.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
#include <pci.h>
|
||||
#include <mpc5xxx.h>
|
||||
|
||||
/* System RAM mapped over PCI */
|
||||
#define CONFIG_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
|
||||
#define CONFIG_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE
|
||||
#define CONFIG_PCI_MEMORY_SIZE (1024 * 1024 * 1024)
|
||||
|
||||
/* PCIIWCR bit fields */
|
||||
#define IWCR_MEM (0 << 3)
|
||||
#define IWCR_IO (1 << 3)
|
||||
#define IWCR_READ (0 << 1)
|
||||
#define IWCR_READLINE (1 << 1)
|
||||
#define IWCR_READMULT (2 << 1)
|
||||
#define IWCR_EN (1 << 0)
|
||||
|
||||
static int mpc5200_read_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev, int offset, u32* value)
|
||||
{
|
||||
*(volatile u32 *)MPC5XXX_PCI_CAR = (1 << 31) | dev | offset;
|
||||
eieio();
|
||||
udelay(10);
|
||||
*value = in_le32((volatile u32 *)CONFIG_PCI_IO_PHYS);
|
||||
eieio();
|
||||
*(volatile u32 *)MPC5XXX_PCI_CAR = 0;
|
||||
udelay(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc5200_write_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev, int offset, u32 value)
|
||||
{
|
||||
*(volatile u32 *)MPC5XXX_PCI_CAR = (1 << 31) | dev | offset;
|
||||
eieio();
|
||||
udelay(10);
|
||||
out_le32((volatile u32 *)CONFIG_PCI_IO_PHYS, value);
|
||||
eieio();
|
||||
*(volatile u32 *)MPC5XXX_PCI_CAR = 0;
|
||||
udelay(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pci_mpc5xxx_init (struct pci_controller *hose)
|
||||
{
|
||||
hose->first_busno = 0;
|
||||
hose->last_busno = 0xff;
|
||||
|
||||
/* System space */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_PCI_MEMORY_BUS,
|
||||
CONFIG_PCI_MEMORY_PHYS,
|
||||
CONFIG_PCI_MEMORY_SIZE,
|
||||
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
|
||||
|
||||
/* PCI memory space */
|
||||
pci_set_region(hose->regions + 1,
|
||||
CONFIG_PCI_MEM_BUS,
|
||||
CONFIG_PCI_MEM_PHYS,
|
||||
CONFIG_PCI_MEM_SIZE,
|
||||
PCI_REGION_MEM);
|
||||
|
||||
/* PCI IO space */
|
||||
pci_set_region(hose->regions + 2,
|
||||
CONFIG_PCI_IO_BUS,
|
||||
CONFIG_PCI_IO_PHYS,
|
||||
CONFIG_PCI_IO_SIZE,
|
||||
PCI_REGION_IO);
|
||||
|
||||
hose->region_count = 3;
|
||||
|
||||
pci_register_hose(hose);
|
||||
|
||||
/* GPIO Multiplexing - enable PCI */
|
||||
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~(1 << 15);
|
||||
|
||||
/* Set host bridge as pci master and enable memory decoding */
|
||||
*(vu_long *)MPC5XXX_PCI_CMD |=
|
||||
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
|
||||
/* Set maximum latency timer */
|
||||
*(vu_long *)MPC5XXX_PCI_CFG |= (0xf800);
|
||||
|
||||
/* Set cache line size */
|
||||
*(vu_long *)MPC5XXX_PCI_CFG = (*(vu_long *)MPC5XXX_PCI_CFG & ~0xff) |
|
||||
(CONFIG_SYS_CACHELINE_SIZE / 4);
|
||||
|
||||
/* Map MBAR to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR0 = CONFIG_SYS_MBAR;
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR0 = CONFIG_SYS_MBAR | 1;
|
||||
|
||||
/* Map RAM to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR1 = CONFIG_PCI_MEMORY_BUS | (1 << 3);
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR1 = CONFIG_PCI_MEMORY_PHYS | 1;
|
||||
|
||||
/* Park XLB on PCI */
|
||||
*(vu_long *)(MPC5XXX_XLBARB + 0x40) &= ~((7 << 8) | (3 << 5));
|
||||
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (3 << 8) | (3 << 5);
|
||||
|
||||
/* Disable interrupts from PCI controller */
|
||||
*(vu_long *)MPC5XXX_PCI_GSCR &= ~(7 << 12);
|
||||
*(vu_long *)MPC5XXX_PCI_ICR &= ~(7 << 24);
|
||||
|
||||
/* Set PCI retry counter to 0 = infinite retry. */
|
||||
/* The default of 255 is too short for slow devices. */
|
||||
*(vu_long *)MPC5XXX_PCI_ICR &= 0xFFFFFF00;
|
||||
|
||||
/* Disable initiator windows */
|
||||
*(vu_long *)MPC5XXX_PCI_IWCR = 0;
|
||||
|
||||
/* Map PCI memory to physical space */
|
||||
*(vu_long *)MPC5XXX_PCI_IW0BTAR = CONFIG_PCI_MEM_PHYS |
|
||||
(((CONFIG_PCI_MEM_SIZE - 1) >> 8) & 0x00ff0000) |
|
||||
(CONFIG_PCI_MEM_BUS >> 16);
|
||||
*(vu_long *)MPC5XXX_PCI_IWCR |= (IWCR_MEM | IWCR_READ | IWCR_EN) << 24;
|
||||
|
||||
/* Map PCI I/O to physical space */
|
||||
*(vu_long *)MPC5XXX_PCI_IW1BTAR = CONFIG_PCI_IO_PHYS |
|
||||
(((CONFIG_PCI_IO_SIZE - 1) >> 8) & 0x00ff0000) |
|
||||
(CONFIG_PCI_IO_BUS >> 16);
|
||||
*(vu_long *)MPC5XXX_PCI_IWCR |= (IWCR_IO | IWCR_READ | IWCR_EN) << 16;
|
||||
|
||||
/* Reset the PCI bus */
|
||||
*(vu_long *)MPC5XXX_PCI_GSCR |= 1;
|
||||
udelay(1000);
|
||||
*(vu_long *)MPC5XXX_PCI_GSCR &= ~1;
|
||||
udelay(1000);
|
||||
|
||||
pci_set_ops(hose,
|
||||
pci_hose_read_config_byte_via_dword,
|
||||
pci_hose_read_config_word_via_dword,
|
||||
mpc5200_read_config_dword,
|
||||
pci_hose_write_config_byte_via_dword,
|
||||
pci_hose_write_config_word_via_dword,
|
||||
mpc5200_write_config_dword);
|
||||
|
||||
udelay(1000);
|
||||
|
||||
#ifdef CONFIG_PCI_SCAN_SHOW
|
||||
printf("PCI: Bus Dev VenId DevId Class Int\n");
|
||||
#endif
|
||||
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
265
u-boot/arch/powerpc/cpu/mpc5xxx/serial.c
Normal file
265
u-boot/arch/powerpc/cpu/mpc5xxx/serial.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* (C) Copyright 2000 - 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
|
||||
* changes based on the file arch/powerpc/mbxboot/m8260_tty.c from the
|
||||
* Linux/PPC sources (m8260_tty.c had no copyright info in it).
|
||||
*
|
||||
* Martin Krause, 8 Jun 2006
|
||||
* Added SERIAL_MULTI support
|
||||
*/
|
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the PSC ports
|
||||
* as serial console interface.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <serial.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if defined(CONFIG_PSC_CONSOLE)
|
||||
|
||||
#if CONFIG_PSC_CONSOLE == 1
|
||||
#define PSC_BASE MPC5XXX_PSC1
|
||||
#elif CONFIG_PSC_CONSOLE == 2
|
||||
#define PSC_BASE MPC5XXX_PSC2
|
||||
#elif CONFIG_PSC_CONSOLE == 3
|
||||
#define PSC_BASE MPC5XXX_PSC3
|
||||
#elif CONFIG_PSC_CONSOLE == 4
|
||||
#define PSC_BASE MPC5XXX_PSC4
|
||||
#elif CONFIG_PSC_CONSOLE == 5
|
||||
#define PSC_BASE MPC5XXX_PSC5
|
||||
#elif CONFIG_PSC_CONSOLE == 6
|
||||
#define PSC_BASE MPC5XXX_PSC6
|
||||
#else
|
||||
#error CONFIG_PSC_CONSOLE must be in 1 ... 6
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PSC_CONSOLE2)
|
||||
|
||||
#if CONFIG_PSC_CONSOLE2 == 1
|
||||
#define PSC_BASE2 MPC5XXX_PSC1
|
||||
#elif CONFIG_PSC_CONSOLE2 == 2
|
||||
#define PSC_BASE2 MPC5XXX_PSC2
|
||||
#elif CONFIG_PSC_CONSOLE2 == 3
|
||||
#define PSC_BASE2 MPC5XXX_PSC3
|
||||
#elif CONFIG_PSC_CONSOLE2 == 4
|
||||
#define PSC_BASE2 MPC5XXX_PSC4
|
||||
#elif CONFIG_PSC_CONSOLE2 == 5
|
||||
#define PSC_BASE2 MPC5XXX_PSC5
|
||||
#elif CONFIG_PSC_CONSOLE2 == 6
|
||||
#define PSC_BASE2 MPC5XXX_PSC6
|
||||
#else
|
||||
#error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int serial_init_dev (unsigned long dev_base)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
unsigned long baseclk;
|
||||
int div;
|
||||
|
||||
/* reset PSC */
|
||||
psc->command = PSC_SEL_MODE_REG_1;
|
||||
|
||||
/* select clock sources */
|
||||
psc->psc_clock_select = 0;
|
||||
baseclk = (gd->arch.ipb_clk + 16) / 32;
|
||||
|
||||
/* switch to UART mode */
|
||||
psc->sicr = 0;
|
||||
|
||||
/* configure parity, bit length and so on */
|
||||
psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
|
||||
psc->mode = PSC_MODE_ONE_STOP;
|
||||
|
||||
/* set up UART divisor */
|
||||
div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
|
||||
psc->ctur = (div >> 8) & 0xff;
|
||||
psc->ctlr = div & 0xff;
|
||||
|
||||
/* disable all interrupts */
|
||||
psc->psc_imr = 0;
|
||||
|
||||
/* reset and enable Rx/Tx */
|
||||
psc->command = PSC_RST_RX;
|
||||
psc->command = PSC_RST_TX;
|
||||
psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void serial_putc_dev (unsigned long dev_base, const char c)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
|
||||
if (c == '\n')
|
||||
serial_putc_dev (dev_base, '\r');
|
||||
|
||||
/* Wait for last character to go. */
|
||||
while (!(psc->psc_status & PSC_SR_TXEMP))
|
||||
;
|
||||
|
||||
psc->psc_buffer_8 = c;
|
||||
}
|
||||
|
||||
void serial_puts_dev (unsigned long dev_base, const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
serial_putc_dev (dev_base, *s++);
|
||||
}
|
||||
}
|
||||
|
||||
int serial_getc_dev (unsigned long dev_base)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
|
||||
/* Wait for a character to arrive. */
|
||||
while (!(psc->psc_status & PSC_SR_RXRDY))
|
||||
;
|
||||
|
||||
return psc->psc_buffer_8;
|
||||
}
|
||||
|
||||
int serial_tstc_dev (unsigned long dev_base)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
|
||||
return (psc->psc_status & PSC_SR_RXRDY);
|
||||
}
|
||||
|
||||
void serial_setbrg_dev (unsigned long dev_base)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
unsigned long baseclk, div;
|
||||
|
||||
baseclk = (gd->arch.ipb_clk + 16) / 32;
|
||||
|
||||
/* set up UART divisor */
|
||||
div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
|
||||
psc->ctur = (div >> 8) & 0xFF;
|
||||
psc->ctlr = div & 0xff;
|
||||
}
|
||||
|
||||
void serial_setrts_dev (unsigned long dev_base, int s)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
|
||||
if (s) {
|
||||
/* Assert RTS (become LOW) */
|
||||
psc->op1 = 0x1;
|
||||
}
|
||||
else {
|
||||
/* Negate RTS (become HIGH) */
|
||||
psc->op0 = 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
int serial_getcts_dev (unsigned long dev_base)
|
||||
{
|
||||
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
|
||||
|
||||
return (psc->ip & 0x1) ? 0 : 1;
|
||||
}
|
||||
|
||||
int serial0_init(void)
|
||||
{
|
||||
return (serial_init_dev(PSC_BASE));
|
||||
}
|
||||
|
||||
void serial0_setbrg (void)
|
||||
{
|
||||
serial_setbrg_dev(PSC_BASE);
|
||||
}
|
||||
|
||||
void serial0_putc(const char c)
|
||||
{
|
||||
serial_putc_dev(PSC_BASE,c);
|
||||
}
|
||||
|
||||
void serial0_puts(const char *s)
|
||||
{
|
||||
serial_puts_dev(PSC_BASE, s);
|
||||
}
|
||||
|
||||
int serial0_getc(void)
|
||||
{
|
||||
return(serial_getc_dev(PSC_BASE));
|
||||
}
|
||||
|
||||
int serial0_tstc(void)
|
||||
{
|
||||
return (serial_tstc_dev(PSC_BASE));
|
||||
}
|
||||
|
||||
struct serial_device serial0_device =
|
||||
{
|
||||
.name = "serial0",
|
||||
.start = serial0_init,
|
||||
.stop = NULL,
|
||||
.setbrg = serial0_setbrg,
|
||||
.getc = serial0_getc,
|
||||
.tstc = serial0_tstc,
|
||||
.putc = serial0_putc,
|
||||
.puts = serial0_puts,
|
||||
};
|
||||
|
||||
__weak struct serial_device *default_serial_console(void)
|
||||
{
|
||||
return &serial0_device;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PSC_CONSOLE2
|
||||
int serial1_init(void)
|
||||
{
|
||||
return serial_init_dev(PSC_BASE2);
|
||||
}
|
||||
|
||||
void serial1_setbrg(void)
|
||||
{
|
||||
serial_setbrg_dev(PSC_BASE2);
|
||||
}
|
||||
|
||||
void serial1_putc(const char c)
|
||||
{
|
||||
serial_putc_dev(PSC_BASE2, c);
|
||||
}
|
||||
|
||||
void serial1_puts(const char *s)
|
||||
{
|
||||
serial_puts_dev(PSC_BASE2, s);
|
||||
}
|
||||
|
||||
int serial1_getc(void)
|
||||
{
|
||||
return serial_getc_dev(PSC_BASE2);
|
||||
}
|
||||
|
||||
int serial1_tstc(void)
|
||||
{
|
||||
return serial_tstc_dev(PSC_BASE2);
|
||||
}
|
||||
|
||||
struct serial_device serial1_device =
|
||||
{
|
||||
.name = "serial1",
|
||||
.start = serial1_init,
|
||||
.stop = NULL,
|
||||
.setbrg = serial1_setbrg,
|
||||
.getc = serial1_getc,
|
||||
.tstc = serial1_tstc,
|
||||
.putc = serial1_putc,
|
||||
.puts = serial1_puts,
|
||||
};
|
||||
#endif /* CONFIG_PSC_CONSOLE2 */
|
||||
|
||||
#endif /* CONFIG_PSC_CONSOLE */
|
||||
84
u-boot/arch/powerpc/cpu/mpc5xxx/speed.c
Normal file
84
u-boot/arch/powerpc/cpu/mpc5xxx/speed.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Bus-to-Core Multipliers */
|
||||
|
||||
static int bus2core[] = {
|
||||
3, 2, 2, 2, 4, 4, 5, 9,
|
||||
6, 11, 8, 10, 3, 12, 7, 0,
|
||||
6, 5, 13, 2, 14, 4, 15, 9,
|
||||
0, 11, 8, 10, 16, 12, 7, 0
|
||||
};
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int get_clocks (void)
|
||||
{
|
||||
ulong val, vco;
|
||||
|
||||
#if !defined(CONFIG_SYS_MPC5XXX_CLKIN)
|
||||
#error clock measuring not implemented yet - define CONFIG_SYS_MPC5XXX_CLKIN
|
||||
#endif
|
||||
|
||||
val = *(vu_long *)MPC5XXX_CDM_PORCFG;
|
||||
if (val & (1 << 6)) {
|
||||
vco = CONFIG_SYS_MPC5XXX_CLKIN * 12;
|
||||
} else {
|
||||
vco = CONFIG_SYS_MPC5XXX_CLKIN * 16;
|
||||
}
|
||||
if (val & (1 << 5)) {
|
||||
gd->bus_clk = vco / 8;
|
||||
} else {
|
||||
gd->bus_clk = vco / 4;
|
||||
}
|
||||
gd->cpu_clk = gd->bus_clk * bus2core[val & 0x1f] / 2;
|
||||
|
||||
val = *(vu_long *)MPC5XXX_CDM_CFG;
|
||||
if (val & (1 << 8)) {
|
||||
gd->arch.ipb_clk = gd->bus_clk / 2;
|
||||
} else {
|
||||
gd->arch.ipb_clk = gd->bus_clk;
|
||||
}
|
||||
switch (val & 3) {
|
||||
case 0:
|
||||
gd->pci_clk = gd->arch.ipb_clk;
|
||||
break;
|
||||
case 1:
|
||||
gd->pci_clk = gd->arch.ipb_clk / 2;
|
||||
break;
|
||||
default:
|
||||
gd->pci_clk = gd->bus_clk / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int prt_mpc5xxx_clks (void)
|
||||
{
|
||||
char buf1[32], buf2[32], buf3[32];
|
||||
|
||||
printf (" Bus %s MHz, IPB %s MHz, PCI %s MHz\n",
|
||||
strmhz(buf1, gd->bus_clk),
|
||||
strmhz(buf2, gd->arch.ipb_clk),
|
||||
strmhz(buf3, gd->pci_clk)
|
||||
);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
76
u-boot/arch/powerpc/cpu/mpc5xxx/spl_boot.c
Normal file
76
u-boot/arch/powerpc/cpu/mpc5xxx/spl_boot.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <spl.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Needed to align size SPL image to a 4-byte length
|
||||
*/
|
||||
u32 end_align __attribute__ ((section(".end_align")));
|
||||
|
||||
/*
|
||||
* Return selected boot device. On MPC5200 its only NOR flash right now.
|
||||
*/
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
return BOOT_DEVICE_NOR;
|
||||
}
|
||||
|
||||
/*
|
||||
* SPL version of board_init_f()
|
||||
*/
|
||||
void board_init_f(ulong bootflag)
|
||||
{
|
||||
end_align = (u32)__spl_flash_end;
|
||||
|
||||
/*
|
||||
* On MPC5200, the initial RAM (and gd) is located in the internal
|
||||
* SRAM. So we can actually call the preloader console init code
|
||||
* before calling initdram(). This makes serial output (printf)
|
||||
* available very early, even before SDRAM init, which has been
|
||||
* an U-Boot priciple from day 1.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init global_data pointer. Has to be done before calling
|
||||
* get_clocks(), as it stores some clock values into gd needed
|
||||
* later on in the serial driver.
|
||||
*/
|
||||
/* 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));
|
||||
|
||||
/*
|
||||
* get_clocks() needs to be called so that the serial driver
|
||||
* works correctly
|
||||
*/
|
||||
get_clocks();
|
||||
|
||||
/*
|
||||
* Do rudimental console / serial setup
|
||||
*/
|
||||
preloader_console_init();
|
||||
|
||||
/*
|
||||
* First we need to initialize the SDRAM, so that the real
|
||||
* U-Boot or the OS (Linux) can be loaded
|
||||
*/
|
||||
initdram(0);
|
||||
|
||||
/* Clear bss */
|
||||
memset(__bss_start, '\0', __bss_end - __bss_start);
|
||||
|
||||
/*
|
||||
* Call board_init_r() (SPL framework version) to load and boot
|
||||
* real U-Boot or OS
|
||||
*/
|
||||
board_init_r(NULL, 0);
|
||||
/* Does not return!!! */
|
||||
}
|
||||
780
u-boot/arch/powerpc/cpu/mpc5xxx/start.S
Normal file
780
u-boot/arch/powerpc/cpu/mpc5xxx/start.S
Normal file
@@ -0,0 +1,780 @@
|
||||
/*
|
||||
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
|
||||
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
|
||||
* Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*
|
||||
* U-Boot - Startup Code for MPC5xxx CPUs
|
||||
*/
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <mpc5xxx.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>
|
||||
|
||||
/* We don't want the MMU yet.
|
||||
*/
|
||||
#undef MSR_KERNEL
|
||||
/* Floating Point enable, Machine Check and Recoverable Interr. */
|
||||
#ifdef DEBUG
|
||||
#define MSR_KERNEL (MSR_FP|MSR_RI)
|
||||
#else
|
||||
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* 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
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version string
|
||||
*/
|
||||
.data
|
||||
.globl version_string
|
||||
version_string:
|
||||
.ascii U_BOOT_VERSION_STRING, "\0"
|
||||
|
||||
/*
|
||||
* Exception vectors
|
||||
*/
|
||||
.text
|
||||
. = EXC_OFF_SYS_RESET
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
|
||||
/*
|
||||
* This is the entry of the real U-Boot from a board port
|
||||
* that supports SPL booting on the MPC5200. We only need
|
||||
* to call board_init_f() here. Everything else has already
|
||||
* been done in the SPL u-boot version.
|
||||
*/
|
||||
GET_GOT /* initialize GOT access */
|
||||
|
||||
/*
|
||||
* The GD (global data) struct needs to get cleared. Lets do
|
||||
* this by calling memset().
|
||||
* This function is called when the platform is build with SPL
|
||||
* support from the main (full-blown) U-Boot. And the GD needs
|
||||
* to get cleared (again) so that the following generic
|
||||
* board support code initializes all variables correctly.
|
||||
*/
|
||||
mr r3, r2 /* parameter 1: GD pointer */
|
||||
li r4,0 /* parameter 2: value to fill */
|
||||
li r5,GD_SIZE /* parameter 3: count */
|
||||
bl memset
|
||||
|
||||
li r3, 0 /* parameter 1: bootflag */
|
||||
bl board_init_f /* run 1st part of board init code (in Flash)*/
|
||||
/* NOTREACHED - board_init_f() does not return */
|
||||
#else
|
||||
mfmsr r5 /* save msr contents */
|
||||
|
||||
/* Move CSBoot and adjust instruction pointer */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_SYS_LOWBOOT)
|
||||
# if defined(CONFIG_SYS_RAMBOOT)
|
||||
# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
|
||||
# endif /* CONFIG_SYS_RAMBOOT */
|
||||
lis r4, CONFIG_SYS_DEFAULT_MBAR@h
|
||||
lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
|
||||
ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
|
||||
stw r3, 0x4(r4) /* CS0 start */
|
||||
lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
|
||||
ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
|
||||
stw r3, 0x8(r4) /* CS0 stop */
|
||||
lis r3, 0x02010000@h
|
||||
ori r3, r3, 0x02010000@l
|
||||
stw r3, 0x54(r4) /* CS0 and Boot enable */
|
||||
|
||||
lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
|
||||
ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
|
||||
mtlr r3
|
||||
blr
|
||||
|
||||
lowboot_reentry:
|
||||
lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
|
||||
ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
|
||||
stw r3, 0x4c(r4) /* Boot start */
|
||||
lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
|
||||
ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
|
||||
stw r3, 0x50(r4) /* Boot stop */
|
||||
lis r3, 0x02000001@h
|
||||
ori r3, r3, 0x02000001@l
|
||||
stw r3, 0x54(r4) /* Boot enable, CS0 disable */
|
||||
#endif /* CONFIG_SYS_LOWBOOT */
|
||||
|
||||
#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
|
||||
lis r3, CONFIG_SYS_MBAR@h
|
||||
ori r3, r3, CONFIG_SYS_MBAR@l
|
||||
/* MBAR is mirrored into the MBAR SPR */
|
||||
mtspr MBAR,r3
|
||||
rlwinm r3, r3, 16, 16, 31
|
||||
lis r4, CONFIG_SYS_DEFAULT_MBAR@h
|
||||
stw r3, 0(r4)
|
||||
#endif /* CONFIG_SYS_DEFAULT_MBAR */
|
||||
|
||||
/* Initialise the MPC5xxx processor core */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
bl init_5xxx_core
|
||||
|
||||
/* initialize some things that are hard to access from C */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
/* set up stack in on-chip SRAM */
|
||||
lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
|
||||
ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
|
||||
ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
|
||||
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 */
|
||||
|
||||
/* let the C-code set up the rest */
|
||||
/* */
|
||||
/* Be careful to keep code relocatable ! */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
GET_GOT /* initialize GOT access */
|
||||
#endif
|
||||
|
||||
/* r3: IMMR */
|
||||
bl cpu_init_f /* run low-level CPU init code (in Flash)*/
|
||||
|
||||
li r3, 0 /* parameter 1: bootflag */
|
||||
bl board_init_f /* run 1st part of board init code (in Flash)*/
|
||||
|
||||
/* NOTREACHED - board_init_f() does not return */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* Vector 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, InstructionTLBMiss, UnknownException)
|
||||
STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
|
||||
STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
|
||||
#ifdef DEBUG
|
||||
. = 0x1300
|
||||
/*
|
||||
* This exception occurs when the program counter matches the
|
||||
* Instruction Address Breakpoint Register (IABR).
|
||||
*
|
||||
* I want the cpu to halt if this occurs so I can hunt around
|
||||
* with the debugger and look at things.
|
||||
*
|
||||
* When DEBUG is defined, both machine check enable (in the MSR)
|
||||
* and checkstop reset enable (in the reset mode register) are
|
||||
* turned off and so a checkstop condition will result in the cpu
|
||||
* halting.
|
||||
*
|
||||
* I force the cpu into a checkstop condition by putting an illegal
|
||||
* instruction here (at least this is the theory).
|
||||
*
|
||||
* well - that didnt work, so just do an infinite loop!
|
||||
*/
|
||||
1: b 1b
|
||||
#else
|
||||
STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
|
||||
#endif
|
||||
STD_EXCEPTION(0x1400, SMI, UnknownException)
|
||||
|
||||
STD_EXCEPTION(0x1500, Trap_15, UnknownException)
|
||||
STD_EXCEPTION(0x1600, Trap_16, UnknownException)
|
||||
STD_EXCEPTION(0x1700, Trap_17, UnknownException)
|
||||
STD_EXCEPTION(0x1800, Trap_18, UnknownException)
|
||||
STD_EXCEPTION(0x1900, Trap_19, UnknownException)
|
||||
STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
|
||||
STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
|
||||
STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
|
||||
STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
|
||||
STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
|
||||
STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
|
||||
STD_EXCEPTION(0x2000, Trap_20, UnknownException)
|
||||
STD_EXCEPTION(0x2100, Trap_21, UnknownException)
|
||||
STD_EXCEPTION(0x2200, Trap_22, UnknownException)
|
||||
STD_EXCEPTION(0x2300, Trap_23, UnknownException)
|
||||
STD_EXCEPTION(0x2400, Trap_24, UnknownException)
|
||||
STD_EXCEPTION(0x2500, Trap_25, UnknownException)
|
||||
STD_EXCEPTION(0x2600, Trap_26, UnknownException)
|
||||
STD_EXCEPTION(0x2700, Trap_27, UnknownException)
|
||||
STD_EXCEPTION(0x2800, Trap_28, UnknownException)
|
||||
STD_EXCEPTION(0x2900, Trap_29, UnknownException)
|
||||
STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
|
||||
STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
|
||||
STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
|
||||
STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
|
||||
STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
|
||||
STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
|
||||
|
||||
|
||||
.globl _end_of_vectors
|
||||
_end_of_vectors:
|
||||
|
||||
. = 0x3000
|
||||
|
||||
/*
|
||||
* 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)
|
||||
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
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
/*
|
||||
* This code initialises the MPC5xxx processor core
|
||||
* (conforms to PowerPC 603e spec)
|
||||
* Note: expects original MSR contents to be in r5.
|
||||
*/
|
||||
|
||||
.globl init_5xx_core
|
||||
init_5xxx_core:
|
||||
|
||||
/* Initialize machine status; enable machine check interrupt */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
li r3, MSR_KERNEL /* Set ME and RI flags */
|
||||
rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
|
||||
#ifdef DEBUG
|
||||
rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
|
||||
#endif
|
||||
SYNC /* Some chip revs need this... */
|
||||
mtmsr r3
|
||||
SYNC
|
||||
mtspr SRR1, r3 /* Make SRR1 match MSR */
|
||||
|
||||
/* Initialize the Hardware Implementation-dependent Registers */
|
||||
/* HID0 also contains cache control */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
lis r3, CONFIG_SYS_HID0_INIT@h
|
||||
ori r3, r3, CONFIG_SYS_HID0_INIT@l
|
||||
SYNC
|
||||
mtspr HID0, r3
|
||||
|
||||
lis r3, CONFIG_SYS_HID0_FINAL@h
|
||||
ori r3, r3, CONFIG_SYS_HID0_FINAL@l
|
||||
SYNC
|
||||
mtspr HID0, r3
|
||||
|
||||
/* clear all BAT's */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
li r0, 0
|
||||
mtspr DBAT0U, r0
|
||||
mtspr DBAT0L, r0
|
||||
mtspr DBAT1U, r0
|
||||
mtspr DBAT1L, r0
|
||||
mtspr DBAT2U, r0
|
||||
mtspr DBAT2L, r0
|
||||
mtspr DBAT3U, r0
|
||||
mtspr DBAT3L, r0
|
||||
mtspr DBAT4U, r0
|
||||
mtspr DBAT4L, r0
|
||||
mtspr DBAT5U, r0
|
||||
mtspr DBAT5L, r0
|
||||
mtspr DBAT6U, r0
|
||||
mtspr DBAT6L, r0
|
||||
mtspr DBAT7U, r0
|
||||
mtspr DBAT7L, r0
|
||||
mtspr IBAT0U, r0
|
||||
mtspr IBAT0L, r0
|
||||
mtspr IBAT1U, r0
|
||||
mtspr IBAT1L, r0
|
||||
mtspr IBAT2U, r0
|
||||
mtspr IBAT2L, r0
|
||||
mtspr IBAT3U, r0
|
||||
mtspr IBAT3L, r0
|
||||
mtspr IBAT4U, r0
|
||||
mtspr IBAT4L, r0
|
||||
mtspr IBAT5U, r0
|
||||
mtspr IBAT5L, r0
|
||||
mtspr IBAT6U, r0
|
||||
mtspr IBAT6L, r0
|
||||
mtspr IBAT7U, r0
|
||||
mtspr IBAT7L, r0
|
||||
SYNC
|
||||
|
||||
/* invalidate all tlb's */
|
||||
/* */
|
||||
/* From the 603e User Manual: "The 603e provides the ability to */
|
||||
/* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
|
||||
/* instruction invalidates the TLB entry indexed by the EA, and */
|
||||
/* operates on both the instruction and data TLBs simultaneously*/
|
||||
/* invalidating four TLB entries (both sets in each TLB). The */
|
||||
/* index corresponds to bits 15-19 of the EA. To invalidate all */
|
||||
/* entries within both TLBs, 32 tlbie instructions should be */
|
||||
/* issued, incrementing this field by one each time." */
|
||||
/* */
|
||||
/* "Note that the tlbia instruction is not implemented on the */
|
||||
/* 603e." */
|
||||
/* */
|
||||
/* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
|
||||
/* incrementing by 0x1000 each time. The code below is sort of */
|
||||
/* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
|
||||
/* */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
li r3, 32
|
||||
mtctr r3
|
||||
li r3, 0
|
||||
1: tlbie r3
|
||||
addi r3, r3, 0x1000
|
||||
bdnz 1b
|
||||
SYNC
|
||||
|
||||
/* Done! */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
blr
|
||||
|
||||
/* Cache functions.
|
||||
*
|
||||
* Note: requires that all cache bits in
|
||||
* HID0 are in the low half word.
|
||||
*/
|
||||
.globl icache_enable
|
||||
icache_enable:
|
||||
mfspr r3, HID0
|
||||
ori r3, r3, HID0_ICE
|
||||
lis r4, 0
|
||||
ori r4, r4, HID0_ILOCK
|
||||
andc r3, r3, r4
|
||||
ori r4, r3, HID0_ICFI
|
||||
isync
|
||||
mtspr HID0, r4 /* sets enable and invalidate, clears lock */
|
||||
isync
|
||||
mtspr HID0, r3 /* clears invalidate */
|
||||
blr
|
||||
|
||||
.globl icache_disable
|
||||
icache_disable:
|
||||
mfspr r3, HID0
|
||||
lis r4, 0
|
||||
ori r4, r4, HID0_ICE|HID0_ILOCK
|
||||
andc r3, r3, r4
|
||||
ori r4, r3, HID0_ICFI
|
||||
isync
|
||||
mtspr HID0, r4 /* sets invalidate, clears enable and lock */
|
||||
isync
|
||||
mtspr HID0, r3 /* clears invalidate */
|
||||
blr
|
||||
|
||||
.globl icache_status
|
||||
icache_status:
|
||||
mfspr r3, HID0
|
||||
rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
|
||||
blr
|
||||
|
||||
.globl dcache_enable
|
||||
dcache_enable:
|
||||
mfspr r3, HID0
|
||||
ori r3, r3, HID0_DCE
|
||||
lis r4, 0
|
||||
ori r4, r4, HID0_DLOCK
|
||||
andc r3, r3, r4
|
||||
ori r4, r3, HID0_DCI
|
||||
sync
|
||||
mtspr HID0, r4 /* sets enable and invalidate, clears lock */
|
||||
sync
|
||||
mtspr HID0, r3 /* clears invalidate */
|
||||
blr
|
||||
|
||||
.globl dcache_disable
|
||||
dcache_disable:
|
||||
mfspr r3, HID0
|
||||
lis r4, 0
|
||||
ori r4, r4, HID0_DCE|HID0_DLOCK
|
||||
andc r3, r3, r4
|
||||
ori r4, r3, HID0_DCI
|
||||
sync
|
||||
mtspr HID0, r4 /* sets invalidate, clears enable and lock */
|
||||
sync
|
||||
mtspr HID0, r3 /* clears invalidate */
|
||||
blr
|
||||
|
||||
.globl dcache_status
|
||||
dcache_status:
|
||||
mfspr r3, HID0
|
||||
rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
|
||||
blr
|
||||
|
||||
.globl get_svr
|
||||
get_svr:
|
||||
mfspr r3, SVR
|
||||
blr
|
||||
|
||||
.globl get_pvr
|
||||
get_pvr:
|
||||
mfspr r3, PVR
|
||||
blr
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
|
||||
rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
|
||||
cmpwi r7,0
|
||||
beq 9f
|
||||
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 */
|
||||
9: mfspr r7,HID0 /* don't do icbi if icache is disabled */
|
||||
rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
|
||||
cmpwi r7,0
|
||||
beq 7f
|
||||
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 /* Global Data pointer */
|
||||
mr r4, r10 /* Destination Address */
|
||||
bl board_init_r
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
mfmsr r3 /* now that the vectors have */
|
||||
lis r7, MSR_IP@h /* relocated into low memory */
|
||||
ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
|
||||
andc r3, r3, r7 /* (if it was on) */
|
||||
SYNC /* Some chip revs need this... */
|
||||
mtmsr r3
|
||||
SYNC
|
||||
|
||||
mtlr r4 /* restore link register */
|
||||
blr
|
||||
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
220
u-boot/arch/powerpc/cpu/mpc5xxx/traps.c
Normal file
220
u-boot/arch/powerpc/cpu/mpc5xxx/traps.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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)
|
||||
* fixed Machine Check Reasons by Reinhard Meyer (r.meyer@emk-elektronik.de)
|
||||
*
|
||||
* (C) Copyright 2000-2003
|
||||
* 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);
|
||||
/* refer to 603e Manual (MPC603EUM/AD), chapter 4.5.2.1 */
|
||||
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)
|
||||
{
|
||||
#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("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);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CMD_BEDBUG)
|
||||
extern void do_bedbug_breakpoint(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
void DebugException(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
printf("Debugger trap at @ %lx\n", regs->nip );
|
||||
show_regs(regs);
|
||||
#if defined(CONFIG_CMD_BEDBUG)
|
||||
do_bedbug_breakpoint( regs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
80
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot-customlayout.lds
Normal file
80
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot-customlayout.lds
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* (C) Copyright 2003-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
arch/powerpc/cpu/mpc5xxx/start.o (.text*)
|
||||
arch/powerpc/cpu/mpc5xxx/traps.o (.text*)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o (.ppcenv*)
|
||||
|
||||
*(.text*)
|
||||
. = ALIGN(16);
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
KEEP(*(.got))
|
||||
_GOT2_TABLE_ = .;
|
||||
KEEP(*(.got2))
|
||||
_FIXUP_TABLE_ = .;
|
||||
KEEP(*(.fixup))
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data*)
|
||||
*(.sdata*)
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
. = .;
|
||||
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
}
|
||||
|
||||
. = .;
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
__bss_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
44
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
Normal file
44
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012 Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
|
||||
LENGTH = CONFIG_SPL_BSS_MAX_SIZE
|
||||
flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
|
||||
LENGTH = CONFIG_SYS_SPL_MAX_LEN
|
||||
}
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
__start = .;
|
||||
arch/powerpc/cpu/mpc5xxx/start.o (.text)
|
||||
*(.text*)
|
||||
} > flash
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
|
||||
|
||||
. = ALIGN(4);
|
||||
.end_align : { *(.end_align*) } > flash
|
||||
__spl_flash_end = .;
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > sdram
|
||||
}
|
||||
75
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot.lds
Normal file
75
u-boot/arch/powerpc/cpu/mpc5xxx/u-boot.lds
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* (C) Copyright 2003-2010
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.text :
|
||||
{
|
||||
arch/powerpc/cpu/mpc5xxx/start.o (.text*)
|
||||
arch/powerpc/cpu/mpc5xxx/traps.o (.text*)
|
||||
*(.text*)
|
||||
. = ALIGN(16);
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_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(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
__bss_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
42
u-boot/arch/powerpc/cpu/mpc5xxx/usb.c
Normal file
42
u-boot/arch/powerpc/cpu/mpc5xxx/usb.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
|
||||
|
||||
#include <mpc5xxx.h>
|
||||
|
||||
int usb_cpu_init(void)
|
||||
{
|
||||
/* Set the USB Clock */
|
||||
*(vu_long *)MPC5XXX_CDM_48_FDC = CONFIG_USB_CLOCK;
|
||||
|
||||
#ifdef CONFIG_PSC3_USB /* USB is using the alternate configuration */
|
||||
/* remove all PSC3 USB bits first before ORing in ours */
|
||||
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00804f00;
|
||||
#else
|
||||
/* remove all USB bits first before ORing in ours */
|
||||
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00807000;
|
||||
#endif
|
||||
/* Activate USB port */
|
||||
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= CONFIG_USB_CONFIG;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_cpu_stop(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_cpu_init_fail(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */
|
||||
1528
u-boot/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
Normal file
1528
u-boot/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
Normal file
File diff suppressed because it is too large
Load Diff
418
u-boot/arch/powerpc/cpu/mpc5xxx/usb_ohci.h
Normal file
418
u-boot/arch/powerpc/cpu/mpc5xxx/usb_ohci.h
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* URB OHCI HCD (Host Controller Driver) for USB.
|
||||
*
|
||||
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||
* (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
|
||||
*
|
||||
* usb-ohci.h
|
||||
*/
|
||||
|
||||
|
||||
static int cc_to_error[16] = {
|
||||
|
||||
/* mapping of the OHCI CC status to error codes */
|
||||
/* No Error */ 0,
|
||||
/* CRC Error */ USB_ST_CRC_ERR,
|
||||
/* Bit Stuff */ USB_ST_BIT_ERR,
|
||||
/* Data Togg */ USB_ST_CRC_ERR,
|
||||
/* Stall */ USB_ST_STALLED,
|
||||
/* DevNotResp */ -1,
|
||||
/* PIDCheck */ USB_ST_BIT_ERR,
|
||||
/* UnExpPID */ USB_ST_BIT_ERR,
|
||||
/* DataOver */ USB_ST_BUF_ERR,
|
||||
/* DataUnder */ USB_ST_BUF_ERR,
|
||||
/* reservd */ -1,
|
||||
/* reservd */ -1,
|
||||
/* BufferOver */ USB_ST_BUF_ERR,
|
||||
/* BuffUnder */ USB_ST_BUF_ERR,
|
||||
/* Not Access */ -1,
|
||||
/* Not Access */ -1
|
||||
};
|
||||
|
||||
/* ED States */
|
||||
|
||||
#define ED_NEW 0x00
|
||||
#define ED_UNLINK 0x01
|
||||
#define ED_OPER 0x02
|
||||
#define ED_DEL 0x04
|
||||
#define ED_URB_DEL 0x08
|
||||
|
||||
/* usb_ohci_ed */
|
||||
struct ed {
|
||||
__u32 hwINFO;
|
||||
__u32 hwTailP;
|
||||
__u32 hwHeadP;
|
||||
__u32 hwNextED;
|
||||
|
||||
struct ed *ed_prev;
|
||||
__u8 int_period;
|
||||
__u8 int_branch;
|
||||
__u8 int_load;
|
||||
__u8 int_interval;
|
||||
__u8 state;
|
||||
__u8 type;
|
||||
__u16 last_iso;
|
||||
struct ed *ed_rm_list;
|
||||
|
||||
struct usb_device *usb_dev;
|
||||
__u32 unused[3];
|
||||
} __attribute__((aligned(16)));
|
||||
typedef struct ed ed_t;
|
||||
|
||||
|
||||
/* TD info field */
|
||||
#define TD_CC 0xf0000000
|
||||
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
|
||||
#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
|
||||
#define TD_EC 0x0C000000
|
||||
#define TD_T 0x03000000
|
||||
#define TD_T_DATA0 0x02000000
|
||||
#define TD_T_DATA1 0x03000000
|
||||
#define TD_T_TOGGLE 0x00000000
|
||||
#define TD_R 0x00040000
|
||||
#define TD_DI 0x00E00000
|
||||
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
|
||||
#define TD_DP 0x00180000
|
||||
#define TD_DP_SETUP 0x00000000
|
||||
#define TD_DP_IN 0x00100000
|
||||
#define TD_DP_OUT 0x00080000
|
||||
|
||||
#define TD_ISO 0x00010000
|
||||
#define TD_DEL 0x00020000
|
||||
|
||||
/* CC Codes */
|
||||
#define TD_CC_NOERROR 0x00
|
||||
#define TD_CC_CRC 0x01
|
||||
#define TD_CC_BITSTUFFING 0x02
|
||||
#define TD_CC_DATATOGGLEM 0x03
|
||||
#define TD_CC_STALL 0x04
|
||||
#define TD_DEVNOTRESP 0x05
|
||||
#define TD_PIDCHECKFAIL 0x06
|
||||
#define TD_UNEXPECTEDPID 0x07
|
||||
#define TD_DATAOVERRUN 0x08
|
||||
#define TD_DATAUNDERRUN 0x09
|
||||
#define TD_BUFFEROVERRUN 0x0C
|
||||
#define TD_BUFFERUNDERRUN 0x0D
|
||||
#define TD_NOTACCESSED 0x0F
|
||||
|
||||
|
||||
#define MAXPSW 1
|
||||
|
||||
struct td {
|
||||
__u32 hwINFO;
|
||||
__u32 hwCBP; /* Current Buffer Pointer */
|
||||
__u32 hwNextTD; /* Next TD Pointer */
|
||||
__u32 hwBE; /* Memory Buffer End Pointer */
|
||||
|
||||
__u8 unused;
|
||||
__u8 index;
|
||||
struct ed *ed;
|
||||
struct td *next_dl_td;
|
||||
struct usb_device *usb_dev;
|
||||
int transfer_len;
|
||||
__u32 data;
|
||||
|
||||
__u32 unused2[2];
|
||||
} __attribute__((aligned(32)));
|
||||
typedef struct td td_t;
|
||||
|
||||
#define OHCI_ED_SKIP (1 << 14)
|
||||
|
||||
/*
|
||||
* The HCCA (Host Controller Communications Area) is a 256 byte
|
||||
* structure defined in the OHCI spec. that the host controller is
|
||||
* told the base address of. It must be 256-byte aligned.
|
||||
*/
|
||||
|
||||
#define NUM_INTS 32 /* part of the OHCI standard */
|
||||
struct ohci_hcca {
|
||||
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
|
||||
__u16 pad1; /* set to 0 on each frame_no change */
|
||||
__u16 frame_no; /* current frame number */
|
||||
__u32 done_head; /* info returned for an interrupt */
|
||||
u8 reserved_for_hc[116];
|
||||
} __attribute__((aligned(256)));
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of root hub ports.
|
||||
*/
|
||||
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
|
||||
|
||||
/*
|
||||
* This is the structure of the OHCI controller's memory mapped I/O
|
||||
* region. This is Memory Mapped I/O. You must use the readl() and
|
||||
* writel() macros defined in asm/io.h to access these!!
|
||||
*/
|
||||
struct ohci_regs {
|
||||
/* control and status registers */
|
||||
__u32 revision;
|
||||
__u32 control;
|
||||
__u32 cmdstatus;
|
||||
__u32 intrstatus;
|
||||
__u32 intrenable;
|
||||
__u32 intrdisable;
|
||||
/* memory pointers */
|
||||
__u32 hcca;
|
||||
__u32 ed_periodcurrent;
|
||||
__u32 ed_controlhead;
|
||||
__u32 ed_controlcurrent;
|
||||
__u32 ed_bulkhead;
|
||||
__u32 ed_bulkcurrent;
|
||||
__u32 donehead;
|
||||
/* frame counters */
|
||||
__u32 fminterval;
|
||||
__u32 fmremaining;
|
||||
__u32 fmnumber;
|
||||
__u32 periodicstart;
|
||||
__u32 lsthresh;
|
||||
/* Root hub ports */
|
||||
struct ohci_roothub_regs {
|
||||
__u32 a;
|
||||
__u32 b;
|
||||
__u32 status;
|
||||
__u32 portstatus[MAX_ROOT_PORTS];
|
||||
} roothub;
|
||||
} __attribute__((aligned(32)));
|
||||
|
||||
|
||||
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
||||
|
||||
/*
|
||||
* HcControl (control) register masks
|
||||
*/
|
||||
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
|
||||
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
|
||||
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
|
||||
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
|
||||
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
|
||||
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
|
||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
|
||||
|
||||
/* pre-shifted values for HCFS */
|
||||
# define OHCI_USB_RESET (0 << 6)
|
||||
# define OHCI_USB_RESUME (1 << 6)
|
||||
# define OHCI_USB_OPER (2 << 6)
|
||||
# define OHCI_USB_SUSPEND (3 << 6)
|
||||
|
||||
/*
|
||||
* HcCommandStatus (cmdstatus) register masks
|
||||
*/
|
||||
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||
#define OHCI_CLF (1 << 1) /* control list filled */
|
||||
#define OHCI_BLF (1 << 2) /* bulk list filled */
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
|
||||
|
||||
/*
|
||||
* masks used with interrupt registers:
|
||||
* HcInterruptStatus (intrstatus)
|
||||
* HcInterruptEnable (intrenable)
|
||||
* HcInterruptDisable (intrdisable)
|
||||
*/
|
||||
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
|
||||
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
|
||||
#define OHCI_INTR_SF (1 << 2) /* start frame */
|
||||
#define OHCI_INTR_RD (1 << 3) /* resume detect */
|
||||
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
|
||||
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
|
||||
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
|
||||
#define OHCI_INTR_OC (1 << 30) /* ownership change */
|
||||
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
|
||||
|
||||
|
||||
/* Virtual Root HUB */
|
||||
struct virt_root_hub {
|
||||
int devnum; /* Address of Root Hub endpoint */
|
||||
void *dev; /* was urb */
|
||||
void *int_addr;
|
||||
int send;
|
||||
int interval;
|
||||
};
|
||||
|
||||
/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
|
||||
|
||||
/* destination of request */
|
||||
#define RH_INTERFACE 0x01
|
||||
#define RH_ENDPOINT 0x02
|
||||
#define RH_OTHER 0x03
|
||||
|
||||
#define RH_CLASS 0x20
|
||||
#define RH_VENDOR 0x40
|
||||
|
||||
/* Requests: bRequest << 8 | bmRequestType */
|
||||
#define RH_GET_STATUS 0x0080
|
||||
#define RH_CLEAR_FEATURE 0x0100
|
||||
#define RH_SET_FEATURE 0x0300
|
||||
#define RH_SET_ADDRESS 0x0500
|
||||
#define RH_GET_DESCRIPTOR 0x0680
|
||||
#define RH_SET_DESCRIPTOR 0x0700
|
||||
#define RH_GET_CONFIGURATION 0x0880
|
||||
#define RH_SET_CONFIGURATION 0x0900
|
||||
#define RH_GET_STATE 0x0280
|
||||
#define RH_GET_INTERFACE 0x0A80
|
||||
#define RH_SET_INTERFACE 0x0B00
|
||||
#define RH_SYNC_FRAME 0x0C80
|
||||
/* Our Vendor Specific Request */
|
||||
#define RH_SET_EP 0x2000
|
||||
|
||||
|
||||
/* Hub port features */
|
||||
#define RH_PORT_CONNECTION 0x00
|
||||
#define RH_PORT_ENABLE 0x01
|
||||
#define RH_PORT_SUSPEND 0x02
|
||||
#define RH_PORT_OVER_CURRENT 0x03
|
||||
#define RH_PORT_RESET 0x04
|
||||
#define RH_PORT_POWER 0x08
|
||||
#define RH_PORT_LOW_SPEED 0x09
|
||||
|
||||
#define RH_C_PORT_CONNECTION 0x10
|
||||
#define RH_C_PORT_ENABLE 0x11
|
||||
#define RH_C_PORT_SUSPEND 0x12
|
||||
#define RH_C_PORT_OVER_CURRENT 0x13
|
||||
#define RH_C_PORT_RESET 0x14
|
||||
|
||||
/* Hub features */
|
||||
#define RH_C_HUB_LOCAL_POWER 0x00
|
||||
#define RH_C_HUB_OVER_CURRENT 0x01
|
||||
|
||||
#define RH_DEVICE_REMOTE_WAKEUP 0x00
|
||||
#define RH_ENDPOINT_STALL 0x01
|
||||
|
||||
#define RH_ACK 0x01
|
||||
#define RH_REQ_ERR -1
|
||||
#define RH_NACK 0x00
|
||||
|
||||
|
||||
/* OHCI ROOT HUB REGISTER MASKS */
|
||||
|
||||
/* roothub.portstatus [i] bits */
|
||||
#define RH_PS_CCS 0x00000001 /* current connect status */
|
||||
#define RH_PS_PES 0x00000002 /* port enable status*/
|
||||
#define RH_PS_PSS 0x00000004 /* port suspend status */
|
||||
#define RH_PS_POCI 0x00000008 /* port over current indicator */
|
||||
#define RH_PS_PRS 0x00000010 /* port reset status */
|
||||
#define RH_PS_PPS 0x00000100 /* port power status */
|
||||
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
|
||||
#define RH_PS_CSC 0x00010000 /* connect status change */
|
||||
#define RH_PS_PESC 0x00020000 /* port enable status change */
|
||||
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
|
||||
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
|
||||
#define RH_PS_PRSC 0x00100000 /* port reset status change */
|
||||
|
||||
/* roothub.status bits */
|
||||
#define RH_HS_LPS 0x00000001 /* local power status */
|
||||
#define RH_HS_OCI 0x00000002 /* over current indicator */
|
||||
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
|
||||
#define RH_HS_LPSC 0x00010000 /* local power status change */
|
||||
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
|
||||
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
|
||||
|
||||
/* roothub.b masks */
|
||||
#define RH_B_DR 0x0000ffff /* device removable flags */
|
||||
#define RH_B_PPCM 0xffff0000 /* port power control mask */
|
||||
|
||||
/* roothub.a masks */
|
||||
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
|
||||
#define RH_A_PSM (1 << 8) /* power switching mode */
|
||||
#define RH_A_NPS (1 << 9) /* no power switching */
|
||||
#define RH_A_DT (1 << 10) /* device type (mbz) */
|
||||
#define RH_A_OCPM (1 << 11) /* over current protection mode */
|
||||
#define RH_A_NOCP (1 << 12) /* no over current protection */
|
||||
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
|
||||
|
||||
/* urb */
|
||||
#define N_URB_TD 48
|
||||
typedef struct
|
||||
{
|
||||
ed_t *ed;
|
||||
__u16 length; /* number of tds associated with this request */
|
||||
__u16 td_cnt; /* number of tds already serviced */
|
||||
int state;
|
||||
unsigned long pipe;
|
||||
int actual_length;
|
||||
td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
|
||||
} urb_priv_t;
|
||||
#define URB_DEL 1
|
||||
|
||||
/*
|
||||
* This is the full ohci controller description
|
||||
*
|
||||
* Note how the "proper" USB information is just
|
||||
* a subset of what the full implementation needs. (Linus)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct ohci {
|
||||
struct ohci_hcca *hcca; /* hcca */
|
||||
/*dma_addr_t hcca_dma;*/
|
||||
|
||||
int irq;
|
||||
int disabled; /* e.g. got a UE, we're hung */
|
||||
int sleeping;
|
||||
unsigned long flags; /* for HC bugs */
|
||||
|
||||
struct ohci_regs *regs; /* OHCI controller's memory */
|
||||
|
||||
ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
|
||||
ed_t *ed_bulktail; /* last endpoint of bulk list */
|
||||
ed_t *ed_controltail; /* last endpoint of control list */
|
||||
int intrstatus;
|
||||
__u32 hc_control; /* copy of the hc control reg */
|
||||
struct usb_device *dev[32];
|
||||
struct virt_root_hub rh;
|
||||
|
||||
const char *slot_name;
|
||||
} ohci_t;
|
||||
|
||||
#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
|
||||
|
||||
struct ohci_device {
|
||||
ed_t ed[NUM_EDS];
|
||||
int ed_cnt;
|
||||
};
|
||||
|
||||
/* hcd */
|
||||
/* endpoint */
|
||||
static int ep_link(ohci_t * ohci, ed_t * ed);
|
||||
static int ep_unlink(ohci_t * ohci, ed_t * ed);
|
||||
static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* we need more TDs than EDs */
|
||||
#define NUM_TD 64
|
||||
|
||||
/* +1 so we can align the storage */
|
||||
td_t gtd[NUM_TD+1];
|
||||
/* pointers to aligned storage */
|
||||
td_t *ptd;
|
||||
|
||||
/* TDs ... */
|
||||
static inline struct td *
|
||||
td_alloc (struct usb_device *usb_dev)
|
||||
{
|
||||
int i;
|
||||
struct td *td;
|
||||
|
||||
td = NULL;
|
||||
for (i = 0; i < NUM_TD; i++)
|
||||
{
|
||||
if (ptd[i].usb_dev == NULL)
|
||||
{
|
||||
td = &ptd[i];
|
||||
td->usb_dev = usb_dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ed_free (struct ed *ed)
|
||||
{
|
||||
ed->usb_dev = NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user