Challenge of handmade OS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

220 lines
8.1 KiB

#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
/*
#include <Pi/PiMultiPhase.h>
#include <Protocol/MpService.h>
*/
#include <Guid/Acpi.h>
#include <Uefi.h>
#include <Uefi/UefiSpec.h>
#include "fb.h"
#include "gdt.h"
#include "interrupt.h"
#include "ramfs.h"
#include "text.h"
#pragma pack(1)
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER header;
EFI_ACPI_DESCRIPTION_HEADER *entry[0];
} XSDT;
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER header;
UINT32 EventTimerBlockID;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE BaseAddress;
UINT8 HPETNumber;
UINT16 MinimumTick;
UINT8 Flags;
} HPET;
#pragma pack()
EFI_ACPI_DESCRIPTION_HEADER *Get_SDT(EFI_SYSTEM_TABLE *SystemTable,
UINT64 Signature) {
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *ACPI_Table;
EFI_GUID gEfiAcpiTableGuid = EFI_ACPI_TABLE_GUID;
for (UINTN i = 0; i < SystemTable->NumberOfTableEntries; i++) {
EFI_CONFIGURATION_TABLE *table = SystemTable->ConfigurationTable + i;
if (table->VendorGuid.Data1 == gEfiAcpiTableGuid.Data1 &&
table->VendorGuid.Data2 == gEfiAcpiTableGuid.Data2 &&
table->VendorGuid.Data3 == gEfiAcpiTableGuid.Data3 &&
table->VendorGuid.Data4[0] == gEfiAcpiTableGuid.Data4[0] &&
table->VendorGuid.Data4[1] == gEfiAcpiTableGuid.Data4[1] &&
table->VendorGuid.Data4[2] == gEfiAcpiTableGuid.Data4[2] &&
table->VendorGuid.Data4[3] == gEfiAcpiTableGuid.Data4[3] &&
table->VendorGuid.Data4[4] == gEfiAcpiTableGuid.Data4[4] &&
table->VendorGuid.Data4[5] == gEfiAcpiTableGuid.Data4[5] &&
table->VendorGuid.Data4[6] == gEfiAcpiTableGuid.Data4[6] &&
table->VendorGuid.Data4[7] == gEfiAcpiTableGuid.Data4[7]) {
ACPI_Table = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)
table->VendorTable;
}
}
XSDT *xsdt = (XSDT *)ACPI_Table->XsdtAddress;
for (int i = 0;
i < (xsdt->header.Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) /
sizeof(EFI_ACPI_DESCRIPTION_HEADER *);
i++) {
if (xsdt->entry[i]->Signature == Signature) return xsdt->entry[i];
}
return NULL;
}
EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable) {
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
// EFI_MP_SERVICES_PROTOCOL *mps;
SystemTable->BootServices->SetWatchdogTimer(
0, 0, 0, NULL); // Disable watch dog timer
Status = SystemTable->BootServices->LocateProtocol(
&gEfiGraphicsOutputProtocolGuid, NULL,
(VOID **)&gop); // Get GOP Protocol
if (EFI_ERROR(Status)) {
Print(L"Error:Failed to locate EFI Graphics Output Protocol - %r",
Status);
return Status;
}
/*
Status = SystemTable->BootServices->LocateProtocol(
&gEfiMpServiceProtocolGuid, NULL,
(VOID **)&mps); // Get MultiProcessor Protocol
if (EFI_ERROR(Status)) {
Print(L"Error:Failed to locate EFI MP Services Protocol - %r",
Status); return Status;
}
*/
// HPET *hpet_table = (HPET *)Get_SDT(
// SystemTable, EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE);
FrameBuffer_init(gop);
ramfsinit(SystemTable);
UINTN MemoryMapSize = 1, MapKey, DescriptorSize;
UINT32 DescriptorVersion;
EFI_MEMORY_DESCRIPTOR *mem_desc;
do {
Status = SystemTable->BootServices->AllocatePool(
EfiLoaderData, MemoryMapSize, (void **)&mem_desc);
if (EFI_ERROR(Status)) {
Print(L"Error:Failed to allocate memory map memory - %r\n", Status);
continue;
}
Status = SystemTable->BootServices->GetMemoryMap(
&MemoryMapSize, mem_desc, &MapKey, &DescriptorSize,
&DescriptorVersion);
if (EFI_ERROR(Status)) {
Print(L"Error:Failed to get memory map - %r\n", Status);
SystemTable->BootServices->FreePool(mem_desc);
continue;
}
Status =
SystemTable->BootServices->ExitBootServices(ImageHandle, MapKey);
if (EFI_ERROR(Status)) {
Print(L"Error:Failed to exit boot service - %r\n", Status);
SystemTable->BootServices->FreePool(mem_desc);
continue;
}
break;
} while (TRUE);
for (int y = 0; y < buffer.VerticalRes; y++) {
for (int x = 0; x < buffer.HorizontalRes; x++) {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel =
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)buffer.BaseAddress +
(buffer.HorizontalRes * y) + x;
RGBtoPixel(pixel, 0x000000);
}
}
for (UINTN i = (UINTN)mem_desc; i < ((UINTN)mem_desc + MemoryMapSize);
i += DescriptorSize) {
((EFI_MEMORY_DESCRIPTOR *)i)->VirtualStart =
((EFI_MEMORY_DESCRIPTOR *)i)->PhysicalStart;
}
SystemTable->RuntimeServices->SetVirtualAddressMap(
MemoryMapSize, DescriptorSize, DescriptorVersion, mem_desc);
for (UINTN i = (UINTN)mem_desc; i < ((UINTN)mem_desc + MemoryMapSize);
i += DescriptorSize) {
print("Type:");
switch (((EFI_MEMORY_DESCRIPTOR *)i)->Type) {
case EfiReservedMemoryType:
print("EfiReservedMemoryType");
break;
case EfiLoaderCode:
print("EfiLoaderCode");
break;
case EfiLoaderData:
print("EfiLoaderData");
break;
case EfiBootServicesCode:
print("EfiBootServicesCode");
break;
case EfiBootServicesData:
print("EfiBootServicesData");
break;
case EfiRuntimeServicesCode:
print("EfiRuntimeServicesCode");
break;
case EfiRuntimeServicesData:
print("EfiRuntimeServicesData");
break;
case EfiConventionalMemory:
print("EfiConventionalMemory");
break;
case EfiUnusableMemory:
print("EfiUnusableMemory");
break;
case EfiACPIReclaimMemory:
print("EfiACPIReclaimMemory");
break;
case EfiACPIMemoryNVS:
print("EfiACPIMemoryNVS");
break;
case EfiMemoryMappedIO:
print("EfiMemoryMappedIO");
break;
case EfiMemoryMappedIOPortSpace:
print("EfiMemoryMappedIOPortSpace");
break;
case EfiPalCode:
print("EfiPalCode");
break;
case EfiPersistentMemory:
print("EfiPersistentMemory");
break;
case EfiMaxMemoryType:
print("EfiMaxMemoryType");
break;
}
print(" Physical:");
printhex(((EFI_MEMORY_DESCRIPTOR *)i)->PhysicalStart, 0);
print(" Virtual:");
printhex(((EFI_MEMORY_DESCRIPTOR *)i)->VirtualStart, 0);
print(" Pages:");
printhex(((EFI_MEMORY_DESCRIPTOR *)i)->NumberOfPages, 0);
print(" Attribute:");
printhex(((EFI_MEMORY_DESCRIPTOR *)i)->Attribute, 0);
print("\n");
}
GDT_init();
interrupt_init();
/*
for (int y = 0; y < buffer.VerticalRes; y++) {
for (int x = 0; x < buffer.HorizontalRes; x++) {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel =
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)buffer.BaseAddress +
(buffer.HorizontalRes * y) + x;
RGBtoPixel(pixel, 0xFF0000);
}
}*/
while (1) asm volatile("hlt");
return Status;
}