diff --git a/arch/arm/src/arm/pg_macros.h b/arch/arm/src/arm/pg_macros.h index 06a4faf4d7..f8d973d7e6 100644 --- a/arch/arm/src/arm/pg_macros.h +++ b/arch/arm/src/arm/pg_macros.h @@ -127,14 +127,23 @@ #define PT_SIZE (4*PTE_NPAGES) -/* We position the locked region PTEs at the beginning of L2 page - * table. +/* We position the locked region PTEs at an offset into the first + * L2 page table. The L1 entry points to an 1Mb aligned virtual + * address. The actual L2 entry will be offset into the aligned + * L2 table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * OFFSET=(((a) & 0x000fffff) >> 12) << 2) + * Fine: PG_L1_PADDRMASK=0xfffff000 + * OFFSET=(((a) & 0x000fffff) >> 10) << 2) */ #define PG_L1_LOCKED_PADDR (PGTABLE_BASE_PADDR + ((PG_LOCKED_VBASE >> 20) << 2)) #define PG_L1_LOCKED_VADDR (PGTABLE_BASE_VADDR + ((PG_LOCKED_VBASE >> 20) << 2)) -#define PG_L2_LOCKED_PADDR PGTABLE_L2_BASE_PADDR -#define PG_L2_LOCKED_VADDR PGTABLE_L2_BASE_VADDR + +#define PG_L2_LOCKED_OFFSET (((PG_LOCKED_PBASE & 0x000fffff) >> PAGESHIFT) << 2) +#define PG_L2_LOCKED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_OFFSET) #define PG_L2_LOCKED_SIZE (4*CONFIG_PAGING_NLOCKED) /* We position the paged region PTEs immediately after the locked @@ -145,14 +154,16 @@ #define PG_L1_PAGED_PADDR (PGTABLE_BASE_PADDR + ((PG_PAGED_VBASE >> 20) << 2)) #define PG_L1_PAGED_VADDR (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) -#define PG_L2_PAGED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_SIZE) -#define PG_L2_PAGED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_SIZE) + +#define PG_L2_PAGED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_SIZE + PG_L2_LOCKED_OFFSET) +#define PG_L2_PAGED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_SIZE + PG_L2_LOCKED_OFFSET) #define PG_L2_PAGED_SIZE (4*CONFIG_PAGING_NVPAGED) /* This describes the overall text region */ #define PG_L1_TEXT_PADDR PG_L1_LOCKED_PADDR #define PG_L1_TEXT_VADDR PG_L1_LOCKED_VADDR + #define PG_L2_TEXT_PADDR PG_L2_LOCKED_PADDR #define PG_L2_TEXT_VADDR PG_L2_LOCKED_VADDR #define PG_L2_TEXT_SIZE (PG_L2_LOCKED_SIZE + PG_L2_PAGED_SIZE) @@ -161,8 +172,9 @@ #define PG_L1_DATA_PADDR (PGTABLE_BASE_PADDR + ((PG_DATA_VBASE >> 20) << 2)) #define PG_L1_DATA_VADDR (PGTABLE_BASE_VADDR + ((PG_DATA_VBASE >> 20) << 2)) -#define PG_L2_DATA_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_TEXT_SIZE) -#define PG_L2_DATA_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_TEXT_SIZE) + +#define PG_L2_DATA_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_TEXT_SIZE + PG_L2_LOCKED_OFFSET) +#define PG_L2_DATA_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_TEXT_SIZE + PG_L2_LOCKED_OFFSET) #define PG_L2_DATA_SIZE (4*PG_DATA_NPAGES) /* Page Table Info: The number of pages in the in the page table @@ -173,8 +185,9 @@ #define PG_PGTABLE_NPAGES (PGTABLE_SIZE >> PAGESHIFT) #define PG_L1_PGTABLE_PADDR (PGTABLE_BASE_PADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) #define PG_L1_PGTABLE_VADDR (PGTABLE_BASE_VADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) -#define PG_L2_PGTABLE_PADDR (PG_L2_DATA_PADDR + PG_L2_DATA_SIZE) -#define PG_L2_PGTABLE_VADDR (PG_L2_DATA_VADDR + PG_L2_DATA_SIZE) + +#define PG_L2_PGTABLE_PADDR (PG_L2_DATA_PADDR + PG_L2_DATA_SIZE + PG_L2_LOCKED_OFFSET) +#define PG_L2_PGTABLE_VADDR (PG_L2_DATA_VADDR + PG_L2_DATA_SIZE + PG_L2_LOCKED_OFFSET) #define PG_L2_PGTABLE_SIZE (4*PG_DATA_NPAGES) /* Vector mapping. One page is required to map the vector table. The @@ -383,20 +396,23 @@ * * ldr r0, =PG_L1_PGTABLE_PADDR <-- Address in the L1 table * ldr r1, =PG_L2_PGTABLE_PADDR <-- Physical address of L2 page table - * ldr r2, =PG_PGTABLE_NPAGES <-- Number of pages - * ldr r3, =MMU_L1_PGTABFLAGS <-- L1 MMU flags - * pg_l1span r0, r1, r2, r3, r4 + * ldr r2, =PG_PGTABLE_NPAGES <-- Total number of pages + * ldr r3, =PG_PGTABLE_NPAGE1 <-- Number of pages in the first PTE + * ldr r4, =MMU_L1_PGTABFLAGS <-- L1 MMU flags + * pg_l1span r0, r1, r2, r3, r4, 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) * npages - Number of pages to required to span that memory region (modified) + * ppage - The number of pages in page 1 (modified) * mmuflags - L1 MMU flags to use * * 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 + * ppage - After the first page, this will be the full number of pages. * tmp - scratch * * Return: @@ -409,7 +425,7 @@ ****************************************************************************/ #ifdef CONFIG_PAGING - .macro pg_l1span, l1, l2, npages, mmuflags, tmp + .macro pg_l1span, l1, l2, npages, ppage, mmuflags, tmp b 2f 1: /* Write the L1 table entry that refers to this (unmapped) coarse page @@ -431,10 +447,12 @@ add \l2, \l2, #PT_SIZE /* Next L2 page table start address */ /* Update the number of pages that we have account for (with - * non-mappings + * non-mappings). NOTE that the first page may have fewer than + * the maximum entries per page table. */ - sub \npages, \npages, #PTE_NPAGES + sub \npages, \npages, \ppage + mov \ppage, #PTE_NPAGES 2: /* Check if all of the pages have been written. If not, then * loop and write the next L1 entry. diff --git a/arch/arm/src/arm/up_head.S b/arch/arm/src/arm/up_head.S index 9e1f8440c6..15d5a8a41d 100644 --- a/arch/arm/src/arm/up_head.S +++ b/arch/arm/src/arm/up_head.S @@ -126,6 +126,25 @@ #endif +/* For each page table offset, the following provide (1) the physical address of + * the start of the page table and (2) the number of page table entries in the + * first page table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * NPAGE1=(256 -((a) & 0x000003ff) >> 2) NPAGE1=1-256 + * Fine: PG_L1_PADDRMASK=0xfffff000 + * NPAGE1=(1024 -((a) & 0x00000fff) >> 2) NPAGE1=1-1024 + */ + +#ifdef CONFIG_PAGING +# define PG_L2_TEXT_PBASE (PG_L2_TEXT_PADDR & PG_L1_PADDRMASK) +# define PG_L2_TEXT_NPAGE1 (PTE_NPAGES - ((PG_L2_TEXT_PADDR & ~PG_L1_PADDRMASK) >> 2)) +# define PG_L2_PGTABLE_PBASE (PG_L2_PGTABLE_PADDR & PG_L1_PADDRMASK) +# define PG_L2_PGTABLE_NPAGE1 (PTE_NPAGES - ((PG_L2_PGTABLE_PADDR & ~PG_L1_PADDRMASK) >> 2)) +# define PG_L2_DATA_PBASE (PG_L2_DATA_PADDR & PG_L1_PADDRMASK) +# define PG_L2_DATA_NPAGE1 (PTE_NPAGES - ((PG_L2_DATA_PADDR & ~PG_L1_PADDRMASK) >> 2)) +#endif + /**************************************************************************** * Definitions ****************************************************************************/ @@ -227,6 +246,7 @@ __start: #endif #ifdef CONFIG_PAGING + /* Map the read-only .text region in place. This must be done * before the MMU is enabled and the virtual addressing takes * effect. First populate the L1 table for the locked and paged @@ -241,8 +261,8 @@ __start: */ adr r0, .Ltxtspan - ldmia r0, {r0, r1, r2, r3} - pg_l1span r0, r1, r2, r3, r5 + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 /* Then populate the L2 table for the locked text region only. */ @@ -255,8 +275,8 @@ __start: */ adr r0, .Lptabspan - ldmia r0, {r0, r1, r2, r3} - pg_l1span r0, r1, r2, r3, r5 + ldmia r0, {r0, r1, r2, r3, r5} + pg_l1span r0, r1, r2, r3, r5, r6 /* Then populate the L2 table. */ @@ -286,6 +306,7 @@ __start: #endif /* CONFIG_PAGING */ #endif /* CONFIG_ARCH_ROMPGTABLE */ + /* The following logic will set up the ARM920/ARM926 for normal operation. * * Here we expect to have: @@ -413,24 +434,26 @@ __start: .Ltxtspan: .long PG_L1_TEXT_PADDR /* Physical address in the L1 table */ - .long PG_L2_TEXT_PADDR /* Physical address of the L2 page table */ + .long PG_L2_TEXT_PBASE /* Physical address of the start of the L2 page table */ .long PG_TEXT_NVPAGES /* Total (virtual) text pages to be mapped */ + .long PG_L2_TEXT_NPAGE1 /* The number of text pages in the first page table */ .long MMU_L1_TEXTFLAGS /* L1 MMU flags to use */ .Ltxtmap: - .long PG_L2_LOCKED_PADDR /* Physical address of L2 table */ + .long PG_L2_LOCKED_PADDR /* Physical address in the L2 table */ .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_L1_PGTABLE_PADDR /* Physical address in the L1 table */ - .long PG_L2_PGTABLE_PADDR /* Physical address of the L2 page table */ + .long PG_L2_PGTABLE_PBASE /* Physical address of the start of the L2 page table */ .long PG_PGTABLE_NPAGES /* Total mapped page table pages */ + .long PG_L2_PGTABLE_NPAGE1 /* The number of text pages in the first page table */ .long MMU_L1_PGTABFLAGS /* L1 MMU flags to use */ .Lptabmap: - .long PG_L2_PGTABLE_PADDR /* Physical address of L2 table */ + .long PG_L2_PGTABLE_PADDR /* Physical address in the L2 table */ .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 */ @@ -455,6 +478,7 @@ __start: * cover additinal RAM sections. */ + #ifndef CONFIG_ARCH_ROMPGTABLE #ifndef CONFIG_IDENTITY_TEXTMAP ldr r4, .LCvpgtable /* r4=virtual page table */ @@ -468,8 +492,8 @@ __start: /* Populate the L1 table for the data region */ adr r0, .Ldataspan - ldmia r0, {r0, r1, r2, r3} - pg_l1span r0, r1, r2, r3, r4 + ldmia r0, {r0, r1, r2, r3, r4} + pg_l1span r0, r1, r2, r3, r4, r5 /* Populate the L2 table for the data region */ @@ -576,12 +600,13 @@ __start: .Ldataspan: .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ - .long PG_L2_DATA_PADDR /* Physical address of the L2 page table */ + .long PG_L2_DATA_PBASE /* Physical address of the start of the L2 page table */ .long PG_DATA_NPAGES /* Number of pages in the data region */ + .long PG_L2_DATA_NPAGE1 /* The number of text pages in the first page table */ .long MMU_L1_DATAFLAGS /* L1 MMU flags to use */ .Ldatamap: - .long PG_L2_DATA_VADDR /* Virtual address of L2 table */ + .long PG_L2_DATA_VADDR /* Virtual address in the L2 table */ .long PG_DATA_VBASE /* Virtual address of data memory */ .long PG_DATA_NPAGES /* Number of pages in the data region */ .long MMU_L2_DATAFLAGS /* L2 MMU flags to use */