]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
8e80aa33e19e2cffacf31474d2a005b519475638
[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/BhyveFwCtlLib.h>
13 #include <Library/MemoryAllocationLib.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
75 Ptr = LocalApic;
76
77 IoApic = Ptr;
78 IoApic->Type = EFI_ACPI_1_0_IO_APIC;
79 IoApic->Length = sizeof (*IoApic);
80 IoApic->IoApicId = (UINT8)CpuCount;
81 IoApic->Reserved = EFI_ACPI_RESERVED_BYTE;
82 IoApic->IoApicAddress = 0xFEC00000;
83 IoApic->SystemVectorBase = 0x00000000;
84 Ptr = IoApic + 1;
85
86 //
87 // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure
88 //
89 Iso = Ptr;
90 Iso->Type = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;
91 Iso->Length = sizeof (*Iso);
92 Iso->Bus = 0x00; // ISA
93 Iso->Source = 0x00; // IRQ0
94 Iso->GlobalSystemInterruptVector = 0x00000002;
95 Iso->Flags = 0x0000; // Conforms to specs of the bus
96 Ptr = Iso + 1;
97
98 ASSERT ((UINTN)((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);
99 Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);
100
101 FreePool (Madt);
102
103 return Status;
104 }
105
106 EFI_STATUS
107 EFIAPI
108 BhyveInstallAcpiTable (
109 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
110 IN VOID *AcpiTableBuffer,
111 IN UINTN AcpiTableBufferSize,
112 OUT UINTN *TableKey
113 )
114 {
115 EFI_ACPI_DESCRIPTION_HEADER *Hdr;
116 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
117
118 Hdr = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTableBuffer;
119 switch (Hdr->Signature) {
120 case EFI_ACPI_1_0_APIC_SIGNATURE:
121 TableInstallFunction = BhyveInstallAcpiMadtTable;
122 break;
123 default:
124 TableInstallFunction = InstallAcpiTable;
125 }
126
127 return TableInstallFunction (
128 AcpiProtocol,
129 AcpiTableBuffer,
130 AcpiTableBufferSize,
131 TableKey
132 );
133 }