Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
ioforge.c
Go to the documentation of this file.
1#include "hal/acpi/hpet.h"
3#include "memory/kalloc.h"
6#include "memory/vm_manager.h"
7#include <console/console.h>
8#include <hal/pci/pci.h>
9#include <ioforge/ioforge.h>
10#include <ioforge/ioforge_usb.h>
11#include <libk/serial.h>
12#include <str.h>
13
14#include "hal/apic/ioapic.h"
15#include "hal/cpu/interrupt.h"
16#include "hal/cpu/paging.h"
17#include "hal/timer/timer.h"
18#include "init/init.h"
19#include "libk/debug/debug.h"
20
21#include "type.h"
22#include <hal/cpu/core.h>
23#include <type.h>
24
25static struct ioforge_device* root = 0;
26static struct ioforge_device* pci_root = 0;
30
31void KERNEL_API print_device_tree(struct ioforge_device* node, int indent) {
32 if (!node)
33 return;
34
35 for (int i = 0; i < indent; i++)
36 serial2_printf(" ");
37
38 if (node->type == IOFORGE_USB_DEVICE) {
39 struct ioforge_usb_device* d = (struct ioforge_usb_device*)node;
40 if (d->base.name[0] != 0 && d->serial_number[0] != 0)
41 serial2_printf("usb device: %s %s\n", d->base.name,
42 d->serial_number);
43 } else if (node->type == IOFORGE_PCI || node->type == IOFORGE_VIRTIO) {
44 struct ioforge_pci_device* pd =
45 (struct ioforge_pci_device*)node;
46 serial2_printf("pci %d:%d\n", pd->vendor_id, pd->device_id);
47 } else {
48 serial2_printf("device: %s\n", node->name);
49 }
50
51 print_device_tree(node->first_child, indent + 1);
52 print_device_tree(node->next_sibling, indent);
53}
54
55INIT(ioforge) {
56 /* setup tree */
57 root = kalloc(sizeof(struct ioforge_device));
58 memset(root, 0, sizeof(*root));
59 strcpy((char*)root->name, "ROOT");
60 root->type = IOFORGE_ROOT;
61
62 struct ioforge_device* acpi_root =
63 kalloc(sizeof(struct ioforge_device));
64 memset(acpi_root, 0, sizeof(*acpi_root));
65 strcpy((char*)acpi_root->name, "_SB");
66 acpi_root->type = IOFORGE_ROOT;
67 ioforge_attach(root, acpi_root);
68
69 pci_root = kalloc(sizeof(struct ioforge_device));
70 memset(pci_root, 0, sizeof(*pci_root));
71 strcpy((char*)pci_root->name, "PCI");
72 pci_root->type = IOFORGE_ROOT;
73 ioforge_attach(acpi_root, pci_root);
74
77 strcpy((char*)usb_controller_root->name, "USB_CTRL");
80
81 usb_devices_root = kalloc(sizeof(struct ioforge_device));
83 strcpy((char*)usb_devices_root->name, "USB_DEV");
86
89 strcpy((char*)block_devices_root->name, "BLOCK");
92
93 // enumerate pci
94 pci_scan();
95 KDEBUG(DEBUG_LEVEL_INFO, "PCI Scan done\n");
96}
97
99 struct ioforge_device* child) {
100
101 if (!parent || !child)
102 return;
103
104 child->parent = parent;
105 child->next_sibling = parent->first_child;
106 child->prev_sibling = 0;
107
108 if (parent->first_child)
109 parent->first_child->prev_sibling = child;
110
111 parent->first_child = child;
112 child->flags |= IOFORGE_F_ENABLE;
113}
114
116 const char* name) {
117 if (!r)
118 return NULL;
119
120 if (strncmp(r->name, name, 64) == 0)
121 return r;
122
123 struct ioforge_device* child = r->first_child;
124 while (child) {
125 struct ioforge_device* found =
127 if (found)
128 return found;
129 child = child->next_sibling;
130 }
131
132 return NULL;
133}
134
136
138 return usb_controller_root;
139}
140
142 return usb_devices_root;
143}
144
146 return block_devices_root;
147}
148
150 switch (type) {
151 case IOFORGE_ROOT:
152 case IOFORGE_ACPI:
153 case IOFORGE_PCI_BUS:
154 case IOFORGE_PCI: /* PCI bridge bisa punya PCI child */
155 return true;
156 default:
157 return false; /* USB, NIC, UART, dll → skip */
158 }
159}
160
164
165 if (!node)
166 return NULL;
167
168 if (node->type == IOFORGE_PCI) {
169 struct ioforge_pci_device* pci =
170 (struct ioforge_pci_device*)node;
171 if (pci->vendor_id == vendor_id && pci->device_id == device_id)
172 return pci;
173 }
174
175 if (!ioforge_can_contain_pci(node->type))
176 return NULL;
177
178 struct ioforge_device* child = node->first_child;
179 while (child) {
180 struct ioforge_pci_device* found =
182 if (found)
183 return found;
184 child = child->next_sibling;
185 }
186
187 return NULL;
188}
189
191
193
194KERNEL_API void ioforge_free(void* ptr, size_t size) { kfree(ptr, size); }
195
196KERNEL_API void ioforge_memset(void* ptr, uint8_t value, size_t num) {
197 memset(ptr, value, num);
198}
199
200KERNEL_API void ioforge_memcpy(void* dst, void* src, size_t num) {
201 memcopy(dst, src, num);
202}
203
204KERNEL_API void* ioforge_dma_alloc(size_t size, uintptr_t* paddr) {
205 size_t aligned_size = ALIGN_UP(size, BLOCK_SIZE) / BLOCK_SIZE;
206 // LOG_DEBUG("IOFORGE DMA", "alloc size %d", aligned_size);
207 uintptr_t paddr_ = (uintptr_t)phys_base_alloc(aligned_size);
210 aligned_size, 0b111);
212 vma_register(get_kernel_vmm_page(), paddr_, vaddr, aligned_size * BLOCK_SIZE);
213 if (paddr != 0) {
214 *paddr = paddr_;
215 }
216 return (void*)vaddr;
217}
218
220void ioforge_dma_free(void* paddr, void* vaddr, size_t size) {
221 size_t aligned_size = ALIGN_UP(size, BLOCK_SIZE) / BLOCK_SIZE;
222 vxPhysBaseFree(paddr, aligned_size);
224 aligned_size);
227}
228
231 auto paddr_base = ALIGN_DOWN(paddr, PAGE_SIZE);
232 auto offset_paddr = paddr - paddr_base;
234 vxMultipleMmap(paging_get_highest_page_map(), vaddr, paddr_base, size,
235 0b111);
237 vma_register(get_kernel_vmm_page(), paddr, vaddr, size / 4096);
238 return vaddr + offset_paddr;
239}
240
242
243// KERNEL_API void ioforge_mmio_outl(uint32_t port, uint32_t value) {
244// mmio_outl(port, value);
245// }
246
247// KERNEL_API uint32_t ioforge_mmio_inl(uint32_t port) {
248// return mmio_inl(port);
249// }
250
252 auto core_id = get_current_core_cpuid();
253 auto irq = irq_alloc_entry(core_id);
254 LOG2_INFO("IOFORGE", "allocating irq on core %d = %d", core_id, irq);
255 return irq;
256}
257
259 return ioapic_isr_get_vector(irq);
260}
261
262KERNEL_API void ioforge_irq_register(uint8_t n, void* handler) {
263 auto core_id = get_current_core_cpuid();
264 LOG2_INFO("IOFORGE", "registering irq %d on core %d", n, core_id);
265 irq_register(core_id, n, handler, true, 0x28, 0, INTERRUPT_ATTR_KERNEL);
266}
267
268KERNEL_API uint32_t isr_irq_register(uint8_t irq, void* handler) {
269 auto curr_isr = ioapic_isr_get_vector(irq);
270 auto core_id = get_current_core_cpuid();
271 auto curr_vector = curr_isr & 0xFF;
272
273 if (curr_isr & (uint32_t) ~(1 << 16) || curr_vector != 0) {
274 auto current_apic_id = ioapic_isr_get_apic_id(irq);
275 LOG2_INFO("ISR", "isr %d already used \n", curr_isr);
276
277 if (current_apic_id != core_id) {
278 LOG2_INFO("ISR",
279 "isr %d is used on another core, running on "
280 "lapic id %d\n",
281 curr_isr, current_apic_id);
282 }
283
284 irq_register(current_apic_id, (uint8_t)curr_vector, handler,
285 true, 0x28, 0, INTERRUPT_ATTR_KERNEL);
286
287 return curr_vector;
288 }
289
291 vxIOAPICMapISR(irq, vector, core_id);
292
293 irq_register(core_id, vector, handler, true, 0x28, 0,
295
296 return vector;
297}
298
299__attribute__((deprecated("deprecated"))) KERNEL_API void
301 auto core_id = get_current_core_cpuid();
302 LOG2_INFO("IOFORGE", "mapping isr %d on core %d", irq, core_id);
303 vxIOAPICMapISR(irq, vector, core_id);
304}
305
306KERNEL_API void IOforgeStrCopy(char* dst, char* src) { strcpy(dst, src); }
307
308KERNEL_API void IOforgeStrnCopy(char* dst, char* src, size_t len) {
309 strncpy(dst, src, len);
310}
311
313 return get_current_core_cpuid();
314}
@ DEBUG_LEVEL_INFO
Definition debug.h:8
#define KDEBUG(...)
Definition debug.h:16
kstring name
Definition dentry.h:5
dentry_ptr parent
Definition dentry.h:7
static ssfn_buf_t dst
Definition graphic.c:82
#define ms2ns(ms)
Definition hpet.h:12
uint8_t get_current_core_cpuid()
typedef __attribute__
Definition msi.c:47
#define INIT(fn)
Definition init.h:26
uint16_t irq_alloc_entry(uint8_t core)
Definition interrupt.c:109
void irq_register(uint8_t core, int n, void *handler, boolean_t use_default_isr, uint16_t selector, uint8_t ist, uint8_t type_attr)
Definition interrupt.c:70
#define INTERRUPT_ATTR_KERNEL
Definition interrupt.h:28
uint32_t ioapic_isr_get_vector(uint8_t irq)
Definition ioapic.c:26
void vxIOAPICMapISR(uint8_t irq, uint8_t vector, uint8_t apic_id)
Definition ioapic.c:36
uint8_t ioapic_isr_get_apic_id(uint8_t irq)
static struct ioforge_device * usb_controller_root
Definition ioforge.c:27
static struct ioforge_device * root
Definition ioforge.c:25
bool ioforge_can_contain_pci(IoForgeType type)
Definition ioforge.c:149
static struct ioforge_device * block_devices_root
Definition ioforge.c:29
static struct ioforge_device * pci_root
Definition ioforge.c:26
static struct ioforge_device * usb_devices_root
Definition ioforge.c:28
uint8_t ioforge_get_current_core_id()
void * ioforge_alloc(size_t size)
void ioforge_memset(void *ptr, uint8_t value, size_t num)
uint32_t ioforge_isr_get_vector(uint8_t irq)
struct ioforge_device * ioforge_get_root()
#define IOFORGE_F_ENABLE
Definition ioforge.h:22
void IOforgeStrCopy(char *dst, char *src)
void ioforge_map_isr(uint8_t irq, uint8_t vector)
struct ioforge_device * ioforge_find_by_name(struct ioforge_device *root, const char *name)
void print_device_tree(struct ioforge_device *node, int indent)
void ioforge_dma_free(void *paddr, void *vaddr, size_t size)
uint32_t isr_irq_register(uint8_t irq, void *handler)
void ioforge_free(void *ptr, size_t size)
void * ioforge_dma_alloc(size_t size, uintptr_t *paddr)
void ioforge_attach(struct ioforge_device *parent, struct ioforge_device *child)
void serial2_printf(const char *fmt,...)
void ioforge_sleep(uint32_t time)
uintptr_t IOforgeMMapPhys(uintptr_t paddr, size_t size)
struct ioforge_device * ioforge_get_pci_root()
struct ioforge_device * ioforge_get_block_devices_root()
void ioforge_memcpy(void *dst, void *src, size_t num)
void IOforgeStrnCopy(char *dst, char *src, size_t len)
uint16_t ioforge_irq_alloc_entry()
struct ioforge_pci_device * ioforge_find_pci_device(struct ioforge_device *node, uint16_t vendor_id, uint16_t device_id)
IoForgeType
Definition ioforge.h:10
@ IOFORGE_ACPI
Definition ioforge.h:14
@ IOFORGE_PCI
Definition ioforge.h:12
@ IOFORGE_PCI_BUS
Definition ioforge.h:13
@ IOFORGE_ROOT
Definition ioforge.h:11
@ IOFORGE_USB_DEVICE
Definition ioforge.h:15
@ IOFORGE_VIRTIO
Definition ioforge.h:18
void ioforge_irq_register(uint8_t n, void *handler)
struct ioforge_device * ioforge_get_usb_devices_root()
struct ioforge_device * ioforge_get_usb_ctrl_root()
struct ioforge_pci_device pci
void kfree(void *ptr, size_t size)
void * kalloc(size_t size)
#define ALIGN_DOWN(x, align)
Definition memory_utils.h:9
#define ALIGN_UP(x, align)
Definition memory_utils.h:6
size_t len
Definition oct2bin.h:7
return value
Definition oct2bin.h:22
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_SIZE
Definition paging.h:6
void pci_scan()
Definition scan.c:425
void * phys_base_alloc(uint64_t block)
void vxPhysBaseFree(void *ptr, uint64_t size)
#define BLOCK_SIZE
#define LOG2_INFO(mod, fmt,...)
Definition serial.h:33
int strncmp(const char *s1, const char *s2, size_t n)
void strcpy(char *dest, const char *src)
char * strncpy(char *dest, const char *src, size_t n)
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
uint32_t flags
Definition ioforge.h:32
struct ioforge_device * parent
Definition ioforge.h:35
struct ioforge_device * first_child
Definition ioforge.h:36
char name[64]
Definition ioforge.h:30
struct ioforge_device * prev_sibling
Definition ioforge.h:38
struct ioforge_device * next_sibling
Definition ioforge.h:37
IoForgeType type
Definition ioforge.h:31
struct ioforge_device base
Definition ioforge_usb.h:35
const char serial_number[64]
Definition ioforge_usb.h:36
void usleep(const uint64_t time_ns)
Definition timer.c:31
#define NULL
Definition type.h:76
unsigned short uint16_t
Definition type.h:13
unsigned int uint32_t
Definition type.h:19
#define KERNEL_API
Definition type.h:93
unsigned long uintptr_t
Definition type.h:73
unsigned char uint8_t
Definition type.h:7
#define DEPRECATED
Definition type.h:96
#define vector(T)
Definition vector.h:11
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()
@ VMA_REGION_A
Definition vm_manager.h:13
uint8_t type
Definition vnode.h:2
size_t size
Definition vnode.h:3
uint64_t ptr
Definition xhci.hpp:0