[project] Lose the battle between tabs & spaces
I'm a tabs guy. I like tabs, it's an elegant way to represent indentation instead of brute-forcing it. But I have to admit that the world seems to be going towards spaces, and tooling tends not to play nice with tabs. So here we go, changing the whole repo to spaces since I'm getting tired of all the inconsistent formatting.
This commit is contained in:
committed by
Justin C. Miller
parent
d36b2d8057
commit
8f529046a9
@@ -26,286 +26,286 @@ static constexpr uint16_t lapic_timer_div = 0x03e0;
|
||||
static uint32_t
|
||||
apic_read(uint32_t volatile *apic, uint16_t offset)
|
||||
{
|
||||
return *(apic + offset/sizeof(uint32_t));
|
||||
return *(apic + offset/sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static void
|
||||
apic_write(uint32_t volatile *apic, uint16_t offset, uint32_t value)
|
||||
{
|
||||
log::debug(logs::apic, "LAPIC write: %x = %08lx", offset, value);
|
||||
*(apic + offset/sizeof(uint32_t)) = value;
|
||||
log::debug(logs::apic, "LAPIC write: %x = %08lx", offset, value);
|
||||
*(apic + offset/sizeof(uint32_t)) = value;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ioapic_read(uint32_t volatile *base, uint8_t reg)
|
||||
{
|
||||
*base = reg;
|
||||
return *(base + 4);
|
||||
*base = reg;
|
||||
return *(base + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
ioapic_write(uint32_t volatile *base, uint8_t reg, uint32_t value)
|
||||
{
|
||||
*base = reg;
|
||||
*(base + 4) = value;
|
||||
*base = reg;
|
||||
*(base + 4) = value;
|
||||
}
|
||||
|
||||
apic::apic(uintptr_t base) :
|
||||
m_base(memory::to_virtual<uint32_t>(base))
|
||||
m_base(memory::to_virtual<uint32_t>(base))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
lapic::lapic(uintptr_t base) :
|
||||
apic(base),
|
||||
m_divisor(0)
|
||||
apic(base),
|
||||
m_divisor(0)
|
||||
{
|
||||
apic_write(m_base, lapic_lvt_error, static_cast<uint32_t>(isr::isrAPICError));
|
||||
apic_write(m_base, lapic_spurious, static_cast<uint32_t>(isr::isrSpurious));
|
||||
apic_write(m_base, lapic_lvt_error, static_cast<uint32_t>(isr::isrAPICError));
|
||||
apic_write(m_base, lapic_spurious, static_cast<uint32_t>(isr::isrSpurious));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lapic::get_id()
|
||||
{
|
||||
return static_cast<uint8_t>(apic_read(m_base, lapic_id) >> 24);
|
||||
return static_cast<uint8_t>(apic_read(m_base, lapic_id) >> 24);
|
||||
}
|
||||
|
||||
void
|
||||
lapic::send_ipi(ipi mode, uint8_t vector, uint8_t dest)
|
||||
{
|
||||
// Wait until the APIC is ready to send
|
||||
ipi_wait();
|
||||
// Wait until the APIC is ready to send
|
||||
ipi_wait();
|
||||
|
||||
uint32_t command =
|
||||
static_cast<uint32_t>(vector) |
|
||||
static_cast<uint32_t>(mode);
|
||||
uint32_t command =
|
||||
static_cast<uint32_t>(vector) |
|
||||
static_cast<uint32_t>(mode);
|
||||
|
||||
apic_write(m_base, lapic_icr_high, static_cast<uint32_t>(dest) << 24);
|
||||
apic_write(m_base, lapic_icr_low, command);
|
||||
apic_write(m_base, lapic_icr_high, static_cast<uint32_t>(dest) << 24);
|
||||
apic_write(m_base, lapic_icr_low, command);
|
||||
}
|
||||
|
||||
void
|
||||
lapic::send_ipi_broadcast(ipi mode, bool self, uint8_t vector)
|
||||
{
|
||||
// Wait until the APIC is ready to send
|
||||
ipi_wait();
|
||||
// Wait until the APIC is ready to send
|
||||
ipi_wait();
|
||||
|
||||
uint32_t command =
|
||||
static_cast<uint32_t>(vector) |
|
||||
static_cast<uint32_t>(mode) |
|
||||
(self ? 0 : (1 << 18)) |
|
||||
(1 << 19);
|
||||
uint32_t command =
|
||||
static_cast<uint32_t>(vector) |
|
||||
static_cast<uint32_t>(mode) |
|
||||
(self ? 0 : (1 << 18)) |
|
||||
(1 << 19);
|
||||
|
||||
apic_write(m_base, lapic_icr_high, 0);
|
||||
apic_write(m_base, lapic_icr_low, command);
|
||||
apic_write(m_base, lapic_icr_high, 0);
|
||||
apic_write(m_base, lapic_icr_low, command);
|
||||
}
|
||||
|
||||
void
|
||||
lapic::ipi_wait()
|
||||
{
|
||||
while (apic_read(m_base, lapic_icr_low) & (1<<12))
|
||||
asm volatile ("pause" : : : "memory");
|
||||
while (apic_read(m_base, lapic_icr_low) & (1<<12))
|
||||
asm volatile ("pause" : : : "memory");
|
||||
}
|
||||
|
||||
void
|
||||
lapic::calibrate_timer()
|
||||
{
|
||||
interrupts_disable();
|
||||
interrupts_disable();
|
||||
|
||||
log::info(logs::apic, "Calibrating APIC timer...");
|
||||
log::info(logs::apic, "Calibrating APIC timer...");
|
||||
|
||||
const uint32_t initial = -1u;
|
||||
enable_timer(isr::isrSpurious);
|
||||
set_divisor(1);
|
||||
apic_write(m_base, lapic_timer_init, initial);
|
||||
const uint32_t initial = -1u;
|
||||
enable_timer(isr::isrSpurious);
|
||||
set_divisor(1);
|
||||
apic_write(m_base, lapic_timer_init, initial);
|
||||
|
||||
uint64_t us = 20000;
|
||||
clock::get().spinwait(us);
|
||||
uint64_t us = 20000;
|
||||
clock::get().spinwait(us);
|
||||
|
||||
uint32_t remaining = apic_read(m_base, lapic_timer_cur);
|
||||
uint64_t ticks_total = initial - remaining;
|
||||
s_ticks_per_us = ticks_total / us;
|
||||
uint32_t remaining = apic_read(m_base, lapic_timer_cur);
|
||||
uint64_t ticks_total = initial - remaining;
|
||||
s_ticks_per_us = ticks_total / us;
|
||||
|
||||
log::info(logs::apic, "APIC timer ticks %d times per microsecond.", s_ticks_per_us);
|
||||
log::info(logs::apic, "APIC timer ticks %d times per microsecond.", s_ticks_per_us);
|
||||
|
||||
interrupts_enable();
|
||||
interrupts_enable();
|
||||
}
|
||||
|
||||
void
|
||||
lapic::set_divisor(uint8_t divisor)
|
||||
{
|
||||
uint32_t divbits = 0;
|
||||
uint32_t divbits = 0;
|
||||
|
||||
switch (divisor) {
|
||||
case 1: divbits = 0xb; break;
|
||||
case 2: divbits = 0x0; break;
|
||||
case 4: divbits = 0x1; break;
|
||||
case 8: divbits = 0x2; break;
|
||||
case 16: divbits = 0x3; break;
|
||||
case 32: divbits = 0x8; break;
|
||||
case 64: divbits = 0x9; break;
|
||||
case 128: divbits = 0xa; break;
|
||||
default:
|
||||
kassert(0, "Invalid divisor passed to lapic::set_divisor");
|
||||
}
|
||||
switch (divisor) {
|
||||
case 1: divbits = 0xb; break;
|
||||
case 2: divbits = 0x0; break;
|
||||
case 4: divbits = 0x1; break;
|
||||
case 8: divbits = 0x2; break;
|
||||
case 16: divbits = 0x3; break;
|
||||
case 32: divbits = 0x8; break;
|
||||
case 64: divbits = 0x9; break;
|
||||
case 128: divbits = 0xa; break;
|
||||
default:
|
||||
kassert(0, "Invalid divisor passed to lapic::set_divisor");
|
||||
}
|
||||
|
||||
apic_write(m_base, lapic_timer_div, divbits);
|
||||
m_divisor = divisor;
|
||||
apic_write(m_base, lapic_timer_div, divbits);
|
||||
m_divisor = divisor;
|
||||
}
|
||||
|
||||
void
|
||||
lapic::enable_timer(isr vector, bool repeat)
|
||||
{
|
||||
uint32_t lvte = static_cast<uint8_t>(vector);
|
||||
if (repeat)
|
||||
lvte |= 0x20000;
|
||||
apic_write(m_base, lapic_lvt_timer, lvte);
|
||||
uint32_t lvte = static_cast<uint8_t>(vector);
|
||||
if (repeat)
|
||||
lvte |= 0x20000;
|
||||
apic_write(m_base, lapic_lvt_timer, lvte);
|
||||
|
||||
log::debug(logs::apic, "Enabling APIC timer at isr %02x", vector);
|
||||
log::debug(logs::apic, "Enabling APIC timer at isr %02x", vector);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lapic::reset_timer(uint64_t interval)
|
||||
{
|
||||
uint64_t remaining = ticks_to_us(apic_read(m_base, lapic_timer_cur));
|
||||
uint64_t ticks = us_to_ticks(interval);
|
||||
uint64_t remaining = ticks_to_us(apic_read(m_base, lapic_timer_cur));
|
||||
uint64_t ticks = us_to_ticks(interval);
|
||||
|
||||
int divisor = 1;
|
||||
while (ticks > 0xffffffffull) {
|
||||
ticks >>= 1;
|
||||
divisor <<= 1;
|
||||
}
|
||||
int divisor = 1;
|
||||
while (ticks > 0xffffffffull) {
|
||||
ticks >>= 1;
|
||||
divisor <<= 1;
|
||||
}
|
||||
|
||||
if (divisor != m_divisor)
|
||||
set_divisor(divisor);
|
||||
if (divisor != m_divisor)
|
||||
set_divisor(divisor);
|
||||
|
||||
apic_write(m_base, lapic_timer_init, ticks);
|
||||
return remaining;
|
||||
apic_write(m_base, lapic_timer_init, ticks);
|
||||
return remaining;
|
||||
}
|
||||
|
||||
void
|
||||
lapic::enable_lint(uint8_t num, isr vector, bool nmi, uint16_t flags)
|
||||
{
|
||||
kassert(num == 0 || num == 1, "Invalid LINT passed to lapic::enable_lint.");
|
||||
kassert(num == 0 || num == 1, "Invalid LINT passed to lapic::enable_lint.");
|
||||
|
||||
uint16_t off = num ? lapic_lvt_lint1 : lapic_lvt_lint0;
|
||||
uint32_t lvte = static_cast<uint8_t>(vector);
|
||||
uint16_t off = num ? lapic_lvt_lint1 : lapic_lvt_lint0;
|
||||
uint32_t lvte = static_cast<uint8_t>(vector);
|
||||
|
||||
uint16_t polarity = flags & 0x3;
|
||||
if (polarity == 3)
|
||||
lvte |= (1 << 13);
|
||||
uint16_t polarity = flags & 0x3;
|
||||
if (polarity == 3)
|
||||
lvte |= (1 << 13);
|
||||
|
||||
uint16_t trigger = (flags >> 2) & 0x3;
|
||||
if (trigger == 3)
|
||||
lvte |= (1 << 15);
|
||||
uint16_t trigger = (flags >> 2) & 0x3;
|
||||
if (trigger == 3)
|
||||
lvte |= (1 << 15);
|
||||
|
||||
apic_write(m_base, off, lvte);
|
||||
log::debug(logs::apic, "APIC LINT%d enabled as %s %d %s-triggered, active %s.",
|
||||
num, nmi ? "NMI" : "ISR", vector,
|
||||
polarity == 3 ? "level" : "edge",
|
||||
trigger == 3 ? "low" : "high");
|
||||
apic_write(m_base, off, lvte);
|
||||
log::debug(logs::apic, "APIC LINT%d enabled as %s %d %s-triggered, active %s.",
|
||||
num, nmi ? "NMI" : "ISR", vector,
|
||||
polarity == 3 ? "level" : "edge",
|
||||
trigger == 3 ? "low" : "high");
|
||||
}
|
||||
|
||||
void
|
||||
lapic::enable()
|
||||
{
|
||||
apic_write(m_base, lapic_spurious,
|
||||
apic_read(m_base, lapic_spurious) | 0x100);
|
||||
log::debug(logs::apic, "LAPIC enabled!");
|
||||
apic_write(m_base, lapic_spurious,
|
||||
apic_read(m_base, lapic_spurious) | 0x100);
|
||||
log::debug(logs::apic, "LAPIC enabled!");
|
||||
}
|
||||
|
||||
void
|
||||
lapic::disable()
|
||||
{
|
||||
apic_write(m_base, lapic_spurious,
|
||||
apic_read(m_base, lapic_spurious) & ~0x100);
|
||||
log::debug(logs::apic, "LAPIC disabled.");
|
||||
apic_write(m_base, lapic_spurious,
|
||||
apic_read(m_base, lapic_spurious) & ~0x100);
|
||||
log::debug(logs::apic, "LAPIC disabled.");
|
||||
}
|
||||
|
||||
|
||||
ioapic::ioapic(uintptr_t base, uint32_t base_gsi) :
|
||||
apic(base),
|
||||
m_base_gsi(base_gsi)
|
||||
apic(base),
|
||||
m_base_gsi(base_gsi)
|
||||
{
|
||||
uint32_t id = ioapic_read(m_base, 0);
|
||||
uint32_t version = ioapic_read(m_base, 1);
|
||||
uint32_t id = ioapic_read(m_base, 0);
|
||||
uint32_t version = ioapic_read(m_base, 1);
|
||||
|
||||
m_id = (id >> 24) & 0xff;
|
||||
m_version = version & 0xff;
|
||||
m_num_gsi = (version >> 16) & 0xff;
|
||||
log::debug(logs::apic, "IOAPIC %d loaded, version %d, GSIs %d-%d",
|
||||
m_id, m_version, base_gsi, base_gsi + (m_num_gsi - 1));
|
||||
m_id = (id >> 24) & 0xff;
|
||||
m_version = version & 0xff;
|
||||
m_num_gsi = (version >> 16) & 0xff;
|
||||
log::debug(logs::apic, "IOAPIC %d loaded, version %d, GSIs %d-%d",
|
||||
m_id, m_version, base_gsi, base_gsi + (m_num_gsi - 1));
|
||||
|
||||
for (uint8_t i = 0; i < m_num_gsi; ++i) {
|
||||
uint16_t flags = (i < 0x10) ? 0 : 0xf;
|
||||
isr vector = isr::irq00 + i;
|
||||
redirect(i, vector, flags, true);
|
||||
}
|
||||
for (uint8_t i = 0; i < m_num_gsi; ++i) {
|
||||
uint16_t flags = (i < 0x10) ? 0 : 0xf;
|
||||
isr vector = isr::irq00 + i;
|
||||
redirect(i, vector, flags, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ioapic::redirect(uint8_t irq, isr vector, uint16_t flags, bool masked)
|
||||
{
|
||||
log::debug(logs::apic, "IOAPIC %d redirecting irq %3d to vector %3d [%04x]%s",
|
||||
m_id, irq, vector, flags, masked ? " (masked)" : "");
|
||||
log::debug(logs::apic, "IOAPIC %d redirecting irq %3d to vector %3d [%04x]%s",
|
||||
m_id, irq, vector, flags, masked ? " (masked)" : "");
|
||||
|
||||
uint64_t entry = static_cast<uint64_t>(vector);
|
||||
uint64_t entry = static_cast<uint64_t>(vector);
|
||||
|
||||
uint16_t polarity = flags & 0x3;
|
||||
if (polarity == 3)
|
||||
entry |= (1 << 13);
|
||||
uint16_t polarity = flags & 0x3;
|
||||
if (polarity == 3)
|
||||
entry |= (1 << 13);
|
||||
|
||||
uint16_t trigger = (flags >> 2) & 0x3;
|
||||
if (trigger == 3)
|
||||
entry |= (1 << 15);
|
||||
uint16_t trigger = (flags >> 2) & 0x3;
|
||||
if (trigger == 3)
|
||||
entry |= (1 << 15);
|
||||
|
||||
if (masked)
|
||||
entry |= (1 << 16);
|
||||
if (masked)
|
||||
entry |= (1 << 16);
|
||||
|
||||
ioapic_write(m_base, (2 * irq) + 0x10, static_cast<uint32_t>(entry & 0xffffffff));
|
||||
ioapic_write(m_base, (2 * irq) + 0x11, static_cast<uint32_t>(entry >> 32));
|
||||
ioapic_write(m_base, (2 * irq) + 0x10, static_cast<uint32_t>(entry & 0xffffffff));
|
||||
ioapic_write(m_base, (2 * irq) + 0x11, static_cast<uint32_t>(entry >> 32));
|
||||
}
|
||||
|
||||
void
|
||||
ioapic::mask(uint8_t irq, bool masked)
|
||||
{
|
||||
log::debug(logs::apic, "IOAPIC %d %smasking irq %3d",
|
||||
m_id, masked ? "" : "un", irq);
|
||||
log::debug(logs::apic, "IOAPIC %d %smasking irq %3d",
|
||||
m_id, masked ? "" : "un", irq);
|
||||
|
||||
uint32_t entry = ioapic_read(m_base, (2 * irq) + 0x10);
|
||||
if (masked)
|
||||
entry |= (1 << 16);
|
||||
else
|
||||
entry &= ~(1 << 16);
|
||||
uint32_t entry = ioapic_read(m_base, (2 * irq) + 0x10);
|
||||
if (masked)
|
||||
entry |= (1 << 16);
|
||||
else
|
||||
entry &= ~(1 << 16);
|
||||
|
||||
ioapic_write(m_base, (2 * irq) + 0x10, entry);
|
||||
ioapic_write(m_base, (2 * irq) + 0x10, entry);
|
||||
}
|
||||
|
||||
void
|
||||
ioapic::dump_redirs() const
|
||||
{
|
||||
log::debug(logs::apic, "IOAPIC %d redirections:", m_id);
|
||||
log::debug(logs::apic, "IOAPIC %d redirections:", m_id);
|
||||
|
||||
for (uint8_t i = 0; i < m_num_gsi; ++i) {
|
||||
uint64_t low = ioapic_read(m_base, 0x10 + (2 *i));
|
||||
uint64_t high = ioapic_read(m_base, 0x10 + (2 *i));
|
||||
uint64_t redir = low | (high << 32);
|
||||
if (redir == 0) continue;
|
||||
for (uint8_t i = 0; i < m_num_gsi; ++i) {
|
||||
uint64_t low = ioapic_read(m_base, 0x10 + (2 *i));
|
||||
uint64_t high = ioapic_read(m_base, 0x10 + (2 *i));
|
||||
uint64_t redir = low | (high << 32);
|
||||
if (redir == 0) continue;
|
||||
|
||||
uint8_t vector = redir & 0xff;
|
||||
uint8_t mode = (redir >> 8) & 0x7;
|
||||
uint8_t dest_mode = (redir >> 11) & 0x1;
|
||||
uint8_t polarity = (redir >> 13) & 0x1;
|
||||
uint8_t trigger = (redir >> 15) & 0x1;
|
||||
uint8_t mask = (redir >> 16) & 0x1;
|
||||
uint8_t dest = (redir >> 56) & 0xff;
|
||||
uint8_t vector = redir & 0xff;
|
||||
uint8_t mode = (redir >> 8) & 0x7;
|
||||
uint8_t dest_mode = (redir >> 11) & 0x1;
|
||||
uint8_t polarity = (redir >> 13) & 0x1;
|
||||
uint8_t trigger = (redir >> 15) & 0x1;
|
||||
uint8_t mask = (redir >> 16) & 0x1;
|
||||
uint8_t dest = (redir >> 56) & 0xff;
|
||||
|
||||
log::debug(logs::apic, " %2d: vec %3d %s active, %s-triggered %s dest %d: %x",
|
||||
m_base_gsi + i, vector,
|
||||
polarity ? "low" : "high",
|
||||
trigger ? "level" : "edge",
|
||||
mask ? "masked" : "",
|
||||
dest_mode,
|
||||
dest);
|
||||
}
|
||||
log::debug(logs::apic, " %2d: vec %3d %s active, %s-triggered %s dest %d: %x",
|
||||
m_base_gsi + i, vector,
|
||||
polarity ? "low" : "high",
|
||||
trigger ? "level" : "edge",
|
||||
mask ? "masked" : "",
|
||||
dest_mode,
|
||||
dest);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user