1#include <acpi/print.h>
2#include <acpi/uacpi_interface.h>
3#include <asm.h>
4#include <compiler/core.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(INIT_FAILED, "uACPI");
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 = (void *) 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(addr, len);
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 = valloc(size);
81 return ret;
82}
83
84void uacpi_kernel_free(void *mem) {
85 vfree(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 = vnew(handle);
95 if (!handle) {
96 return UACPI_STATUS_INTERNAL_ERROR;
97 }
98
99 handle->base = base;
100 handle->len = len;
101 handle->valid = true;
102
103 *out_handle = (uacpi_handle) handle;
104 return UACPI_STATUS_OK;
105}
106
107void uacpi_kernel_io_unmap(uacpi_handle h) {
108 if (!h)
109 return;
110
111 uacpi_io_handle *handle = (uacpi_io_handle *) h;
112 handle->valid = false;
113 vfree(handle);
114}
115
116uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void) {
117 if (tsc_freq == 0)
118 return 0;
119
120 return (rdtsc() * 1000000000ull) / tsc_freq;
121}
122
123void uacpi_kernel_stall(uacpi_u8 usec) {
124 uint64_t start = rdtsc();
125 uint64_t target = start + (HZ_TO_MHZ(tsc_freq) * usec);
126
127 while (rdtsc() < target)
128 cpu_pause();
129}
130
131void uacpi_kernel_sleep(uacpi_u64 msec) {
132
133 for (uacpi_u64 i = 0; i < msec * 10; i++)
134 uacpi_kernel_stall(usec: 100);
135}
136
137struct uacpi_irq_shim {
138 uacpi_interrupt_handler handler;
139 uacpi_handle ctx;
140};
141
142static struct uacpi_irq_shim uacpi_irq_shims[256];
143
144static enum irq_result uacpi_irq_trampoline(struct irq_context *ictx,
145 void *data) {
146 cc_ignore(ictx);
147 struct uacpi_irq_shim *shim = data;
148 return shim->handler(shim->ctx) == UACPI_INTERRUPT_HANDLED ? IRQ_HANDLED
149 : IRQ_NONE;
150}
151
152uacpi_status uacpi_kernel_install_interrupt_handler(
153 uacpi_u32 irq, uacpi_interrupt_handler handler, uacpi_handle ctx,
154 uacpi_handle *out_irq_handle) {
155 irq += 32;
156
157 if (irq >= 256)
158 return UACPI_STATUS_INVALID_ARGUMENT;
159
160 uacpi_irq_shims[irq].handler = handler;
161 uacpi_irq_shims[irq].ctx = ctx;
162 irq_register(name: "uacpi", vector: irq, handler: uacpi_irq_trampoline, ctx: &uacpi_irq_shims[irq],
163 flags: IRQ_FLAG_NONE);
164
165 if (out_irq_handle)
166 *out_irq_handle = (uacpi_handle) (uintptr_t) irq;
167
168 return UACPI_STATUS_OK;
169}
170
171uacpi_status
172uacpi_kernel_uninstall_interrupt_handler(uacpi_interrupt_handler handler,
173 uacpi_handle irq_handle) {
174 uint32_t irq = (uint32_t) (uintptr_t) irq_handle;
175
176 cc_ignore(handler);
177
178 if (irq >= 256)
179 return UACPI_STATUS_INVALID_ARGUMENT;
180
181 irq_free_entry(entry: irq);
182 return UACPI_STATUS_OK;
183}
184
185uacpi_handle uacpi_kernel_create_spinlock(void) {
186 struct spinlock *lock = vnew(lock, ALLOC_ZERO);
187 spinlock_init(lock);
188 return lock;
189}
190
191void uacpi_kernel_free_spinlock(uacpi_handle a) {
192 vfree(a);
193}
194
195uacpi_handle uacpi_kernel_create_mutex(void) {
196 struct mutex_simple *m = vnew(m, ALLOC_ZERO);
197 mutex_simple_init(m);
198 return m;
199}
200
201void uacpi_kernel_free_mutex(uacpi_handle a) {
202 vfree(a);
203}
204
205uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle m,
206 uacpi_u16 b) TSA_NO_ANALYSIS {
207 cc_ignore(b);
208 mutex_simple_lock(m);
209 return UACPI_STATUS_OK;
210}
211
212void uacpi_kernel_release_mutex(uacpi_handle m) TSA_NO_ANALYSIS {
213 mutex_simple_unlock(m);
214}
215
216uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle a) TSA_NO_ANALYSIS {
217 return spin_lock((struct spinlock *) a);
218}
219
220void uacpi_kernel_unlock_spinlock(uacpi_handle a,
221 uacpi_cpu_flags b) TSA_NO_ANALYSIS {
222 spin_unlock((struct spinlock *) a, b);
223}
224
225uacpi_thread_id uacpi_kernel_get_thread_id(void) {
226 return thread_get_current();
227}
228
229//
230//
231//
232// stuff down here is unfinished/not complete
233// vvvvvvvvvvv
234//
235//
236//
237//
238//
239
240uacpi_status uacpi_kernel_schedule_work(uacpi_work_type type,
241 uacpi_work_handler handler,
242 uacpi_handle ctx) {
243 cc_ignore(type, handler, ctx);
244 return UACPI_STATUS_OK;
245}
246
247uacpi_status uacpi_kernel_wait_for_work_completion(void) {
248
249 return UACPI_STATUS_OK;
250}
251
252uacpi_handle uacpi_kernel_create_event(void) {
253
254 return valloc(8, ALLOC_ZERO);
255}
256void uacpi_kernel_free_event(uacpi_handle a) {
257
258 vfree(a);
259}
260
261uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle handle, uacpi_u16 timeout) {
262 cc_ignore(handle, timeout);
263 return false;
264}
265void uacpi_kernel_signal_event(uacpi_handle handle) {
266 cc_ignore(handle);
267}
268
269void uacpi_kernel_reset_event(uacpi_handle handle) {
270 cc_ignore(handle);
271}
272
273uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *req) {
274 cc_ignore(req);
275 return UACPI_STATUS_UNIMPLEMENTED;
276}
277