if (!multiboot_initialize())
for (;;);
- idt_register_callback(14, [](const Registers& regs) {
+ idt_register_callback(14, [](auto& regs) {
term.write("Page fault! eip=");
term.write(regs.eip);
term.write('\n');
gdt_initialize();
pic_initialize();
idt_initialize();
- pit_initialize(100);
+ pit_initialize();
asm volatile("sti");
tasking_initialize();
term.write("Tasking enabled.\n");
tasking_spawn([] {
for (;;) {
- do pit_busy_wait(1);
+ do pit_delay_ms(1);
while (termBusy);
termBusy = true;
tasking_spawn([] {
for (;;) {
- do pit_busy_wait(1);
+ do pit_delay_ms(1);
while (termBusy);
termBusy = true;
}, 256);
for (;;) {
- do pit_busy_wait(1);
+ do pit_delay_ms(1);
while (termBusy);
termBusy = true;
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
{
static constexpr std::uint32_t MAGIC = 0xE85250D6;
static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH);
alignas(8)
- std::uint32_t magic = MAGIC;
- std::uint32_t flags = 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 magic;
+ std::uint32_t flags;
std::uint32_t length;
- std::uint32_t data[];
-} __attribute__((packed));
-
-__attribute__((section(".multiboot2")))
-multiboot2 multibootHeader;
+ std::uint32_t checksum;
-__attribute__((section(".multiboot2")))
-multiboot2_tag multibootTagInfoRequest = {
- 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t),
- {4}
-};
+ multiboot2_tag tags[];
+} __attribute__((packed));
__attribute__((section(".multiboot2")))
-multiboot2_tag multibootTagEnd = {
- 0, 0, sizeof(multiboot2_tag), {}
+multiboot2 multibootHeader = {
+ .magic = multiboot2::MAGIC,
+ .flags = multiboot2::FLAGS,
+ .length = multiboot2::LENGTH,
+ .checksum = multiboot2::CHECKSUM,
+ .tags = {
+ {
+ 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t),
+ {4}
+ },
+ {
+ 0, 0, 8, {}
+ }
+ }
};
std::uint32_t multiboot_magic;
#include "portio.hpp"
#include "tasking.hpp"
+constexpr std::uint32_t Frequency = 1000;
+
static volatile std::uint32_t ticks = 0;
static void timer_callback(const Registers& regs)
schedule(regs);
}
-void pit_initialize(std::uint32_t frequency)
+void pit_initialize()
{
// Firstly, register our timer callback.
idt_register_callback(32, timer_callback);
// 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
// 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.
outb(0x43, 0x36);
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)
asm volatile("nop");
}
#include <cstdint>
-void pit_initialize(std::uint32_t frequency);
-void pit_busy_wait(std::int32_t tks);
+void pit_initialize();
+void pit_delay_ms(std::int32_t ms);
#endif // PIT_HPP
void VGATerminal::updatecursor() const noexcept
{
- asm volatile("cli");
outb(0x03d4, 0x0f);
outb(0x03d5, static_cast<std::uint8_t>(offset));
outb(0x03d4, 0x0e);
outb(0x03d5, static_cast<std::uint8_t>(offset >> 8));
- asm volatile("sti");
}