kernel: C++ read_once() and write_once() functions

This commit is contained in:
2023-03-25 20:37:37 +00:00
parent e615b7dec1
commit e1634de1b4
3 changed files with 87 additions and 72 deletions

View File

@@ -8,58 +8,58 @@
#define IOAPICREDTBL(n) (0x10 + 2 * n)
namespace arch::acpi {
io_apic::io_apic(uint32_t *base, unsigned int first_irq) : io_base(base), io_first_irq(first_irq)
{
io_nr_irq = ((read(IOAPICVER) >> 16) + 1) & 0xFF;
}
uint32_t io_apic::read(uint32_t reg)
{
*(volatile uint32_t *)(io_base) = reg & 0xFF;
return *(volatile uint32_t *)((char *)io_base + 0x10);
}
void io_apic::write(uint32_t reg, uint32_t val)
{
*(volatile uint32_t *)(io_base) = reg & 0xFF;
*(volatile uint32_t *)((char *)io_base + 0x10) = val;
}
kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry)
{
if (index >= io_nr_irq) {
return KERN_NO_ENTRY;
}
uint32_t *entry_data = (uint32_t *)&entry;
entry_data[0] = read(IOAPICREDTBL(index));
entry_data[1] = read(IOAPICREDTBL(index) + 1);
return KERN_OK;
}
void io_apic::write_irq(unsigned int index, const irq_entry &entry)
{
if (index >= io_nr_irq) {
return;
}
const uint32_t *entry_data = (const uint32_t *)&entry;
write(IOAPICREDTBL(index), entry_data[0]);
write(IOAPICREDTBL(index) + 1, entry_data[1]);
}
void io_apic::map_irq(unsigned int src, unsigned int dest)
{
io_apic::irq_entry irq{};
irq.irq_vec = dest;
irq.irq_delivery = 0;
irq.irq_destmode = 0;
irq.irq_polarity = 0;
irq.irq_triggermode = 0;
irq.irq_mask = 0;
irq.irq_dest = 0;
write_irq(src, irq);
}
io_apic::io_apic(uint32_t *base, unsigned int first_irq) : io_base(base), io_first_irq(first_irq)
{
io_nr_irq = ((read(IOAPICVER) >> 16) + 1) & 0xFF;
}
uint32_t io_apic::read(uint32_t reg)
{
write_once(io_base, reg & 0xFF);
return read_once(io_base + 4);
}
void io_apic::write(uint32_t reg, uint32_t val)
{
write_once(io_base, reg & 0xFF);
write_once(io_base + 4, val);
}
kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry)
{
if (index >= io_nr_irq) {
return KERN_NO_ENTRY;
}
uint32_t *entry_data = (uint32_t *)&entry;
entry_data[0] = read(IOAPICREDTBL(index));
entry_data[1] = read(IOAPICREDTBL(index) + 1);
return KERN_OK;
}
void io_apic::write_irq(unsigned int index, const irq_entry &entry)
{
if (index >= io_nr_irq) {
return;
}
const uint32_t *entry_data = (const uint32_t *)&entry;
write(IOAPICREDTBL(index), entry_data[0]);
write(IOAPICREDTBL(index) + 1, entry_data[1]);
}
void io_apic::map_irq(unsigned int src, unsigned int dest)
{
io_apic::irq_entry irq{};
irq.irq_vec = dest;
irq.irq_delivery = 0;
irq.irq_destmode = 0;
irq.irq_polarity = 0;
irq.irq_triggermode = 0;
irq.irq_mask = 0;
irq.irq_dest = 0;
write_irq(src, irq);
}
}