diff options
author | Michael Brown | 2016-02-26 16:34:28 +0100 |
---|---|---|
committer | Michael Brown | 2016-02-26 16:34:28 +0100 |
commit | 99b5216b1c71dba22dab734e0945887525493cde (patch) | |
tree | 30829acea232821f26d7bfb38aac5c089e252ef8 /src/arch/x86/transitions/librm.S | |
parent | [ioapi] Split ioremap() out to a separate IOMAP API (diff) | |
download | ipxe-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.S | 17 |
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 ) + \ |