165 lines
4.6 KiB
C
165 lines
4.6 KiB
C
/// lcrash entry point
|
|
/// super awesome...
|
|
|
|
#include <lcrash/gdb/gdb.h>
|
|
#include <lcrash/pci/pci.h>
|
|
#include <lcrash/mm/phys.h>
|
|
#include <lcrash/mm/kmalloc.h>
|
|
#include <lcrash/cmdline.h>
|
|
#include <lcrash/debug/debug.h>
|
|
#include <lcrash/driver/sysbus.h>
|
|
#include <lcrash/mm/virt.h>
|
|
#include <lcrash/driver/cap/textdisplay.h>
|
|
#include <lcrash/irq.h>
|
|
|
|
#include "types.h"
|
|
#include "lnxboot.h"
|
|
|
|
#include "efi/efi.h"
|
|
|
|
struct SysbusDevice* TryFindScreen(struct SysbusDevice* Device) {
|
|
if (SysbusGetCapability(Device, TextModeDisplayCapabilityGetCapability()) != NULL) {
|
|
return Device;
|
|
}
|
|
|
|
for (int i = 0; i < Device->ChildCount; i++) {
|
|
struct SysbusDevice* ChildDevice = TryFindScreen(Device->Children[i]);
|
|
|
|
if (ChildDevice != NULL) return ChildDevice;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Fill a screen range with a character.
|
|
* Positions are 1-indexed
|
|
*/
|
|
void FillScreenCharRange(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, c8 Char, u32 FG, u32 BG) {
|
|
R0 -= 1;
|
|
R1 -= 1;
|
|
C0 -= 1;
|
|
C1 -= 1;
|
|
|
|
for (int r = R0; r <= R1; r++) {
|
|
for (int c = C0; c <= C1; c++) {
|
|
TMDC->SetCharacter(Device, r, c, Char, FG, BG);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw text at a location
|
|
* Positions are 1-indexed
|
|
*/
|
|
void DrawTextBox(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, u32 FG, u32 BG, c8* Text) {
|
|
R0 -= 1;
|
|
R1 -= 1;
|
|
C0 -= 1;
|
|
C1 -= 1;
|
|
|
|
bool InText = true;
|
|
int Row = R0;
|
|
int Col = 0;
|
|
for (Row = R0; Row <= R1; Row++) {
|
|
for (Col = C0; Col <= C1;) {
|
|
if (*Text == 0) InText = false;
|
|
if (InText) {
|
|
c8 Char = *Text;
|
|
if (Char >= 'a' && Char <= 'z') Char = Char - 'a' + 'A';
|
|
if (Char == '\r') {
|
|
Col = C0;
|
|
} else if (Char == '\n') {
|
|
Row += 1;
|
|
} else {
|
|
TMDC->SetCharacter(Device, Row, Col, Char, FG, BG);
|
|
Col += 1;
|
|
}
|
|
|
|
Text += 1;
|
|
} else {
|
|
TMDC->SetCharacter(Device, Row, Col, ' ', FG, BG);
|
|
Col += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
[[noreturn]]
|
|
void entry64(struct boot_params* BootParams) {
|
|
BootBootParams = BootParams;
|
|
BootSetupInfo = (void*)BootParams + 0x1f1;
|
|
|
|
// Notify the debugger that we're ready
|
|
struct GdbDataBlock* GdbDataBlock = (struct GdbDataBlock*)0x100000;
|
|
GdbDataBlock->KernelLoaded = true;
|
|
GdbDataBlock->KernelBase = (void*)BootSetupInfo->code32_start;
|
|
GdbDataBlock->Update++;
|
|
|
|
// Parse the kernel command line
|
|
CmdlineParse((c8*)( ((uptr)BootSetupInfo->cmd_line_ptr)
|
|
|((uptr)BootBootParams->ext_cmd_line_ptr << 32)));
|
|
|
|
// Initialize the physical memory manager
|
|
if (PmemInitialize()) while (1) {}
|
|
|
|
// Initialize the kernel heap
|
|
if (KernelHeapInitialize()) while (1) {}
|
|
|
|
// Initialize the IRQ handler
|
|
if (IrqHandlerInitialize()) while (1) {}
|
|
|
|
// Enable interrupts
|
|
IrqHandlerEnableInterrupts();
|
|
|
|
// Initialize the extended debugging information block
|
|
if (DebugInitialize()) while (1) {}
|
|
|
|
// Initialize the virtual memory manager
|
|
VmemInitialize();
|
|
|
|
// Initialize the system bus
|
|
SysbusInitialize();
|
|
|
|
// Initialize EFI code if we had EFI
|
|
EfiInitialize();
|
|
|
|
// Initialize ACPI code if we have ACPI
|
|
AcpiInitialize();
|
|
|
|
// Initialize PCI code..
|
|
PciInitialize();
|
|
|
|
// Try to find a screen and write some crap to it.
|
|
// TODO: REMOVE WHEN DONE WITH DISPLAY DRIVERS
|
|
if (!TextModeDisplayCapabilityIsInitialized()) TextModeDisplayCapabilityInitialize();
|
|
|
|
struct SysbusDevice* Screen = TryFindScreen(SysbusGetRootDevice());
|
|
if (Screen == 0) Panic("No screen found");
|
|
struct TextModeDisplayCapability* ScreenTMDC = SysbusGetCapability(Screen, TextModeDisplayCapabilityGetCapability());
|
|
|
|
if (ScreenTMDC->Reset(Screen)) Panic("Failed to reset screen");
|
|
if (ScreenTMDC->Enable(Screen)) Panic("Failed to enable screen");
|
|
|
|
// Set color palette
|
|
ScreenTMDC->SetPaletteColor(Screen, 0, 0, 0, 0 );
|
|
ScreenTMDC->SetPaletteColor(Screen, 1, 200, 0, 0 );
|
|
ScreenTMDC->SetPaletteColor(Screen, 2, 200, 200, 200);
|
|
|
|
// Clear screen
|
|
FillScreenCharRange(Screen, ScreenTMDC, 1, 1, 25, 80, ' ', 1, 1);
|
|
|
|
// Draw header
|
|
DrawTextBox(Screen, ScreenTMDC, 4, 32, 4, 47, 2, 1, " YOU FUCKED UP! ");
|
|
|
|
// Draw body
|
|
DrawTextBox(Screen, ScreenTMDC, 6, 5, 8, 75, 1, 2, "A fatal error has occurred and Lindows has shut down to prevent damage to your device.");
|
|
DrawTextBox(Screen, ScreenTMDC, 10, 5, 13, 75, 1, 2, "If this error occurs again after a reboot, check the logs in `C:/Windows/Logs/`. If you are unable to correct the error, try dumping the system and analyzing it in GDB or submitting a bug report with the dump and logs included.");
|
|
DrawTextBox(Screen, ScreenTMDC, 21, 5, 22, 75, 1, 2, "Press any key to reboot.\r\nPress ESC to dump the system state to `C:/Windows/SystemDump/`.");
|
|
|
|
// Hang :)
|
|
while (1) {}
|
|
}
|