diff options
author | Michael Brown <mcb30@ipxe.org> | 2016-02-26 15:34:28 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2016-02-26 15:34:28 +0000 |
commit | 99b5216b1c71dba22dab734e0945887525493cde (patch) | |
tree | 30829acea232821f26d7bfb38aac5c089e252ef8 /src/arch/x86/include | |
parent | 5bd8427d3dad38993c1f8f175454f7fde0af34ca (diff) | |
download | ipxe-99b5216b1c71dba22dab734e0945887525493cde.tar.gz |
[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/include')
-rw-r--r-- | src/arch/x86/include/bits/iomap.h | 2 | ||||
-rw-r--r-- | src/arch/x86/include/ipxe/iomap_pages.h | 24 | ||||
-rw-r--r-- | src/arch/x86/include/librm.h | 45 |
3 files changed, 71 insertions, 0 deletions
diff --git a/src/arch/x86/include/bits/iomap.h b/src/arch/x86/include/bits/iomap.h index 6110e3187..d6fff257e 100644 --- a/src/arch/x86/include/bits/iomap.h +++ b/src/arch/x86/include/bits/iomap.h @@ -9,4 +9,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include <ipxe/iomap_pages.h> + #endif /* _BITS_IOMAP_H */ diff --git a/src/arch/x86/include/ipxe/iomap_pages.h b/src/arch/x86/include/ipxe/iomap_pages.h new file mode 100644 index 000000000..18e0a3002 --- /dev/null +++ b/src/arch/x86/include/ipxe/iomap_pages.h @@ -0,0 +1,24 @@ +#ifndef _IPXE_IOMAP_PAGES_H +#define _IPXE_IOMAP_PAGES_H + +/** @file + * + * I/O mapping API using page tables + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#ifdef IOMAP_PAGES +#define IOMAP_PREFIX_pages +#else +#define IOMAP_PREFIX_pages __pages_ +#endif + +static inline __always_inline unsigned long +IOMAP_INLINE ( pages, io_to_bus ) ( volatile const void *io_addr ) { + /* Not easy to do; just return the CPU address for debugging purposes */ + return ( ( intptr_t ) io_addr ); +} + +#endif /* _IPXE_IOMAP_PAGES_H */ diff --git a/src/arch/x86/include/librm.h b/src/arch/x86/include/librm.h index 02d3081b4..311748bec 100644 --- a/src/arch/x86/include/librm.h +++ b/src/arch/x86/include/librm.h @@ -378,6 +378,51 @@ struct interrupt_vector { extern void set_interrupt_vector ( unsigned int intr, void *vector ); +/** A page table */ +struct page_table { + /** Page address and flags */ + uint64_t page[512]; +}; + +/** Page flags */ +enum page_flags { + /** Page is present */ + PAGE_P = 0x01, + /** Page is writable */ + PAGE_RW = 0x02, + /** Page is accessible by user code */ + PAGE_US = 0x04, + /** Page-level write-through */ + PAGE_PWT = 0x08, + /** Page-level cache disable */ + PAGE_PCD = 0x10, + /** Page is a large page */ + PAGE_PS = 0x80, + /** Page is the last page in an allocation + * + * This bit is ignored by the hardware. We use it to track + * the size of allocations made by ioremap(). + */ + PAGE_LAST = 0x800, +}; + +/** The I/O space page table */ +extern struct page_table io_pages; + +/** I/O page size + * + * We choose to use 2MB pages for I/O space, to minimise the number of + * page table entries required. + */ +#define IO_PAGE_SIZE 0x200000UL + +/** I/O page base address + * + * We choose to place I/O space immediately above the identity-mapped + * 32-bit address space. + */ +#define IO_BASE ( ( void * ) 0x100000000ULL ) + #endif /* ASSEMBLY */ #endif /* LIBRM_H */ |