]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
Add BhyvePkg, to support the bhyve hypervisor
[mirror_edk2.git] / OvmfPkg / Bhyve / AcpiPlatformDxe / 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
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/MemoryAllocationLib.h>
13 #include <Library/BhyveFwCtlLib.h>
14
15 STATIC
16 EFI_STATUS
17 EFIAPI
18 BhyveInstallAcpiMadtTable (
19 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
20 IN VOID *AcpiTableBuffer,
21 IN UINTN AcpiTableBufferSize,
22 OUT UINTN *TableKey
23 )
24 {
25 UINT32 CpuCount;
26 UINTN cSize;
27 UINTN NewBufferSize;
28 EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
29 EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApic;
30 EFI_ACPI_1_0_IO_APIC_STRUCTURE *IoApic;
31 EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *Iso;
32 VOID *Ptr;
33 UINTN Loop;
34 EFI_STATUS Status;
35
36 ASSERT (AcpiTableBufferSize >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));
37
38 // Query the host for the number of vCPUs
39 CpuCount = 0;
40 cSize = sizeof(CpuCount);
41 if (BhyveFwCtlGet ("hw.ncpu", &CpuCount, &cSize) == RETURN_SUCCESS) {
42 DEBUG ((DEBUG_INFO, "Retrieved CpuCount %d\n", CpuCount));
43 ASSERT (CpuCount >= 1);
44 } else {
45 DEBUG ((DEBUG_INFO, "CpuCount retrieval error\n"));
46 CpuCount = 1;
47 }
48
49 NewBufferSize = 1 * sizeof (*Madt) +
50 CpuCount * sizeof (*LocalApic) +
51 1 * sizeof (*IoApic) +
52 1 * sizeof (*Iso);
53
54 Madt = AllocatePool (NewBufferSize);
55 if (Madt == NULL) {
56 return EFI_OUT_OF_RESOURCES;
57 }
58
59 CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
60 Madt->Header.Length = (UINT32) NewBufferSize;
61 Madt->LocalApicAddress = 0xFEE00000;
62 Madt->Flags = EFI_ACPI_1_0_PCAT_COMPAT;
63 Ptr = Madt + 1;
64
65 LocalApic = Ptr;
66 for (Loop = 0; Loop < CpuCount; ++Loop) {
67 LocalApic->Type = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;
68 LocalApic->Length = sizeof (*LocalApic);
69 LocalApic->AcpiProcessorId = (UINT8) Loop;
70 LocalApic->ApicId = (UINT8) Loop;
71 LocalApic->Flags = 1; // enabled
72 ++LocalApic;
73 }
74 Ptr = LocalApic;
75
76 IoApic = Ptr;
77 IoApic->Type = EFI_ACPI_1_0_IO_APIC;
78 IoApic->Length = sizeof (*IoApic);
79 IoApic->IoApicId = (UINT8) CpuCount;
80 IoApic->Reserved = EFI_ACPI_RESERVED_BYTE;
81 IoApic->IoApicAddress = 0xFEC00000;
82 IoApic->SystemVectorBase = 0x00000000;
83 Ptr = IoApic + 1;
84
85 //
86 // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure
87 //
88 Iso = Ptr;
89 Iso->Type = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;
90 Iso->Length = sizeof (*Iso);
91 Iso->Bus = 0x00; // ISA
92 Iso->Source = 0x00; // IRQ0
93 Iso->GlobalSystemInterruptVector = 0x00000002;
94 Iso->Flags = 0x0000; // Conforms to specs of the bus
95 Ptr = Iso + 1;
96
97 ASSERT ((UINTN) ((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);
98 Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);
99
100 FreePool (Madt);
101
102 return Status;
103 }
104
105 EFI_STATUS
106 EFIAPI
107 BhyveInstallAcpiTable (
108 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
109 IN VOID *AcpiTableBuffer,
110 IN UINTN AcpiTableBufferSize,
111 OUT UINTN *TableKey
112 )
113 {
114 EFI_ACPI_DESCRIPTION_HEADER *Hdr;
115 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
116
117 Hdr = (EFI_ACPI_DESCRIPTION_HEADER*) AcpiTableBuffer;
118 switch (Hdr->Signature) {
119 case EFI_ACPI_1_0_APIC_SIGNATURE:
120 TableInstallFunction = BhyveInstallAcpiMadtTable;
121 break;
122 default:
123 TableInstallFunction = InstallAcpiTable;
124 }
125
126 return TableInstallFunction (
127 AcpiProtocol,
128 AcpiTableBuffer,
129 AcpiTableBufferSize,
130 TableKey
131 );
132 }