initgraph, whole lot of refactor
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#include <zinnia/init.h>
|
||||
#include <zinnia/pci.h>
|
||||
#include <zinnia/spin.h>
|
||||
#include <x86_64/asm.h>
|
||||
|
||||
constexpr uint16_t PCI_CONFIG_ADDRESS = 0xcf8;
|
||||
constexpr uint16_t PCI_CONFIG_DATA = 0xcfc;
|
||||
|
||||
static struct spinlock port_lock = {};
|
||||
|
||||
static void port_select(const struct pci_address* addr, uint16_t offset) {
|
||||
asm_outl(
|
||||
PCI_CONFIG_ADDRESS,
|
||||
1u << 31 | (uint32_t)addr->bus << 16 | (uint32_t)(addr->device & 0x1f) << 11 |
|
||||
(uint32_t)(addr->function & 0x7) << 8 | (offset & 0xfc)
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t port_read32(struct pci_access*, const struct pci_address* addr, uint16_t offset) {
|
||||
spin_lock(&port_lock);
|
||||
port_select(addr, offset);
|
||||
uint32_t value = asm_inl(PCI_CONFIG_DATA);
|
||||
spin_unlock(&port_lock);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void port_write32(struct pci_access*, const struct pci_address* addr, uint16_t offset, uint32_t value) {
|
||||
spin_lock(&port_lock);
|
||||
port_select(addr, offset);
|
||||
asm_outl(PCI_CONFIG_DATA, value);
|
||||
spin_unlock(&port_lock);
|
||||
}
|
||||
|
||||
static struct pci_access port_access = {
|
||||
.name = "port",
|
||||
.domain = 0,
|
||||
.start_bus = 0,
|
||||
.end_bus = 255,
|
||||
.priority = PCI_ACCESS_PRIO_LEGACY,
|
||||
.read32 = port_read32,
|
||||
.write32 = port_write32,
|
||||
};
|
||||
|
||||
[[__init]]
|
||||
static void pci_x86_stage_init(struct boot_info*) {
|
||||
pci_access_register(&port_access);
|
||||
}
|
||||
INIT_TASK(pci_x86_stage, "arch.x86_64.pci", pci_x86_stage_init);
|
||||
INIT_DEPENDS(pci_x86_stage, mem_stage);
|
||||
INIT_ENTAILS(pci_x86_stage, pci_stage);
|
||||
Reference in New Issue
Block a user