summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2011-03-16 03:53:18 +0000
committermarcel <marcel@FreeBSD.org>2011-03-16 03:53:18 +0000
commit8e0b0a22844d3d1383011c024b1eb1a3b2ee51a8 (patch)
tree55215f77e655236a449e347f8f98d98dfb718eed /sys/ia64
parente79931d6175d1a1999786ee313a144784de8d6a9 (diff)
downloadFreeBSD-src-8e0b0a22844d3d1383011c024b1eb1a3b2ee51a8.zip
FreeBSD-src-8e0b0a22844d3d1383011c024b1eb1a3b2ee51a8.tar.gz
MFaltix:
Add support for Pre-Boot Virtual Memory (PBVM) to the loader. PBVM allows us to link the kernel at a fixed virtual address without having to make any assumptions about the physical memory layout. On the SGI Altix 350 for example, there's no usuable physical memory below 192GB. Also, the PBVM allows us to control better where we're going to physically load the kernel and its modules so that we can make sure we load the kernel in memory that's close to the BSP. The PBVM is managed by a simple page table. The minimum size of the page table is 4KB (EFI page size) and the maximum is currently set to 1MB. A page in the PBVM is 64KB, as that's the maximum alignment one can specify in a linker script. The bottom line is that PBVM is between 64KB and 8GB in size. The loader maps the PBVM page table at a fixed virtual address and using a single translations. The PBVM itself is also mapped using a single translation for a maximum of 32MB. While here, increase the heap in the EFI loader from 512KB to 2MB and set the stage for supporting relocatable modules.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/include/bootinfo.h5
-rw-r--r--sys/ia64/include/vmparam.h46
2 files changed, 49 insertions, 2 deletions
diff --git a/sys/ia64/include/bootinfo.h b/sys/ia64/include/bootinfo.h
index 2a065e9..6b14d1a 100644
--- a/sys/ia64/include/bootinfo.h
+++ b/sys/ia64/include/bootinfo.h
@@ -30,7 +30,8 @@ struct bootinfo {
uint64_t bi_magic; /* BOOTINFO_MAGIC */
#define BOOTINFO_MAGIC 0xdeadbeeffeedface
uint64_t bi_version; /* version 1 */
- uint64_t bi_spare[6]; /* was: name of booted kernel */
+ uint64_t bi_spare[5]; /* was: name of booted kernel */
+ uint64_t bi_pbvm_pgtbl; /* PA of PBVM page table. */
uint64_t bi_hcdp; /* DIG64 HCDP table */
uint64_t bi_fpswa; /* FPSWA interface */
uint64_t bi_boothowto; /* value for boothowto */
@@ -39,7 +40,7 @@ struct bootinfo {
uint64_t bi_memmap_size; /* size of EFI memory map */
uint64_t bi_memdesc_size; /* sizeof EFI memory desc */
uint32_t bi_memdesc_version; /* EFI memory desc version */
- uint32_t bi_spare2;
+ uint32_t bi_pbvm_pgtblsz; /* PBVM page table size. */
uint64_t bi_symtab; /* start of kernel sym table */
uint64_t bi_esymtab; /* end of kernel sym table */
uint64_t bi_kernend; /* end of kernel space */
diff --git a/sys/ia64/include/vmparam.h b/sys/ia64/include/vmparam.h
index edf5710..169b0c9 100644
--- a/sys/ia64/include/vmparam.h
+++ b/sys/ia64/include/vmparam.h
@@ -131,6 +131,16 @@
#define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7))
/*
+ * The Itanium architecture defines that all implementations support at
+ * least 51 virtual address bits (i.e. IMPL_VA_MSB=50). The unimplemented
+ * bits are sign-extended from VA{IMPL_VA_MSB}. As such, there's a gap in
+ * the virtual address range, which extends at most from 0x0004000000000000
+ * to 0x1ffbffffffffffff. We define the top half of a region in terms of
+ * this worst-case gap.
+ */
+#define IA64_REGION_TOP_HALF 0x1ffc000000000000
+
+/*
* Page size of the identity mappings in region 7.
*/
#ifndef LOG2_ID_PAGE_SIZE
@@ -144,6 +154,42 @@
#define IA64_BACKINGSTORE IA64_RR_BASE(4)
/*
+ * Parameters for Pre-Boot Virtual Memory (PBVM).
+ * The kernel, its modules and metadata are loaded in the PBVM by the loader.
+ * The PBVM consists of pages for which the mapping is maintained in a page
+ * table. The page table is at least 1 EFI page large (i.e. 4KB), but can be
+ * larger to accommodate more PBVM. The maximum page table size is 1MB. With
+ * 8 bytes per page table entry, this means that the PBVM has at least 512
+ * pages and at most 128K pages.
+ * The GNU toolchain (in particular GNU ld) does not support an alignment
+ * larger than 64K. This means that we cannot guarantee page alignment for
+ * a page size that's larger than 64K. We do want to have text and data in
+ * different pages, which means that the maximum usable page size is 64KB.
+ * Consequently:
+ * The maximum total PBVM size is 8GB -- enough for a DVD image. A page table
+ * of a single EFI page (4KB) allows for 32MB of PBVM.
+ *
+ * The kernel is given the PA and size of the page table that provides the
+ * mapping of the PBVM. The page table itself is assumed to be mapped at a
+ * known virtual address and using a single translation wired into the CPU.
+ * As such, the page table is assumed to be a power of 2 and naturally aligned.
+ * The kernel also assumes that a good portion of the kernel text is mapped
+ * and wired into the CPU, but does not assume that the mapping covers the
+ * whole of PBVM.
+ */
+#define IA64_PBVM_RR 4
+#define IA64_PBVM_BASE \
+ (IA64_RR_BASE(IA64_PBVM_RR) + IA64_REGION_TOP_HALF)
+
+#define IA64_PBVM_PGTBL_MAXSZ 1048576
+#define IA64_PBVM_PGTBL \
+ (IA64_RR_BASE(IA64_PBVM_RR + 1) - IA64_PBVM_PGTBL_MAXSZ)
+
+#define IA64_PBVM_PAGE_SHIFT 16 /* 64KB */
+#define IA64_PBVM_PAGE_SIZE (1 << IA64_PBVM_PAGE_SHIFT)
+#define IA64_PBVM_PAGE_MASK (IA64_PBVM_PAGE_SIZE - 1)
+
+/*
* Mach derived constants
*/
OpenPOWER on IntegriCloud