📄 rominit111.s
字号:
/* romInit.s - Sandpoint w/PPMC8240 ROM initialization module */
/* Copyright 1984-1999 Wind River Systems, Inc. */
/* Copyright 1996-1998 Motorola, Inc. */
/*
modification history
--------------------
01a,10oct99,mtl written from SPS/Motorola & yk 750 by teamF1
*/
/*
DESCRIPTION
This module contains the entry code for VxWorks images that start
running from ROM, such as 'bootrom' and 'vxWorks_rom'.
The entry point, romInit(), is the first code executed on power-up.
It performs the minimal setup needed to call
the generic C routine romStart() with parameter BOOT_COLD.
RomInit() typically masks interrupts in the processor, sets the initial
stack pointer (to STACK_ADRS which is defined in configAll.h), and
readies system memory by configuring the DRAM controller if necessary.
Other hardware and device initialization is performed later in the
BSP's sysHwInit() routine.
A second entry point in romInit.s is called romInitWarm(). It is called
by sysToMonitor() in sysLib.c to perform a warm boot.
The warm-start entry point must be written to allow a parameter on
the stack to be passed to romStart().
WARNING:
This code must be Position Independent Code (PIC). This means that it
should not contain any absolute address references. If an absolute address
must be used, it must be relocated by the macro ROM_ADRS(x). This macro
will convert the absolute reference to the appropriate address within
ROM space no matter how the boot code was linked. (For PPC, ROM_ADRS does
not work. You must subtract _romInit and add ROM_TEXT_ADRS to each
absolute address). (NOTE: ROM_ADRS(x) macro does not work for current
PPC compiler).
This code should not call out to subroutines declared in other modules,
specifically sysLib.o, and sysALib.o. If an outside module is absolutely
necessary, it can be linked into the system by adding the module
to the makefile variable BOOT_EXTRA. If the same module is referenced by
other BSP code, then that module must be added to MACH_EXTRA as well.
Note that some C compilers can generate code with absolute addresses.
Such code should not be called from this module. If absolute addresses
cannot be avoided, then only ROM resident code can be generated from this
module. Compressed and uncompressed bootroms or VxWorks images will not
work if absolute addresses are not processed by the macro ROM_ADRS.
WARNING:
The most common mistake in BSP development is to attempt to do too much
in romInit.s. This is not the main hardware initialization routine.
Only do enough device initialization to get memory functioning. All other
device setup should be done in sysLib.c, as part of sysHwInit().
Unlike other RTOS systems, VxWorks does not use a single linear device
initialization phase. It is common for inexperienced BSP writers to take
a BSP from another RTOS, extract the assembly language hardware setup
code and try to paste it into this file. Because VxWorks provides 3
different memory configurations, compressed, uncompressed, and rom-resident,
this strategy will usually not work successfully.
WARNING:
The second most common mistake made by BSP writers is to assume that
hardware or CPU setup functions done by romInit.o do not need to be
repeated in sysALib.s or sysLib.c. A vxWorks image needs only the following
from a boot program: The startType code, and the boot parameters string
in memory. Each VxWorks image will completely reset the CPU and all
hardware upon startup. The image should not rely on the boot program to
initialize any part of the system (it may assume that the memory controller
is initialized).
This means that all initialization done by romInit.s must be repeated in
either sysALib.s or sysLib.c. The only exception here could be the
memory controller. However, in most cases even that can be
reinitialized without harm.
Failure to follow this rule may require users to rebuild bootrom's for
minor changes in configuration. It is WRS policy that bootroms and vxWorks
images should not be linked in this manner.
INCLUDE FILES: mpc107.h, sysL2BackCache.s
*/
/* includes */
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "sysLib.h"
#include "asm.h"
#include "regs.h"
#include "config.h"
#include "mpc107.h"
/* defines */
/*
* Some releases of h/arch/ppc/toolPpc.h had a bad definition of
* LOADPTR. So we will define it correctly. [REMOVE WHEN NO LONGER NEEDED].
* This is tracked at WRS under SPR#20104.
* LOADPTR initializes a register with a 32 bit constant, presumably the
* address of something.
*/
#undef LOADPTR
#define LOADPTR(reg,const32) \
addis reg,r0,HIADJ(const32); addi reg,reg,LO(const32)
/*
* LOADVAR initializes a register with the contents of a specified memory
* address. The difference being that the value loaded is the contents of
* the memory location and not just the address of it. [REMOVE WHEN NO LONGER
* NEEDED].
* This is tracked at WRS under SPR#20104.
*/
#undef LOADVAR
#define LOADVAR(reg,addr32) \
addis reg,r0,HIADJ(addr32); lwz reg,LO(addr32)(reg)
/*
* NOTE: Cannot use ROM_ADRS macro with HIADJ and LO macro
* functions, for PPC
*/
/* Exported internal functions */
.data
.globl _romInit /* start of system code */
.globl romInit /* start of system code */
.globl _romInitWarm /* start of system code */
.globl romInitWarm /* start of system code */
.globl SEROUT /*QDIMCZH useful serial output routine */
/* externals */
.extern romStart /* system initialization routine */
.text
.align 2
/******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*
* romInit
* (
* int startType /@ only used by 2nd entry point @/
* )
*/
/*
* After reset, the processor fetches from ROM_BASE_ADRS + 0x100.
* We offset the _romInit entry by 0x100 bytes to compensate.
* In other WRS PPC BSP's, this offset was accounted for in the
* elfHex stage of building the rom image by setting HEX_FLAGS
* to "-a 100". Explictly adding the space here seems more
* straitforward, and it also helps when not using elfToHex
* such as in a flash programmed binary image. Therefore
* the Yellowknife BSP Makefile uses HEX_FLAGS of "-a 0".
* This also means that ROM_TEXT_ADRS must be defined
* equivalent to ROM_BASE_ADRS + 0x100 in config.h and Makefile.
*/
.space (0x100)
_romInit:
romInit:
/* This is the cold boot entry (ROM_TEXT_ADRS) */
bl cold
nop
/*
* This warm boot entry point is defined as ROM_WARM_ADRS in config.h.
* It is defined as an offset from ROM_TEXT_ADRS. Please make sure
* that the offset from _romInit to romInitWarm matches that specified
* in config.h. Since WRS is standardizing this offset to 8 bytes,
* we insert a nop to ensure romInitWarm is a 8 byte offset from
* ROM_TEXT_ADRS.
*/
_romInitWarm:
romInitWarm:
bl warm
/*
* copyright notice appears at beginning of ROM (in TEXT segment)
* This is also useful for debugging images.
*/
.ascii "Copyright 2001-2002 iMaxNetworks Systems, Inc."
.align 2
cold:
li r11, BOOT_COLD
bl start /* skip over next instruction */
warm:
or r11, r3, r3 /* startType to r11 */
start:
/* Zero-out the CPU's registers */
addis r0,r0,0
mtspr SPRG0,r0
mtspr SPRG1,r0
mtspr SPRG2,r0
mtspr SPRG3,r0
/* initialize the stack pointer */
LOADPTR (sp, STACK_ADRS)
/* Set MPU/MSR to a known state. Turn on FP */
LOADPTR (r3, _PPC_MSR_FP)
sync
mtmsr r3
isync
/* Init the floating point control/status register */
mtfsfi 7,0x0
mtfsfi 6,0x0
mtfsfi 5,0x0
mtfsfi 4,0x0
mtfsfi 3,0x0
mtfsfi 2,0x0
mtfsfi 1,0x0
mtfsfi 0,0x0
isync
/* Initialize the floating point data regsiters to a known state */
bl ifpdr_value
.long 0x3f800000 /* 1.0 */
ifpdr_value:
mfspr r3,8
lfs f0,0(r3)
lfs f1,0(r3)
lfs f2,0(r3)
lfs f3,0(r3)
lfs f4,0(r3)
lfs f5,0(r3)
lfs f6,0(r3)
lfs f7,0(r3)
lfs f8,0(r3)
lfs f9,0(r3)
lfs f10,0(r3)
lfs f11,0(r3)
lfs f12,0(r3)
lfs f13,0(r3)
lfs f14,0(r3)
lfs f15,0(r3)
lfs f16,0(r3)
lfs f17,0(r3)
lfs f18,0(r3)
lfs f19,0(r3)
lfs f20,0(r3)
lfs f21,0(r3)
lfs f22,0(r3)
lfs f23,0(r3)
lfs f24,0(r3)
lfs f25,0(r3)
lfs f26,0(r3)
lfs f27,0(r3)
lfs f28,0(r3)
lfs f29,0(r3)
lfs f30,0(r3)
lfs f31,0(r3)
sync
/* Set MPU/MSR to a known state. Turn off FP */
andi. r3, r3, 0
sync
mtmsr r3
isync
/* Init the Segment registers */
andi. r3, r3, 0
isync
mtsr 0,r3
isync
mtsr 1,r3
isync
mtsr 2,r3
isync
mtsr 3,r3
isync
mtsr 4,r3
isync
mtsr 5,r3
isync
mtsr 6,r3
isync
mtsr 7,r3
isync
mtsr 8,r3
isync
mtsr 9,r3
isync
mtsr 10,r3
isync
mtsr 11,r3
isync
mtsr 12,r3
isync
mtsr 13,r3
isync
mtsr 14,r3
isync
mtsr 15,r3
isync
/* Turn off data and instruction cache control bits */
mfspr r3, HID0
isync
rlwinm r4, r3, 0, 18, 15 /* r4 has ICE and DCE bits cleared */
sync
isync
mtspr HID0, r4 /* HID0 = r4 */
isync
/* Get cpu type */
mfspr r28, PVR
rlwinm r28, r28, 16, 16, 31
/* invalidate the MPU's data/instruction caches */
lis r3, 0x0
cmpli 0, 0, r28, CPU_TYPE_750
beq CPU_IS_750
cmpli 0, 0, r28, CPU_TYPE_603
beq CPU_IS_603
cmpli 0, 0, r28, CPU_TYPE_603E
beq CPU_IS_603
cmpli 0, 0, r28, CPU_TYPE_603P
beq CPU_IS_603
cmpli 0, 0, r28, CPU_TYPE_604R
bne CPU_NOT_604R
CPU_IS_604R:
lis r3, 0x0
mtspr HID0, r3 /* disable the caches */
isync
ori r4, r4, 0x0002 /* disable BTAC by setting bit 30 */
CPU_NOT_604R:
ori r3, r3, (_PPC_HID0_ICFI | _PPC_HID0_DCFI)
CPU_IS_603:
ori r3, r3, (_PPC_HID0_ICE | _PPC_HID0_DCE)
or r4, r4, r3 /* set bits */
sync
isync
mtspr HID0, r4 /* HID0 = r4 */
andc r4, r4, r3 /* clear bits */
isync
cmpli 0, 0, r28, CPU_TYPE_604
beq CPU_IS_604
cmpli 0, 0, r28, CPU_TYPE_604E
beq CPU_IS_604
cmpli 0, 0, r28, CPU_TYPE_604R
beq CPU_IS_604
cmpli 0, 0, r28, CPU_TYPE_750
beq CPU_IS_750
mtspr HID0, r4
isync
#ifdef USER_I_CACHE_ENABLE
b I_CACHE_ON_603
#else
b CACHE_ENABLE_DONE
#endif
CPU_IS_750:
mfspr r3,HID0
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x8800 /* Setup bit pattern for ICE/ICFI */
or r3,r4,r3
isync
mtspr HID0,r3 /* set ICE/ICFI */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x0800 /* Setup bit pattern for ICFI */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear IFCI (bit 16) */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x2000 /* Setup bit pattern for ILOCK */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear ILOCK (bit 18) */
sync
b CACHE_ENABLE_DONE
CPU_IS_604:
LOADPTR (r5, 0x1000) /* loop count, 0x1000 */
mtspr CTR, r5
LOOP_DELAY:
nop
bdnz LOOP_DELAY
isync
mtspr HID0, r4
isync
/* turn the Instruction cache ON for faster FLASH ROM boots */
#ifdef USER_I_CACHE_ENABLE
ori r4, r4, (_PPC_HID0_ICE | _PPC_HID0_ICFI)
isync /* Synchronize for ICE enable */
b WRITE_R4
I_CACHE_ON_603:
ori r4, r4, (_PPC_HID0_ICE | _PPC_HID0_ICFI)
rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */
/*
* The setting of the instruction cache enable (ICE) bit must be
* preceded by an isync instruction to prevent the cache from being
* enabled or disabled while an instruction access is in progress.
*/
isync
WRITE_R4:
mtspr HID0, r4 /* Enable Instr Cache & Inval cache */
cmpli 0, 0, r28, CPU_TYPE_604
beq CACHE_ENABLE_DONE
cmpli 0, 0, r28, CPU_TYPE_604E
beq CACHE_ENABLE_DONE
cmpli 0, 0, r28, CPU_TYPE_604R
beq CACHE_ENABLE_DONE
cmpli 0, 0, r28, CPU_TYPE_750
beq CACHE_ENABLE_DONE
mtspr HID0, r3 /* using 2 consec instructions */
/* PPC603 recommendation */
#endif
CACHE_ENABLE_DONE:
/*
* Below we setup the MPC107 embedded memory controller.
* This procedure detects the MPC107's address map configuration.
* Address map A conforms to the PowerPC reference platform
* specification (PReP). Map B conforms to the PowerPC
* microprocessor common hardware reference platform (CHRP).
* A board pull up/down resistor selects the map in hardware.
* We assume that the memory map is Map B (Sandpoint default),
* and attempt to read the MPC107's PCI Vendor and Device IDs.
* If we read it ok, then use map B, else assume map A.
* Emulation mode address mapping is not suppported.
* No "compatability hole" is configured.
*/
LOADPTR (r5, MPC107_CFG_ADDR_CHRP)
LOADPTR (r6, MPC107_CFG_DATA_CHRP)
addis r9,r0, MPC107_PICR1_MAPB /* r9 is used later to select map */
LOADPTR (r4, PPMC8240_ID)
addis r3,r0, MPC107_CFG_BASE_16
stwbrx r3,0,(r5)
lwbrx r3,0,(r6)
cmp 0,0,r3,r4
beq cr0, startMemInit /* if we found ID, then init mem */
LOADPTR (r4, PPMC8245_ID)
cmp 0,0,r3,r4
beq cr0, startMemInit /* if we found ID, then init mem */
LOADPTR (r5, M107_CFG_ADDR_PREP)/* else setup map A and init mem */
LOADPTR (r6, M107_CFG_DATA_PREP)
addis r9,r0, MPC107_PICR1_MAPA /* r9 is used later to select map */
startMemInit:
/* QDIMCZH debug start */
LOADPTR (r5, 0xfec00000)
LOADPTR (r6, 0xfee00000)
/* ===EUMBBAR=== Embedded Utility Memory Block Base Address Register*/
LOADPTR (r3, MPC107_EUMBBA_ADRS)
stwbrx r3,0,r5
sync
lis r4,0xfc00 /* EUMBBAR = 0xFC00_0000 */
stwbrx r4,0,r6 /* Don't forget to map this area */
sync /* into the BATs */
/* QDIMCZH debug end */
/*
* we have proper map setting in r9, now setup the MPC107 for
* the Sandpoint board.
*/
/*
* First setup the PCI cmd register and clear the PCI status reg
*
*/
/* Errata to address latency timer RP 7/20/99*/
lis r3,0x8000 /* Select LATENCY_TIMER*/
ori r3,r3,0x000d
li r4,0x20 /* Set to 0x20 */
stwbrx r3,0,r5
sync
stb r4,1(r6)
sync
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -