📄 cpregxsc1.s
字号:
; TITLE("XSC1 CoRegister Access Routines")
;++
;
; Copyright (c) 2001 Intel Corporation
;
;--
; Conditional Includes
IF BSP_MAINSTONE = "1"
INCLUDE Mainstone.mac
ENDIF
OPT 2 ; disable listing
INCLUDE kxarm.h
INCLUDE bvd1.inc
INCLUDE bvd1bd.inc
OPT 1 ; reenable listing
TEXTAREA
;
; XSC1EnterTurbo - Enters Turbo Mode
;
; Uses r0 - contains value for writing to PWRMODE coprocessor register
;
; Preserve the Fast Bus Mode, B bit.
;
LEAF_ENTRY XSC1EnterTurbo
mrc p14, 0, r0, c6, c0, 0 ; read c6
and r0, r0, #0xd ; clear F bit
orr r0, r0, #1 ; or in Turbo bit
mcr p14, 0, r0, c6, c0, 0 ; enter Turbo mode
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; XSC1ExitTurbo - Exits Turbo Mode
;
; Uses r0 - contains value for writing to PWRMODE coprocessor register
;
; Preserve the Fast Bus Mode, B bit.
;
LEAF_ENTRY XSC1ExitTurbo
mrc p14, 0, r0, c6, c0, 0 ; read c6
and r0, r0, #0xe ; clear Turbo bit to
mcr p14, 0, r0, c6, c0, 0 ; exit Turbo mode
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
;XSC1ReadCLKCFG - Reads CCLKCFG register
;
; Uses r0 - contains return value -> CCLKCFG register contents
;
LEAF_ENTRY XSC1ReadCLKCFG
mrc p14, 0, r0, c6, c0, 0 ; Read CCLKCFG
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; XSC1GetCPUId - Get the CPU ID from CP15 R0 Register
;
; This routine reads R0 from CoProcesser 15 to get the CPU ID
;
; Uses r0 - return value of CPU ID
;
LEAF_ENTRY XSC1GetCPUId
mrc p15, 0, r0, c0, c0, 0
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; XSC1ChangeVoltage - change voltage
;
; Uses r0 - contains value for writing to PWRMODE coprocessor register
;
;
;
LEAF_ENTRY XSC1ChangeVoltage
mrc p14, 0, r0, c7, c0, 0 ; read c7
orr r0, r0, #0x8 ; Voltage change sequence begins
mcr p14, 0, r0, c7, c0, 0 ; exit Turbo mode
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; XSC1FreqChange - Do a Frequency Change
;
; Uses
; r0 - arg1 - mask to set the CLKCFG register
;
LEAF_ENTRY XSC1FreqChange
orr r0, r0, #2 ; set F=1
mcr p14, 0, r0, c6, c0, 0 ; do Freq Change
FreqRet
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; TURN_ON_BTB - Enables the Branch Target Buffer
;
; Turn on the BTB via cp15.1[11] - Uses r0
;
;
LEAF_ENTRY TURN_ON_BTB
mcr p15, 0, r0, c7, c5, 0 ; flush the icache & BTB
mrc p15,0,r0,c1,c0,0
orr r0, r0, #0x800
mcr p15,0,r0,c1,c0,0
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
IF :DEF: USING_COPROCSUPPORT
;
; ENABLE_COPROC_ACCESS - Enables the access bits to Coprocessors 0 & 1
;
; Uses R0, R1. R2
;
LEAF_ENTRY ENABLE_COPROC_ACCESS
stmdb sp!, {r0 - r2} ; stack the regsiters I intend to use
mrc p15, 0, r0, c15, c1, 0 ;Get Reg15 of CP15 for Access to CP0
mov r1, #0x3 ;Load R1 with mask for setting lowest bit
orr r2, r0, r1 ;OR current value with 1 to set the lowest bit
mcr p15, 0, r2, c15, c1, 0 ;Now set the value back into R15 of CP15
CPWAIT r0
ldmia sp!, {r0 - r2} ; unstack the registers I saved off
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; BVDStoreAllCoProcRegs - Store all coprocessor registers
; Saving:
; CP0, R0 - 15
; CP1, R2, R3, R8 - 11
;
; NOTE: This routine was written to optimize both the read performance and
; the register usage. It was designed against the EAS stated instruction
; latencies for tmrc and tmrrc instructions in hopes of keeping the
; connection between the coprocessor and core maximized with respect to bandwitdh.
; As such, the registes are not saved in a completely linear fashion, they are
; interleaved. As a result, the restore must treat these like a stack and pop
; off the registers in a similar order.
;
LEAF_ENTRY BVDStoreAllCoProcRegs
stmdb sp!, {r0 - r11,r14} ; Store registers to the stack so we don't munge anything
;Save pointer comes in R0, move to R10
mov r10, r0
tmrc r0, wC2 ;CP1, Reg2 -> Core, R0
tmrc r1, wC3 ;CP1, Reg3 -> Core, R1
tmrrc r2, r3, wR0 ;CP0, Reg0 -> Core, R2 (Lo) R3 (High)
;Now store to location referenced by R10, post-increment by 4 bytes
str r0, [r10],#4
str r1, [r10],#4
tmrrc r4, r5, wR1
str r2, [r10], #4 ;Now store wR0
str r3, [r10], #4
tmrrc r0, r1, wR2
str r4, [r10], #4 ;Store wR1
str r5, [r10], #4
tmrc r2, wC8 ;CP1, Reg8 -> Core, R2
tmrrc r6, r7, wR3
str r0, [r10], #4 ;Store wR2
str r1, [r10], #4
tmrrc r4, r5, wR4
str r2, [r10], #4 ;Store wC3
tmrrc r8, r9, wR5
str r6, [r10], #4 ;Store wR3
str r7, [r10], #4
tmrrc r2, r3, wR6
str r4, [r10], #4 ;Store wR4
str r5, [r10], #4
tmrrc r0, r1, wR7
str r8, [r10], #4 ;Store wR5
str r9, [r10], #4
tmrrc r6, r7, wR8
str r2, [r10], #4 ;Store wR6
str r3, [r10], #4
tmrrc r4, r5, wR9
str r0, [r10], #4 ;Store wR7
str r1, [r10], #4
tmrrc r8, r9, wR10
str r6, [r10], #4 ;Store wR8
str r7, [r10], #4
tmrrc r2, r3, wR11
str r4, [r10], #4 ;Store wR9
str r5, [r10], #4
tmrrc r0, r1, wR12
str r8, [r10], #4 ;Store wR10
str r9, [r10], #4
tmrrc r6, r7, wR13
str r2, [r10], #4 ;Store wR11
str r3, [r10], #4
tmrrc r4, r5, wR14
str r0, [r10], #4 ;Store wR12
str r1, [r10], #4
tmrrc r8, r9, wR15
str r6, [r10], #4 ;Store wR13
str r7, [r10], #4
tmrc r2, wC9
str r4, [r10], #4 ;Store wR14
str r5, [r10], #4
tmrc r0, wC10
str r8, [r10], #4 ;Store wR15
str r9, [r10], #4
tmrc r1, wC11
str r2, [r10], #4 ;Store wC9
str r0, [r10], #4 ;Store wC10
str r1, [r10], #4 ;Store wC11
; Now clear the control MUP & CUP bits (Control Update Bits)
; These are WRITE 1 TO CLEAR!
mov r3, #0x3 ;Set the 2 lowest bits == 1
tmcr wC1, r3 ;Now Clear the CUP & MUP bits
CPWAIT r0
ldmia sp!, {r0 - r11,r14} ;Now restore the regsiters we stacked
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; BVDRestoreAllCoProcRegs - Restore all coprocessor registers
; Restoring:
; CP0, R0 - 15
; CP1, R2, R3, R8 - 11
;
; NOTE: This routine was written to optimize both the read performance and
; the register usage. It was designed against the EAS stated instruction
; latencies for tmcr and tmcrr instructions in hopes of keeping the
; connection between the coprocessor and core maximized with respect to bandwitdh.
; As such, the registes are not saved in a completely linear fashion, they are
; interleaved. Due to the order saved, the restore order is also not sequential.
;
LEAF_ENTRY BVDRestoreAllCoProcRegs
stmdb sp!, {r0 - r11,r14} ; Store registers to the stack so we don't munge anything
;Save pointer comes in R0, move to R10
mov r10, r0
ldr r0, [r10], #4 ;Load wC2
ldr r1, [r10], #4 ;Load wC3
ldr r2, [r10], #4 ;Load wR0
ldr r3, [r10], #4
tmcr wC2, r0
tmcr wC3, r1
ldr r0, [r10], #4 ;Load wR1
ldr r1, [r10], #4
tmcrr wR0, r2, r3
ldr r2, [r10], #4 ;Load wR2
ldr r3, [r10], #4
tmcrr wR1, r0, r1
ldr r0, [r10], #4 ;Load wC8
ldr r4, [r10], #4 ;Load wR3
ldr r5, [r10], #4
tmcrr wR2, r2, r3
ldr r6, [r10], #4 ;Load wR4
ldr r7, [r10], #4
tmcr wC8, r0
ldr r0, [r10], #4 ;Load wR5
ldr r1, [r10], #4
tmcrr wR3, r4, r5
ldr r2, [r10], #4 ;Load wR6
ldr r3, [r10], #4
tmcrr wR4, r6, r7
ldr r4, [r10], #4 ;Load wR7
ldr r5, [r10], #4
tmcrr wR5, r0, r1
ldr r0, [r10], #4 ;Load wR8
ldr r1, [r10], #4
tmcrr wR6, r2, r3
ldr r2, [r10], #4 ;Load wR9
ldr r3, [r10], #4
tmcrr wR7, r4, r5
ldr r4, [r10], #4 ;Load wR10
ldr r5, [r10], #4
tmcrr wR8, r0, r1
ldr r0, [r10], #4 ;Load wR11
ldr r1, [r10], #4
tmcrr wR9, r2, r3
ldr r2, [r10], #4 ;Load wR12
ldr r3, [r10], #4
tmcrr wR10, r4, r5
ldr r4, [r10], #4 ;Load wR13
ldr r5, [r10], #4
tmcrr wR11, r0, r1
ldr r0, [r10], #4 ;Load wR14
ldr r1, [r10], #4
tmcrr wR12, r2, r3
ldr r2, [r10], #4 ;Load wR15
ldr r3, [r10], #4
tmcrr wR13, r4, r5
ldr r4, [r10], #4 ;Load wC9
tmcrr wR14, r0, r1
ldr r5, [r10], #4 ;Load wC10
tmcrr wR15, r2, r3
ldr r0, [r10], #4 ;Load wC11
tmcr wC9, r4
tmcr wC10, r5
tmcr wC11, r0
; Now clear the control MUP & CUP bits (Control Update Bits)
; These are WRITE 1 TO CLEAR!
mov r1, #0x3 ;Set the 2 lowest bits == 1
tmcr wC1, r1 ;Now Clear the CUP & MUP bits
CPWAIT r2
ldmia sp!, {r0 - r11,r14} ;Now restore the regsiters we stacked
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; BVDSaveCoProcessors - Get the Accumulator Register from CP0 ;
; This routine reads R0 from CoProcesser 0
;
; Uses r0, - R0 contains a pointer to the alloced memory buffer of 8 bytes long
;
LEAF_ENTRY BVDSaveCoProcessors
stmdb sp!, {r0 - r4,r14} ; store registers so we don't stomp anything (INC LR)
mov r4, r0 ;Save R0 to R4, so pointer value doesn't get killed by CPWAIT
tmrc r1, wC1 ;Grab the CUP & MUP bits in CP1, Reg1
CPWAIT r0
ands r1, r1, #0x3 ;We only are concerned with the lowest 2 bits
;if flag == 0 then no change since last save, skip save functionality
beq Finish_Save
mov r0, #0x1 ;Set a flag in the memory area indicating we have actually SAVED
str r0, [r4], #4 ;Save & increment pointer
; Now branch to the 'save' function, R0 = pointer to save area
mov r0, r4
bl BVDStoreAllCoProcRegs
Finish_Save
ldmia sp!, {r0 - r4,r14} ;Now restore the regsiters we stacked3
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;
; BVDRestoreCoProcessors - Set CP0's Accumulator Register
;
; This routine sets R0 on CoProcessor 0
;
; Uses r0 - pointer to the memory buffer containing the 40-bit value
; Uses r1, r2 - R1 & R2 contain the value to be written to the Accumulator Register
; r1 = bits 0:31, r2 = 32:39
;
LEAF_ENTRY BVDRestoreCoProcessors
stmdb sp!, {r0 - r4,r14} ;stack the registers used, so don't munge anything
ldr r1, [r0], #4 ;Load the first 4 bytes containing 'if saving' flag
cmp r1, #0
beq Skip_Restore
;Branch to the 'Restore' Function, R0= pointer to save/restore memory area
bl BVDRestoreAllCoProcRegs
Skip_Restore
ldmia sp!, {r0 - r4,r14}
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
ENDIF ;Endif of USING_COPROCSUPPORT
;
; GetCP1Regs - Gets all the registers of CP1
;
; This routine Reads all the registers of CP1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -