📄 paget.s
字号:
; Simple macro to clear all page table entries.$label INIT_PGTABLE $count, $val, $ptr, $offset LDR $ptr, =Level1tab ADD $ptr, $ptr, $offset ; Real address of Level1 TTB MOV $val, #0 ; Invalid LDR $count, =L1_TABLE_ENTRIES77 STR $val, [$ptr], #4 SUBS $count, $count, #1 ; decrement loop count BNE %B77 LDR $ptr, =Level2tab_ROM ADD $ptr, $ptr, $offset ; Real address of Level2 TTB LDR $count, =L2_TABLE_ENTRIES78 STR $val, [$ptr], #4 SUBS $count, $count, #1 ; decrement loop count BNE %B78 MEND ; If this platform supports auto-memory sizing, the size found ; should be in $tmp2$label BUILD_PGTABLE $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $addr, $offset ; Offset between physical & virtual addresses for TTBs LDR $offset, =TTB_OFFSET ; ---------------------------------------------------- ; First clear all TT entries - FAULT ; ---------------------------------------------------- INIT_PGTABLE $tmp3, $tmp4, $tmp5, $offset ; ---------------------------------------------------- ; Here lies the MMU memory map for this board ; ---------------------------------------------------- ldr $addr, =uHAL_AddressTable ; ---------------------------------------------------- ; For executables which are linked for a different ; address to the physically executed address: ; ; Need to adjust from the linked address of the table ; to a relative offset from here. First, work out the ; offset from the RO$$Base, then find out how far we ; are from our actual start. Lastly, add the ; difference to the current pc. LDR $tmp4, =|Image$$RO$$Base| ; get linked location of code SUB $addr, $addr, $tmp4 ; A. table offset from start LDR $tmp3, =%F79 SUB $tmp3, $tmp3, $tmp4 ; B. Offset to next label SUB $addr, $addr, $tmp3 ; A-B ; ---------------------------------------------------- ; Note: no more than 2 instructions between here and ; the label. Since pc is here + 8, add A-B to get ; current table address MOV $tmp3, pc ADD $addr, $addr, $tmp379 ; ---------------------------------------------------- ; Check 1st Entry in address table ; If this value is non-zero, size of first memory area is taken ; from target-specific memory sizing code rather than this table ; ---------------------------------------------------- LDR $tmp3, [$addr], #4 CMP $tmp3, #0 BEQ %F81 ; Not autosizing, read all params ; Make sure given memory size is a multiple of 1MB ; tmp3 is no. of 1MB segments MOV $tmp3, $tmp1, LSR #20 MOV $tmp4, $tmp3, LSL #20 CMP $tmp4, $tmp1 ADDNE $tmp3, #1 ; ---------------------------------------------------- ; Read 1st Entry from MMU table seperately to allow ; memory sizing. ; NOTE: 1st entry cannot abort & can't be Level2 !! LDR $tmp4, =Level1tab ADD $tmp4, $tmp4, $offset ; Virtual base address -> Level1 offset in tmp2 LDR $tmp5, [$addr], #4 ADD $tmp2, $tmp4, $tmp5, LSR #(20-2) ; Physical base address -> tmp4 LDR $tmp4, [$addr], #4 ; Access permissions etc -> tmp3 (NOTE: Size is skipped!) LDR $tmp5, [$addr], #8 CMP $tmp5, #0 ; Halt if access is zero BEQ %F80 TST $tmp4, #PT_PAGE BNE %F80 ; Halt if Level2 table ADD $tmp1, $tmp4, $tmp5 ; Level1 Table Entry ; Registers set, so build 1st entry & rest of TLB. B %F83 ; All causes for error end up here80 IF :DEF: ARM7T B %F90 ; No Page Table if no MMU ENDIF B .81 LDR $tmp4, =Level1tab ADD $tmp4, $tmp4, $offset82 ; Calculate offset to virtual base address entry -> tmp2 LDR $tmp1, [$addr], #4 ; Virtual address ADD $tmp2, $tmp4, $tmp1, LSR #(20-2) ; Physical base address -> tmp1 LDR $tmp1, [$addr], #4 ; Access permissions etc -> tmp3 LDR $tmp3, [$addr], #4 CMP $tmp3, #0 ; All done if access is zero BEQ %F90 TST $tmp1, #PT_PAGE ; Check for Level2 table BNE %F84 ; Yes, do it ; ---------------------------------------------------- ; Level 1 Entries, calculate size & fill table ; ---------------------------------------------------- ADD $tmp1, $tmp1, $tmp3 ; Level1 Table Entry LDR $tmp3, [$addr], #4 ; area size MOV $tmp3, $tmp3, LSR #20 ; no. of 1MB segments83 STR $tmp1, [$tmp2], #4 ; store Table Entry ADD $tmp1, $tmp1, #SZ_1M ; add section number field SUBS $tmp3, $tmp3, #1 ; decrement loop count BGT %B83 B %B82 ; Repeat until done84 ; Convert logical addresses to real addresses ADD $tmp1, $tmp1, $offset ; Pointer to Level2 table ; ---------------------------------------------------- ; Check for Fine table and process seperately ; ---------------------------------------------------- TST $tmp3, #(PT_FINE - PT_PAGE) ; Read size! LDR $tmp5, [$addr], #4 BIC $tmp4, $tmp1, #0x0ff BNE %F87 ; ---------------------------------------------------- ; Large Level2: Strip address of Level2 Table -> tmp4 ; ---------------------------------------------------- BIC $tmp4, $tmp4, #0x0300 MOV $tmp5, $tmp5, LSR #16 ; no. of 64KB segments MOV $tmp5, $tmp5, LSL #4 ; no. of 4KB aliases85 STR $tmp1, [$tmp2], #4 ; Level1 points to Level2 entry86 ; Add each entry aliased 16 times (64KB/4KB, so $tmp3 & 0xF == 0) STR $tmp3, [$tmp4], #4 ; store large L2 TT entry SUB $tmp5, $tmp5, #1 ; decrement page count TST $tmp5, #0xF BNE %B86 ; upto 16 L2 entries ; Add 16 L2 entries per L1 entry (1MB/64KB, so $tmp3 & 0xF0 == 0) ADD $tmp3, $tmp3, #SZ_64K ; next page field TST $tmp5, #0xf0 BNE %B86 ; upto 16 L2 entries CMP $tmp5, #0 ; All done? ADD $tmp1, $tmp1, #0x400 ; Next 1MB is 256 entries further down BNE %B85 ; No, do another L1 entry. B %B8187 ; ---------------------------------------------------- ; Fine Level2: Strip address of Level2 Table -> tmp4 ; ---------------------------------------------------- BIC $tmp4, $tmp4, #0x0f00 MOV $tmp5, $tmp5, LSR #16 ; no. of 64KB segments MOVEQ $tmp5, $tmp5, LSL #8 ; no. of 1KB aliases MOVNE $tmp5, $tmp5, LSL #4 ; no. of 4KB aliases88 STR $tmp1, [$tmp2], #4 ; Level1 points to Level2 entry89 STR $tmp3, [$tmp4], #4 ; store fine L2 TT entry SUBS $tmp5, $tmp5, #1 ; decrement page count ADD $tmp3, $tmp3, #SZ_1K ; next page field TST $tmp5, #0x0ff BNE %B89 ; 4 x 256 L2 entries TST $tmp5, #0x300 BNE %B89 ; 3ff won't fit inside an instruction CMP $tmp5, #0 ; All done? ADD $tmp1, $tmp1, #0x4000 ; Next 1MB is 1K entries further down BNE %B88 ; No, do another L1 entry. B %B8190 MEND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -