Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
acpi.c
Go to the documentation of this file.
1// #include "hal/acpi/bytestream.h"
2#include "hal/apic/apic.h"
3#include "hal/apic/ioapic.h"
4#include "hal/cpu/paging.h"
5#include "hal/pci/pcie.h"
6#include "init/init.h"
7#include "libk/debug/debug.h"
8#include "libk/io.h"
9#include "libk/serial.h"
10#include "memory/memory_utils.h"
12#include "memory/vm_manager.h"
13#include "type.h"
14#include <hal/acpi/acpi.h>
15#include <hal/acpi/hpet.h>
16#include <str.h>
17#include <type.h>
18
19static struct cpu_core* cpu_list = 0;
20
22 struct cpu_core* core = cpu_list;
23 while (core) {
24 if (core->apicid == apicid)
25 return core;
26 core = core->next;
27 }
28 return 0;
29}
30
31extern void apicSetBaseAddr(uintptr_t addr);
32
34 uint32_t flag) {
35 struct cpu_core* core =
36 (struct cpu_core*)kalloc(sizeof(struct cpu_core));
37 core->apicid = apicid;
38 core->cpuid = cpuid;
39 core->flag = flag;
40 core->next = cpu_list;
41 core->status = Off;
42 cpu_list = core;
43}
44
46 uint8_t count = 0;
47 struct cpu_core* core = cpu_list;
48 while (core) {
49 count++;
50 core = core->next;
51 }
52 return count;
53}
54
57 uintptr_t offset = phys_addr - aligned_phys;
58
59 uintptr_t vaddr =
61
62 vma_register(get_kernel_vmm_page(), aligned_phys, vaddr,
63 len * BLOCK_SIZE);
64
65 vxMultipleMmap(paging_get_highest_page_map(), vaddr, aligned_phys, len,
69 asm volatile("mfence" ::: "memory");
70
71 // paging_debug(paging_get_highest_page_map(), vaddr);
72
73 return (uintptr_t)(vaddr + offset);
74}
75
81
82// static void parsing_dsdt(uintptr_t dsdt_addr) {
83// // uintptr_t ddsdt = acpi_map_phys_page(dsdt_addr, 1);
84// // struct SDT *sdt = (struct SDT *)ddsdt;
85// // LOG_INFO("ACPI", "DSDT header length %d", sdt->Length);
86// // uintptr_t new_dsdt = acpi_map_phys_page(dsdt_addr, (BLOCK_SIZE +
87// // sdt->Length - 1) / BLOCK_SIZE); acpi_phys_page_unmap(ddsdt); sdt =
88// // (struct SDT *)new_dsdt; uint8_t *dsdt = (uint8_t *)new_dsdt;
89
90// // uint32_t slp_typa = 0;
91// // uint32_t slp_typb = 0;
92
93// // for (size_t i = 0; i < sdt->Length; i++)
94// // {
95// // if (dsdt[i] == NAME_OP)
96// // { // NameOp
97// // if (strncmp((char *)((uintptr_t)dsdt + i + 1), "_S5_", 4) ==
98// // 0)
99// // {
100// // LOG_INFO("ACPI", "found _S5_ at %d", i);
101// // for (size_t j = i + 5; j < sdt->Length; j++)
102// // {
103// // if (dsdt[j] == PACKAGE_OP)
104// // {
105// // LOG_INFO("ACPI", "found Package at %d", j);
106
107// // for (size_t l = j + 1; l < sdt->Length; l++)
108// // {
109// // if (dsdt[l] == BYTE_PREFIX)
110// // {
111// // LOG_INFO("ACPI", "found byte prefix
112// // first at %d", l); break;
113// // }
114// // }
115// // // break;
116// // break;
117// // }
118// // i = j;
119// // }
120
121// // // break;
122// // // if (*data == 0x12)
123// // // { // PackageOp
124// // // data++; // skip opcode
125// // // size_t pkg_size = *data++; // asumsi kecil, 1
126// // byte
127// // // uint8_t num_elem = *data++;
128// // // // ambil SLP_TYP_A
129// // // slp_typa = *data; // simplifikasi, bisa 1/2/4
130// // bytes
131// // // // ambil SLP_TYP_B
132// // // slp_typb = *(data + 1); // jika ada
133// // // }
134// // }
135// // }
136// // }
137
138// // LOG_INFO("ACPI", "slp_typa %x slptypb %x", slp_typa, slp_typb);
139// }
140
141static void parsing_fadt(uintptr_t fadt_addr) {
142 UNUSED(fadt_addr);
143 // struct FADT *fadt = (struct FADT *)fadt_addr;
144 // LOG_INFO("ACPI", "FADT header length %d", fadt->header.Length);
145 // LOG_INFO("ACPI", "FADT PM1a cblk 0x%x", fadt->PM1aControlBlock);
146 // LOG_INFO("ACPI", "FADT DSDT 0x%x", fadt->Dsdt);
147 // parsing_dsdt(fadt->Dsdt);
148
149 // outw(fadt->PM1aControlBlock, (0x1 << 10) | 1);
150 // outw(fadt->PM1bControlBlock, (0x1 << 10) | 1);
151 // outw(0x604, 0x2000);
152}
153
154static void parsing_madt(struct MADT* madt) {
155 LOG_INFO("ACPI", "APIC addr 0x%x", madt->localApicAddress);
156 uintptr_t apic_addr = acpi_map_phys_page(madt->localApicAddress, 1);
157 apicSetBaseAddr(apic_addr);
159
160 uint8_t* ptr = (uint8_t*)&madt->table;
161 uint8_t* ptr_end = (uint8_t*)madt + madt->header.Length;
162 LOG_INFO("ACPI", "madt header 0x%x length 0x%x", ptr, ptr_end);
163
164 // uint8_t bspid = cpuid_get_bsp_id();
165 // LOG_INFO("ACPI", "current bsp id : %d", bspid);
166
167 // madt_record_table_entry_t *a = (madt_record_table_entry_t
168 // *)((uintptr_t)madt + 0x2C);
169
170 while (ptr < ptr_end) {
172 // LOG_INFO("MADT", "type %d, len %d", t->entry_type,
173 // t->record_length);
174 if (t->record_length == 0)
175 break;
176 switch (t->entry_type) {
178 uint8_t apic_id = *(uint8_t*)(void*)(ptr + 0x3);
179 uint8_t cpu_id = *(uint8_t*)(void*)(ptr + 0x2);
180 uint32_t flags = *(uint32_t*)(void*)(ptr + 0x4);
181
182 LOG_INFO("ACPI", "found APIC Id %d CPU Id %d", apic_id,
183 cpu_id);
184 vxACPIRegisterNewCore(apic_id, cpu_id, flags);
185
186 break;
187 }
189 uint8_t bus_src = *(uint8_t*)(void*)(ptr + 0x2);
190 uint8_t irq_src = *(uint8_t*)(void*)(ptr + 0x3);
191 uint32_t gsi = *(uint8_t*)(void*)(ptr + 0x4);
192 uint16_t flags = *(uint16_t*)(void*)(ptr + 0x6);
193 LOG_DEBUG("ACPI INT", "BUS %d IRQ %d GSI %d flags %d",
194 bus_src, irq_src, gsi, flags);
196 break;
197 }
198 case ACPI_IO_APIC: {
199 uint8_t ioapic_id = *(uint8_t*)(void*)(ptr + 0x2);
200 uint32_t ioapic_addr = *(uint32_t*)(void*)(ptr + 0x4);
201 uint32_t ioapic_gsi_base =
202 *(uint32_t*)(void*)(ptr + 0x8);
203 LOG_DEBUG("ACPIO IOAPIC",
204 "found IOAPIC id %d addr 0x%x GSI Base %d",
205 ioapic_id, ioapic_addr, ioapic_gsi_base);
206 ioapic_setup(acpi_map_phys_page(ioapic_addr, 1));
207 break;
208 }
209 case ACPI_NMI: {
210 uint8_t processor = *(uint8_t*)(void*)(ptr + 0x2);
211 uint16_t flags = *(uint16_t*)(void*)(ptr + 0x4);
212 uint8_t lint = *(uint8_t*)(void*)(ptr + 0x6);
213 LOG_DEBUG("ACPI NMI", "processor %d flags %d lint %d",
214 processor, flags, lint);
215
216 break;
217 }
218 }
219 ptr += t->record_length;
220 }
221}
222
223#define APIC_SIGNATURE 0x43495041
224#define HPET_SIGNATURE 0x54455048
225#define MCFG_SIGNATURE 0x4746434D
226#define WAET_SIGNATURE 0x54454157
227#define FACP_SIGNATURE 0x50434146
228#define TPM2_SIGNATURE 0x324D5054
229#define DSDT_SIGNATURE 0x54445344
230
231INIT(acpi) {
232 struct RSDP_t* rsdp_ptr =
233 (struct RSDP_t*)acpi_map_phys_page(VIRT2PHYS(ctx->rsdp_addr), 1);
234
235 if (!rsdp_ptr) {
236 serial_trace("failed to map RSDP\n");
237 return;
238 }
239
240 if (strncmp(rsdp_ptr->Signature, "RSD PTR ", 8) != 0) {
241 serial_trace("invalid rsdp signature: %.8s\n",
242 rsdp_ptr->Signature);
243 return;
244 }
245
246 uintptr_t rsdt_addr = rsdp_ptr->RsdtAddress;
247 LOG_INFO("ACPI", "rsdt addr 0x%x", rsdt_addr);
248
249 struct RSDT* rsdt = (struct RSDT*)acpi_map_phys_page(rsdt_addr, 1);
250 if (!rsdt) {
251 serial_trace("failed to map RSDT\n");
252 return;
253 }
254
255 uint32_t entry_count = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
256 LOG_INFO("RSDT", "rsdt entry count %d", entry_count);
257
258 for (uint32_t i = 0; i < entry_count; i++) {
261
262 if (!addr)
263 continue;
264
265 struct SDT* sdt = (struct SDT*)addr;
266
267 uint32_t sig = *(uint32_t*)(void*)(sdt->Signature);
268 LOG_INFO("ACPI", "signature %.4s (0x%x) found", sdt->Signature,
269 sig);
270
271 switch (sig) {
272 case APIC_SIGNATURE:
273 parsing_madt((struct MADT*)addr);
274 break;
275 case HPET_SIGNATURE:
277 break;
278 case MCFG_SIGNATURE:
280 break;
281 case FACP_SIGNATURE:
283 break;
284 case WAET_SIGNATURE:
285 case TPM2_SIGNATURE:
286 default:
287 break;
288 }
289 }
290
291 LOG_INFO("ACPI", "end search at rsdt");
292}
#define TPM2_SIGNATURE
Definition acpi.c:228
#define HPET_SIGNATURE
Definition acpi.c:224
#define FACP_SIGNATURE
Definition acpi.c:227
void apicSetBaseAddr(uintptr_t addr)
Definition apic.c:58
void acpi_phys_page_unmap(uintptr_t addr)
Definition acpi.c:76
static void parsing_fadt(uintptr_t fadt_addr)
Definition acpi.c:141
struct cpu_core * vxGetCpuInfo(uint8_t apicid)
Definition acpi.c:21
uint8_t vxGetNumberOfCores()
Definition acpi.c:45
#define APIC_SIGNATURE
Definition acpi.c:223
#define MCFG_SIGNATURE
Definition acpi.c:225
static void vxACPIRegisterNewCore(uint8_t apicid, uint8_t cpuid, uint32_t flag)
Definition acpi.c:33
uintptr_t acpi_map_phys_page(uintptr_t phys_addr, size_t len)
Definition acpi.c:55
static struct cpu_core * cpu_list
Definition acpi.c:19
static void parsing_madt(struct MADT *madt)
Definition acpi.c:154
#define WAET_SIGNATURE
Definition acpi.c:226
@ ACPI_PROCESSOR_LAPIC
Definition acpi.h:49
@ ACPI_NMI
Definition acpi.h:52
@ ACPI_IO_INT_OVERRIDE
Definition acpi.h:51
@ Off
Definition acpi.h:66
madt_record_table_entry_t
Definition acpi.h:34
void apicInitialize()
Definition apic.c:62
int count
Definition cache.h:2
void cpuid(uint32_t leaf, uint32_t subleaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition cpuid.c:4
volatile uint64_t addr
Definition e1000.hpp:0
void vxHPETInitialize(uintptr_t addr)
Definition hpet.c:54
uint16_t flags
Definition thread.h:5
#define INIT(fn)
Definition init.h:26
void ioapic_setup(uintptr_t ioapic_addr)
Definition ioapic.c:55
void ioapic_add_irq_gsi_map(uint8_t irq, uint32_t gsi, uint16_t flags)
Definition ioapic.c:79
uint32_t gsi
Definition ioapic.h:0
void * kalloc(size_t size)
#define ALIGN_DOWN(x, align)
Definition memory_utils.h:9
#define VIRT2PHYS(x)
size_t len
Definition oct2bin.h:7
void paging_reload(page_t p)
Definition paging.c:457
page_t paging_get_highest_page_map(void)
Definition paging.c:463
void paging_unmap_fill(page_t page_dir, uint64_t virt, size_t size)
Definition paging.c:451
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
Definition paging.c:340
#define PAGE_PRESENT
Definition paging.h:34
#define PAGE_NO_EXECUTE
Definition paging.h:43
#define PAGE_CACHE_DISABLE
Definition paging.h:38
#define PAGE_WRITABLE
Definition paging.h:35
#define PAGE_WRITE_THROUGH
Definition paging.h:37
void mcfg_parse(uintptr_t addr)
Definition pcie.c:36
#define BLOCK_SIZE
#define LOG_INFO(mod, fmt,...)
Definition serial.h:20
#define serial_trace(...)
Definition serial.h:19
#define LOG_DEBUG(mod, fmt,...)
Definition serial.h:22
uintptr_t phys_addr
Definition slab.h:6
int strncmp(const char *s1, const char *s2, size_t n)
Definition acpi.h:36
struct SDT header
Definition acpi.h:37
madt_record_table_entry_t table[]
Definition acpi.h:40
uint32_t localApicAddress
Definition acpi.h:38
Definition acpi.h:6
char Signature[8]
Definition acpi.h:7
uint32_t RsdtAddress
Definition acpi.h:11
Definition acpi.h:26
struct SDT h
Definition acpi.h:27
uint32_t PointerToOtherSDT[]
Definition acpi.h:28
Definition acpi.h:14
char Signature[4]
Definition acpi.h:15
uint32_t Length
Definition acpi.h:16
uint8_t apicid
Definition acpi.h:70
uint32_t flag
Definition acpi.h:72
unsigned short uint16_t
Definition type.h:13
unsigned int uint32_t
Definition type.h:19
unsigned long uintptr_t
Definition type.h:73
#define UNUSED(x)
Definition type.h:100
unsigned char uint8_t
Definition type.h:7
uint32_t offset
Definition virtio.h:6
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
Definition vm_manager.c:156
void vma_register(struct virtual_memory_page *page, uintptr_t phys_address, uintptr_t virt_addr, size_t size)
Definition vm_manager.c:101
void vma_unregister(struct virtual_memory_page *page, uintptr_t virt_addr)
Definition vm_manager.c:126
struct virtual_memory_page * get_kernel_vmm_page()
int core
Definition vm_manager.h:5
@ VMA_REGION_A
Definition vm_manager.h:13
uint64_t ptr
Definition xhci.hpp:0