Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/kernel/arch/riscv64/paging.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void mm_paging_fence(void) {
sfence_vma();
}

static bool mm_paging_walk(uaddr va, paddr *pte, bool alloc) {
bool mm_paging_walk(uaddr va, paddr *pte, bool alloc) {
assert(is_aligned(va, PAGE_BITS), "va={uaddr}", va);
assert((uaddr)(((iaddr)va >> 39) + 1) <= 1, "va={uaddr}", va);
assert(pte);
Expand Down
9 changes: 9 additions & 0 deletions src/kernel/devices/netdev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: ukoOS Contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#include <devices/netdev.h>

struct list_head netdevs = LIST_INIT(netdevs);
49 changes: 49 additions & 0 deletions src/kernel/devices/pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2026 ukoOS Contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#include <devices/pci.h>

struct list_head pcis = LIST_INIT(pcis);

struct registered_device {
void (*callback)(struct pci_regs *regs);
u16 vid;
u16 did;
};

struct registered_device *handlers = nullptr;
usize handlers_len = 0, handlers_cap = 0;

void pci_register(u16 vid, u16 did, void (*callback)(struct pci_regs *regs)) {
if (!handlers) {
assert(!handlers_len);
handlers_cap = 16;
handlers = alloc(sizeof(struct registered_device) * handlers_cap);
assert(handlers, "Failed to allocate handlers vector");
}

if (handlers_cap == handlers_len) {
handlers_cap *= 2;
struct registered_device *new_handlers =
realloc(handlers, sizeof(struct registered_device) * handlers_cap);
assert(new_handlers, "Failed to reallocate pci handlers vector");
handlers = new_handlers;
}

handlers[handlers_len++] = (struct registered_device) {
.vid = vid,
.did = did,
.callback = callback
};
}

void (*pci_get_handler(u16 vid, u16 did))(struct pci_regs *regs) {
for (usize i = 0; i<handlers_len; ++i) {
if (handlers[i].vid == vid && handlers[i].did == did)
return handlers[i].callback;
}
return nullptr;
}
2 changes: 2 additions & 0 deletions src/kernel/drivers/include.mak
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
# SPDX-License-Identifier: GPL-3.0-or-later

kernel-objs-c += drivers/ns16550a
kernel-objs-c += drivers/pci_device
kernel-objs-c += drivers/rtl8139
118 changes: 118 additions & 0 deletions src/kernel/drivers/pci_device.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 2026 ukoOS Contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <print.h>
#include <mm/paging.h>
#include <mm/virtual_alloc.h>
#include <physical.h>
#include <devicetree.h>

#include <devices/pci.h>

struct pci_device {
struct device device;
struct pci pci;
void *reg_base;
};
union pci_device_addr {
struct {
u32 offset : 8;
u32 func : 3;
u32 dev : 5;
u32 bus : 8;
u32 rsvd : 7;
u32 enable : 1;
};
u32 bits;
};

void register_device(struct pci *this, u16 vid, u16 did, void (*callback)(void *regs));

static struct pci_ops pci_device_ops = {
};
static_assert( offsetof(struct pci_regs, memar) == 0x14);

void pci_enumerate(uaddr reg_base) {
uaddr lo, hi;
struct vma *vma;

vma = vma_alloc(&kernel_virtual_allocator, 32);
assert(vma);

vma_bounds(vma, &lo, &hi);

for (u32 bus=0; bus<256; ++bus) {
for (u32 dev=0; dev<32; ++dev) {
union pci_device_addr addr;
addr.offset = 0;
addr.func = 0;
addr.dev = dev & 31;
addr.bus = bus & 255;

struct pci_regs *device = (struct pci_regs *)(reg_base + addr.bits);

u16 did = device->did;
u16 vid = device->vid;

if (did == 0xffff && vid == 0xffff)
continue;

void (*callback)(struct pci_regs *) = pci_get_handler(vid, did);

if (callback) {
callback(device);
} else {
print("Unbekannt pci Gerät: {u16:x} Anbieter: {u16:x}", did, vid);
}
}
}
}

static struct device *pci_enumerate_dt(struct devicetree_node *node) {
struct pci_device *device = nullptr;
paddr reg_addr;
usize reg_size;

if (!devicetree_reg(node, 0, &reg_addr, &reg_size))
goto fail;

if (reg_size < sizeof(struct pci_regs))
goto fail;

device = alloc(sizeof(struct pci_device));
if (!device)
goto fail;

*device = (struct pci_device){
.device = DEVICE_INIT(device->device, "pci@{paddr}", reg_addr),
.pci =
{
.list = LIST_INIT(device->pci.list),
.ops = &pci_device_ops,
.device = &device->device,
},
.reg_base = iomem_map(reg_addr, reg_size),
};
if (!device->device.name || !device->reg_base)
goto fail;

list_push(&pcis, &device->pci.list);

pci_enumerate((uaddr) device->reg_base);

return &device->device;

fail:
if (device) {
free(device->device.name);
iomem_unmap(device->reg_base, reg_size);
}
free(device);
return nullptr;
}

DEFINE_INIT(INIT_REGISTER_DRIVERS) {
devicetree_register("pci-host-ecam-generic", pci_enumerate_dt);
}
Loading
Loading