VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c

Last change on this file was 99404, checked in by vboxsync, 2 years ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2020, Rebecca Cran <[email protected]>
3 * Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
4 * Copyright (C) 2012, Red Hat, Inc.
5 * Copyright (c) 2014, Pluribus Networks, Inc.
6 *
7 * SPDX-License-Identifier: BSD-2-Clause-Patent
8 */
9#include "AcpiPlatform.h"
10
11#include <Library/BaseMemoryLib.h>
12#include <Library/BhyveFwCtlLib.h>
13#include <Library/MemoryAllocationLib.h>
14#include <Library/QemuFwCfgLib.h> // QemuFwCfgFindFile()
15
16STATIC
17EFI_STATUS
18EFIAPI
19BhyveGetCpuCount (
20 OUT UINT32 *CpuCount
21 )
22{
23 FIRMWARE_CONFIG_ITEM Item;
24 UINTN Size;
25
26 if (QemuFwCfgIsAvailable ()) {
27 if (EFI_ERROR (QemuFwCfgFindFile ("opt/bhyve/hw.ncpu", &Item, &Size))) {
28 return EFI_NOT_FOUND;
29 } else if (Size != sizeof (*CpuCount)) {
30 return EFI_BAD_BUFFER_SIZE;
31 }
32
33 QemuFwCfgSelectItem (Item);
34 QemuFwCfgReadBytes (Size, CpuCount);
35
36 return EFI_SUCCESS;
37 }
38
39 //
40 // QemuFwCfg not available, try BhyveFwCtl.
41 //
42 Size = sizeof (*CpuCount);
43 if (BhyveFwCtlGet ("hw.ncpu", CpuCount, &Size) == RETURN_SUCCESS) {
44 return EFI_SUCCESS;
45 }
46
47 return EFI_UNSUPPORTED;
48}
49
50STATIC
51EFI_STATUS
52EFIAPI
53BhyveInstallAcpiMadtTable (
54 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
55 IN VOID *AcpiTableBuffer,
56 IN UINTN AcpiTableBufferSize,
57 OUT UINTN *TableKey
58 )
59{
60 UINT32 CpuCount;
61 UINTN NewBufferSize;
62 EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
63 EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApic;
64 EFI_ACPI_1_0_IO_APIC_STRUCTURE *IoApic;
65 EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *Iso;
66 VOID *Ptr;
67 UINTN Loop;
68 EFI_STATUS Status;
69
70 ASSERT (AcpiTableBufferSize >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));
71
72 // Query the host for the number of vCPUs
73 Status = BhyveGetCpuCount (&CpuCount);
74 if (!EFI_ERROR (Status)) {
75 DEBUG ((DEBUG_INFO, "Retrieved CpuCount %d\n", CpuCount));
76 ASSERT (CpuCount >= 1);
77 } else {
78 DEBUG ((DEBUG_INFO, "CpuCount retrieval error\n"));
79 CpuCount = 1;
80 }
81
82 NewBufferSize = 1 * sizeof (*Madt) +
83 CpuCount * sizeof (*LocalApic) +
84 1 * sizeof (*IoApic) +
85 1 * sizeof (*Iso);
86
87 Madt = AllocatePool (NewBufferSize);
88 if (Madt == NULL) {
89 return EFI_OUT_OF_RESOURCES;
90 }
91
92 CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
93 Madt->Header.Length = (UINT32)NewBufferSize;
94 Madt->LocalApicAddress = 0xFEE00000;
95 Madt->Flags = EFI_ACPI_1_0_PCAT_COMPAT;
96 Ptr = Madt + 1;
97
98 LocalApic = Ptr;
99 for (Loop = 0; Loop < CpuCount; ++Loop) {
100 LocalApic->Type = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;
101 LocalApic->Length = sizeof (*LocalApic);
102 LocalApic->AcpiProcessorId = (UINT8)Loop;
103 LocalApic->ApicId = (UINT8)Loop;
104 LocalApic->Flags = 1; // enabled
105 ++LocalApic;
106 }
107
108 Ptr = LocalApic;
109
110 IoApic = Ptr;
111 IoApic->Type = EFI_ACPI_1_0_IO_APIC;
112 IoApic->Length = sizeof (*IoApic);
113 IoApic->IoApicId = (UINT8)CpuCount;
114 IoApic->Reserved = EFI_ACPI_RESERVED_BYTE;
115 IoApic->IoApicAddress = 0xFEC00000;
116 IoApic->SystemVectorBase = 0x00000000;
117 Ptr = IoApic + 1;
118
119 //
120 // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure
121 //
122 Iso = Ptr;
123 Iso->Type = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;
124 Iso->Length = sizeof (*Iso);
125 Iso->Bus = 0x00; // ISA
126 Iso->Source = 0x00; // IRQ0
127 Iso->GlobalSystemInterruptVector = 0x00000002;
128 Iso->Flags = 0x0000; // Conforms to specs of the bus
129 Ptr = Iso + 1;
130
131 ASSERT ((UINTN)((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);
132 Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);
133
134 FreePool (Madt);
135
136 return Status;
137}
138
139EFI_STATUS
140EFIAPI
141BhyveInstallAcpiTable (
142 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
143 IN VOID *AcpiTableBuffer,
144 IN UINTN AcpiTableBufferSize,
145 OUT UINTN *TableKey
146 )
147{
148 EFI_ACPI_DESCRIPTION_HEADER *Hdr;
149 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
150
151 Hdr = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTableBuffer;
152 switch (Hdr->Signature) {
153 case EFI_ACPI_1_0_APIC_SIGNATURE:
154 TableInstallFunction = BhyveInstallAcpiMadtTable;
155 break;
156 default:
157 TableInstallFunction = InstallAcpiTable;
158 }
159
160 return TableInstallFunction (
161 AcpiProtocol,
162 AcpiTableBuffer,
163 AcpiTableBufferSize,
164 TableKey
165 );
166}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette