millisecond pit; fix multiboot headers for optimization

main
Clyne 3 weeks ago
parent 8f9329da62
commit 376d7ec265
Signed by: clyne
GPG Key ID: 1B74EE6C49C96795

@ -20,7 +20,7 @@ void kernel_main(void)
if (!multiboot_initialize()) if (!multiboot_initialize())
for (;;); for (;;);
idt_register_callback(14, [](const Registers& regs) { idt_register_callback(14, [](auto& regs) {
term.write("Page fault! eip="); term.write("Page fault! eip=");
term.write(regs.eip); term.write(regs.eip);
term.write('\n'); term.write('\n');
@ -32,14 +32,14 @@ void kernel_main(void)
gdt_initialize(); gdt_initialize();
pic_initialize(); pic_initialize();
idt_initialize(); idt_initialize();
pit_initialize(100); pit_initialize();
asm volatile("sti"); asm volatile("sti");
tasking_initialize(); tasking_initialize();
term.write("Tasking enabled.\n"); term.write("Tasking enabled.\n");
tasking_spawn([] { tasking_spawn([] {
for (;;) { for (;;) {
do pit_busy_wait(1); do pit_delay_ms(1);
while (termBusy); while (termBusy);
termBusy = true; termBusy = true;
@ -50,7 +50,7 @@ void kernel_main(void)
tasking_spawn([] { tasking_spawn([] {
for (;;) { for (;;) {
do pit_busy_wait(1); do pit_delay_ms(1);
while (termBusy); while (termBusy);
termBusy = true; termBusy = true;
@ -60,7 +60,7 @@ void kernel_main(void)
}, 256); }, 256);
for (;;) { for (;;) {
do pit_busy_wait(1); do pit_delay_ms(1);
while (termBusy); while (termBusy);
termBusy = true; termBusy = true;

@ -4,6 +4,15 @@
extern TextOutput& term; extern TextOutput& term;
struct multiboot2_tag
{
alignas(8)
std::uint16_t id;
std::uint16_t flags;
std::uint32_t length;
std::uint32_t data[1];
} __attribute__((packed));
struct multiboot2 struct multiboot2
{ {
static constexpr std::uint32_t MAGIC = 0xE85250D6; static constexpr std::uint32_t MAGIC = 0xE85250D6;
@ -12,33 +21,29 @@ struct multiboot2
static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH); static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH);
alignas(8) alignas(8)
std::uint32_t magic = MAGIC; std::uint32_t magic;
std::uint32_t flags = FLAGS; std::uint32_t flags;
std::uint32_t length = LENGTH;
std::uint32_t checksum = CHECKSUM;
} __attribute__((packed));
struct multiboot2_tag
{
alignas(8)
std::uint16_t id;
std::uint16_t flags;
std::uint32_t length; std::uint32_t length;
std::uint32_t data[]; std::uint32_t checksum;
} __attribute__((packed));
__attribute__((section(".multiboot2"))) multiboot2_tag tags[];
multiboot2 multibootHeader; } __attribute__((packed));
__attribute__((section(".multiboot2"))) __attribute__((section(".multiboot2")))
multiboot2_tag multibootTagInfoRequest = { multiboot2 multibootHeader = {
.magic = multiboot2::MAGIC,
.flags = multiboot2::FLAGS,
.length = multiboot2::LENGTH,
.checksum = multiboot2::CHECKSUM,
.tags = {
{
1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t), 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t),
{4} {4}
}; },
{
__attribute__((section(".multiboot2"))) 0, 0, 8, {}
multiboot2_tag multibootTagEnd = { }
0, 0, sizeof(multiboot2_tag), {} }
}; };
std::uint32_t multiboot_magic; std::uint32_t multiboot_magic;

@ -3,6 +3,8 @@
#include "portio.hpp" #include "portio.hpp"
#include "tasking.hpp" #include "tasking.hpp"
constexpr std::uint32_t Frequency = 1000;
static volatile std::uint32_t ticks = 0; static volatile std::uint32_t ticks = 0;
static void timer_callback(const Registers& regs) static void timer_callback(const Registers& regs)
@ -12,7 +14,7 @@ static void timer_callback(const Registers& regs)
schedule(regs); schedule(regs);
} }
void pit_initialize(std::uint32_t frequency) void pit_initialize()
{ {
// Firstly, register our timer callback. // Firstly, register our timer callback.
idt_register_callback(32, timer_callback); idt_register_callback(32, timer_callback);
@ -20,7 +22,7 @@ void pit_initialize(std::uint32_t frequency)
// The value we send to the PIT is the value to divide it's input clock // The value we send to the PIT is the value to divide it's input clock
// (1193180 Hz) by, to get our required frequency. Important to note is // (1193180 Hz) by, to get our required frequency. Important to note is
// that the divisor must be small enough to fit into 16-bits. // that the divisor must be small enough to fit into 16-bits.
auto divisor = 1193180 / frequency; const auto divisor = 1193180ul / Frequency;
// Send the command byte. // Send the command byte.
outb(0x43, 0x36); outb(0x43, 0x36);
@ -30,9 +32,9 @@ void pit_initialize(std::uint32_t frequency)
outb(0x40, (divisor >> 8) & 0xFF); outb(0x40, (divisor >> 8) & 0xFF);
} }
void pit_busy_wait(std::int32_t tks) void pit_delay_ms(std::int32_t ms)
{ {
const auto end = ticks + tks; const auto end = ticks + ms;
while (static_cast<std::int32_t>(end - ticks) > 0) while (static_cast<std::int32_t>(end - ticks) > 0)
asm volatile("nop"); asm volatile("nop");
} }

@ -3,8 +3,8 @@
#include <cstdint> #include <cstdint>
void pit_initialize(std::uint32_t frequency); void pit_initialize();
void pit_busy_wait(std::int32_t tks); void pit_delay_ms(std::int32_t ms);
#endif // PIT_HPP #endif // PIT_HPP

@ -46,11 +46,9 @@ void VGATerminal::checkpos() noexcept
void VGATerminal::updatecursor() const noexcept void VGATerminal::updatecursor() const noexcept
{ {
asm volatile("cli");
outb(0x03d4, 0x0f); outb(0x03d4, 0x0f);
outb(0x03d5, static_cast<std::uint8_t>(offset)); outb(0x03d5, static_cast<std::uint8_t>(offset));
outb(0x03d4, 0x0e); outb(0x03d4, 0x0e);
outb(0x03d5, static_cast<std::uint8_t>(offset >> 8)); outb(0x03d5, static_cast<std::uint8_t>(offset >> 8));
asm volatile("sti");
} }

Loading…
Cancel
Save