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