📄 start.s
字号:
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
/* Cache functions.
*/
.globl icache_enable
icache_enable:
mfspr r5,HID0 /* turn on the I cache. */
ori r5,r5,0x8800 /* Instruction cache only! */
addis r6,0,0xFFFF
ori r6,r6,0xF7FF
and r6,r5,r6 /* clear the invalidate bit */
sync
mtspr HID0,r5
mtspr HID0,r6
isync
sync
blr
.globl icache_disable
icache_disable:
mfspr r5,HID0
addis r6,0,0xFFFF
ori r6,r6,0x7FFF
and r5,r5,r6
sync
mtspr HID0,r5
isync
sync
blr
.globl icache_status
icache_status:
mfspr r3, HID0
srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
andi. r3, r3, 1
blr
.globl dcache_enable
dcache_enable:
mfspr r5,HID0 /* turn on the D cache. */
ori r5,r5,0x4400 /* Data cache only! */
mfspr r4, PVR /* read PVR */
srawi r3, r4, 16 /* shift off the least 16 bits */
cmpi 0, 0, r3, 0xC /* Check for Max pvr */
bne NotMax
ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
NotMax:
addis r6,0,0xFFFF
ori r6,r6,0xFBFF
and r6,r5,r6 /* clear the invalidate bit */
sync
mtspr HID0,r5
mtspr HID0,r6
isync
sync
blr
.globl dcache_disable
dcache_disable:
mfspr r5,HID0
addis r6,0,0xFFFF
ori r6,r6,0xBFFF
and r5,r5,r6
sync
mtspr HID0,r5
isync
sync
blr
.globl dcache_status
dcache_status:
mfspr r3, HID0
srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
andi. r3, r3, 1
blr
.globl dc_read
dc_read:
/*TODO : who uses this, what should it do?
*/
blr
.globl get_pvr
get_pvr:
mfspr r3, PVR
blr
/*------------------------------------------------------------------------------*/
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* r3 = dest
* r4 = src
* r5 = length in bytes
* r6 = cachelinesize
*/
.globl relocate_code
relocate_code:
mr r1, r3 /* Set new stack pointer */
mr r9, r4 /* Save copy of Global Data pointer */
mr r10, r5 /* Save copy of Destination Address */
mr r3, r5 /* Destination Address */
#ifdef CFG_RAMBOOT
lis r4, CFG_SDRAM_BASE@h /* Source Address */
ori r4, r4, CFG_SDRAM_BASE@l
#else
lis r4, CFG_MONITOR_BASE@h /* Source Address */
ori r4, r4, CFG_MONITOR_BASE@l
#endif
lwz r5, GOT(__init_end)
sub r5, r5, r4
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
*
* Offset:
*/
sub r15, r10, r4
/* First our own GOT */
add r14, r14, r15
/* the the one used by the C code */
add r30, r30, r15
/*
* Now relocate code
*/
cmplw cr1,r3,r4
addi r0,r5,3
srwi. r0,r0,2
beq cr1,4f /* In place copy is not necessary */
beq 7f /* Protect against 0 count */
mtctr r0
bge cr1,2f
la r8,-4(r4)
la r7,-4(r3)
1: lwzu r0,4(r8)
stwu r0,4(r7)
bdnz 1b
b 4f
2: slwi r0,r0,2
add r8,r4,r0
add r7,r3,r0
3: lwzu r0,-4(r8)
stwu r0,-4(r7)
bdnz 3b
/*
* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
4: cmpwi r6,0
add r5,r3,r5
beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1
andc r3,r3,r0
mr r4,r3
5: dcbst 0,r4
add r4,r4,r6
cmplw r4,r5
blt 5b
sync /* Wait for all dcbst to complete on bus */
mr r4,r3
6: icbi 0,r4
add r4,r4,r6
cmplw r4,r5
blt 6b
7: sync /* Wait for all icbi to complete on bus */
isync
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
mtlr r0
blr
in_ram:
/*
* Relocation Function, r14 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)
add r0,r0,r11
stw r0,0(r3)
bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
2: 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
add r0,r0,r11
stw r10,0(r3)
stw r0,0(r4)
bdnz 3b
4:
clear_bss:
/*
* Now clear BSS segment
*/
lwz r3,GOT(__bss_start)
lwz r4,GOT(_end)
cmplw 0, r3, r4
beq 6f
li r0, 0
5:
stw r0, 0(r3)
addi r3, r3, 4
cmplw 0, r3, r4
blt 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:
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 */
mflr r4 /* save link register */
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
mtlr r4 /* restore link register */
blr
/*
* Function: relocate entries for one exception vector
*/
trap_reloc:
lwz r0, 0(r7) /* hdlr ... */
add r0, r0, r3 /* ... += dest_addr */
stw r0, 0(r7)
lwz r0, 4(r7) /* int_return ... */
add r0, r0, r3 /* ... += dest_addr */
stw r0, 4(r7)
blr
/* Setup the BAT registers.
*/
setup_bats:
lis r4, CFG_IBAT0L@h
ori r4, r4, CFG_IBAT0L@l
lis r3, CFG_IBAT0U@h
ori r3, r3, CFG_IBAT0U@l
mtspr IBAT0L, r4
mtspr IBAT0U, r3
isync
lis r4, CFG_DBAT0L@h
ori r4, r4, CFG_DBAT0L@l
lis r3, CFG_DBAT0U@h
ori r3, r3, CFG_DBAT0U@l
mtspr DBAT0L, r4
mtspr DBAT0U, r3
isync
lis r4, CFG_IBAT1L@h
ori r4, r4, CFG_IBAT1L@l
lis r3, CFG_IBAT1U@h
ori r3, r3, CFG_IBAT1U@l
mtspr IBAT1L, r4
mtspr IBAT1U, r3
isync
lis r4, CFG_DBAT1L@h
ori r4, r4, CFG_DBAT1L@l
lis r3, CFG_DBAT1U@h
ori r3, r3, CFG_DBAT1U@l
mtspr DBAT1L, r4
mtspr DBAT1U, r3
isync
lis r4, CFG_IBAT2L@h
ori r4, r4, CFG_IBAT2L@l
lis r3, CFG_IBAT2U@h
ori r3, r3, CFG_IBAT2U@l
mtspr IBAT2L, r4
mtspr IBAT2U, r3
isync
lis r4, CFG_DBAT2L@h
ori r4, r4, CFG_DBAT2L@l
lis r3, CFG_DBAT2U@h
ori r3, r3, CFG_DBAT2U@l
mtspr DBAT2L, r4
mtspr DBAT2U, r3
isync
lis r4, CFG_IBAT3L@h
ori r4, r4, CFG_IBAT3L@l
lis r3, CFG_IBAT3U@h
ori r3, r3, CFG_IBAT3U@l
mtspr IBAT3L, r4
mtspr IBAT3U, r3
isync
lis r4, CFG_DBAT3L@h
ori r4, r4, CFG_DBAT3L@l
lis r3, CFG_DBAT3U@h
ori r3, r3, CFG_DBAT3U@l
mtspr DBAT3L, r4
mtspr DBAT3U, r3
isync
/* Invalidate TLBs.
* -> for (val = 0; val < 0x20000; val+=0x1000)
* -> tlbie(val);
*/
lis r3, 0
lis r5, 2
1:
tlbie r3
addi r3, r3, 0x1000
cmp 0, 0, r3, r5
blt 1b
blr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -