kernel: C++ read_once() and write_once() functions
This commit is contained in:
@@ -8,58 +8,58 @@
|
|||||||
#define IOAPICREDTBL(n) (0x10 + 2 * n)
|
#define IOAPICREDTBL(n) (0x10 + 2 * n)
|
||||||
|
|
||||||
namespace arch::acpi {
|
namespace arch::acpi {
|
||||||
io_apic::io_apic(uint32_t *base, unsigned int first_irq) : io_base(base), io_first_irq(first_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;
|
io_nr_irq = ((read(IOAPICVER) >> 16) + 1) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t io_apic::read(uint32_t reg)
|
uint32_t io_apic::read(uint32_t reg)
|
||||||
{
|
{
|
||||||
*(volatile uint32_t *)(io_base) = reg & 0xFF;
|
write_once(io_base, reg & 0xFF);
|
||||||
return *(volatile uint32_t *)((char *)io_base + 0x10);
|
return read_once(io_base + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_apic::write(uint32_t reg, uint32_t val)
|
void io_apic::write(uint32_t reg, uint32_t val)
|
||||||
{
|
{
|
||||||
*(volatile uint32_t *)(io_base) = reg & 0xFF;
|
write_once(io_base, reg & 0xFF);
|
||||||
*(volatile uint32_t *)((char *)io_base + 0x10) = val;
|
write_once(io_base + 4, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry)
|
kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry)
|
||||||
{
|
{
|
||||||
if (index >= io_nr_irq) {
|
if (index >= io_nr_irq) {
|
||||||
return KERN_NO_ENTRY;
|
return KERN_NO_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *entry_data = (uint32_t *)&entry;
|
uint32_t *entry_data = (uint32_t *)&entry;
|
||||||
entry_data[0] = read(IOAPICREDTBL(index));
|
entry_data[0] = read(IOAPICREDTBL(index));
|
||||||
entry_data[1] = read(IOAPICREDTBL(index) + 1);
|
entry_data[1] = read(IOAPICREDTBL(index) + 1);
|
||||||
|
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_apic::write_irq(unsigned int index, const irq_entry &entry)
|
void io_apic::write_irq(unsigned int index, const irq_entry &entry)
|
||||||
{
|
{
|
||||||
if (index >= io_nr_irq) {
|
if (index >= io_nr_irq) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t *entry_data = (const uint32_t *)&entry;
|
const uint32_t *entry_data = (const uint32_t *)&entry;
|
||||||
write(IOAPICREDTBL(index), entry_data[0]);
|
write(IOAPICREDTBL(index), entry_data[0]);
|
||||||
write(IOAPICREDTBL(index) + 1, entry_data[1]);
|
write(IOAPICREDTBL(index) + 1, entry_data[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_apic::map_irq(unsigned int src, unsigned int dest)
|
void io_apic::map_irq(unsigned int src, unsigned int dest)
|
||||||
{
|
{
|
||||||
io_apic::irq_entry irq{};
|
io_apic::irq_entry irq{};
|
||||||
irq.irq_vec = dest;
|
irq.irq_vec = dest;
|
||||||
irq.irq_delivery = 0;
|
irq.irq_delivery = 0;
|
||||||
irq.irq_destmode = 0;
|
irq.irq_destmode = 0;
|
||||||
irq.irq_polarity = 0;
|
irq.irq_polarity = 0;
|
||||||
irq.irq_triggermode = 0;
|
irq.irq_triggermode = 0;
|
||||||
irq.irq_mask = 0;
|
irq.irq_mask = 0;
|
||||||
irq.irq_dest = 0;
|
irq.irq_dest = 0;
|
||||||
|
|
||||||
write_irq(src, irq);
|
write_irq(src, irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
#include <arch/acpi/local_apic.hpp>
|
#include <arch/acpi/local_apic.hpp>
|
||||||
#include <socks/vm.h>
|
#include <socks/vm.h>
|
||||||
|
#include <socks/compiler.h>
|
||||||
|
|
||||||
#define LAPIC_REG_EOI 0xB0
|
#define LAPIC_REG_EOI 0xB0
|
||||||
|
|
||||||
namespace arch::acpi {
|
namespace arch::acpi {
|
||||||
local_apic::local_apic(uint32_t *base) : base_(base)
|
local_apic::local_apic(uint32_t *base) : base_(base)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t local_apic::read(uint32_t reg)
|
uint32_t local_apic::read(uint32_t reg)
|
||||||
{
|
{
|
||||||
return *(volatile uint32_t *)((char *)base_ + reg);
|
return read_once(base_ + (reg >> 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void local_apic::write(uint32_t reg, uint32_t val)
|
void local_apic::write(uint32_t reg, uint32_t val)
|
||||||
{
|
{
|
||||||
*(volatile uint32_t *)((char *)base_ + reg) = val;
|
write_once(base_ + (reg >> 2), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void local_apic::ack()
|
void local_apic::ack()
|
||||||
{
|
{
|
||||||
*(volatile uint32_t *)((char *)base_ + LAPIC_REG_EOI) = 0;
|
write(LAPIC_REG_EOI, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,20 @@
|
|||||||
#define READ_ONCE(t, p) (*((const volatile t *)&(p)))
|
#define READ_ONCE(t, p) (*((const volatile t *)&(p)))
|
||||||
#define WRITE_ONCE(t, p, v) *(volatile t *)&(p) = (v)
|
#define WRITE_ONCE(t, p, v) *(volatile t *)&(p) = (v)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
template <typename T>
|
||||||
|
T read_once(const volatile T *ptr)
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void write_once(volatile T *ptr, T value)
|
||||||
|
{
|
||||||
|
*ptr = value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef __used
|
#undef __used
|
||||||
#define __used __attribute__((used))
|
#define __used __attribute__((used))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user