summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/transitions/librm.S
diff options
context:
space:
mode:
authorMichael Brown2016-02-26 16:34:28 +0100
committerMichael Brown2016-02-26 16:34:28 +0100
commit99b5216b1c71dba22dab734e0945887525493cde (patch)
tree30829acea232821f26d7bfb38aac5c089e252ef8 /src/arch/x86/transitions/librm.S
parent[ioapi] Split ioremap() out to a separate IOMAP API (diff)
downloadipxe-99b5216b1c71dba22dab734e0945887525493cde.tar.gz
ipxe-99b5216b1c71dba22dab734e0945887525493cde.tar.xz
ipxe-99b5216b1c71dba22dab734e0945887525493cde.zip
[librm] Support ioremap() for addresses above 4GB in a 64-bit build
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/x86/transitions/librm.S')
-rw-r--r--src/arch/x86/transitions/librm.S17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/arch/x86/transitions/librm.S b/src/arch/x86/transitions/librm.S
index dbb0b084..bb04ad67 100644
--- a/src/arch/x86/transitions/librm.S
+++ b/src/arch/x86/transitions/librm.S
@@ -1340,11 +1340,19 @@ interrupt_wrapper:
* These point to the PDPT. This creates some aliased
* addresses within unused portions of the 64-bit address
* space, but allows us to use just a single PDPT.
+ *
+ * - PDE[...] covering arbitrary 2MB portions of I/O space
+ *
+ * These are 2MB pages created by ioremap() to cover I/O
+ * device addresses.
*/
pml4e:
.space SIZEOF_PT
.size pml4e, . - pml4e
+ .globl io_pages
+ .equ io_pages, pml4e
+
/* Page directory pointer table entries (PDPTEs)
*
* This comprises:
@@ -1357,6 +1365,11 @@ pml4e:
* These point to the appropriate page directories (in pde_low)
* used to identity-map the whole of the 32-bit address space.
*
+ * - PDPTE[0x004] covering [0x0000000100000000-0x000000013fffffff]
+ *
+ * This points back to the PML4, allowing the PML4 to be
+ * (ab)used to hold 2MB pages used for I/O device addresses.
+ *
* - PDPTE[0x1ff] covering [0xffffffffc0000000-0xffffffffffffffff]
*
* This points back to the PDPT itself, allowing the PDPT to be
@@ -1421,6 +1434,10 @@ init_pages:
/* Initialise PDPTE for negative 1GB */
movl %eax, ( VIRTUAL(pdpte) + SIZEOF_PT - SIZEOF_PTE )
+ /* Initialise PDPTE for I/O space */
+ leal ( VIRTUAL(pml4e) + ( PG_P | PG_RW | PG_US ) )(%edi), %eax
+ movl %eax, ( VIRTUAL(pdpte) + ( PDE_LOW_PTS * SIZEOF_PTE ) )
+
/* Initialise PDPTEs for low 4GB */
movl $PDE_LOW_PTS, %ecx
leal ( VIRTUAL(pde_low) + ( PDE_LOW_PTS * SIZEOF_PT ) + \