lindows/lcrash/main.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) {}
}