aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/x86/include
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2016-02-26 15:34:28 +0000
committerMichael Brown <mcb30@ipxe.org>2016-02-26 15:34:28 +0000
commit99b5216b1c71dba22dab734e0945887525493cde (patch)
tree30829acea232821f26d7bfb38aac5c089e252ef8 /src/arch/x86/include
parent5bd8427d3dad38993c1f8f175454f7fde0af34ca (diff)
downloadipxe-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.h2
-rw-r--r--src/arch/x86/include/ipxe/iomap_pages.h24
-rw-r--r--src/arch/x86/include/librm.h45
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 */