Update On-demand paging documentation
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2877 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
944e132e95
commit
315b7c521a
@ -292,46 +292,49 @@
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pg_map
|
||||
* Name: pg_l2map
|
||||
*
|
||||
* Description:
|
||||
* Write several, contiguous L2 page table entries. npages entries will be
|
||||
* written. This macro is used when CONFIG_PAGING is enable. This case,
|
||||
* it is used asfollows:
|
||||
*
|
||||
* ldr r0, =PG_L2_BASE_PADDR
|
||||
* ldr r1, =PG_LOCKED_PBASE
|
||||
* ldr r2, =CONFIG_PAGING_NLOCKED
|
||||
* ldr r3, =MMUFLAGS
|
||||
* pg_map r0, r1, r2, r3, r4
|
||||
* ldr r0, =PG_L2_BASE_PADDR <-- Address in L2 table
|
||||
* ldr r1, =PG_LOCKED_PBASE <-- Physical page memory address
|
||||
* ldr r2, =CONFIG_PAGING_NLOCKED <-- number of pages
|
||||
* ldr r3, =MMUFLAGS <-- L2 MMU flags
|
||||
* pg_l2map r0, r1, r2, r3, r4
|
||||
*
|
||||
* Inputs:
|
||||
* l2 - Physical start address in the L2 page table (modified)
|
||||
* paddr - The physical address of the start of the region to span. Must
|
||||
* be aligned to 1Mb section boundaries (modified)
|
||||
* l2 - Physical or virtual start address in the L2 page table, depending
|
||||
* upon the context. (modified)
|
||||
* ppage - The physical address of the start of the region to span. Must
|
||||
* be aligned to 1Mb section boundaries (modified)
|
||||
* npages - Number of pages to write in the section (modified)
|
||||
* mmuflags - L2 MMU FLAGS
|
||||
*
|
||||
* Scratch registers (modified): tmp
|
||||
* l2 - Physical address in the L2 page table.
|
||||
* l2 - Next address in the L2 page table.
|
||||
* ppage - Start of next physical page
|
||||
* npages - Loop counter
|
||||
* tmp - scratch
|
||||
*
|
||||
* Assumptions:
|
||||
* - The MMU is not yet enabled
|
||||
* - The L2 page tables have been zeroed prior to calling this function
|
||||
* - pg_span has been called to initialize the L1 table.
|
||||
* - pg_l1span has been called to initialize the L1 table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
.macro pg_map, paddr, npages, mmuflags, l2, tmp
|
||||
.macro pg_l2map, l2, ppage, npages, mmuflags, tmp
|
||||
b 2f
|
||||
1:
|
||||
/* Write the one L2 entries. First, get tmp = (paddr | mmuflags),
|
||||
/* Write the one L2 entries. First, get tmp = (ppage | mmuflags),
|
||||
* the value to write into the L2 PTE
|
||||
*/
|
||||
|
||||
orr \tmp, \paddr, \mmuflags
|
||||
orr \tmp, \ppage, \mmuflags
|
||||
|
||||
/* Write value into table at the current table address */
|
||||
|
||||
@ -341,7 +344,7 @@
|
||||
* table entry.
|
||||
*/
|
||||
|
||||
add \paddr, \paddr, #CONFIG_PAGING_PAGESIZE
|
||||
add \ppage, \ppage, #CONFIG_PAGING_PAGESIZE
|
||||
add \l2, \l2, #4
|
||||
|
||||
/* Decrement the number of pages written */
|
||||
@ -357,7 +360,7 @@
|
||||
#endif /* CONFIG_PAGING */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pg_span
|
||||
* Name: pg_l1span
|
||||
*
|
||||
* Description:
|
||||
* Write several, contiguous unmapped coarse L1 page table entries. As
|
||||
@ -365,24 +368,24 @@
|
||||
* macro is used when CONFIG_PAGING is enable. This case, it is used as
|
||||
* follows:
|
||||
*
|
||||
* ldr r0, =PG_L2_BASE_PADDR
|
||||
* ldr r1, =PG_LOCKED_PBASE
|
||||
* ldr r2, =(CONFIG_PAGING_NLOCKED+CONFIG_PAGING_NPAGES)
|
||||
* ldr r3, =MMU_FLAGS
|
||||
* pg_span r0, r1, r2, r3, r4
|
||||
* ldr r0, =PGTABLE_BASE_PADDR <-- Address in L1 table
|
||||
* ldr r1, =PG_LOCKED_VBASE <-- Virtual address of region
|
||||
* pg_l1addr r0, r1, r0
|
||||
* ldr r1, =PG_LOCKED_PBASE <-- Physical address of region
|
||||
* ldr r1, =(CONFIG_PAGING_NLOCKED+CONFIG_PAGING_NVPAGED) <-- number of pages
|
||||
* ldr r3, =MMU_FLAGS <-- L1 MMU flags
|
||||
* pg_l1span r0, r1, r2, r3, r4
|
||||
*
|
||||
* Inputs (unmodified unless noted):
|
||||
* l1 - Physical or virtual address in the L1 table to begin writing (modified)
|
||||
* l2 - Physical start address in the L2 page table (modified)
|
||||
* addr - The virtual address of the start of the region to span. Must
|
||||
* be aligned to 1Mb section boundaries (modified)
|
||||
* npages - Number of pages to required to span that memory region (modified)
|
||||
* mmuflags - L1 MMU flags to use
|
||||
*
|
||||
* Scratch registers (modified):
|
||||
* addr, npages, tmp
|
||||
* l2 - L2 page table physical address
|
||||
* addr - Physical address in the L1 page table.
|
||||
* npages - The number of pages remaining to be accounted for
|
||||
* Scratch registers (modified): l1, l2, npages, tmp
|
||||
* l1 - Next L1 table address
|
||||
* l2 - Physical start address of the next L2 page table
|
||||
* npages - Loop counter
|
||||
* tmp - scratch
|
||||
*
|
||||
* Return:
|
||||
@ -395,32 +398,24 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
.macro pg_span, l2, addr, npages, mmuflags, tmp
|
||||
|
||||
/* Get addr = the L1 page table address coresponding to the virtual
|
||||
* address of the start of memory region to be mapped.
|
||||
*/
|
||||
|
||||
ldr \tmp, =PGTABLE_BASE_PADDR
|
||||
lsr \addr, \addr, #20
|
||||
add \addr, \tmp, \addr, lsl #2
|
||||
.macro pg_l1span, l1, l2, npages, mmuflags, tmp
|
||||
b 2f
|
||||
1:
|
||||
/* Write the L1 table entry that refers to this (unmapped) coarse page
|
||||
* table.
|
||||
*
|
||||
* tmp = (paddr | mmuflags), the value to write into the page table
|
||||
* tmp = (l2table | mmuflags), the value to write into the page table
|
||||
*/
|
||||
|
||||
orr \tmp, \l2, \mmuflags
|
||||
|
||||
/* Write the value into the L1 table at the correct offset. */
|
||||
|
||||
str \tmp, [\addr], #4
|
||||
str \tmp, [\l1], #4
|
||||
|
||||
/* Update the L2 page table address for the next L1 table entry. */
|
||||
|
||||
add \l2, \l2, #PT_SIZE /* Next L2 page table start paddr */
|
||||
add \l2, \l2, #PT_SIZE /* Next L2 page table start address */
|
||||
|
||||
/* Update the number of pages that we have account for (with
|
||||
* non-mappings
|
||||
@ -436,6 +431,45 @@
|
||||
bgt 1b
|
||||
.endm
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pg_l1addr
|
||||
*
|
||||
* Description:
|
||||
* Given the start of an L1 table and a virtual address, return the offset
|
||||
* address into the L1 table for that address.
|
||||
*
|
||||
* ldr r0, =PGTABLE_BASE_PADDR
|
||||
* ldr r1, =PG_LOCKED_VBASE
|
||||
* pg_l1addr r0, r1, r0
|
||||
*
|
||||
* Inputs (unmodified unless noted):
|
||||
* l1 - The physical or virtual address of the start of the L1 table
|
||||
* vaddr - The virtual address of the start of the region to span. Must
|
||||
* be aligned to 1Mb section boundaries (modified)
|
||||
* npages - Number of pages to required to span that memory region (modified)
|
||||
* mmuflags - L1 MMU flags to use
|
||||
*
|
||||
* Scratch registers (modified): vaddr
|
||||
*
|
||||
* Return:
|
||||
* The offset L1 table address is returned in result.
|
||||
*
|
||||
* Assumptions:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
.macro pg_l1addr, l1, vaddr, result
|
||||
|
||||
/* Get result = the L1 table address coresponding to a virtual
|
||||
* address.
|
||||
*/
|
||||
|
||||
lsr \vaddr, \vaddr, #20
|
||||
add \result, \l1, \vaddr, lsl #2
|
||||
.endm
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@ -185,34 +185,36 @@ __start:
|
||||
* effect. First populate the L1 table for the locked and paged
|
||||
* text regions.
|
||||
*
|
||||
* We could probably make the the pg_span and pg_map macros into
|
||||
* We could probably make the the pg_l1span and pg_l2map macros into
|
||||
* call-able subroutines, but we would have to be carefully during
|
||||
* this phase while we are operating in a physical address space.
|
||||
*/
|
||||
|
||||
adr r0, .Ltxtspan
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_span r0, r1, r2, r3, r4
|
||||
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1addr r0, r1, r0
|
||||
pg_l1span r0, r2, r3, r4, r1
|
||||
|
||||
/* Then populate the L2 table for the locked text region only. */
|
||||
|
||||
adr r0, .Ltxtmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_map r0, r1, r2, r3, r4
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
|
||||
/* Make sure that the page table is itself mapped and and read/write-able.
|
||||
* First, populate the L1 table:
|
||||
*/
|
||||
|
||||
adr r0, .Lptabspan
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_span r0, r1, r2, r3, r4
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1addr r0, r1, r0
|
||||
pg_l1span r0, r2, r3, r4, r1
|
||||
|
||||
/* Then populate the L2 table. */
|
||||
|
||||
adr r0, .Lptabmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_map r0, r1, r2, r3, r4
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
|
||||
#else
|
||||
/* Create a virtual single section mapping for the first MB of the .text
|
||||
@ -350,27 +352,29 @@ __start:
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
.Ltxtspan:
|
||||
.long PG_L2_TEXT_PADDR /* Physical address of L2 table */
|
||||
.long PG_TEXT_VBASE /* Virtual address of text base */
|
||||
.long PG_TEXT_NVPAGES /* Total virtual text pages to be mapped */
|
||||
.long PGTABLE_BASE_PADDR /* Physical address of L1 table */
|
||||
.long PG_L2_TEXT_VADDR /* Virtual address of the L2 page table */
|
||||
.long PG_L2_TEXT_PADDR /* Physical address of the L2 page table */
|
||||
.long PG_TEXT_NVPAGES /* Total (virtual) text pages to be mapped */
|
||||
.long MMU_L1_TEXTFLAGS /* L1 MMU flags to use */
|
||||
|
||||
.Ltxtmap:
|
||||
.long PG_L2_LOCKED_PADDR /* Physical address of L2 table */
|
||||
.long PG_LOCKED_PBASE /* Physical address of locked base */
|
||||
.long PG_LOCKED_PBASE /* Physical address of locked base memory */
|
||||
.long CONFIG_PAGING_NLOCKED /* Number of pages in the locked region */
|
||||
.long MMU_L2_TEXTFLAGS /* L2 MMU flags to use */
|
||||
|
||||
.Lptabspan:
|
||||
.long PG_L2_PGTABLE_PADDR /* Physical address of L2 table */
|
||||
.long PGTABLE_BASE_VADDR /* Virtual address of the page table */
|
||||
.long PG_TEXT_NPAGES /* Total mapped page table pages */
|
||||
.long PGTABLE_BASE_PADDR /* Physical address of L1 table */
|
||||
.long PG_L2_PGTABLE_VADDR /* Virtual address of the L2 page table */
|
||||
.long PG_L2_PGTABLE_PADDR /* Physical address of the L2 page table */
|
||||
.long PG_PGTABLE_NPAGES /* Total mapped page table pages */
|
||||
.long MMU_L1_PGTABFLAGS /* L1 MMU flags to use */
|
||||
|
||||
.Lptabmap:
|
||||
.long PG_L2_PGTABLE_PADDR /* Physical address of L2 table */
|
||||
.long PGTABLE_BASE_PADDR /* Physical address of the page table */
|
||||
.long CONFIG_PAGING_NLOCKED /* Total mapped page table pages */
|
||||
.long PGTABLE_BASE_PADDR /* Physical address of the page table memory */
|
||||
.long PG_PGTABLE_NPAGES /* Total mapped page table pages */
|
||||
.long MMU_L2_PGTABFLAGS /* L2 MMU flags to use */
|
||||
#endif
|
||||
.size _start, .-_start
|
||||
@ -403,14 +407,15 @@ __start:
|
||||
/* Populate the L1 table for the data regions */
|
||||
|
||||
adr r0, .Ldataspan
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_span r0, r1, r2, r3, r4
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1addr r0, r1, r0
|
||||
pg_l1span r0, r2, r3, r4, r1
|
||||
|
||||
/* Populate the L2 table for the data region */
|
||||
|
||||
adr r0, .Ldatamap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_map r0, r1, r2, r3, r4
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
|
||||
#elif defined(CONFIG_BOOT_RUNFROMFLASH)
|
||||
# error "Logic not implemented"
|
||||
@ -508,14 +513,15 @@ __start:
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
.Ldataspan:
|
||||
.long PG_L2_DATA_PADDR /* Physical address of L2 table */
|
||||
.long PG_DATA_PBASE /* Physical address of data base */
|
||||
.long PGTABLE_BASE_VADDR /* Virtual address of the L1 table */
|
||||
.long PG_L2_DATA_VADDR /* Virtual address of the L2 page table */
|
||||
.long PG_L2_DATA_PADDR /* Physical address of the L2 page table */
|
||||
.long PG_DATA_NPAGED /* Number of pages in the data region */
|
||||
.long MMU_L1_DATAFLAGS /* L1 MMU flags to use */
|
||||
|
||||
.Ldatamap:
|
||||
.long PG_L2_DATA_PADDR /* Physical address of L2 table */
|
||||
.long PG_DATA_VBASE /* Virtual address of data base */
|
||||
.long PG_L2_DATA_VADDR /* Virtual address of L2 table */
|
||||
.long PG_DATA_VBASE /* Virtual address of data memory */
|
||||
.long PG_DATA_NPAGED /* Number of pages in the data region */
|
||||
.long MMU_L2_DATAFLAGS /* L2 MMU flags to use */
|
||||
#endif
|
||||
|
@ -54,19 +54,7 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
# ifndef CONFIG_PAGING_PAGESIZE
|
||||
# error "CONFIG_PAGING_PAGESIZE is not defined in your .config file"
|
||||
# endif
|
||||
# ifndef CONFIG_PAGING_NLOCKED
|
||||
# error "CONFIG_PAGING_NLOCKED is not defined in your .config file"
|
||||
# endif
|
||||
# ifndef CONFIG_PAGING_NPAGES
|
||||
# error "CONFIG_PAGING_NPAGES is not defined in your .config file"
|
||||
# endif
|
||||
#endif
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
|
Loading…
x
Reference in New Issue
Block a user