vmm/arch/x86_64/layout.rs
1// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
5// Use of this source code is governed by a BSD-style license that can be
6// found in the THIRD-PARTY file.
7
8//! Magic addresses externally used to lay out x86_64 VMs.
9
10use crate::device_manager::mmio::MMIO_LEN;
11use crate::utils::mib_to_bytes;
12
13/// Initial stack for the boot CPU.
14pub const BOOT_STACK_POINTER: u64 = 0x8ff0;
15
16/// Kernel command line start address.
17pub const CMDLINE_START: u64 = 0x20000;
18/// Kernel command line maximum size.
19pub const CMDLINE_MAX_SIZE: usize = 2048;
20
21/// Start of the high memory.
22pub const HIMEM_START: u64 = 0x0010_0000; // 1 MB.
23
24// Typically, on x86 systems 24 IRQs are used for legacy devices (0-23).
25// However, the first 5 are reserved.
26// We allocate the remaining GSIs to MSIs.
27/// First usable GSI for legacy interrupts (IRQ) on x86_64.
28pub const GSI_LEGACY_START: u32 = 5;
29/// Last usable GSI for legacy interrupts (IRQ) on x86_64.
30pub const GSI_LEGACY_END: u32 = 23;
31/// Number of legacy GSI (IRQ) available on x86_64.
32pub const GSI_LEGACY_NUM: u32 = GSI_LEGACY_END - GSI_LEGACY_START + 1;
33/// First GSI used by MSI after legacy GSI.
34pub const GSI_MSI_START: u32 = GSI_LEGACY_END + 1;
35/// The highest available GSI in KVM (KVM_MAX_IRQ_ROUTES=4096).
36pub const GSI_MSI_END: u32 = 4095;
37/// Number of GSI available for MSI.
38pub const GSI_MSI_NUM: u32 = GSI_MSI_END - GSI_MSI_START + 1;
39
40/// Address for the TSS setup.
41pub const KVM_TSS_ADDRESS: u64 = 0xfffb_d000;
42
43/// Address of the hvm_start_info struct used in PVH boot
44pub const PVH_INFO_START: u64 = 0x6000;
45
46/// Starting address of array of modules of hvm_modlist_entry type.
47/// Used to enable initrd support using the PVH boot ABI.
48pub const MODLIST_START: u64 = 0x6040;
49
50/// Address of memory map table used in PVH boot. Can overlap
51/// with the zero page address since they are mutually exclusive.
52pub const MEMMAP_START: u64 = 0x7000;
53
54/// The 'zero page', a.k.a linux kernel bootparams.
55pub const ZERO_PAGE_START: u64 = 0x7000;
56
57/// APIC address
58pub const APIC_ADDR: u32 = 0xfee0_0000;
59
60/// IOAPIC address
61pub const IOAPIC_ADDR: u32 = 0xfec0_0000;
62
63/// Location of RSDP pointer in x86 machines
64pub const RSDP_ADDR: u64 = 0x000e_0000;
65
66/// Start of memory region we will use for system data (MPTable, ACPI, etc). We are putting its
67/// start address where EBDA normally starts, i.e. in the last 1 KiB of the first 640KiB of memory
68pub const SYSTEM_MEM_START: u64 = 0x9fc00;
69
70/// Size of memory region for system data.
71///
72/// We reserve the memory between the start of the EBDA up until the location of RSDP pointer,
73/// [0x9fc00, 0xe0000) for system data. This is 257 KiB of memory we is enough for our needs and
74/// future proof.
75///
76/// For ACPI we currently need:
77///
78/// FADT size: 276 bytes
79/// XSDT size: 52 bytes (header: 36 bytes, plus pointers of FADT and MADT)
80/// MADT size: 2104 bytes (header: 44 bytes, IO-APIC: 12 bytes, LocalAPIC: 8 * #vCPUS)
81/// DSDT size: 1907 bytes (header: 36 bytes, legacy devices: 345, GED: 161, VMGenID: 87, VirtIO
82/// devices: 71 bytes per device)
83///
84/// The above assumes a maximum of 256 vCPUs, because that's what ACPI allows, but currently
85/// we have a hard limit of up to 32 vCPUs.
86///
87/// Moreover, for MPTable we need up to 5304 bytes (284 + 20 * #vCPUS) assuming again
88/// a maximum number of 256 vCPUs.
89///
90/// 257KiB is more than we need, however we reserve this space for potential future use of
91/// ACPI features (new tables and/or devices).
92pub const SYSTEM_MEM_SIZE: u64 = RSDP_ADDR - SYSTEM_MEM_START;
93
94/// First address that cannot be addressed using 32 bit anymore.
95pub const FIRST_ADDR_PAST_32BITS: u64 = 1 << 32;
96
97/// The size of the memory area reserved for MMIO 32-bit accesses.
98pub const MMIO32_MEM_SIZE: u64 = mib_to_bytes(1024) as u64;
99/// The start of the memory area reserved for MMIO 32-bit accesses.
100pub const MMIO32_MEM_START: u64 = FIRST_ADDR_PAST_32BITS - MMIO32_MEM_SIZE;
101
102// We dedicate the last 256 MiB of the 32-bit MMIO address space PCIe for memory-mapped access to
103// configuration.
104/// Size of MMIO region for PCIe configuration accesses.
105pub const PCI_MMCONFIG_SIZE: u64 = 256 << 20;
106/// Start of MMIO region for PCIe configuration accesses.
107pub const PCI_MMCONFIG_START: u64 = IOAPIC_ADDR as u64 - PCI_MMCONFIG_SIZE;
108/// MMIO space per PCIe segment
109pub const PCI_MMIO_CONFIG_SIZE_PER_SEGMENT: u64 = 4096 * 256;
110
111// We reserve 768 MiB for devices at the beginning of the MMIO region. This includes space both for
112// pure MMIO and PCIe devices.
113
114/// Memory region start for boot device.
115pub const BOOT_DEVICE_MEM_START: u64 = MMIO32_MEM_START;
116
117/// Beginning of memory region for device MMIO 32-bit accesses
118pub const MEM_32BIT_DEVICES_START: u64 = BOOT_DEVICE_MEM_START + MMIO_LEN;
119/// Size of memory region for device MMIO 32-bit accesses
120pub const MEM_32BIT_DEVICES_SIZE: u64 = PCI_MMCONFIG_START - MEM_32BIT_DEVICES_START;
121
122// 64-bits region for MMIO accesses
123/// The start of the memory area reserved for MMIO 64-bit accesses.
124pub const MMIO64_MEM_START: u64 = 256 << 30;
125/// The size of the memory area reserved for MMIO 64-bit accesses.
126pub const MMIO64_MEM_SIZE: u64 = 256 << 30;
127
128// At the moment, all of this region goes to devices
129/// Beginning of memory region for device MMIO 64-bit accesses
130pub const MEM_64BIT_DEVICES_START: u64 = MMIO64_MEM_START;
131/// Size of memory region for device MMIO 32-bit accesses
132pub const MEM_64BIT_DEVICES_SIZE: u64 = MMIO64_MEM_SIZE;
133/// First address past the 64-bit MMIO gap
134pub const FIRST_ADDR_PAST_64BITS_MMIO: u64 = MMIO64_MEM_START + MMIO64_MEM_SIZE;
135/// Size of the memory past 64-bit MMIO gap
136pub const PAST_64BITS_MMIO_SIZE: u64 = 512 << 30;