[zion] Move all APIC functions into a global class.
This commit is contained in:
		
							parent
							
								
									f8de60e2dd
								
							
						
					
					
						commit
						35b1844862
					
				| 
						 | 
				
			
			@ -12,6 +12,9 @@ namespace {
 | 
			
		|||
static uint64_t gPcieEcBase = 0x0;
 | 
			
		||||
static uint64_t gPcieEcSize = 0x0;
 | 
			
		||||
 | 
			
		||||
static uint64_t gLApicBase = 0x0;
 | 
			
		||||
static uint64_t gIOApicBase = 0x0;
 | 
			
		||||
 | 
			
		||||
struct RsdpDescriptor {
 | 
			
		||||
  char signature[8];
 | 
			
		||||
  uint8_t checksum;
 | 
			
		||||
| 
						 | 
				
			
			@ -136,12 +139,12 @@ void ParseMcfg(SdtHeader* rsdt) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void ParseMadt(SdtHeader* rsdt) {
 | 
			
		||||
#if K_ACPI_DEBUG
 | 
			
		||||
  dbgsz(rsdt->signature, 4);
 | 
			
		||||
  uint64_t max_addr = reinterpret_cast<uint64_t>(rsdt) + rsdt->length;
 | 
			
		||||
  MadtHeader* header = reinterpret_cast<MadtHeader*>(rsdt);
 | 
			
		||||
 | 
			
		||||
  dbgln("Local APIC %x", header->local_apic_address);
 | 
			
		||||
  gLApicBase = header->local_apic_address;
 | 
			
		||||
  dbgln("Flags: %x", header->flags);
 | 
			
		||||
 | 
			
		||||
  MadtEntry* entry = &header->first_entry;
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +161,10 @@ void ParseMadt(SdtHeader* rsdt) {
 | 
			
		|||
        MadtIoApic* io = reinterpret_cast<MadtIoApic*>(entry);
 | 
			
		||||
        dbgln("IO Apic (id, addr, gsi base): %x, %x, %x", io->io_apic_id,
 | 
			
		||||
              io->io_apic_address, io->global_system_interrupt_base);
 | 
			
		||||
        if (gIOApicBase != 0) {
 | 
			
		||||
          dbgln("More than one IOApic, unhandled");
 | 
			
		||||
        }
 | 
			
		||||
        gIOApicBase = io->io_apic_address;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 2: {
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +188,6 @@ void ParseMadt(SdtHeader* rsdt) {
 | 
			
		|||
    entry = reinterpret_cast<MadtEntry*>(reinterpret_cast<uint64_t>(entry) +
 | 
			
		||||
                                         entry->length);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParseSdt(SdtHeader* rsdt) {
 | 
			
		||||
| 
						 | 
				
			
			@ -262,3 +268,11 @@ glcr::ErrorOr<PcieConfiguration> GetPciExtendedConfiguration() {
 | 
			
		|||
 | 
			
		||||
  return PcieConfiguration{gPcieEcBase, gPcieEcSize};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glcr::ErrorOr<ApicConfiguration> GetApicConfiguration() {
 | 
			
		||||
  if (gLApicBase == 0 || gIOApicBase == 0) {
 | 
			
		||||
    return glcr::NOT_FOUND;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ApicConfiguration{gLApicBase, gIOApicBase};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,3 +12,9 @@ struct PcieConfiguration {
 | 
			
		|||
  uint64_t offset;
 | 
			
		||||
};
 | 
			
		||||
glcr::ErrorOr<PcieConfiguration> GetPciExtendedConfiguration();
 | 
			
		||||
 | 
			
		||||
struct ApicConfiguration {
 | 
			
		||||
  uint64_t lapic_base;
 | 
			
		||||
  uint64_t ioapic_base;
 | 
			
		||||
};
 | 
			
		||||
glcr::ErrorOr<ApicConfiguration> GetApicConfiguration();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,51 +16,22 @@ namespace {
 | 
			
		|||
#define IA32_APIC_BASE_MSR_BSP 0x100  // Processor is a BSP
 | 
			
		||||
#define IA32_APIC_BASE_MSR_ENABLE 0x800
 | 
			
		||||
 | 
			
		||||
const uint64_t kEoiOffset = 0xB0;
 | 
			
		||||
const uint64_t kLvtTimerOffset = 0x320;
 | 
			
		||||
const uint64_t kTimerInitOffset = 0x380;
 | 
			
		||||
const uint64_t kTimerCurrOffset = 0x390;
 | 
			
		||||
const uint64_t kTimerDivOffset = 0x3E0;
 | 
			
		||||
#define LAPIC_TIMER_ONESHOT 0
 | 
			
		||||
#define LAPIC_TIMER_PERIODIC 1 << 17
 | 
			
		||||
 | 
			
		||||
// FIXME: parse these from madt.
 | 
			
		||||
constexpr uint64_t kLApicBase = 0xFEE0'0000;
 | 
			
		||||
constexpr uint64_t kIoApicAddr = 0xFEC0'0000;
 | 
			
		||||
constexpr uint64_t kIoApicData = 0xFEC0'0010;
 | 
			
		||||
#define APIC_MASK 0x10000
 | 
			
		||||
 | 
			
		||||
const uint16_t kEoiOffset = 0xB0;
 | 
			
		||||
const uint16_t kLvtTimerOffset = 0x320;
 | 
			
		||||
const uint16_t kTimerInitOffset = 0x380;
 | 
			
		||||
const uint16_t kTimerCurrOffset = 0x390;
 | 
			
		||||
const uint16_t kTimerDivOffset = 0x3E0;
 | 
			
		||||
 | 
			
		||||
uint32_t volatile* GetPhys(uint64_t base, uint64_t offset = 0) {
 | 
			
		||||
  return reinterpret_cast<uint32_t*>(boot::GetHigherHalfDirectMap() + base +
 | 
			
		||||
                                     offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t GetLocalReg(uint64_t offset) {
 | 
			
		||||
  uint32_t volatile* reg = GetPhys(kLApicBase, offset);
 | 
			
		||||
  return *reg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteLocalReg(uint64_t offset, uint32_t value) {
 | 
			
		||||
  *GetPhys(kLApicBase, offset) = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t GetIoReg(uint8_t reg) {
 | 
			
		||||
  *GetPhys(kIoApicAddr) = reg;
 | 
			
		||||
  return *GetPhys(kIoApicData);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t GetIoEntry(uint8_t reg) {
 | 
			
		||||
  *GetPhys(kIoApicAddr) = reg;
 | 
			
		||||
  uint64_t entry = *GetPhys(kIoApicData);
 | 
			
		||||
  *GetPhys(kIoApicAddr) = reg + 1;
 | 
			
		||||
  entry |= ((uint64_t)*GetPhys(kIoApicData)) << 32;
 | 
			
		||||
  return entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetIoEntry(uint8_t reg, uint64_t value) {
 | 
			
		||||
  *GetPhys(kIoApicAddr) = reg;
 | 
			
		||||
  *GetPhys(kIoApicData) = value & 0xFFFFFFFF;
 | 
			
		||||
  *GetPhys(kIoApicAddr) = reg + 1;
 | 
			
		||||
  *GetPhys(kIoApicData) = value >> 32;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PIC1_COMMAND 0x20
 | 
			
		||||
#define PIC2_COMMAND 0xA0
 | 
			
		||||
#define PIC1_DATA 0x21
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +57,17 @@ void MaskPic() {
 | 
			
		|||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
void InspectApic() {
 | 
			
		||||
Apic* gApic = nullptr;
 | 
			
		||||
 | 
			
		||||
void Apic::Init() {
 | 
			
		||||
  auto config_or = GetApicConfiguration();
 | 
			
		||||
  if (!config_or.ok()) {
 | 
			
		||||
    panic("Error fetching APIC info from ACPI: %x", config_or.error());
 | 
			
		||||
  }
 | 
			
		||||
  gApic = new Apic(config_or.value());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Apic::DumpInfo() {
 | 
			
		||||
#if APIC_DEBUG
 | 
			
		||||
  dbgln("APIC:");
 | 
			
		||||
  dbgln("ID: %x", GetLocalReg(0x20));
 | 
			
		||||
| 
						 | 
				
			
			@ -118,36 +99,85 @@ void InspectApic() {
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For now set these based on the presets in the following spec.
 | 
			
		||||
// FIXME: However in the future we should likely use the MADT for legacy
 | 
			
		||||
// interrupts and AML for PCI etc.
 | 
			
		||||
//
 | 
			
		||||
// http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf
 | 
			
		||||
void EnableApic() {
 | 
			
		||||
  MaskPic();
 | 
			
		||||
  // Map Timer.
 | 
			
		||||
  SetIoEntry(0x14, 0x10020);
 | 
			
		||||
uint32_t Apic::GetLocalTimerValue() { return GetLocalReg(kTimerCurrOffset); }
 | 
			
		||||
void Apic::InitializeLocalTimer(uint32_t init_cnt, TimerMode mode) {
 | 
			
		||||
  // FIXME: Don't hardcode this.
 | 
			
		||||
  uint32_t vector = 0x21;
 | 
			
		||||
  switch (mode) {
 | 
			
		||||
    case ONESHOT:
 | 
			
		||||
      vector |= LAPIC_TIMER_ONESHOT;
 | 
			
		||||
      break;
 | 
			
		||||
    case PERIODIC:
 | 
			
		||||
      vector |= LAPIC_TIMER_PERIODIC;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      panic("Unhandled timer mode.");
 | 
			
		||||
  }
 | 
			
		||||
  SetLocalReg(kLvtTimerOffset, vector);
 | 
			
		||||
 | 
			
		||||
  SetLocalReg(kTimerInitOffset, init_cnt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Apic::SignalEOI() { SetLocalReg(kEoiOffset, 0x0); }
 | 
			
		||||
 | 
			
		||||
void Apic::UnmaskPit() {
 | 
			
		||||
  SetIoDoubleReg(0x14, GetIoDoubleReg(0x14) & ~(APIC_MASK));
 | 
			
		||||
}
 | 
			
		||||
void Apic::MaskPit() { SetIoDoubleReg(0x14, GetIoDoubleReg(0x14) | APIC_MASK); }
 | 
			
		||||
 | 
			
		||||
Apic::Apic(const ApicConfiguration& config)
 | 
			
		||||
    : l_apic_base_(config.lapic_base),
 | 
			
		||||
      io_apic_addr_(
 | 
			
		||||
          reinterpret_cast<volatile uint8_t*>(GetPhys(config.ioapic_base))),
 | 
			
		||||
      io_apic_data_(GetPhys(config.ioapic_base, 0x10)) {
 | 
			
		||||
  MaskPic();
 | 
			
		||||
 | 
			
		||||
  // Map Timer.
 | 
			
		||||
  // FIXME: Get this offset from ACPI.
 | 
			
		||||
  SetIoDoubleReg(0x14, 0x20 | APIC_MASK);
 | 
			
		||||
 | 
			
		||||
  // For now set these based on the presets in the following spec.
 | 
			
		||||
  // http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf
 | 
			
		||||
  // FIXME: However in the future we should likely use the MADT for legacy
 | 
			
		||||
  // interrupts and AML for PCI etc.
 | 
			
		||||
  // PCI Line 1-4
 | 
			
		||||
  // FIXME: These should be level triggered according to spec I believe
 | 
			
		||||
  // but because we handle the interrupt outside of the kernel it is tricky
 | 
			
		||||
  // to wait to send the end of interrupt message.
 | 
			
		||||
  // Because of this leave them as edge triggered and send EOI immediately.
 | 
			
		||||
  SetIoEntry(0x30, 0x30);
 | 
			
		||||
  SetIoEntry(0x32, 0x31);
 | 
			
		||||
  SetIoEntry(0x34, 0x32);
 | 
			
		||||
  SetIoEntry(0x36, 0x33);
 | 
			
		||||
  SetIoDoubleReg(0x30, 0x30);
 | 
			
		||||
  SetIoDoubleReg(0x32, 0x31);
 | 
			
		||||
  SetIoDoubleReg(0x34, 0x32);
 | 
			
		||||
  SetIoDoubleReg(0x36, 0x33);
 | 
			
		||||
 | 
			
		||||
  InspectApic();
 | 
			
		||||
  DumpInfo();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetLocalTimer(uint32_t init_cnt, uint64_t mode) {
 | 
			
		||||
  WriteLocalReg(kTimerInitOffset, init_cnt);
 | 
			
		||||
  WriteLocalReg(kLvtTimerOffset, mode | 0x21);
 | 
			
		||||
uint32_t Apic::GetLocalReg(uint16_t offset) {
 | 
			
		||||
  uint32_t volatile* reg = GetPhys(l_apic_base_, offset);
 | 
			
		||||
  return *reg;
 | 
			
		||||
}
 | 
			
		||||
uint32_t GetLocalTimer() { return GetLocalReg(kTimerCurrOffset); }
 | 
			
		||||
 | 
			
		||||
void UnmaskPit() { SetIoEntry(0x14, GetIoEntry(0x14) & ~(0x10000)); }
 | 
			
		||||
void MaskPit() { SetIoEntry(0x14, GetIoEntry(0x14) | 0x10000); }
 | 
			
		||||
void Apic::SetLocalReg(uint16_t offset, uint32_t value) {
 | 
			
		||||
  *GetPhys(l_apic_base_, offset) = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SignalEOI() { WriteLocalReg(kEoiOffset, 0x0); }
 | 
			
		||||
uint32_t Apic::GetIoReg(uint8_t offset) {
 | 
			
		||||
  *io_apic_addr_ = offset;
 | 
			
		||||
  return *io_apic_data_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t Apic::GetIoDoubleReg(uint8_t offset) {
 | 
			
		||||
  *io_apic_addr_ = offset;
 | 
			
		||||
  uint64_t entry = *io_apic_data_;
 | 
			
		||||
  *io_apic_addr_ = offset + 1;
 | 
			
		||||
  entry |= ((uint64_t)*io_apic_data_) << 32;
 | 
			
		||||
  return entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Apic::SetIoDoubleReg(uint8_t offset, uint64_t value) {
 | 
			
		||||
  *io_apic_addr_ = offset;
 | 
			
		||||
  *io_apic_data_ = value & 0xFFFFFFFF;
 | 
			
		||||
  *io_apic_addr_ = offset + 1;
 | 
			
		||||
  *io_apic_data_ = value >> 32;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,17 +2,39 @@
 | 
			
		|||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
void InspectApic();
 | 
			
		||||
#include "boot/acpi.h"
 | 
			
		||||
 | 
			
		||||
void EnableApic();
 | 
			
		||||
class Apic {
 | 
			
		||||
 public:
 | 
			
		||||
  static void Init();
 | 
			
		||||
  static void DumpInfo();
 | 
			
		||||
 | 
			
		||||
#define LAPIC_TIMER_ONESHOT 0
 | 
			
		||||
#define LAPIC_TIMER_PERIODIC 1 << 17
 | 
			
		||||
  uint32_t GetLocalTimerValue();
 | 
			
		||||
  enum TimerMode {
 | 
			
		||||
    ONESHOT,
 | 
			
		||||
    PERIODIC,
 | 
			
		||||
  };
 | 
			
		||||
  void InitializeLocalTimer(uint32_t init_cnt, TimerMode mode);
 | 
			
		||||
 | 
			
		||||
void SetLocalTimer(uint32_t init_cnt, uint64_t mode);
 | 
			
		||||
uint32_t GetLocalTimer();
 | 
			
		||||
  void SignalEOI();
 | 
			
		||||
 | 
			
		||||
void UnmaskPit();
 | 
			
		||||
void MaskPit();
 | 
			
		||||
  void UnmaskPit();
 | 
			
		||||
  void MaskPit();
 | 
			
		||||
 | 
			
		||||
void SignalEOI();
 | 
			
		||||
 private:
 | 
			
		||||
  uint64_t l_apic_base_;
 | 
			
		||||
  volatile uint8_t* io_apic_addr_;
 | 
			
		||||
  volatile uint32_t* io_apic_data_;
 | 
			
		||||
 | 
			
		||||
  Apic(const ApicConfiguration& config);
 | 
			
		||||
 | 
			
		||||
  uint32_t GetLocalReg(uint16_t offset);
 | 
			
		||||
  void SetLocalReg(uint16_t offset, uint32_t value);
 | 
			
		||||
 | 
			
		||||
  uint64_t GetIoDoubleReg(uint8_t offset);
 | 
			
		||||
  void SetIoDoubleReg(uint8_t offset, uint64_t value);
 | 
			
		||||
 | 
			
		||||
  uint32_t GetIoReg(uint8_t offset);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern Apic* gApic;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,26 +17,26 @@ void ApicTimer::Init() {
 | 
			
		|||
 | 
			
		||||
void ApicTimer::StartCalibration() {
 | 
			
		||||
  SetFrequency(100);
 | 
			
		||||
  SetLocalTimer(0xFFFFFFFF, 0);
 | 
			
		||||
  UnmaskPit();
 | 
			
		||||
  gApic->InitializeLocalTimer(0xFFFFFFFF, Apic::ONESHOT);
 | 
			
		||||
  gApic->UnmaskPit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApicTimer::Calibrate() {
 | 
			
		||||
  if (calibration_.initial_measurement == 0) {
 | 
			
		||||
    calibration_.initial_measurement = GetLocalTimer();
 | 
			
		||||
    calibration_.initial_measurement = gApic->GetLocalTimerValue();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  calibration_.tick_count++;
 | 
			
		||||
 | 
			
		||||
  if (calibration_.tick_count == 10) {
 | 
			
		||||
    calculated_frequency_ =
 | 
			
		||||
        10 * (calibration_.initial_measurement - GetLocalTimer());
 | 
			
		||||
        10 * (calibration_.initial_measurement - gApic->GetLocalTimerValue());
 | 
			
		||||
    FinishCalibration();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApicTimer::FinishCalibration() {
 | 
			
		||||
  MaskPit();
 | 
			
		||||
  SetLocalTimer(calculated_frequency_ / kScheduleFrequency,
 | 
			
		||||
                LAPIC_TIMER_PERIODIC);
 | 
			
		||||
  gApic->MaskPit();
 | 
			
		||||
  gApic->InitializeLocalTimer(calculated_frequency_ / kScheduleFrequency,
 | 
			
		||||
                              Apic::PERIODIC);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ extern "C" void interrupt_page_fault(InterruptFrame* frame) {
 | 
			
		|||
extern "C" void isr_timer();
 | 
			
		||||
extern "C" void interrupt_timer(InterruptFrame*) {
 | 
			
		||||
  gApicTimer->Calibrate();
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t cnt = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) {
 | 
			
		|||
    }
 | 
			
		||||
    dbgln("timer: %us", cnt * 50 / 1000);
 | 
			
		||||
  }
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
  gScheduler->Preempt();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,25 +150,25 @@ extern "C" void isr_pci1();
 | 
			
		|||
extern "C" void interrupt_pci1(InterruptFrame*) {
 | 
			
		||||
  dbgln("Interrupt PCI line 1");
 | 
			
		||||
  pci1_port->Send(0, nullptr, 0, nullptr);
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void isr_pci2();
 | 
			
		||||
extern "C" void interrupt_pci2(InterruptFrame*) {
 | 
			
		||||
  dbgln("Interrupt PCI line 2");
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void isr_pci3();
 | 
			
		||||
extern "C" void interrupt_pci3(InterruptFrame*) {
 | 
			
		||||
  dbgln("Interrupt PCI line 3");
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void isr_pci4();
 | 
			
		||||
extern "C" void interrupt_pci4(InterruptFrame*) {
 | 
			
		||||
  dbgln("Interrupt PCI line 4");
 | 
			
		||||
  SignalEOI();
 | 
			
		||||
  gApic->SignalEOI();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InitIdt() {
 | 
			
		||||
| 
						 | 
				
			
			@ -189,8 +189,6 @@ void InitIdt() {
 | 
			
		|||
      .base = reinterpret_cast<uint64_t>(gIdt),
 | 
			
		||||
  };
 | 
			
		||||
  asm volatile("lidt %0" ::"m"(idtp));
 | 
			
		||||
 | 
			
		||||
  EnableApic();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegisterPciPort(const glcr::RefPtr<Port>& port) { pci1_port = port; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include "boot/acpi.h"
 | 
			
		||||
#include "common/gdt.h"
 | 
			
		||||
#include "debug/debug.h"
 | 
			
		||||
#include "interrupt/apic.h"
 | 
			
		||||
#include "interrupt/apic_timer.h"
 | 
			
		||||
#include "interrupt/interrupt.h"
 | 
			
		||||
#include "interrupt/timer.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,10 @@ extern "C" void zion() {
 | 
			
		|||
  dbgln("[boot] Probing Hardware");
 | 
			
		||||
  ProbeRsdp();
 | 
			
		||||
 | 
			
		||||
  // These two need to occur after memory allocation is available.
 | 
			
		||||
  Apic::Init();
 | 
			
		||||
  ApicTimer::Init();
 | 
			
		||||
 | 
			
		||||
  dbgln("[boot] Init Kernel Stack Manager.");
 | 
			
		||||
  KernelStackManager::Init();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +44,6 @@ extern "C" void zion() {
 | 
			
		|||
  dbgln("[boot] Init scheduler.");
 | 
			
		||||
  ProcessManager::Init();
 | 
			
		||||
  Scheduler::Init();
 | 
			
		||||
  ApicTimer::Init();
 | 
			
		||||
 | 
			
		||||
  dbgln("[boot] Loading sys init program.");
 | 
			
		||||
  LoadInitProgram();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue