xref: /cloud-hypervisor/arch/src/x86_64/layout.rs (revision 7d7bfb2034001d4cb15df2ddc56d2d350c8da30f)
1 // Copyright © 2020, Oracle and/or its affiliates.
2 //
3 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 // SPDX-License-Identifier: Apache-2.0
5 //
6 // Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE-BSD-3-Clause file.
9 
10 use vm_memory::GuestAddress;
11 
12 /*
13 
14 Memory layout documentation and constants
15 ~~~~~~ ~~~~~~ ~~~~~~~~~~~~~ ~~~ ~~~~~~~~~
16 
17 Constants are in order and grouped by range. Take care to update all references
18 when making changes and keep them in order.
19 
20 */
21 
22 // ** Low RAM (start: 0, length: 640KiB) **
23 pub const LOW_RAM_START: GuestAddress = GuestAddress(0x0);
24 
25 // == Fixed addresses within the "Low RAM" range: ==
26 
27 // Location of EBDA address
28 pub const EBDA_POINTER: GuestAddress = GuestAddress(0x40e);
29 
30 // Initial GDT/IDT needed to boot kernel
31 pub const BOOT_GDT_START: GuestAddress = GuestAddress(0x500);
32 pub const BOOT_IDT_START: GuestAddress = GuestAddress(0x520);
33 
34 /// Address for the hvm_start_info struct used in PVH boot
35 pub const PVH_INFO_START: GuestAddress = GuestAddress(0x6000);
36 
37 /// Starting address of array of modules of hvm_modlist_entry type.
38 /// Used to enable initrd support using the PVH boot ABI.
39 pub const MODLIST_START: GuestAddress = GuestAddress(0x6040);
40 
41 /// Address of memory map table used in PVH boot. Can overlap
42 /// with the zero page address since they are mutually exclusive.
43 pub const MEMMAP_START: GuestAddress = GuestAddress(0x7000);
44 
45 /// The 'zero page', a.k.a linux kernel bootparams.
46 pub const ZERO_PAGE_START: GuestAddress = GuestAddress(0x7000);
47 
48 /// Initial stack for the boot CPU.
49 pub const BOOT_STACK_START: GuestAddress = GuestAddress(0x8000);
50 pub const BOOT_STACK_POINTER: GuestAddress = GuestAddress(0x8ff0);
51 
52 // Initial pagetables.
53 pub const PML5_START: GuestAddress = GuestAddress(0x9000);
54 pub const PML4_START: GuestAddress = GuestAddress(0xa000);
55 pub const PDPTE_START: GuestAddress = GuestAddress(0xb000);
56 pub const PDE_START: GuestAddress = GuestAddress(0xc000);
57 
58 /// Kernel command line start address.
59 pub const CMDLINE_START: GuestAddress = GuestAddress(0x20000);
60 /// Kernel command line start address maximum size.
61 pub const CMDLINE_MAX_SIZE: usize = 0x10000;
62 
63 // MPTABLE, describing VCPUS.
64 pub const MPTABLE_START: GuestAddress = GuestAddress(0x9fc00);
65 
66 // == End of "Low RAM" range. ==
67 
68 // ** EBDA reserved area (start: 640KiB, length: 384KiB) **
69 pub const EBDA_START: GuestAddress = GuestAddress(0xa0000);
70 
71 // == Fixed constants within the "EBDA" range ==
72 
73 // ACPI RSDP table
74 pub const RSDP_POINTER: GuestAddress = EBDA_START;
75 
76 pub const SMBIOS_START: u64 = 0xf0000; // First possible location per the spec.
77 
78 // == End of "EBDA" range ==
79 
80 // ** High RAM (start: 1MiB, length: 3071MiB) **
81 pub const HIGH_RAM_START: GuestAddress = GuestAddress(0x100000);
82 
83 // == No fixed addresses in the "High RAM" range ==
84 
85 // ** 32-bit reserved area (start: 3GiB, length: 896MiB) **
86 pub const MEM_32BIT_RESERVED_START: GuestAddress = GuestAddress(0xc000_0000);
87 pub const MEM_32BIT_RESERVED_SIZE: u64 = PCI_MMCONFIG_SIZE + MEM_32BIT_DEVICES_SIZE;
88 
89 // == Fixed constants within the "32-bit reserved" range ==
90 
91 // Sub range: 32-bit PCI devices (start: 3GiB, length: 640Mib)
92 pub const MEM_32BIT_DEVICES_START: GuestAddress = MEM_32BIT_RESERVED_START;
93 pub const MEM_32BIT_DEVICES_SIZE: u64 = 640 << 20;
94 
95 // PCI MMCONFIG space (start: after the device space, length: 256MiB)
96 pub const PCI_MMCONFIG_START: GuestAddress =
97     GuestAddress(MEM_32BIT_DEVICES_START.0 + MEM_32BIT_DEVICES_SIZE);
98 pub const PCI_MMCONFIG_SIZE: u64 = 256 << 20;
99 // One bus with potentially 256 devices (32 slots x 8 functions).
100 pub const PCI_MMIO_CONFIG_SIZE_PER_SEGMENT: u64 = 4096 * 256;
101 
102 // TSS is 3 pages after the PCI MMCONFIG space
103 pub const KVM_TSS_START: GuestAddress = GuestAddress(PCI_MMCONFIG_START.0 + PCI_MMCONFIG_SIZE);
104 pub const KVM_TSS_SIZE: u64 = (3 * 4) << 10;
105 
106 // Identity map is a one page region after the TSS
107 pub const KVM_IDENTITY_MAP_START: GuestAddress = GuestAddress(KVM_TSS_START.0 + KVM_TSS_SIZE);
108 pub const KVM_IDENTITY_MAP_SIZE: u64 = 4 << 10;
109 
110 // IOAPIC
111 pub const IOAPIC_START: GuestAddress = GuestAddress(0xfec0_0000);
112 pub const IOAPIC_SIZE: u64 = 0x20;
113 
114 // APIC
115 pub const APIC_START: GuestAddress = GuestAddress(0xfee0_0000);
116 
117 // == End of "32-bit reserved" range. ==
118 
119 // ** 64-bit RAM start (start: 4GiB, length: varies) **
120 pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);
121