Skip to content

Commit 6ba1973

Browse files
committed
Don't fully initialize uACPI unless absolutely needed
Main concern for doing that is that running AML might put the hardware into a non-PC compatible state with no reliable way to reverse that (as per comment on #54). For now `acpi_init` only sets up "early table access", as it previously did, to allow ACPI table enumeration, but if the need arises one can call `acpi_full_init` to be able to call into uACPI functions that require the namespace to be loaded and initialized.
1 parent d526124 commit 6ba1973

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

src/acpi.c

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *rsdp)
379379
return UACPI_STATUS_OK;
380380
}
381381

382+
static void *early_table_buffer;
383+
382384
EFI_STATUS acpi_init(struct csmwrap_priv *priv)
383385
{
384386
UINTN i;
@@ -406,34 +408,63 @@ EFI_STATUS acpi_init(struct csmwrap_priv *priv)
406408
}
407409

408410
if (g_rsdp) {
409-
enum uacpi_status uacpi_status;
411+
const size_t table_buffer_size = 4096;
410412

411-
uacpi_status = uacpi_initialize(UACPI_FLAG_NO_ACPI_MODE);
412-
if (uacpi_status != UACPI_STATUS_OK) {
413-
printf("uACPI initialization failed: %s\n", uacpi_status_to_string(uacpi_status));
414-
return EFI_DEVICE_ERROR;
415-
}
413+
EFI_STATUS status;
414+
status = gBS->AllocatePool(EfiLoaderData, table_buffer_size, &early_table_buffer);
415+
if (status != EFI_SUCCESS)
416+
return status;
416417

417-
uacpi_status = uacpi_namespace_load();
418+
enum uacpi_status uacpi_status;
419+
uacpi_status = uacpi_setup_early_table_access(early_table_buffer, table_buffer_size);
418420
if (uacpi_status != UACPI_STATUS_OK) {
419-
printf("uACPI namespace load failed: %s\n", uacpi_status_to_string(uacpi_status));
421+
printf("uACPI early table setup failed: %s\n", uacpi_status_to_string(uacpi_status));
420422
return EFI_DEVICE_ERROR;
421423
}
422424

423-
uacpi_status = uacpi_namespace_initialize();
424-
if (uacpi_status != UACPI_STATUS_OK) {
425-
printf("uACPI namespace initialization failed: %s\n", uacpi_status_to_string(uacpi_status));
426-
return EFI_DEVICE_ERROR;
427-
}
428-
429425
return EFI_SUCCESS;
430426
}
431427

432428
printf("No ACPI RSDT found\n");
433429
return EFI_UNSUPPORTED;
434430
}
435431

432+
EFI_STATUS acpi_full_init(void)
433+
{
434+
enum uacpi_status uacpi_status;
435+
436+
uacpi_status = uacpi_initialize(UACPI_FLAG_NO_ACPI_MODE);
437+
if (uacpi_status != UACPI_STATUS_OK) {
438+
printf("uACPI initialization failed: %s\n", uacpi_status_to_string(uacpi_status));
439+
return EFI_DEVICE_ERROR;
440+
}
441+
442+
uacpi_status = uacpi_namespace_load();
443+
if (uacpi_status != UACPI_STATUS_OK) {
444+
printf("uACPI namespace load failed: %s\n", uacpi_status_to_string(uacpi_status));
445+
return EFI_DEVICE_ERROR;
446+
}
447+
448+
uacpi_status = uacpi_namespace_initialize();
449+
if (uacpi_status != UACPI_STATUS_OK) {
450+
printf("uACPI namespace initialization failed: %s\n", uacpi_status_to_string(uacpi_status));
451+
return EFI_DEVICE_ERROR;
452+
}
453+
454+
if (early_table_buffer != NULL) {
455+
gBS->FreePool(early_table_buffer);
456+
early_table_buffer = NULL;
457+
}
458+
459+
return EFI_SUCCESS;
460+
}
461+
436462
void acpi_prepare_exitbs(void)
437463
{
438464
uacpi_state_reset();
465+
466+
if (early_table_buffer != NULL) {
467+
gBS->FreePool(early_table_buffer);
468+
early_table_buffer = NULL;
469+
}
439470
}

src/csmwrap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct csmwrap_priv {
4242
extern int unlock_bios_region();
4343
extern int build_coreboot_table(struct csmwrap_priv *priv);
4444
EFI_STATUS acpi_init(struct csmwrap_priv *priv);
45+
EFI_STATUS acpi_full_init(void);
4546
void acpi_prepare_exitbs(void);
4647
int build_e820_map(struct csmwrap_priv *priv, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN memory_map_size, UINTN descriptor_size);
4748
int apply_intel_platform_workarounds(void);

0 commit comments

Comments
 (0)