Skip to content

Commit

Permalink
Fix EFI startup
Browse files Browse the repository at this point in the history
  • Loading branch information
djphoenix committed May 18, 2019
1 parent 6f1b009 commit abe3696
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 39 deletions.
34 changes: 33 additions & 1 deletion src/boot/efiboot.cpp
Expand Up @@ -7,6 +7,38 @@
namespace EFI {
const struct EFI::SystemTable *SystemTable = nullptr;
const void *ImageHandle = nullptr;
const void *acpi1 = nullptr, *acpi2 = nullptr;
void load();
Framebuffer fb, *fbPtr = nullptr;
}
const struct EFI::SystemTable *EFI::getSystemTable() { return SystemTable; }
const struct EFI::SystemTable *EFI::getSystemTable() { load(); return SystemTable; }
const void *EFI::getImageHandle() { return ImageHandle; }

const void *EFI::getACPI1Addr() { return acpi1; }
const void *EFI::getACPI2Addr() { return acpi2; }
const struct EFI::Framebuffer *EFI::getFramebuffer() { return fbPtr; }

void EFI::load() {
static bool loaded = false;
if (loaded || !SystemTable) return;

if (SystemTable->ConfigurationTable) {
for (uint64_t i = 0; i < SystemTable->NumberOfTableEntries; i++) {
const EFI::ConfigurationTable *tbl = SystemTable->ConfigurationTable + i;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI1) acpi1 = tbl->VendorTable;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI2) acpi2 = tbl->VendorTable;
}
}
EFI::GraphicsOutput *graphics_output = nullptr;
SystemTable->BootServices->LocateProtocol(
&EFI::GUID_GraphicsOutputProtocol, nullptr,
reinterpret_cast<void**>(&graphics_output));
if (graphics_output) {
fb.base = graphics_output->Mode->FrameBufferBase;
fb.width = graphics_output->Mode->Info->HorizontalResolution;
fb.height = graphics_output->Mode->Info->VerticalResolution;
fb.pixelFormat = graphics_output->Mode->Info->PixelFormat;
fbPtr = &fb;
}
loaded = true;
}
8 changes: 8 additions & 0 deletions src/boot/include/efi.hpp
Expand Up @@ -332,6 +332,14 @@ namespace EFI {
};
const struct SystemTable *getSystemTable() PURE;
const void *getImageHandle() PURE;
const void *getACPI1Addr() PURE;
const void *getACPI2Addr() PURE;
struct Framebuffer {
void *base;
size_t width, height;
GraphicsPixelFormat pixelFormat;
};
const Framebuffer *getFramebuffer() PURE;
}; // namespace EFI

static inline bool operator ==(const EFI::GUID &lhs, const EFI::GUID &rhs) {
Expand Down
16 changes: 4 additions & 12 deletions src/kernlib/display.cpp
Expand Up @@ -187,14 +187,10 @@ static Display *getSerialDisplay() { return &serialConsole; }

void Display::setup() {
if (instance != &serialConsole) return;
const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST) { // EFI Framebuffer
EFI::GraphicsOutput *graphics_output = nullptr;
ST->BootServices->LocateProtocol(
&EFI::GUID_GraphicsOutputProtocol, nullptr,
reinterpret_cast<void**>(&graphics_output));
const struct EFI::Framebuffer *fb = EFI::getFramebuffer();
if (fb) { // EFI Framebuffer
PixelFormat pixelFormat;
switch (graphics_output->Mode->Info->PixelFormat) {
switch (fb->pixelFormat) {
case EFI::GRAPHICS_PIXEL_FORMAT_RGBX_8BPP:
pixelFormat = PixelFormatRGBX;
break;
Expand All @@ -204,11 +200,7 @@ void Display::setup() {
default:
return;
}
instance = new FramebufferDisplay(
graphics_output->Mode->FrameBufferBase,
graphics_output->Mode->Info->HorizontalResolution,
graphics_output->Mode->Info->VerticalResolution,
pixelFormat);
instance = new FramebufferDisplay(fb->base, fb->width, fb->height, pixelFormat);
return;
}

Expand Down
45 changes: 19 additions & 26 deletions src/platform/acpi.cpp
Expand Up @@ -32,36 +32,29 @@ ACPI::ACPI() {
localApicAddr = nullptr;
ioApicAddr = nullptr;

const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST && ST->ConfigurationTable) {
const EFI::ConfigurationTable *acpi1 = nullptr, *acpi2 = nullptr;
for (uint64_t i = 0; i < ST->NumberOfTableEntries; i++) {
const EFI::ConfigurationTable *tbl = ST->ConfigurationTable + i;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI1) acpi1 = tbl;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI2) acpi2 = tbl;
}

bool found = 0;
if (acpi2) {
const uint64_t *ptr = reinterpret_cast<const uint64_t*>(acpi2->VendorTable);
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) found = 1;
}
if (!found && acpi1) {
const uint64_t *ptr = reinterpret_cast<const uint64_t*>(acpi1->VendorTable);
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) found = 1;
}
} else {
const uint64_t *p = static_cast<const uint64_t*>(ACPI_FIND_START);
const uint64_t *ptr = nullptr;
if (!ptr && (ptr = static_cast<const uint64_t*>(EFI::getACPI2Addr()))) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);
if ((*ptr != ACPI_SIG_RTP_DSR) || !ParseRsdp(ptr)) ptr = nullptr;
}
if (!ptr && (ptr = static_cast<const uint64_t*>(EFI::getACPI1Addr()))) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);
if ((*ptr != ACPI_SIG_RTP_DSR) || !ParseRsdp(ptr)) ptr = nullptr;
}
if (!ptr) {
ptr = static_cast<const uint64_t*>(ACPI_FIND_START);
const uint64_t *end = static_cast<const uint64_t*>(ACPI_FIND_TOP);
while (p < end) {
Pagetable::map(p);
Pagetable::map(p + 1);
uint64_t signature = *p;
while (ptr < end) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);

if ((signature == ACPI_SIG_RTP_DSR) && ParseRsdp(p)) break;
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) break;

p += 2;
ptr += 2;
}
if (ptr >= end) ptr = nullptr;
}

if ((CPU::getFeatures() & CPU::CPUID_FEAT_APIC) && !localApicAddr) {
Expand Down
1 change: 1 addition & 0 deletions src/platform/pagetable.cpp
Expand Up @@ -105,6 +105,7 @@ void Pagetable::init() {
uintptr_t ptbase = 0x600000 + (RAND::get<uintptr_t>() & 0x3FFF000);

pagetable = static_cast<PTE*>(efiAllocatePage(ptbase, ST));
efiMapPage(pagetable, nullptr, ST, 0);
efiMapPage(pagetable, pagetable, ST);

size_t mapSize = 0, entSize = 0;
Expand Down

0 comments on commit abe3696

Please sign in to comment.