📄 rominit.s
字号:
/* romInit.s - ARM Integrator ROM initialization module */
/* Copyright 1999-2001 ARM Limited */
/* Copyright 1999-2001 Wind River Systems, Inc. */
/*
modification history
--------------------
01m,25jan02,m_h sdata needs "_" for bootrom_res
01l,09oct01,jpd added clock speed setting for 946ES.
01k,03oct01,jpd tidied slightly.
01j,28sep01,pr added support for ARM946ES.
01i,04jun01,rec memory clock rate changes for 740t
01h,21feb01,h_k added support for ARM966ES and ARM966ES_T.
01g,20nov00,jpd change speeds on 920T and add conditional early
enabling of I-cache on 920T.
01f,18sep00,rec Add delay during power up
01e,23feb00,jpd comments changes.
01d,22feb00,jpd changed copyright string.
01c,20jan00,jpd added support for ARM720T/ARM920T.
01b,13jan00,pr added support for ARM740T.
01a,30nov99,ajb created, based on PID version 01i.
*/
/*
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() masks interrupts in the processor and the interrupt
controller and sets the initial stack pointer (to STACK_ADRS which is
defined in configAll.h). Other hardware and device initialisation is
performed later in the sysHwInit routine in sysLib.c.
The routine sysToMonitor() jumps to a location after the beginning of
romInit, (defined by ROM_WARM_ADRS) to perform a "warm boot". This
entry point allows a parameter to be passed to romStart().
The routines in this module don't use the "C" frame pointer %r11@ ! or
establish a stack frame.
SEE ALSO:
.I "ARM Architecture Reference Manual,"
.I "ARM 7TDMI Data Sheet,"
.
"ARM 720T Data Sheet,"
.I "ARM 740T Data Sheet,"
.I "ARM 920T Technical Reference Manual",
.I "ARM 940T Technical Reference Manual",
.I "ARM 946E-S Technical Reference Manual",
.I "ARM 966E-S Technical Reference Manual",
.I "ARM Reference Peripherals Specification,"
.I "ARM Integrator/AP User Guide",
.I "ARM Integrator/CM7TDMI User Guide",
.I "ARM Integrator/CM720T User Guide",
.I "ARM Integrator/CM740T User Guide",
.I "ARM Integrator/CM920T User Guide",
.I "ARM Integrator/CM940T User Guide",
.I "ARM Integrator/CM946E User Guide",
.I "ARM Integrator/CM9x6ES Datasheet".
*/
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "sysLib.h"
#include "asm.h"
#include "regs.h"
#include "config.h"
#include "arch/arm/mmuArmLib.h"
.data
.globl VAR(copyright_wind_river)
.long VAR(copyright_wind_river)
/* internals */
.globl FUNC(romInit) /* start of system code */
.globl VAR(sdata) /* start of data */
.globl _sdata
.globl VAR(integratorMemSize) /* actual memory size */
/* externals */
.extern FUNC(romStart) /* system initialization routine */
_sdata:
VAR_LABEL(sdata)
.asciz "start of data"
.balign 4
/* variables */
.data
VAR_LABEL(integratorMemSize)
.long 0
/* .long 0x2000000*/
.text
.balign 4
/*******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*
* romInit
* (
* int startType /@ only used by 2nd entry point @/
* )
* INTERNAL
* sysToMonitor examines the ROM for the first instruction and the string
* "Copy" in the third word so if this changes, sysToMonitor must be updated.
*/
_ARM_FUNCTION(romInit)
_romInit:
LDR r1, = AT91C_BASE_CKGR
LDR r0, = AT91C_CKGR_MOSCEN | AT91C_CKGR_OSCOUNT
STR r0, [r1, #0x0] /* Enabling the Main Oscillator*/
cold:
MOV r0, #BOOT_COLD /* fall through to warm boot entry */
warm:
B start
/* copyright notice appears at beginning of ROM (in TEXT segment) */
.ascii "Copyright 1999-2001 ARM Limited"
.ascii "\nCopyright 1999-2001 Wind River Systems, Inc."
.balign 4
start:
/*
* There have been reports of problems with certain boards and
* certain power supplies not coming up after a power-on reset,
* and adding a delay at the start of romInit appears to help
* with this.
*/
TEQS r0, #BOOT_COLD
MOVEQ r1, #INTEGRATOR_DELAY_VALUE
MOVNE r1, #1
delay_loop:
SUBS r1, r1, #1
BNE delay_loop
#if defined(CPU_720T) || defined(CPU_720T_T) || \
defined(CPU_740T) || defined(CPU_740T_T) || \
defined(CPU_920T) || defined(CPU_920T_T) || \
defined(CPU_940T) || defined(CPU_940T_T) || \
defined(CPU_946ES) || defined(CPU_946ES_T)
/*
* Set processor and MMU to known state as follows (we may have not
* been entered from a reset). We must do this before setting the CPU
* mode as we must set PROG32/DATA32.
*
* MMU Control Register layout.
*
* bit
* 0 M 0 MMU disabled
* 1 A 0 Address alignment fault disabled, initially
* 2 C 0 Data cache disabled
* 3 W 0 Write Buffer disabled
* 4 P 1 PROG32
* 5 D 1 DATA32
* 6 L 1 Should Be One (Late abort on earlier CPUs)
* 7 B ? Endianness (1 => big)
* 8 S 0 System bit to zero } Modifies MMU protections, not really
* 9 R 1 ROM bit to one } relevant until MMU switched on later.
* 10 F 0 Should Be Zero
* 11 Z 0 Should Be Zero (Branch prediction control on 810)
* 12 I 0 Instruction cache control
*/
/* Setup MMU Control Register */
MOV r1, #MMU_INIT_VALUE /* Defined in mmuArmLib.h */
#if defined(CPU_920T) || defined(CPU_920T_T)
#if defined(INTEGRATOR_EARLY_I_CACHE_ENABLE)
ORR r1, r1, #MMUCR_I_ENABLE /* conditionally enable Icache*/
#endif
#endif
MCR CP_MMU, 0, r1, c1, c0, 0 /* Write to MMU CR */
/*
* If MMU was on before this, then we'd better hope it was set
* up for flat translation or there will be problems. The next
* 2/3 instructions will be fetched "translated" (number depends
* on CPU).
*
* We would like to discard the contents of the Write-Buffer
* altogether, but there is no facility to do this. Failing that,
* we do not want any pending writes to happen at a later stage,
* so drain the Write-Buffer, i.e. force any pending writes to
* happen now.
*/
#if defined(CPU_720T) || defined(CPU_720T_T) || \
defined(CPU_740T) || defined(CPU_740T_T)
MOV r2, #INTEGRATOR_RESET_RAM_BASE /* RAM base at reset */
SWPB r1, r1, [r2] /* Drain write-buffer */
/* Flush, (i.e. invalidate) all entries in the ID-cache */
MCR CP_MMU, 0, r1, c7, c0, 0 /* Flush (inval) all ID-cache */
#endif /* defined(CPU_720T,740T) */
#if defined(CPU_920T) || defined(CPU_920T_T) || \
defined(CPU_946ES) || defined(CPU_946ES_T)
MOV r1, #0 /* data SBZ */
MCR CP_MMU, 0, r1, c7, c10, 4 /* drain write-buffer */
/* Flush (invalidate) both I and D caches */
MCR CP_MMU, 0, r1, c7, c7, 0 /* R1 = 0 from above, data SBZ*/
#endif /* defined(CPU_920T,946ES) */
#if defined(CPU_940T) || defined(CPU_940T_T)
LDR r1, L$_sysCacheUncachedAdrs /* R1 -> uncached area */
LDR r1, [r1] /* drain write-buffer */
/* Flush (invalidate) both caches */
MOV r1, #0 /* data SBZ */
MCR CP_MMU, 0, r1, c7, c5, 0 /* Flush (inval) all I-cache */
MCR CP_MMU, 0, r1, c7, c6, 0 /* Flush (inval) all D-cache */
#endif /* defined(CPU_940T,940T_T) */
#if defined(CPU_720T) || defined(CPU_720T_T) || \
defined(CPU_920T) || defined(CPU_920T_T)
/*
* Set Process ID Register to zero, this effectively disables
* the process ID remapping feature.
*/
MOV r1, #0
MCR CP_MMU, 0, r1, c13, c0, 0
#endif /* defined(CPU_720T,920T) */
#endif /* defined(CPU_720T,740T,920T,940T,946ES) */
/* disable interrupts in CPU and switch to SVC32 mode */
MRS r1, cpsr
BIC r1, r1, #MASK_MODE
ORR r1, r1, #MODE_SVC32 | I_BIT | F_BIT
MSR cpsr, r1
/*
* CPU INTERRUPTS DISABLED
*
* disable individual interrupts in the interrupt controller
*/
/* MOV r2, #IC_BASE *//* R2->interrupt controller */
/* MVN r1, #0 *//* &FFFFFFFF */
/* STR r1, [r2, #FIQ_DISABLE-IC_BASE] *//* disable all FIQ sources */
/* STR r1, [r2, #IRQ_DISABLE-IC_BASE] *//* disable all IRQ sources */
LDR r2, =AT91C_BASE_AIC /* R2->interrupt controller */
MVN r1, #0 /* &FFFFFFFF */
STR r1, [r2,#0x124] /* disable all IRQ sources */
/*
* Jump to the normal (higher) ROM Position. After a reset, the
* ROM is mapped into memory from* location zero upwards as well
* as in its normal position at This code could be executing in
* the lower position. We wish to be executing the code, still
* in ROM, but in its normal (higher) position before we remap
* the machine so that the ROM is no longer dual-mapped from zero
* upwards, but so that RAM appears from 0 upwards.
*/
LDR pc, L$_HiPosn
HiPosn:
#if defined(CPU_966ES) || defined(CPU_966ES_T)
/*
* Set 966RAM emulation, makes external SSRAM look like
* internal RAM.
*/
MOV r2, #INTEGRATOR_HDR_BASE
LDR r1, =0xA05F
STR r1, [r2, #INTEGRATOR_HDR_LOCK_OFFSET]
LDR r1, =INTEGRATOR_HDR_TCRAM_EMULATE | \
INTEGRATOR_HDR_CLKRATIO_2 | \
INTEGRATOR_HDR_HCLKDIV_3 | \
INTEGRATOR_HDR_PLLBYPASS_ON
STR r1, [r2, #INTEGRATOR_HDR_INIT_OFFSET]
MOV r1, #0
STR r1, [r2, #INTEGRATOR_HDR_LOCK_OFFSET]
/*
* Enable Instruction SRAM, Data SRAM and Write buffer.
*/
LDR r1, =ARM966_I_SRAM_ENABLE | ARM966_WBUFF_ENABLE | \
ARM966_D_SRAM_ENABLE
MCR CP_MMU, 0, r1, c1, c0, 0
#endif
/*
* We are now executing in the normal (higher, still in ROM)
* position in the memory map. Remap memory to post-reset state,
* so that the ROM is not now dual-mapped to zero upwards, but
* RAM is mapped from zero, instead.
*/
/*
MOV r1, #INTEGRATOR_HDR_REMAP
MOV r2, #INTEGRATOR_HDR_BASE
STR r1, [r2, #INTEGRATOR_HDR_CTRL_OFFSET]
*/
/* Remap the AT91RM9200*/
MOV r1, #0x1
MOV r2, #AT91C_BASE_MC
STR r1, [r2, #0x0]
/*
* SSRAM is now mapped from 0 upwards.
*
* Setup asynchronous clocking (eg. core and memory clocks different)
*/
LDR r1, =INTEGRATOR_HDR_BASE
LDR r2, [r1, #INTEGRATOR_HDR_OSC_OFFSET]
AND r2, r2, #(3 << 23)
CMP r2, #(1 << 23)
BNE clock1
#if defined(CPU_920T) || defined(CPU_920T_T) || \
defined(CPU_940T) || defined(CPU_940T_T)
/*
* if HDR_OSC indicates (bits[23:24] = 01), set
* implementation-specific bits in the MMU control register - set
* asynchronous mode.
*/
MRC CP_MMU, 0, r2, c1, c0, 0
ORR r2, r2, #MMUCR_ASYNC
MCR CP_MMU, 0, r2, c1, c0, 0
#endif
clock1:
/* If bits[23:24] were 0, set asynchronous mode in HDR_CTRL */
LDRLT r2, [r1, #INTEGRATOR_HDR_CTRL_OFFSET]
BICLT r2, r2, #INTEGRATOR_HDR_CTRL_FASTBUS
STRLT r2, [r1, #INTEGRATOR_HDR_CTRL_OFFSET]
/*
* setup default clocks
*
* Core clock must always be greater than memory clock.
*
* Read HDR_PROC register, if this is non zero then there is no
* coprocessor, in this case use the default settings. First,
* load the default settings.
*/
LDR r2, =INTEGRATOR_HDR_OSC_DFLT_VAL
LDR r1, =INTEGRATOR_HDR_BASE
LDR r3, [r1, #INTEGRATOR_HDR_PROC_OFFSET]
CMP r3, #0
BNE write_clock
/*
* HDR_PROC was zero => there is a coprocessor. Get the processor ID.
*
* If the processor type is not recognised then the default settings
* will be used.
*
* For safety's sake, make the following conditional upon there being a
* coprocessor in the CPU.
*/
#if defined(CPU_720T) || defined(CPU_720T_T) || \
defined(CPU_740T) || defined(CPU_740T_T) || \
defined(CPU_920T) || defined(CPU_920T_T) || \
defined(CPU_940T) || defined(CPU_940T_T) || \
defined(CPU_946ES) || defined(CPU_946ES_T) || \
defined(CPU_966ES) || defined(CPU_966ES_T)
MRC CP_MMU, 0, r1, c0, c0, 0
MOV r3, r1, LSL #16
MOV r3, r3, LSR #20 /* move bits 15-3 to 12-0 */
CMP r3, #0x720 /* is this a 720 */
LDREQ r2, =INTEGRATOR_HDR_OSC_720T_VAL
BEQ write_clock
CMP r3, #0x740 /* is this a 740 */
LDREQ r2, =INTEGRATOR_HDR_OSC_740T_VAL
BEQ write_clock
CMP r3, #0x940 /* is this a 940 */
LDREQ r2, =INTEGRATOR_HDR_OSC_940T_VAL
BEQ write_clock
LDR r12, =0x946
CMP r3, r12 /* is this a 946ES */
LDREQ r2, =INTEGRATOR_HDR_OSC_946ES_VAL
BEQ write_clock
CMP r3, #0x920 /* is this a 920 */
LDREQ r2, =INTEGRATOR_HDR_OSC_920T_VAL
BEQ write_clock
MOV r1, r3, LSR #4 /* is this a 966 */
CMP r1, #0x96
BNE write_clock
AND r1, r3, #0xF
CMP r1, #6
LDREQ r2, =INTEGRATOR_HDR_OSC_966ES_VAL
#endif /* defined(CPU_720T/740T/920T/940T/966ES) */
write_clock:
/* Write clock settings */
/*
LDR r1, =INTEGRATOR_HDR_BASE
LDR r3, =0xA05F
STR r3, [r1, #INTEGRATOR_HDR_LOCK_OFFSET]
STR r2, [r1, #INTEGRATOR_HDR_OSC_OFFSET]
MOV r2, #0
STR r2, [r1, #INTEGRATOR_HDR_LOCK_OFFSET]
*/
/* Set up System BUS and PCI clocks */
/*
LDR r1, =INTEGRATOR_SC_BASE
STR r3, [r1, #INTEGRATOR_SC_LOCK_OFFSET]
LDR r2, =(INTEGRATOR_SC_OSC_SYS_20MHz | INTEGRATOR_SC_OSC_PCI_33MHz)
STR r2, [r1, #INTEGRATOR_SC_OSC_OFFSET]
MOV r2, #0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -