summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/HalKernelMain.cc
blob: b7ff30381ffd1b3b5556bc2f293598a1fdf2d2a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* -------------------------------------------

  Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.

------------------------------------------- */

#include <ArchKit/ArchKit.h>
#include <CFKit/Property.h>
#include <FirmwareKit/EFI/API.h>
#include <FirmwareKit/EFI/EFI.h>
#include <KernelKit/CodeMgr.h>
#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/ProcessScheduler.h>
#include <KernelKit/Timer.h>
#include <NetworkKit/IPC.h>
#include <StorageKit/AHCI.h>
#include <modules/ACPI/ACPIFactoryInterface.h>
#include <modules/CoreGfx/TextGfx.h>

#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];

/// @brief Kernel init function.
/// @param handover_hdr Handover boot header.
EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
  if (handover_hdr->f_Magic != kHandoverMagic && handover_hdr->f_Version != kHandoverVersion) {
    return kEfiFail;
  }

  Kernel::HAL::rt_sti();

  kHandoverHeader = handover_hdr;

  FB::fb_clear_video();

  fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]);

  Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey,
                         handover_hdr->f_HardwareTables.f_ImageHandle);

  kKernelCR3 = kHandoverHeader->f_PageStart;

  hal_write_cr3(kKernelCR3);

  /************************************** */
  /*     INITIALIZE BIT MAP.              */
  /************************************** */

  kKernelBitMpSize  = kHandoverHeader->f_BitMapSize;
  kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
      reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));

  /************************************** */
  /*     INITIALIZE GDT AND SEGMENTS. */
  /************************************** */

  STATIC CONST auto kGDTEntriesCount = 6;

  /* The GDT, mostly descriptors for user and kernel segments. */
  STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = {
      {.fLimitLow   = 0,
       .fBaseLow    = 0,
       .fBaseMid    = 0,
       .fAccessByte = 0x00,
       .fFlags      = 0x00,
       .fBaseHigh   = 0},  // Null entry
      {.fLimitLow   = 0x0,
       .fBaseLow    = 0,
       .fBaseMid    = 0,
       .fAccessByte = 0x9A,
       .fFlags      = 0xAF,
       .fBaseHigh   = 0},  // Kernel code
      {.fLimitLow   = 0x0,
       .fBaseLow    = 0,
       .fBaseMid    = 0,
       .fAccessByte = 0x92,
       .fFlags      = 0xCF,
       .fBaseHigh   = 0},  // Kernel data
      {.fLimitLow   = 0x0,
       .fBaseLow    = 0,
       .fBaseMid    = 0,
       .fAccessByte = 0xFA,
       .fFlags      = 0xAF,
       .fBaseHigh   = 0},  // User code
      {.fLimitLow   = 0x0,
       .fBaseLow    = 0,
       .fBaseMid    = 0,
       .fAccessByte = 0xF2,
       .fFlags      = 0xCF,
       .fBaseHigh   = 0},  // User data
  };

  // Load memory descriptors.
  Kernel::HAL::Register64 gdt_reg;

  gdt_reg.Base  = reinterpret_cast<Kernel::UIntPtr>(kGDTArray);
  gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1;

  //! GDT will load hal_read_init after it successfully loads the segments.
  Kernel::HAL::GDTLoader gdt_loader;
  gdt_loader.Load(gdt_reg);

  return kEfiFail;
}

EXTERN_C void rtl_ne_task(void);

EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
  Kernel::rtl_create_user_process(rtl_ne_task, "MGMTCTL");
  Kernel::rtl_create_user_process(rtl_ne_task, "LAUNCHCTL");
  Kernel::rtl_create_user_process(rtl_ne_task, "SECURITYCTL");

  Kernel::HAL::Register64 idt_reg;
  idt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kInterruptVectorTable);

  Kernel::HAL::IDTLoader idt_loader;

  idt_loader.Load(idt_reg);

  Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);

#ifdef __FSKIT_INCLUDES_HEFS__
  if (Kernel::HeFS::fs_init_hefs()) {
    goto hal_spin_kernel;
  }
#endif
  if (!Kernel::NeFS::fs_init_nefs()) {
    kout << "NeFS cannot be formated on the disk. Aborting\r";
    dbg_break_point();
  }

hal_spin_kernel:
  while (YES)
    ;
}
#endif  // ifndef __NE_MODULAR_KERNEL_COMPONENTS__