PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
acpi.c
Go to the documentation of this file.
1#include <kernel/fs/path.h>
2#include <kernel/acpi/acpi.h>
3
7
8#include <kernel/fs/mount.h>
10#include <kernel/fs/sysfs.h>
12#include <kernel/init/init.h>
13#include <kernel/log/log.h>
14#include <kernel/log/panic.h>
15#include <kernel/mem/pmm.h>
17#include <kernel/proc/process.h>
18#include <kernel/sched/sched.h>
19
20#ifdef _TESTING_
21#include <kernel/utils/test.h>
22#endif
23
24#include <boot/boot_info.h>
25#include <string.h>
26
27static bool dirInitialized = false;
28static dentry_t* acpi = NULL;
29
30bool acpi_is_checksum_valid(void* table, uint64_t length)
31{
32 uint8_t sum = 0;
33 for (uint64_t i = 0; i < length; i++)
34 {
35 sum += ((uint8_t*)table)[i];
36 }
37
38 return sum == 0;
39}
40
42{
43 if (!dirInitialized)
44 {
46 if (ns == NULL)
47 {
48 panic(NULL, "failed to get kernel process namespace for ACPI sysfs group");
49 }
50 UNREF_DEFER(ns);
51
52 acpi = sysfs_dir_new(NULL, "acpi", NULL, NULL);
53 if (acpi == NULL)
54 {
55 panic(NULL, "failed to initialize ACPI sysfs group");
56 }
57
58 dirInitialized = true;
59 }
60
61 return REF(acpi);
62}
63
65{
66 for (uint64_t i = 0; i < map->length; i++)
67 {
68 const EFI_MEMORY_DESCRIPTOR* desc = BOOT_MEMORY_MAP_GET_DESCRIPTOR(map, i);
69
70 if (desc->Type == EfiACPIReclaimMemory)
71 {
72 pmm_free_region(PHYS_TO_PFN(desc->PhysicalStart), desc->NumberOfPages);
73 LOG_INFO("reclaim memory [%p-%p]\n", desc->PhysicalStart,
74 ((uintptr_t)desc->PhysicalStart) + desc->NumberOfPages * PAGE_SIZE);
75 }
76 }
77}
78
80{
81 switch (event->type)
82 {
84 {
86 if (bootInfo == NULL || bootInfo->rsdp == NULL)
87 {
88 LOG_ERR("no RSDP provided by bootloader\n");
89 return ERR;
90 }
91
93 {
94 LOG_ERR("failed to initialize ACPI tables\n");
95 return ERR;
96 }
97
98 if (aml_init() == ERR)
99 {
100 LOG_ERR("failed to initialize AML subsystem\n");
101 return ERR;
102 }
103
104#ifdef _TESTING_
105#ifndef _ACPI_NOTEST_
106 TEST_ALL();
107#endif
108#endif
109
110 if (acpi_devices_init() == ERR)
111 {
112 LOG_ERR("failed to initialize ACPI devices\n");
113 return ERR;
114 }
115
117
118 if (acpi_tables_expose() == ERR)
119 {
120 LOG_ERR("failed to expose ACPI tables via sysfs\n");
121 return ERR;
122 }
123
124 if (aml_namespace_expose() == ERR)
125 {
126 LOG_ERR("failed to expose ACPI devices via sysfs\n");
127 return ERR;
128 }
129 }
130 break;
131 default:
132 break;
133 }
134
135 return 0;
136}
137
138MODULE_INFO("ACPI Module", "Kai Norberg",
139 "ACPI subsystem providing ACPI table handling, AML parsing and device management", OS_VERSION, "MIT", "BOOT_RSDP");
static bool dirInitialized
Definition acpi.c:27
static dentry_t * acpi
Definition acpi.c:28
uint64_t _module_procedure(const module_event_t *event)
Definition acpi.c:79
boot_memory_map_t * map
Definition main.c:241
boot_info_t * bootInfo
Definition boot_info.c:14
#define BOOT_MEMORY_MAP_GET_DESCRIPTOR(map, index)
Definition boot_info.h:52
uint64_t aml_namespace_expose(void)
Expose the entire namespace heirarchy to devfs.
Definition namespace.c:121
uint64_t aml_init(void)
Initialize the AML subsystem.
Definition aml.c:103
uint64_t acpi_devices_init(void)
Enumerate, configure and load modules for ACPI devices.
Definition devices.c:480
uint64_t acpi_tables_init(rsdp_t *rsdp)
Initialize ACPI tables and call their init handlers.
Definition tables.c:194
uint64_t acpi_tables_expose(void)
Expose ACPI tables to devfs.
Definition tables.c:220
bool acpi_is_checksum_valid(void *table, uint64_t length)
Check if the sum of all bytes in a table is 0.
Definition acpi.c:30
void acpi_reclaim_memory(const boot_memory_map_t *map)
Reclaim ACPI memory regions.
Definition acpi.c:64
dentry_t * acpi_get_dir(void)
Retrieve the devfs root directory for ACPI.
Definition acpi.c:41
dentry_t * sysfs_dir_new(dentry_t *parent, const char *name, const vnode_ops_t *vnodeOps, void *data)
Create a new directory inside a mounted sysfs instance.
Definition sysfs.c:114
boot_info_t * boot_info_get(void)
Gets the boot info structure.
Definition boot_info.c:16
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:292
#define LOG_ERR(format,...)
Definition log.h:93
#define LOG_INFO(format,...)
Definition log.h:91
#define PHYS_TO_PFN(_addr)
Convert a physical address to its PFN.
void pmm_free_region(pfn_t pfn, size_t count)
Free a contiguous region of physical memory.
Definition pmm.c:358
#define MODULE_INFO(_name, _author, _description, _version, _licence, _deviceTypes)
Macro to define module information.
Definition module.h:200
@ MODULE_EVENT_DEVICE_ATTACH
Definition module.h:251
process_t * process_get_kernel(void)
Gets the kernel process.
Definition process.c:374
namespace_t * process_get_ns(process_t *process)
Gets the namespace of a process.
Definition process.c:206
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:122
#define REF(ptr)
Increment reference count.
Definition ref.h:82
#define TEST_ALL()
Run all registered tests in the ._tests section.
Definition test.h:37
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
#define PAGE_SIZE
The size of a memory page in bytes.
Definition PAGE_SIZE.h:8
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
boot_memory_t memory
Definition boot_info.h:106
void * rsdp
Definition boot_info.h:102
boot_memory_map_t map
Definition boot_info.h:95
Directory entry structure.
Definition dentry.h:155
module_event_type_t type
Definition module.h:268
Namespace structure.
Definition namespace.h:57