📄 start.s
字号:
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
#if 0
andi. r23,r23,MSR_PR
mfspr r23,SPRG3 /* if from user, fix up tss.regs */
beq 2f
addi r24,r1,STACK_FRAME_OVERHEAD
stw r24,PT_REGS(r23)
2: addi r2,r23,-TSS /* set r2 to current */
tovirt(r2,r2,r23)
#endif
mflr r23
andi. r24,r23,0x3f00 /* get vector offset */
stw r24,TRAP(r21)
li r22,0
stw r22,RESULT(r21)
mtspr SPRG2,r22 /* r1 is now kernel sp */
#if 0
addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
cmplw 0,r1,r2
cmplw 1,r1,r24
crand 1,1,4
bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
#endif
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 r29 /* Disable interrupts */
li r4,0
ori r4,r4,MSR_EE
andc r29,r29,r4
SYNC /* Some chip revs need this... */
mtmsr r29
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
/* Cache functions.
*/
invalidate_icache:
iccci r0,r0 // for 405, iccci invalidates the
blr // entire I cache
invalidate_dcache:
addi r6,0,0x0000 // clear GPR 6
addi r7,r0, 128 // do loop for # of dcache lines
// NOTE: dccci invalidates both
mtctr r7 // ways in the D cache
..dcloop:
dccci 0,r6 // invalidate line
addi r6,r6, 32 // bump to next line
bdnz ..dcloop
blr
flush_dcache:
addis r9,r0,0x0002 // set mask for EE and CE msr bits
ori r9,r9,0x8000
mfmsr r12 // save msr
andc r9,r12,r9
mtmsr r9 // disable EE and CE
addi r10,r0,0x0001 // enable data cache for unused memory
mfdccr r9 // region 0xF8000000-0xFFFFFFFF via
or r10,r10,r9 // bit 31 in dccr
mtdccr r10
addi r10,r0,128 // do loop for # of lines
addi r11,r0,4096 // D cache set size=4K
mtctr r10
addi r10,r0,(0xE000-0x10000) // start at 0xFFFFE000
add r11,r10,r11 // add to get to other side of cache line
..flush_dcache_loop:
lwz r3,0(r10) // least recently used side
lwz r3,0(r11) // the other side
dccci r0,r11 // invalidate both sides
addi r10,r10,0x0020 // bump to next line (32 bytes)
addi r11,r11,0x0020 // bump to next line (32 bytes)
bdnz ..flush_dcache_loop
sync // allow memory access to complete
mtdccr r9 // restore dccr
mtmsr r12 // restore msr
blr
.globl icache_enable
icache_enable:
mflr r8
bl invalidate_icache
mtlr r8
isync
addis r3,r0, 0x8000 /* set bit 0 */
mticcr r3
blr
.globl icache_disable
icache_disable:
addis r3,r0, 0x0000 /* clear bit 0 */
mticcr r3
isync
blr
.globl icache_status
icache_status:
mficcr r3
srwi r3, r3, 31 /* >>31 => select bit 0 */
blr
.globl dcache_enable
dcache_enable:
mflr r8
bl invalidate_dcache
mtlr r8
isync
addis r3,r0, 0x8000 /* set bit 0 */
mtdccr r3
blr
.globl dcache_disable
dcache_disable:
mflr r8
bl flush_dcache
mtlr r8
addis r3,r0, 0x0000 /* clear bit 0 */
mtdccr r3
blr
.globl dcache_status
dcache_status:
mfdccr r3
srwi r3, r3, 31 /* >>31 => select bit 0 */
blr
/*
* Delay for a number of microseconds
* -- Use the BUS timer (assumes 66 MHz) -- FIXME --
*/
.globl udelay
udelay:
#ifdef CONFIG_ADCIOP
mulli r4,r3,66 /* 66 MHz (15ns) -> 1us = 66 * 15ns */
#endif
#ifdef CONFIG_PPC405GP
mulli r4,r3,200 /* 200 MHz (5ns) -> 1us = 200 * 5ns */
#endif
1: mftbu r5
mftb r6
mftbu r7
cmp 0,r5,r7
bne 1b /* Get [synced] base time */
addc r9,r6,r4 /* Compute end time */
addze r8,r5
2: mftbu r5
cmp 0,r5,r8
blt 2b
bgt 3f
mftb r6
cmp 0,r6,r9
blt 2b
3: blr
.globl get_pvr
get_pvr:
mfspr r3, PVR
blr
.globl wr_pit
wr_pit:
mtspr pit, r3
blr
.globl wr_tcr
wr_tcr:
mtspr tcr, r3
blr
//-------------------------------------------------------------------------------
// Function: in8
// Description: Input 8 bits
//-------------------------------------------------------------------------------
.globl in8
in8:
lbz r3,0x0000(r3)
blr
//-------------------------------------------------------------------------------
// Function: out8
// Description: Output 8 bits
//-------------------------------------------------------------------------------
.globl out8
out8:
stb r4,0x0000(r3)
blr
//-------------------------------------------------------------------------------
// Function: out16
// Description: Output 16 bits
//-------------------------------------------------------------------------------
.globl out16
out16:
sth r4,0x0000(r3)
blr
//-------------------------------------------------------------------------------
// Function: out16r
// Description: Byte reverse and output 16 bits
//-------------------------------------------------------------------------------
.globl out16r
out16r:
sthbrx r4,r0,r3
blr
//-------------------------------------------------------------------------------
// Function: out32
// Description: Output 32 bits
//-------------------------------------------------------------------------------
.globl out32
out32:
stw r4,0x0000(r3)
blr
//-------------------------------------------------------------------------------
// Function: out32r
// Description: Byte reverse and output 32 bits
//-------------------------------------------------------------------------------
.globl out32r
out32r:
stwbrx r4,r0,r3
blr
//-------------------------------------------------------------------------------
// Function: in16
// Description: Input 16 bits
//-------------------------------------------------------------------------------
.globl in16
in16:
lhz r3,0x0000(r3)
blr
//-------------------------------------------------------------------------------
// Function: in16r
// Description: Input 16 bits and byte reverse
//-------------------------------------------------------------------------------
.globl in16r
in16r:
lhbrx r3,r0,r3
blr
//-------------------------------------------------------------------------------
// Function: in32
// Description: Input 32 bits
//-------------------------------------------------------------------------------
.globl in32
in32:
lwz 3,0x0000(3)
blr
//-------------------------------------------------------------------------------
// Function: in32r
// Description: Input 32 bits and byte reverse
//-------------------------------------------------------------------------------
.globl in32r
in32r:
lwbrx r3,r0,r3
blr
//-------------------------------------------------------------------------------
// Function: ppcDcbf
// Description: Data Cache block flush
// Input: r3 = effective address
// Output: none.
//-------------------------------------------------------------------------------
.globl ppcDcbf
ppcDcbf:
dcbf r0,r3
blr
//-------------------------------------------------------------------------------
// Function: ppcDcbi
// Description: Data Cache block Invalidate
// Input: r3 = effective address
// Output: none.
//-------------------------------------------------------------------------------
.globl ppcDcbi
ppcDcbi:
dcbi r0,r3
blr
//-------------------------------------------------------------------------------
// Function: ppcSync
// Description: Processor Synchronize
// Input: none.
// Output: none.
//-------------------------------------------------------------------------------
.globl ppcSync
ppcSync:
sync
blr
/*------------------------------------------------------------------------------*/
/*
* void relocate_code (addr_sp, bd, 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 Board Info pointer */
mr r10, r5 /* Save copy of Destination Address */
mr r3, r5 /* Destination Address */
lis r4, CFG_FLASH_BASE@h /* Source Address */
ori r4, r4, CFG_FLASH_BASE@l
lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
ori r5, r5, CFG_MONITOR_LEN@l
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_FLASH_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: cmplw r4,r5
dcbst 0,r4
add r4,r4,r6
blt 5b
sync /* Wait for all dcbst to complete on bus */
mr r4,r3
6: cmplw r4,r5
icbi 0,r4
add r4,r4,r6
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -