TianoCore EDK2 master
Loading...
Searching...
No Matches
Bhyve.c
1/*
2 * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>
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
14#include <Library/QemuFwCfgLib.h> // QemuFwCfgFindFile()
15
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
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
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;
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
140EFIAPI
141BhyveInstallAcpiTable (
142 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
143 IN VOID *AcpiTableBuffer,
144 IN UINTN AcpiTableBufferSize,
145 OUT UINTN *TableKey
146 )
147{
149 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
150
151 Hdr = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTableBuffer;
152 switch (Hdr->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}
UINT64 UINTN
#define EFI_ACPI_1_0_APIC_SIGNATURE
Definition: Acpi10.h:627
#define EFI_ACPI_1_0_PCAT_COMPAT
Definition: Acpi10.h:527
EFI_STATUS EFIAPI InstallAcpiTable(IN EFI_ACPI_TABLE_PROTOCOL *This, IN VOID *AcpiTableBuffer, IN UINTN AcpiTableBufferSize, OUT UINTN *TableKey)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
RETURN_STATUS EFIAPI BhyveFwCtlGet(IN CONST CHAR8 *Name, OUT VOID *Item, IN OUT UINTN *Size)
VOID EFIAPI FreePool(IN VOID *Buffer)
STATIC CONST ACPI_PARSER IoApic[]
Definition: MadtParser.c:305
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define RETURN_SUCCESS
Definition: Base.h:1066
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS(EFIAPI * EFI_ACPI_TABLE_INSTALL_ACPI_TABLE)(IN EFI_ACPI_TABLE_PROTOCOL *This, IN VOID *AcpiTableBuffer, IN UINTN AcpiTableBufferSize, OUT UINTN *TableKey)
Definition: AcpiTable.h:72
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFIAPI QemuFwCfgFindFile(IN CONST CHAR8 *Name, OUT FIRMWARE_CONFIG_ITEM *Item, OUT UINTN *Size)
Definition: QemuFwCfgLib.c:250
VOID EFIAPI QemuFwCfgReadBytes(IN UINTN Size, IN VOID *Buffer OPTIONAL)
Definition: QemuFwCfgNull.c:66
VOID EFIAPI QemuFwCfgSelectItem(IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem)
Definition: QemuFwCfgLib.c:33
BOOLEAN EFIAPI QemuFwCfgIsAvailable(VOID)
Definition: QemuFwCfgDxe.c:44
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT32 Length
Definition: AcpiParser.h:347