Move system calls to the SDK and normalize their names
[monolithium.git] / kernel / src / acpica / osmlxf.c
1 /*
2  * osmlxf.c (Monolithium ACPICA OSL)
3  *
4  * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <common.h>
21 #include <heap.h>
22 #include <memory.h>
23 #include <thread.h>
24 #include <cpu.h>
25 #include <timer.h>
26 #include <interrupt.h>
27 #include <acpica/acpi.h>
28
29 static ACPI_OSD_HANDLER acpica_int_handlers[256] = { NULL };
30 static void *acpica_int_contexts[256] = { NULL };
31
32 static void acpica_osl_handler(registers_t *regs, byte_t int_num)
33 {
34     acpica_int_handlers[int_num](acpica_int_contexts[int_num]);
35 }
36
37 ACPI_STATUS AcpiOsInitialize(void)
38 {
39     return AE_OK;
40 }
41
42 ACPI_STATUS AcpiOsTerminate(void)
43 {
44     return AE_OK;
45 }
46
47 ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
48 {
49     ACPI_PHYSICAL_ADDRESS Address;
50     AcpiFindRootPointer(&Address);
51     return Address;
52 }
53
54 ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
55 {
56     *NewValue = NULL;
57     return AE_OK;
58 }
59
60 ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable)
61 {
62     *NewTable = NULL;
63     return AE_OK;
64 }
65
66 ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
67 {
68     *NewAddress = 0;
69     return AE_OK;
70 }
71
72 ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
73 {
74     return AE_SUPPORT; // TODO
75 }
76
77 void AcpiOsVprintf(const char *Format, va_list Args)
78 {
79     vprintf(Format, Args);
80 }
81
82 void AcpiOsPrintf(const char *Format, ...)
83 {
84     va_list args;
85     va_start(args, Format);
86     AcpiOsVprintf(Format, args);
87     va_end(args);
88 }
89
90 ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
91 {
92     switch (Width)
93     {
94     case 8:
95         *Value = inportb(Address);
96         break;
97     case 16:
98         *Value = inportw(Address);
99         break;
100     case 32:
101         *Value = inportl(Address);
102         break;
103     default:
104         return AE_SUPPORT;
105     }
106
107     return AE_OK;
108 }
109
110 ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
111 {
112     switch (Width)
113     {
114     case 8:
115         outportb(Address, Value);
116         break;
117     case 16:
118         outportw(Address, Value);
119         break;
120     case 32:
121         outportl(Address, Value);
122         break;
123     default:
124         return AE_SUPPORT;
125     }
126
127     return AE_OK;
128 }
129
130 void *AcpiOsAllocate(ACPI_SIZE Size)
131 {
132     return malloc(Size);
133 }
134
135 void AcpiOsFree(void *Memory)
136 {
137     free(Memory);
138 }
139
140 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
141 {
142     *Value = 0;
143     dword_t ret = read_physical((void*)((uintptr_t)Address), Value, Width / 8);
144
145     if (ret == ERR_SUCCESS) return AE_OK;
146     if (ret == ERR_NOMEMORY) return AE_NO_MEMORY;
147     return AE_ERROR;
148 }
149
150 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
151 {
152     dword_t ret = write_physical((void*)((uintptr_t)Address), &Value, Width / 8);
153
154     if (ret == ERR_SUCCESS) return AE_OK;
155     if (ret == ERR_NOMEMORY) return AE_NO_MEMORY;
156     return AE_ERROR;
157 }
158
159 void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Address, ACPI_SIZE Length)
160 {
161     void *virtual = NULL;
162
163     if (map_memory((void*)PAGE_ALIGN((uintptr_t)Address),
164                    &virtual,
165                    PAGE_ALIGN_UP(PAGE_OFFSET((uintptr_t)Address) + Length),
166                    MEMORY_BLOCK_ACCESSIBLE | MEMORY_BLOCK_WRITABLE) == ERR_SUCCESS)
167     {
168         return (void*)((uintptr_t)virtual + PAGE_OFFSET((uintptr_t)Address));
169     }
170     else
171     {
172         return NULL;
173     }
174 }
175
176 void AcpiOsUnmapMemory(void *Address, ACPI_SIZE Length)
177 {
178     UNUSED_PARAMETER(Length);
179     unmap_memory(Address);
180 }
181
182 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
183 {
184     *OutHandle = malloc(sizeof(critical_t));
185     if (*OutHandle == NULL) return AE_NO_MEMORY;
186     return AE_OK;
187 }
188
189 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
190 {
191     free(Handle);
192 }
193
194 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
195 {
196     enter_critical(Handle);
197     return *(critical_t*)Handle;
198 }
199
200 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
201 {
202     UNUSED_PARAMETER(Flags);
203     leave_critical(Handle);
204 }
205
206 ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
207 {
208     semaphore_t *semaphore = malloc(sizeof(semaphore_t));
209     if (semaphore == NULL) return AE_NO_MEMORY;
210
211     init_semaphore(semaphore, InitialUnits, MaxUnits);
212     *OutHandle = (ACPI_SEMAPHORE)semaphore;
213     return AE_OK;
214 }
215
216 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
217 {
218     free(Handle);
219     return AE_OK;
220 }
221
222 ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
223 {
224     dword_t ret = wait_semaphore((semaphore_t*)Handle, Units, (int32_t)((int16_t)Timeout));
225
226     if (ret == ERR_SUCCESS) return AE_OK;
227     else if (ret == ERR_TIMEOUT) return AE_TIME;
228     else return AE_ERROR;
229 }
230
231 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
232 {
233     release_semaphore((semaphore_t*)Handle, Units);
234     return AE_OK;
235 }
236
237 UINT64 AcpiOsGetTimer(void)
238 {
239     return syscall_get_nanoseconds() / 100ULL;
240 }
241
242 void AcpiOsSleep(UINT64 Milliseconds)
243 {
244     syscall_sleep(Milliseconds);
245 }
246
247 void AcpiOsStall(UINT32 Microseconds)
248 {
249     qword_t end_time = syscall_get_nanoseconds() + (qword_t)Microseconds * 1000ULL;
250     while (syscall_get_nanoseconds() < end_time) continue;
251 }
252
253 ACPI_THREAD_ID AcpiOsGetThreadId(void)
254 {
255     return syscall_get_thread_id() + 1;
256 }
257
258 ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
259 {
260     if (InterruptLevel >= 256) return AE_BAD_PARAMETER;
261
262     acpica_int_handlers[InterruptLevel] = Handler;
263     acpica_int_contexts[InterruptLevel] = Context;
264     return AE_OK;
265 }
266
267 ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler)
268 {
269     acpica_int_handlers[InterruptLevel] = NULL;
270     acpica_int_contexts[InterruptLevel] = NULL;
271     return AE_OK;
272 }
273
274 ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
275 {
276     thread_t *thread;
277     dword_t ret = create_system_thread((thread_procedure_t)Function, 0, THREAD_PRIORITY_MID, 0, Context, &thread);
278
279     if (ret == ERR_SUCCESS)
280     {
281         dereference(&thread->header);
282         return AE_OK;
283     }
284     else if (ret == ERR_INVALID)
285     {
286         return AE_BAD_PARAMETER;
287     }
288     else
289     {
290         return AE_ERROR;
291     }
292 }
293
294 void AcpiOsWaitEventsComplete(void)
295 {
296     // TODO
297 }
298
299 ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
300 {
301     return AE_SUPPORT; // TODO
302 }
303
304 ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
305 {
306      return AE_SUPPORT; // TODO
307 }