📄 rominit.s
字号:
/* romInit.s - V100R001SCB ROM initialization module */
/* Copyright 2002-2005 Founder Communications, Inc. */
.data
.globl copyright_wind_river
.long copyright_wind_river
/*
modification history
--------------------
01a,20jan05,fhchen adapted from wrSbc8260Atm/romInit.s (ver 01a).
*/
/*
DESCRIPTION
This module contains the entry code for the VxWorks bootrom.
The entry point romInit, is the first code executed on power-up.
It sets the BOOT_COLD parameter to be passed to the generic
romStart() routine.
The routine sysToMonitor() jumps to the location 4 bytes
past the beginning of romInit, to perform a "warm boot".
This entry point allows a parameter to be passed to romStart().
*/
/*
REFERENCE
- Programming Environments Manual For 32-Bit Implementations
of the PowerPC Architecture 12/2001 rev2
- MPC8260 PowerQUICC II User's Manual 4/1999 rev0
*/
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "asm.h"
#include "cacheLib.h"
#include "config.h"
#include "regs.h"
#include "sysLib.h"
#include "drv/timer/m8260Clock.h"
#include "drv/mem/m8260Siu.h"
#include "drv/mem/m8260Memc.h"
/* internals */
FUNC_EXPORT(_romInit) /* start of system code */
FUNC_EXPORT(romInit) /* start of system code */
/* external */
FUNC_IMPORT(romStart) /* system initialization routine */
/* Hard Reset Configuration Word */
#ifdef INCLUDE_HRCW
.text
.fill 1,1,HRCW_BYTE_0
.fill 7,1,0
.fill 1,1,HRCW_BYTE_1
.fill 7,1,0
.fill 1,1,HRCW_BYTE_2
.fill 7,1,0
.fill 1,1,HRCW_BYTE_3
.fill 231,1,0
.align 2
#endif /* INCLUDE_HRCW */
.text
.align 2
/******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*
* romInit
* (
* int startType /@ only used by 2nd entry point @/
* )
*
*/
FUNC_BEGIN(_romInit)
FUNC_BEGIN(romInit)
bl cold /* jump to the cold boot */
nop
bl start /* jump to the warm boot */
/* copyright notice appears at beginning of ROM (in TEXT segment) */
.ascii "Copyright 2002-2005 Founder Communications, Inc."
.ascii "BSP for V100R001 System Control Board. By Feihu Chen"
.align 2
cold:
li r3, BOOT_COLD /* set cold boot as start type */
start:
/*
* disable external interrupts (by zeroing out msr - bit 16),
* machine check exception also disabled.
*/
xor r5, r5, r5
isync
mtmsr r5
isync
/*
* invalidate and disable data and instruction caches
* ICE(bit16), DCE(bit17), ICFI(bit20), DCFI(bit21)
* ICE and DCE are 0 at power-up.
*/
mfspr r6, HID0
ori r5, r5, 0xc000
andc r6, r6, r5 /* r6 preserve bit 16,17 of HID0 */
mr r5, r6 /* r5 = r6 */
ori r5, r5, 0xCC00 /* r5 has DCE,ICE,ICFI,DCFI set */
sync
mtspr HID0,r5 /* enable, invalidate I&D caches */
mtspr HID0,r6 /* disable both caches */
isync
mtspr SPRG0, r3 /* save r3 */
/* clear MMU and FP */
bl romClearBATs
bl romInvalidateTLBs
bl romClearSegs
bl romClearFPRegs
mfspr r3,SPRG0 /* restore r3 */
/* Zero-out registers: r0 & SPRGs */
xor r0, r0, r0
mtspr SPRG0, r0
mtspr SPRG1, r0
mtspr SPRG2, r0
mtspr SPRG3, r0
/*
* MSR - clear EE(bit16),DR,IR, set ME(bit19),RI(bit30)
*
* EE: external interrupt enable
* ME: machine check enable ?
* RI: recoverable exception
*/
mfmsr r4
ori r4, r0, 0x1002 /* 0x0002 to disable MC */
mtmsr r4
isync
/*
* initialize the IMMR register before any non-core registers
* modification.
*
* [INTERNAL_MEM_MAP_ADDR + 0x10000 + INIT_IMMR] =
* INTERNAL_MEM_MAP_ADDR
*/
lis r4, HIADJ(INTERNAL_MEM_MAP_ADDR+0x10000)
addi r4, r4, LO(INTERNAL_MEM_MAP_ADDR+0x10000)
sync
lis r5, HIADJ(INTERNAL_MEM_MAP_ADDR)
addi r5, r5, LO(INTERNAL_MEM_MAP_ADDR)
sync
stw r5, INIT_IMMR(r4) /* initialize the IMMR register */
/*---------------------------------------------------------
* Initialize the SIU
*--------------------------------------------------------*/
bl romSiuInit
/*---------------------------------------------------------
* Initialize the Memc
*--------------------------------------------------------*/
bl romMemcInit
/*---------------------------------------------------------
* Initialize Instruction and Data Caches
*--------------------------------------------------------*/
bl romCacheInit
/* initialize the stack pointer */
lis sp, HIADJ(STACK_ADRS)
addi sp, sp, LO(STACK_ADRS)
/* go to c entry point: romStart */
addi sp, sp, -FRAMEBASESZ /* get frame stack. ?? */
/*
* calculate C entry point: routine - entry point + ROM base
* routine = romStart = R6
* entry point = romInit = R7
* ROM base = ROM_TEXT_ADRS = R8
* C entry point: R6 - R7 + R8
*/
lis r6, HIADJ(romStart)
addi r6, r6, LO(romStart) /* load R6 with C entry point */
lis r7, HIADJ(romInit)
addi r7, r7, LO(romInit)
lis r8, HIADJ(ROM_TEXT_ADRS)
addi r8, r8, LO(ROM_TEXT_ADRS)
sub r6, r6, r7 /* routine - entry point */
add r6, r6, r8 /* + ROM base */
mtlr r6 /* move C entry point to LR */
blr /* jump to the C entry point */
FUNC_END(romInit)
FUNC_END(_romInit)
/*******************************************************************************
*
* romClearBATs - clear BAT regs
*
* This routine will zero the BAT registers.
*
* RETURNS: None
*
*/
FUNC_BEGIN(romClearBATs) /* zero out the BAT registers */
xor r5, r5, r5
isync
mtspr IBAT0U, r5 /* clear all upper BATS first */
mtspr IBAT1U, r5
mtspr IBAT2U, r5
mtspr IBAT3U, r5
mtspr DBAT0U, r5
mtspr DBAT1U, r5
mtspr DBAT2U, r5
mtspr DBAT3U, r5
mtspr IBAT0L, r5 /* then clear lower BATS */
mtspr IBAT1L, r5
mtspr IBAT2L, r5
mtspr IBAT3L, r5
mtspr DBAT0L, r5
mtspr DBAT1L, r5
mtspr DBAT2L, r5
mtspr DBAT3L, r5
isync
blr
FUNC_END(romClearBATs)
/*******************************************************************************
*
* romInvalidateTLBs - invalidate TLBs
*
* This routine will invalidate the TLBs.
*
* RETURNS: None
*
*/
FUNC_BEGIN(romInvalidateTLBs)
isync
/* invalidate entries within both TLBs */
li r5, 128 /* 128 ? */
mtctr r5 /* CTR = 128 */
xor r5, r5, r5 /* r5 = 0 */
isync /* context sync reqired before tlbie */
tlbloop:
tlbie r5
sync /* sync instr reqired after tlbie */
addi r5, r5, 0x1000 /* increment bits 15-19. 0x1000 ? */
bdnz tlbloop /* decrement CTR, branch if CTR != 0 */
isync
blr
FUNC_END(romInvalidateTLBs)
/*******************************************************************************
*
* romClearSegs - clear seg regs
*
* This routine will zero the MMU's segment registers.
*
* RETURNS: None
*
*/
FUNC_BEGIN(romClearSegs) /* Init the Segment registers */
xor r5, r5, r5
isync
mtsr 0, r5
mtsr 1, r5
mtsr 2, r5
mtsr 3, r5
mtsr 4, r5
mtsr 5, r5
mtsr 6, r5
mtsr 7, r5
mtsr 8, r5
mtsr 9, r5
mtsr 10,r5
mtsr 11,r5
mtsr 12,r5
mtsr 13,r5
mtsr 14,r5
mtsr 15,r5
isync
blr
FUNC_END(romClearSegs)
/*******************************************************************************
*
* romClearFPRegs - clear FPU regs
*
* This routine will initialize the FPU's registers.
*
* RETURNS: None
*
*/
FUNC_BEGIN(romClearFPRegs)
mflr r30 /* save return address */
/* Turn on FP */
li r3, 0x2000
mtmsr r3
sync
/* Init the Floating Point Control and Status Register */
mtfsfi 7, 0x0 /* move to FPSCR field immediate */
mtfsfi 6, 0x0 /* why 0 ~ 7 ? */
mtfsfi 5, 0x0
mtfsfi 4, 0x0
mtfsfi 3, 0x0
mtfsfi 2, 0x0
mtfsfi 1, 0x0
mtfsfi 0, 0x0
isync
/* Initialize the floating point data registers to a known state */
bl initFPRs
.long 0x3f800000 /* 1.0 ? */
initFPRs:
mflr r3
lfs f0, 0(r3) /* set all FPRs to 0x3f800000 ? */
lfs f1, 0(r3) /* load floating point single */
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 MSR to a known state, Turn off FP */
andi. r3, r3, 0
sync
mtmsr r3 /* all 0s except reserved bits */
isync
mtlr r30
bclr 20, 0 /* Return to caller */
FUNC_END(romClearFPRegs)
/******************************************************************************
*
* romSiuInit - initialize the general SIU.
*
* RETURNS: N/A.
*/
FUNC_BEGIN(romSiuInit)
/*
* <SIUMCR>
* r4 is (INTERNAL_MEM_MAP_ADDR+0x10000)
* INIT_SIUMCR defined in $BOARDNAME.h
*/
lis r5, HIADJ(0x01240000)
addi r5, r5, LO(0x01240000) /* wrSbc8260Atm: 0x0E240000 */
stw r5, INIT_SIUMCR(r4)
/*
* <SYPCR>
* PBME(bit24): 60x bus monitor
* LBME(bit25): local bus monitor
* SWE(bit29): sofware watchdog enable
* SWRI(bit30): sofware watchdog machine check or reset(1)
* SWP(bit31): prescale, divide-by-2048(1)
*
* SYPCR can be written only once after reset
*/
lis r5, HIADJ(0xFFFFFFC3) /* wrSbc8260Atm: 0xFFFFFFC3 */
addi r5, r5, LO(0xFFFFFFC3)
stw r5, INIT_SYPCR(r4)
#if FALSE
/*
* <SWT>
* 0x10008 from IMMR base is reserved in MPC8260, so comment it out
*/
lis r5, HIADJ(0xFFFF0000)
addi r5, r5, LO(0xFFFF0000)
stw r5, INIT_SWT(r4)
#endif
/*
* <SWSR>
* Actual value does not matter, because sw watchdog is disabled before.
* Write 0x556C followed by 0xAA39 to service the software watchdog,
* but SWSR always return zero when read。
*/
lis r5, HIADJ(0x0000000E)
addi r5, r5, LO(0x0000000E)
sth r5, INIT_SWSR(r4)
/*
* <BCR>
* if SIUMCR[APPC] is 10, should we set EAV bit?
*/
lis r5, HIADJ(0x70000000) /* wrSbc8260Atm: 0x00000000 */
addi r5, r5, LO(0x70000000)
stw r5, INIT_BCR(r4)
/*
* <PPC_ACR>
* PPKM(bit4~7):
* - 0010: CPM low request level (default value)
* - 0110: internal core
*/
li r5, 0x02
stb r5, INIT_PPC_ACR(r4)
/*
* <PPC_ALRH> <PPC_ALRL>
* use default value
*/
lis r5, HIADJ(0x01234567)
addi r5, r5, LO(0x01234567)
stw r5, INIT_PPC_ALRH(r4)
lis r5, HIADJ(0x89ABCDEF)
addi r5, r5, LO(0x89ABCDEF)
stw r5, INIT_PPC_ALRL(r4)
/*
* <LCL_ACR>
* PPKM(bit4~7):
* - 0010: CPM low request level (default value)
* - 0011: host bridge
*/
li r5, 0x02
stb r5, INIT_LCL_ACR(r4)
/*
* <LCL_ALPH> <LCL_ALRL>
* use default value
*/
lis r5, HIADJ(0x01234567)
addi r5, r5, LO(0x01234567)
stw r5, INIT_LCL_ALRH(r4)
lis r5, HIADJ(0x89ABCDEF)
addi r5, r5, LO(0x89ABCDEF)
stw r5, INIT_LCL_ALRL(r4)
/*
* <TESCR1> <TESCR2> <LTESCR1> <LTESCR2>
*
* TESCR1[DMD](bit17): 60x bus data errors disable
* LTESCR1[DMD](bit17): local bus data errors disable
*/
lis r5, HIADJ(0x00004000) /* wrSbc8260Atm: 0x80020000 */
addi r5, r5, LO(0x00004000)
stw r5, INIT_TESCR1(r4)
lis r5, HIADJ(0x00000000)
addi r5, r5,LO(0x00000000)
stw r5, INIT_TESCR2(r4)
lis r5, HIADJ(0x00004000) /* wrSbc8260Atm: 0x00000000 */
addi r5, r5, LO(0x00004000)
stw r5, INIT_LTESCR1(r4)
lis r5, HIADJ(0x00000000)
addi r5, r5, LO(0x00000000)
stw r5, INIT_LTESCR2(r4)
/*
* <SCCR>
* BRG_CLK = 2 * CPM_CLK /{2^[2*(DFBRG+1)]}
* M8260_SCCR_DFBRG_4(0x00000000) defined in m8260Clock.h
*/
lis r5, HIADJ(M8260_SCCR_DFBRG_16) /* wrSbc8260Atm: 4 */
addi r5, r5, LO(M8260_SCCR_DFBRG_16)
stw r5, INIT_SCCR(r4)
/* <PDTEA> <PDTEM> <LDTEA> <LDTEM>
* Because these registers' values are undefined at reset, so
* set them to 0.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -