// SPDX-License-Identifier: MPL-2.0
#ifndef SH_LIB_ACPI_H
#define SH_LIB_ACPI_H
#include "std/stdlib.h"
// ACPI v1 RSDP structure
typedef struct {
  sh_uint8 signature[8];
  sh_uint8 checksum;
  sh_uint8 oem_id[6];
  sh_uint8 revision;
  sh_uint32 rsdt_address;
} sh_acpi_RSDP_V1;
// ACPI v2 RSDP structure
typedef struct {
  sh_acpi_RSDP_V1 first_part;
  sh_uint32 length;
  sh_uint64 xsdt_address;
  sh_uint8 extended_checksum;
  sh_uint8 reserved[3];
} sh_acpi_RSDP_V2;
// ACPI pointers root structure
typedef struct {
  sh_uint64 rsdt;
  sh_uint64 xsdt; // set to 0 if ACPI v2 isn't supported
} sh_apci_ACPI_POINTERS_ROOT;
// ACPI XSDT header
typedef struct {
  char signature[4];
  sh_uint32 length;
  sh_uint8 revision;
  sh_uint8 checksum;
  char oem_id[6];
  char oem_table_id[8];
  sh_uint32 oem_revision;
  sh_uint32 creator_id;
  sh_uint32 creator_revision;
} sh_acpi_ACPI_XSDT_HEADER;
// ACPI XSTD body
typedef struct {
  sh_uint64 *entries;
  sh_uint64 entry_count;
} sh_acpi_ACPI_XSDT_BODY;
// ACPI tables list
typedef struct {
  sh_uint64 madt_physical_address;
} sh_acpi_ACPI_TABLES;
// ACPI table header
typedef struct {
  char signature[4];
  sh_uint32 length;
  sh_uint8 revision;
  sh_uint8 checksum;
  char oem_id[6];
  char oem_table_id[8];
  sh_uint32 oem_revision;
  sh_uint32 creator_id;
  sh_uint32 creator_revision;
} sh_acpi_TABLE_HEADER;
// Try to obtain ACPI root pointer
SH_STATUS sh_acpi_parse_rsdp(sh_uint64 rsdp,sh_uint8 acpi_ver,sh_apci_ACPI_POINTERS_ROOT *out);
// Parse XSDT header and ensure that all entries are mapped
SH_STATUS sh_acpi_parse_xsdt(sh_uint64 xsdt,sh_acpi_ACPI_XSDT_BODY *xsdt_body);
// Parse XSDT entries, ensure that all the headers of each table is mapped and sort all entries into their respectives fields inside acpi_tables. Doesn't parse each table header
SH_STATUS sh_acpi_parse_tables(sh_acpi_ACPI_XSDT_BODY *xsdt_body,sh_acpi_ACPI_TABLES *acpi_tables);
#endif
