Author: andrew
Date: Thu Feb 13 21:30:54 2014
New Revision: 261855
URL: http://svnweb.freebsd.org/changeset/base/261855

Log:
  Allow the kernel to be loaded at any 1MiB address. This requirement is
  because we use the 1MiB section maps as they only need a single pagetable.
  
  To allow this we only use pc relative loads to ensure we only load from
  physical addresses until we are running from a known virtual address.
  
  As a side effect any data from before or 64MiB after the kernel needs to
  be mapped in to be used. This should not be an issue for kernels loaded
  with ubldr as it places this data just after the kernel. It will be a
  problem when loading directly from anything using the Linux ABI that
  places the ATAG data outside this range, for example U-Boot.

Modified:
  head/sys/arm/arm/locore.S

Modified: head/sys/arm/arm/locore.S
==============================================================================
--- head/sys/arm/arm/locore.S   Thu Feb 13 20:41:25 2014        (r261854)
+++ head/sys/arm/arm/locore.S   Thu Feb 13 21:30:54 2014        (r261855)
@@ -148,15 +148,31 @@ Lunmapped:
         * Build page table from scratch.
         */
 
-       /* Load the page tables physical address */
-       ldr     r1, Lstartup_pagetable
-       ldr     r2, =(KERNVIRTADDR - KERNPHYSADDR)
+       /* Find the delta between VA and PA */
+       adr     r0, Lpagetable
+       ldr     r1, [r0]
+       sub     r2, r1, r0
+       /* At this point: r2 = VA - PA */
+
+       /*
+        * Find the physical address of the table. After these two
+        * instructions:
+        * r1 = va(pagetable)
+        *
+        * r0 = va(pagetable) - (VA - PA)
+        *    = va(pagetable) - VA + PA
+        *    = pa(pagetable)
+        */
+       ldr     r1, [r0, #4]
        sub     r0, r1, r2
 
        /*
         * Map PA == VA
         */
-       ldr     r5, =(PHYSADDR)
+       /* Find the start kernels load address */
+       adr     r5, _start
+       ldr     r2, =(L1_S_OFFSET)
+       bic     r5, r2
        mov     r1, r5
        mov     r2, r5
        /* Map 64MiB, preserved over calls to build_pagetables */
@@ -165,7 +181,7 @@ Lunmapped:
 
        /* Create the kernel map to jump to */
        mov     r1, r5
-       ldr     r2, =(KERNBASE)
+       ldr     r2, =(KERNVIRTADDR)
        bl      build_pagetables
        
 #if defined(SOCDEV_PA) && defined(SOCDEV_VA)
@@ -223,16 +239,16 @@ mmu_done:
 virt_done:
        mov     r1, #28                 /* loader info size is 28 bytes also 
second arg */
        subs    sp, sp, r1              /* allocate arm_boot_params struct on 
stack */
-       bic     sp, sp, #7              /* align stack to 8 bytes */
        mov     r0, sp                  /* loader info pointer is first arg */
+       bic     sp, sp, #7              /* align stack to 8 bytes */
        str     r1, [r0]                /* Store length of loader info */
        str     r9, [r0, #4]            /* Store r0 from boot loader */
        str     r8, [r0, #8]            /* Store r1 from boot loader */
        str     ip, [r0, #12]           /* store r2 from boot loader */
        str     fp, [r0, #16]           /* store r3 from boot loader */
-       ldr     r5, =KERNPHYSADDR       /* load KERNPHYSADDR as the physical 
address */
        str     r5, [r0, #20]           /* store the physical address */
-       ldr     r5, Lstartup_pagetable
+       adr     r4, Lpagetable          /* load the pagetable address */
+       ldr     r5, [r4, #4]
        str     r5, [r0, #24]           /* store the pagetable address */
        mov     fp, #0                  /* trace back starts here */
        bl      _C_LABEL(initarm)       /* Off we go */
@@ -279,16 +295,19 @@ build_pagetables:
 
        RET
 
+Lpagetable:
+       .word   .
+       .word   pagetable
+
 Lvirtaddr:
        .word   KERNVIRTADDR
 Lphysaddr:
        .word   KERNPHYSADDR
 Lreal_start:
        .word   _start
-Lend:  
+Lend:
        .word   _edata
-Lstartup_pagetable:
-       .word   pagetable
+
 #ifdef SMP
 Lstartup_pagetable_secondary:
        .word   temp_pagetable
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to