📄 sys_support.s
字号:
EMI_PADDR = 0xDF000000 // Physical address for Internal Register area
EMI_SIZE = 0x00004000 // Size = 16KB.
EMI_ATR = AP_RW
VRAM_LADDR = 0xFF000000 // Logical address for Internal Register area
VRAM_PADDR = 0xFF000000 // Physical address for Internal Register area
VRAM_SIZE = 0x01000000 // Size = 16KB.
VRAM_ATR = AP_RW
MMU_TABLE:
.long BROM_SIZE, BROM_LADDR, BROM_PADDR, BROM_ATR
.long SFR_SIZE, SFR_LADDR, SFR_PADDR, SFR_ATR
.long SDRAM_SIZE, SDRAM_LADDR, SDRAM_PADDR, SDRAM_ATR
.long FLASH_SIZE, FLASH_LADDR, FLASH_PADDR, FLASH_ATR
.long EXT_SIZE, EXT_LADDR, EXT_PADDR, EXT_ATR
.long CSI_SIZE, CSI_LADDR, CSI_PADDR, CSI_ATR
.long BMI_SIZE, BMI_LADDR, BMI_PADDR, BMI_ATR
.long CF_SIZE, CF_LADDR, CF_PADDR, CF_ATR
.long EMI_SIZE, EMI_LADDR, EMI_PADDR, EMI_ATR
.long VRAM_SIZE, VRAM_LADDR, VRAM_PADDR, VRAM_ATR
.long 0
//-------------------------------------------------------------------------------
//******************************************************************************
// Routine to Initialize MMU Controller.
// Instruction Cache control is enabled if CACHE_I macro is defined.
// Data Cache control is enabled if CACHE_D macro is defined.
//******************************************************************************
_MMU_init:
stmfd sp!, {r0-r8} // Please use stack PUSH command if required.
// By default MMU initialization routine does
// not utilize Stack Pointer. This allows
// Remapping of Stack Memory.
mrc p15, 0, r1, c0, c0, 0
ldr r0, =CPUID_CODE
and r1, r1, r0 // If NOT ARM920T cpu then
cmp r1, r0 // MMU Initialization is not done.
bne MMU_init_end
mov r2, #0x00
mcr p15, 0, r2, c8, c7, 0 // Invalidate TLB's.
ldr r1, =TTB_ADDR
ldr r2, =TTB_SIZE
mov r0,#0x0
Clear_TTB:
cmp r2, r0 // Clear TTB memory for new updation.
strne r0, [r1], #4
subne r2, r2, #1
bne Clear_TTB
ldr r5, =MMU_TABLE // Address where MMU Table is kept
ldr r8, =CTTB_ADDR // Get Coarse Table Base address
Update_TLB:
ldr r4, [r5], #4 // Get TLB Entry size.
cmp r4, #0 // Check if End of TLB entry table.
beq Set_TTBase
ldr r0, [r5], #4 // Get TLB Entry Logical address.
ldr r6, [r5], #4 // Get TLB Entry Physical address.
ldr r7, [r5], #4 // Get Attributes.
ldr r1, =TTB_ADDR
mov r2, r0, LSR #20 // Get Logical address.
add r1, r1, r2, LSL #2
TTBL1_Entry: //********* Level-1 Entry in Translation Table *********
cmp r4, #TTBSZ_SEC // If remaining page size < 1MB,
blt MMU_setCOARSE // Set Coarse table Entry.
sub r4, r4, #TTBSZ_SEC
ldr r0, =TTBMSK_SEC
and r0, r6, r0
orr r0, r0, r7
orr r0, r0, #TTB_SECTION // Section page table entry data is ready.
str r0, [r1], #4 // TTB single entry updated.
add r6, r6, #TTBSZ_SEC // Update next Physical page address.
b TTBL1_Entry
MMU_setCOARSE:
cmp r4, #0
beq Update_TLB
//********* Prepare for Coarse Table Entry *********
ldr r0, =TTBMSK_COARSE
and r0, r8, r0
ldr r3, =DOMAIN_MSK
and r3, r7, r3
orr r0, r0, r3 // Set Domain.
orr r0, r0, #TTB_COARSE // Section page table entry data is ready.
str r0, [r1] // TTB Level-1 entry updated.
mov r3, r8 // Collect Coarse Table Base address.
ldr r2, =CTTB_SIZE
mov r0, #0
Clear_CTTB:
cmp r2, r0 // Clear Coarse Table for new updation.
strne r0, [r8], #4 // Update Coarse Table Base Addr for next entry.
subne r2, r2, #1
bne Clear_CTTB
ldr r1, =ATR_MSK
and r1, r7, r1
ldr r0, =AP_MSK
and r0, r7, r0
mov r0, r0, LSR #10
add r0, r0, r0, LSL #2
add r0, r0, r0, LSL #4 // Access control word defined for Small
mov r7, #0
add r7, r1, r0, LSL #4 // Page entry.
TTBL2_Entry: //********* Level-2 Entry in Translation Table *********
cmp r4, #TTBSZ_SMALL // If page size < 4KB,
blt Update_TLB // Coarse Table entry is done.
sub r4, r4, #TTBSZ_SMALL // Update size information.
ldr r0, =TTBMSK_SMALL
and r0, r6, r0
orr r0, r0, r7
orr r0, r0, #TTBL2_SMALL // Small page table entry data is ready.
str r0, [r3], #4 // TTB Second level Table entry updated.
add r6, r6, #TTBSZ_SMALL // Update next Physical page address.
b TTBL2_Entry
Set_TTBase:
ldr r0, =TTB_ADDR
mcr p15, 0, r0, c2, c0, 0 // Set TTB base address register.
ldr r2, =D_DOMAIN_ACCESS
mcr p15, 0, r2, c3, c0, 0 // Set Domain access control.
mov r0, #0x0
mcr p15, 0, r0, c13, c0, 0 // Process ID = 0.
// Enable MMU operation.
mrc p15, 0, r0, c1, c0, 0
ldr r1, =R1_SBZ_DATA
bic r0, r0, r1 // Clear SBZ bits.
ldr r1, =R1_SBO_DATA
orr r0, r0, r1 // Set SBO bits.
orr r0, r0, #0x0001 // Set MMU Control.
#if CACHE_I
orr r0, r0, #0x1000 // Set I-Cache Control.
#endif
#if CACHE_D
orr r0, r0, #0x0004 // Set D-Cache Control.
#endif
mcr p15, 0, r0, c1, c0, 0
ldr r3, =MMU_TABLE // Flat fetch.
ldr r2, [r3]
ldr r2, [r3] // MMU is enabled after this step
MMU_init_end:
ldmfd sp!, {r0-r8} // Please use stack POP command if required.
// By default MMU initialization routine does
// not utilize Stack Pointer. This allows
// Remapping of Stack Memory.
init_done:
mov pc, lr
.section .init
.align 4
.global software_init_hook
software_init_hook:
mov pc, lr
.text
.align 4
.global software_term_hook
software_term_hook:
mov pc, lr
/*
* Gateway processing of interrupt
*
*/
.text
.align 4
.global IRQ_Handler
IRQ_Handler:
/*
* Interrrupt mode
*
* Cpsr enters in the spsr_irq and the return pointer enters r14_irq(lp).
* spsr_irq and r14_irq and r13(sp)_irq become r14,r13.
*/
/*
* To the task operation mode(Supervisor mode )
*/
mov sp,#(CPSR_SVC | CPSR_FIQ_BIT | CPSR_IRQ_BIT)
msr cpsr_all, sp
stmfd sp!, {r0-r3,ip,lr,pc} /* pc is a dummy */
/*
* Enters IRQ mode in order to get the spsr and return address
*/
mov r0,#(CPSR_IRQ | CPSR_FIQ_BIT | CPSR_IRQ_BIT)
msr cpsr,r0
sub r0,lr,#4
mrs r1,spsr
/*
* To supervisor mode
*/
and r2, r1, #CPSR_FIQ_BIT /* Inherit FIQ bit */
orr r2, r2, #(CPSR_SVC|CPSR_IRQ_BIT)
msr cpsr_all, r2
str r0, [sp,#0x18] /* Store pc */
stmfd sp!,{r1} /* spsr */
/*
* Judgement on if there is multiple interrupts
*/
ldr r2, =interrupt_count
ldr r3, [r2]
add r0,r3,#1
str r0, [r2]
cmp r3, #0x00
moveq r2,sp /* when there is no nested interrupts */
ldreq sp,=STACKTOP /* modification of the stack */
stmeqfd sp!,{r2} /* Save the stack of the task */
/*
* Check the interrupt factor(Intterrupt High)
*/
Intterrupt_High:
ldr r1, =IRQ0_STATUS_H
ldr r0, =IRQ0_ENABLEREG_H
ldr r0, [r0]
find_irq_status:
ldr r2, [r1]
and r2, r2, r0
cmp r2, #0x00000000
beq Intterrupt_Low
mov r0, #31
find_bit_loop:
mov r3, r2, asr r0
tst r3, #1
bne find_bit_end
subs r0, r0, #1
bpl find_bit_loop
find_bit_end:
mov r3, r0
add r3, r0,#32
/* Fix bug 2006.5.29 <Start> */
// ldr r2, =IRQ0_ENABLEREG_H
/* Save the enable register */
// ldr r0, [r2]
/* Save the mask bit */
// mov r0,#0
// str r0,[r2]
/* Fix bug 2006.5.29 <End> */
b Handler_Proc
/*
* Check the interrupt factor(Intterrupt Low)
*/
Intterrupt_Low:
ldr r1, =IRQ0_STATUS_L
ldr r0, =IRQ0_ENABLEREG_L
ldr r0, [r0]
find_irq_status2:
ldr r2, [r1]
and r2, r2, r0
cmp r2, #0x00000000
beq Handler_Proc_End
mov r0, #31
find_bit_loop2:
mov r3, r2, asr r0
tst r3, #1
bne find_bit_end2
subs r0, r0, #1
bpl find_bit_loop2
find_bit_end2:
mov r3, r0
/* Fix bug 2006.5.29 <Start> */
Handler_Proc:
ldr r2, =IRQ0_ENABLEREG_H
stmfd sp!, {r2} /* Save the enable register */
ldr r0, [r2]
stmfd sp!, {r0} /* Save the mask bit */
mov r0,#0
str r0,[r2] /* Disable the interrupt */
/* Fix bug 2006.5.29 <End> */
ldr r2, =IRQ0_ENABLEREG_L
stmfd sp!, {r2} /* Save the enable register */
ldr r0, [r2]
stmfd sp!, {r0} /* Save the mask bit */
mov r0,#0
str r0,[r2]
ldr r0, =int_table /* Read the suspected interrupt table */
ldr r0, [r0,r3,lsl #2] /* r0<-interrupt handler */
/*
* Check the undefined interrupts
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -