1#include <acpi/print.h>
2#include <acpi/uacpi_interface.h>
3#include <asm.h>
4#include <compiler.h>
5#include <console/printf.h>
6#include <drivers/mmio.h>
7#include <irq/idt.h>
8#include <mem/alloc.h>
9#include <mem/vmm.h>
10#include <pit.h>
11#include <sch/sched.h>
12#include <smp/core.h>
13#include <stdbool.h>
14#include <stdint.h>
15#include <sync/mutex.h>
16#include <sync/mutex_simple.h>
17#include <sync/spinlock.h>
18#include <thread/thread.h>
19#include <uacpi/event.h>
20#include <uacpi/platform/arch_helpers.h>
21#include <uacpi/status.h>
22#include <uacpi/types.h>
23#include <uacpi/uacpi.h>
24
25#include "uacpi/kernel_api.h"
26#include <types/freq.h>
27#include <types/types.h>
28
29#include "uacpi/log.h"
30#include "uacpi/namespace.h"
31
32freq_hz_t tsc_freq = 0;
33
34#define panic_if_error(x) \
35 if (uacpi_unlikely_error(x)) \
36 panic("uACPI initialization failed!");
37
38static uint64_t our_rsdp = 0;
39void uacpi_init(uint64_t rsdp) {
40 our_rsdp = rsdp;
41 tsc_freq = pit_measure_tsc_freq();
42
43 panic_if_error(uacpi_initialize(0));
44 panic_if_error(uacpi_namespace_load());
45 panic_if_error(uacpi_namespace_initialize());
46 panic_if_error(uacpi_finalize_gpe_initialization());
47}
48
49uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) {
50
51 if (our_rsdp == 0) {
52 printf(format: "no rsdp set\n");
53 return UACPI_STATUS_INTERNAL_ERROR;
54 }
55 *out_rsdp_address = our_rsdp;
56 return UACPI_STATUS_OK;
57}
58
59void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
60 void *ret = mmio_map(phys: addr, size: len);
61 return ret;
62}
63
64void uacpi_kernel_unmap(void *addr, uacpi_size len) {
65 return;
66 vmm_unmap_virt(addr, len, vflags: VMM_FLAG_NONE);
67}
68
69void uacpi_kernel_log(uacpi_log_level level, const uacpi_char *data) {
70 switch (level) {
71 case UACPI_LOG_ERROR: printf(format: ">> UACPI ERROR: %s", data); break;
72 case UACPI_LOG_TRACE: printf(format: ">> UACPI TRACE: %s", data); break;
73 case UACPI_LOG_INFO: printf(format: ">> UACPI INFO: %s", data); break;
74 case UACPI_LOG_WARN: printf(format: ">> UACPI WARN: %s", data); break;
75 default: break;
76 }
77}
78
79void *uacpi_kernel_alloc(uacpi_size size) {
80 void *ret = kmalloc(size);
81 return ret;
82}
83
84void uacpi_kernel_free(void *mem) {
85 kfree(mem);
86}
87
88uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len,
89 uacpi_handle *out_handle) {
90 if (!out_handle || len == 0) {
91 return UACPI_STATUS_INVALID_ARGUMENT;
92 }
93
94 uacpi_io_handle *handle =
95 (uacpi_io_handle *) kmalloc(sizeof(uacpi_io_handle));
96 if (!handle) {
97 return UACPI_STATUS_INTERNAL_ERROR;
98 }
99
100 handle->base = base;
101 handle->len = len;
102 handle->valid = true;
103
104 *out_handle = (uacpi_handle) handle;
105 return UACPI_STATUS_OK;
106}
107
108void uacpi_kernel_io_unmap(uacpi_handle h) {
109 if (!h)
110 return;
111
112 uacpi_io_handle *handle = (uacpi_io_handle *) h;
113 handle->valid = false;
114 kfree(handle);
115}
116
117uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void) {
118 if (tsc_freq == 0)
119 return 0;
120
121 return (rdtsc() * 1000000000ull) / tsc_freq;
122}
123
124void uacpi_kernel_stall(uacpi_u8 usec) {
125 uint64_t start = rdtsc();
126 uint64_t target = start + (HZ_TO_MHZ(tsc_freq) * usec);
127
128 while (rdtsc() < target)
129 cpu_relax();
130}
131
132void uacpi_kernel_sleep(uacpi_u64 msec) {
133
134 for (uacpi_u64 i = 0; i < msec * 10; i++)
135 uacpi_kernel_stall(usec: 100);
136}
137
138uacpi_status uacpi_kernel_install_interrupt_handler(
139 uacpi_u32 irq, uacpi_interrupt_handler handler, uacpi_handle ctx,
140 uacpi_handle *out_irq_handle) {
141 irq += 32;
142
143 if (irq >= 256)
144 return UACPI_STATUS_INVALID_ARGUMENT;
145
146 irq_register(name: "uacpi", vector: irq, handler: (void *) handler, ctx, flags: IRQ_FLAG_NONE);
147
148 if (out_irq_handle)
149 *out_irq_handle = (uacpi_handle) (uintptr_t) irq;
150
151 return UACPI_STATUS_OK;
152}
153
154uacpi_status
155uacpi_kernel_uninstall_interrupt_handler(uacpi_interrupt_handler handler,
156 uacpi_handle irq_handle) {
157 uint32_t irq = (uint32_t) (uintptr_t) irq_handle;
158 irq += 32;
159
160 (void) handler;
161
162 if (irq >= 256)
163 return UACPI_STATUS_INVALID_ARGUMENT;
164
165 irq_free_entry(entry: irq);
166 return UACPI_STATUS_OK;
167}
168
169uacpi_handle uacpi_kernel_create_spinlock(void) {
170 struct spinlock *lock = kmalloc(sizeof(struct spinlock), ALLOC_FLAGS_ZERO);
171 spinlock_init(lock);
172 return lock;
173}
174
175void uacpi_kernel_free_spinlock(uacpi_handle a) {
176 kfree(a);
177}
178
179uacpi_handle uacpi_kernel_create_mutex(void) {
180 struct mutex_simple *m =
181 kmalloc(sizeof(struct mutex_simple), ALLOC_FLAGS_ZERO);
182 mutex_simple_init(m);
183 return m;
184}
185
186void uacpi_kernel_free_mutex(uacpi_handle a) {
187 kfree(a);
188}
189
190uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle m, uacpi_u16 b) {
191 (void) b;
192 mutex_simple_lock(m);
193 return UACPI_STATUS_OK;
194}
195
196void uacpi_kernel_release_mutex(uacpi_handle m) {
197 mutex_simple_unlock(m);
198}
199
200uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle a) {
201 return spin_lock((struct spinlock *) a);
202}
203
204void uacpi_kernel_unlock_spinlock(uacpi_handle a, uacpi_cpu_flags b) {
205 spin_unlock((struct spinlock *) a, b);
206}
207
208uacpi_thread_id uacpi_kernel_get_thread_id(void) {
209 return thread_get_current();
210}
211
212//
213//
214//
215// stuff down here is unfinished/not complete
216// vvvvvvvvvvv
217//
218//
219//
220//
221//
222
223uacpi_status uacpi_kernel_schedule_work(uacpi_work_type, uacpi_work_handler,
224 uacpi_handle) {
225 return UACPI_STATUS_OK;
226}
227
228uacpi_status uacpi_kernel_wait_for_work_completion(void) {
229
230 return UACPI_STATUS_OK;
231}
232
233uacpi_handle uacpi_kernel_create_event(void) {
234
235 return kmalloc(8, ALLOC_FLAGS_ZERO);
236}
237void uacpi_kernel_free_event(uacpi_handle a) {
238
239 kfree(a);
240}
241
242uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16) {
243 return false;
244}
245void uacpi_kernel_signal_event(uacpi_handle) {}
246
247void uacpi_kernel_reset_event(uacpi_handle) {}
248
249uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *) {
250
251 return UACPI_STATUS_UNIMPLEMENTED;
252}
253