summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-19 16:36:51 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-19 16:37:54 -0400
commit472ec944d2ed81d0304cc6cac80946a6a44776be (patch)
treef6cae641c143a0b45bb289d9d9fc6145706025b0 /kernel
parentset mmap limit (diff)
downloadcomus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.gz
comus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.bz2
comus-472ec944d2ed81d0304cc6cac80946a6a44776be.zip
UEFI and republicans
Diffstat (limited to 'kernel')
-rw-r--r--kernel/drivers/gpu.c95
-rw-r--r--kernel/drivers/gpu/bochs.c62
-rw-r--r--kernel/drivers/gpu/gop.c27
-rw-r--r--kernel/drivers/gpu/vga_text.c (renamed from kernel/drivers/vga.c)6
-rw-r--r--kernel/efi/efi.c28
-rw-r--r--kernel/efi/efi.h9
-rw-r--r--kernel/efi/gop.c52
-rw-r--r--kernel/efi/mmap.c87
-rw-r--r--kernel/entry.S69
-rw-r--r--kernel/include/comus/drivers/gpu.h38
-rw-r--r--kernel/include/comus/drivers/gpu/bochs.h27
-rw-r--r--kernel/include/comus/drivers/gpu/gop.h20
-rw-r--r--kernel/include/comus/drivers/gpu/vga_text.h (renamed from kernel/include/comus/drivers/vga.h)5
-rw-r--r--kernel/include/comus/efi.h35
-rw-r--r--kernel/include/comus/limits.h2
-rw-r--r--kernel/include/comus/mboot.h11
-rw-r--r--kernel/include/comus/memory.h7
-rw-r--r--kernel/include/comus/term.h21
-rw-r--r--kernel/include/efi.h1457
-rw-r--r--kernel/main.c4
-rw-r--r--kernel/mboot/efi.c38
-rw-r--r--kernel/mboot/mboot.c2
-rw-r--r--kernel/mboot/mmap.c30
-rw-r--r--kernel/memory/memory.c12
-rw-r--r--kernel/memory/paging.c41
-rw-r--r--kernel/memory/physalloc.c22
-rw-r--r--kernel/term.c22
27 files changed, 1986 insertions, 243 deletions
diff --git a/kernel/drivers/gpu.c b/kernel/drivers/gpu.c
index 730fa42..17e7e18 100644
--- a/kernel/drivers/gpu.c
+++ b/kernel/drivers/gpu.c
@@ -1,91 +1,44 @@
#include <lib.h>
#include <comus/drivers/gpu.h>
+#include <comus/drivers/gpu/gop.h>
#include <comus/drivers/gpu/bochs.h>
+#include <comus/drivers/gpu/vga_text.h>
#include <comus/error.h>
#include <comus/term.h>
#include <comus/asm.h>
-enum gpu_type {
- GPU_UNSET = 0,
- GPU_BOCHS = 1,
- N_GPU_TYPE,
-};
-
-static enum gpu_type type = GPU_UNSET;
-
-static const char *gpu_type_str[N_GPU_TYPE] = { "Unknown", "Bochs" };
-
-struct psf2_font {
- uint8_t magic[4];
- uint32_t version;
- uint32_t header_size;
- uint32_t flags;
- uint32_t length;
- uint32_t glyph_size;
- uint32_t height;
- uint32_t width;
- uint8_t data[];
-};
-
-extern struct psf2_font en_font;
+struct gpu *gpu_dev = NULL;
int gpu_init(void)
{
- if (bochs_init() == SUCCESS)
- type = GPU_BOCHS;
-
- if (type != GPU_UNSET) {
- uint16_t width = gpu_width() / en_font.width;
- uint16_t height = gpu_height() / en_font.height;
- term_switch_handler(width, height, gpu_draw_char);
+ // try to get a gpu device
+ if (!gpu_dev && gop_init(&gpu_dev) == SUCCESS) {
}
-
- return type != GPU_UNSET;
-}
-
-uint32_t gpu_width(void)
-{
- switch (type) {
- case GPU_BOCHS:
- return bochs_width();
- default:
- return 0;
+ if (!gpu_dev && bochs_init(&gpu_dev) == SUCCESS) {
}
-}
-uint32_t gpu_height(void)
-{
- switch (type) {
- case GPU_BOCHS:
- return bochs_height();
- default:
- return 0;
- }
-}
+ // if we did (yay!) resize terminal
+ if (gpu_dev)
+ term_resize(gpu_dev->width, gpu_dev->height);
-uint8_t gpu_bit_depth(void)
-{
- switch (type) {
- case GPU_BOCHS:
- return bochs_bit_depth();
- default:
- return 0;
- }
+ return gpu_dev != NULL;
}
void gpu_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b)
{
- switch (type) {
- case GPU_BOCHS:
- bochs_set_pixel(x, y, r, g, b);
- break;
- default:
- break;
- }
+ // TODO: handle other bpp
+ volatile uint32_t *fb = (volatile uint32_t *)gpu_dev->framebuffer;
+ int offset = y * gpu_dev->width + x;
+ fb[offset] = (b << 0) | (g << 8) | (r << 16);
}
void gpu_draw_char(char c, uint16_t cx, uint16_t cy)
{
+ if (gpu_dev == NULL) {
+ vga_text_draw_char(c, cx, cy);
+ return;
+ }
+
uint32_t sx = en_font.width * cx;
uint32_t sy = en_font.height * cy;
@@ -107,11 +60,11 @@ void gpu_draw_char(char c, uint16_t cx, uint16_t cy)
void gpu_report(void)
{
- if (type == GPU_UNSET)
+ if (gpu_dev == NULL)
return;
- kprintf("GPU (%s)\n", gpu_type_str[type]);
- kprintf("Width: %d\n", gpu_width());
- kprintf("Height: %d\n", gpu_height());
- kprintf("Bit depth: %d\n\n", gpu_bit_depth());
+ kprintf("GPU (%s)\n", gpu_dev->name);
+ kprintf("Width: %d\n", gpu_dev->width);
+ kprintf("Height: %d\n", gpu_dev->height);
+ kprintf("Bit depth: %d\n\n", gpu_dev->bit_depth);
}
diff --git a/kernel/drivers/gpu/bochs.c b/kernel/drivers/gpu/bochs.c
index a100908..3438ab5 100644
--- a/kernel/drivers/gpu/bochs.c
+++ b/kernel/drivers/gpu/bochs.c
@@ -2,6 +2,7 @@
#include <comus/asm.h>
#include <comus/memory.h>
#include <comus/drivers/pci.h>
+#include <comus/drivers/gpu.h>
#include <comus/drivers/gpu/bochs.h>
#define INDEX 0x1CE
@@ -30,10 +31,7 @@
#define BOCHS_HEIGHT 768
#define BOCHS_BIT_DEPTH 32
-static volatile uint32_t *framebuffer;
-static uint16_t width = BOCHS_WIDTH;
-static uint16_t height = BOCHS_HEIGHT;
-static uint8_t bit_depth = BOCHS_BIT_DEPTH;
+struct gpu bochs_dev = { 0 };
static void write(uint16_t index, uint16_t data)
{
@@ -47,23 +45,7 @@ static uint16_t read(uint16_t value)
return inw(DATA);
}
-static int is_available(void)
-{
- return (read(INDEX_ID) == 0xB0C5);
-}
-
-static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth,
- int lfb, int clear)
-{
- write(INDEX_ENABLE, DATA_DISP_DISABLE);
- write(INDEX_XRES, width);
- write(INDEX_YRES, height);
- write(INDEX_BPP, bit_depth);
- write(INDEX_ENABLE, DATA_DISP_ENABLE | (lfb ? DATA_LFB_ENABLE : 0) |
- (clear ? 0 : DATA_NO_CLEAR_MEM));
-}
-
-int bochs_init(void)
+int bochs_init(struct gpu **gpu_dev)
{
struct pci_device bochs = { 0 };
bool found =
@@ -71,34 +53,24 @@ int bochs_init(void)
if (!found)
return 1;
- set_mode(width, height, bit_depth, true, true);
- if (!is_available())
+ write(INDEX_ENABLE, DATA_DISP_DISABLE);
+ write(INDEX_XRES, BOCHS_WIDTH);
+ write(INDEX_YRES, BOCHS_HEIGHT);
+ write(INDEX_BPP, BOCHS_BIT_DEPTH);
+ write(INDEX_ENABLE, DATA_DISP_ENABLE | DATA_LFB_ENABLE);
+ if (read(INDEX_ID) != 0xB0C5)
return 1;
uint32_t bar0 = pci_rcfg_d(bochs, PCI_BAR0_D);
uint32_t *addr = (uint32_t *)(uintptr_t)bar0;
- framebuffer = kmapaddr(addr, NULL, width * height * bit_depth, F_WRITEABLE);
- return 0;
-}
+ bochs_dev.name = "Bochs";
+ bochs_dev.width = BOCHS_WIDTH;
+ bochs_dev.height = BOCHS_HEIGHT;
+ bochs_dev.bit_depth = BOCHS_BIT_DEPTH;
+ bochs_dev.framebuffer = kmapaddr(
+ addr, NULL, BOCHS_WIDTH * BOCHS_HEIGHT * BOCHS_BIT_DEPTH, F_WRITEABLE);
+ *gpu_dev = &bochs_dev;
-uint32_t bochs_width(void)
-{
- return width;
-}
-
-uint32_t bochs_height(void)
-{
- return height;
-}
-
-uint8_t bochs_bit_depth(void)
-{
- return bit_depth;
-}
-
-void bochs_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b)
-{
- uint32_t index = x + y * width;
- framebuffer[index] = (b << 0) | (g << 8) | (r << 16);
+ return 0;
}
diff --git a/kernel/drivers/gpu/gop.c b/kernel/drivers/gpu/gop.c
new file mode 100644
index 0000000..47da952
--- /dev/null
+++ b/kernel/drivers/gpu/gop.c
@@ -0,0 +1,27 @@
+#include <lib.h>
+#include <comus/asm.h>
+#include <comus/drivers/gpu.h>
+#include <comus/drivers/gpu/gop.h>
+#include <comus/efi.h>
+#include <efi.h>
+
+struct gpu gop_dev = { 0 };
+
+static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+
+int gop_init(struct gpu **gpu_dev)
+{
+ gop = efi_get_gop();
+ if (gop == NULL || gop->Mode == NULL)
+ return 1;
+
+ gop_dev.name = "GOP";
+ gop_dev.width = gop->Mode->Info->HorizontalResolution;
+ gop_dev.height = gop->Mode->Info->VerticalResolution;
+ gop_dev.bit_depth = 32; // we only allow 8bit color in efi/gop.c
+ gop_dev.framebuffer = kmapaddr((void *)gop->Mode->FrameBufferBase, NULL,
+ gop->Mode->FrameBufferSize, F_WRITEABLE);
+ *gpu_dev = &gop_dev;
+
+ return 1;
+}
diff --git a/kernel/drivers/vga.c b/kernel/drivers/gpu/vga_text.c
index d73fa9f..e3359c3 100644
--- a/kernel/drivers/vga.c
+++ b/kernel/drivers/gpu/vga_text.c
@@ -2,15 +2,17 @@
#include <comus/term.h>
#include <comus/asm.h>
#include <comus/memory.h>
-#include <comus/drivers/vga.h>
+#include <comus/drivers/gpu/vga_text.h>
#define VGA_ADDR 0xB8000
+#define VGA_WIDTH 80
+#define VGA_HEIGHT 25
static volatile uint16_t *buffer = (uint16_t *)VGA_ADDR;
// color
static uint8_t fg = 15, bg = 0;
-void vga_draw_char(char c, uint16_t x, uint16_t y)
+void vga_text_draw_char(char c, uint16_t x, uint16_t y)
{
// output character
const size_t index = y * VGA_WIDTH + x;
diff --git a/kernel/efi/efi.c b/kernel/efi/efi.c
new file mode 100644
index 0000000..4f253a7
--- /dev/null
+++ b/kernel/efi/efi.c
@@ -0,0 +1,28 @@
+#include "lib/klib.h"
+#include <lib.h>
+#include <comus/efi.h>
+#include <comus/mboot.h>
+#include <comus/memory.h>
+#include <efi.h>
+
+#include "efi.h"
+
+void efi_init(EFI_HANDLE IH, EFI_SYSTEM_TABLE *ST)
+{
+ EFI_STATUS status;
+
+ if (IH == NULL || ST == NULL)
+ return;
+
+ status = efi_load_mmap(ST);
+ if (EFI_ERROR(status))
+ panic("Failed to load efi memory map, EFI_STATUS = %lu\n", status);
+
+ status = efi_load_gop(ST);
+ if (EFI_ERROR(status))
+ panic(
+ "Failed to locate graphics output protocol (GOP), EFI_STATUS = %lu\n",
+ status);
+
+ ST->BootServices->ExitBootServices(IH, 0);
+}
diff --git a/kernel/efi/efi.h b/kernel/efi/efi.h
new file mode 100644
index 0000000..7428f37
--- /dev/null
+++ b/kernel/efi/efi.h
@@ -0,0 +1,9 @@
+#ifndef __EFI_H
+#define __EFI_H
+
+#include <efi.h>
+
+EFI_STATUS efi_load_mmap(EFI_SYSTEM_TABLE *ST);
+EFI_STATUS efi_load_gop(EFI_SYSTEM_TABLE *ST);
+
+#endif /* efi.h */
diff --git a/kernel/efi/gop.c b/kernel/efi/gop.c
new file mode 100644
index 0000000..899bbee
--- /dev/null
+++ b/kernel/efi/gop.c
@@ -0,0 +1,52 @@
+#include <lib.h>
+#include <efi.h>
+#include <comus/efi.h>
+
+static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
+
+EFI_STATUS efi_load_gop(EFI_SYSTEM_TABLE *ST)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ UINTN SizeOfInfo, numModes, nativeMode;
+
+ status = ST->BootServices->LocateProtocol(&gopGuid, NULL, (void **)&gop);
+ if (EFI_ERROR(status))
+ return status;
+
+ status = gop->QueryMode(gop, gop->Mode == NULL ? 0 : gop->Mode->Mode,
+ &SizeOfInfo, &info);
+ if (status == EFI_NOT_STARTED)
+ status = gop->SetMode(gop, 0);
+ if (EFI_ERROR(status))
+ return status;
+
+ nativeMode = gop->Mode->Mode;
+ numModes = gop->Mode->MaxMode;
+
+ // find the best mode
+ UINTN best = nativeMode;
+ UINTN width = 0;
+ for (UINTN i = 0; i < numModes; i++) {
+ status = gop->QueryMode(gop, i, &SizeOfInfo, &info);
+ if (info->PixelFormat != PixelBlueGreenRedReserved8BitPerColor &&
+ info->PixelFormat != PixelRedGreenBlueReserved8BitPerColor)
+ continue;
+ if (info->HorizontalResolution > width) {
+ width = info->HorizontalResolution;
+ best = i;
+ }
+ }
+
+ gop->SetMode(gop, best);
+ if (EFI_ERROR(status))
+ return status;
+
+ return status;
+}
+
+EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(void)
+{
+ return gop;
+}
diff --git a/kernel/efi/mmap.c b/kernel/efi/mmap.c
new file mode 100644
index 0000000..26aba6a
--- /dev/null
+++ b/kernel/efi/mmap.c
@@ -0,0 +1,87 @@
+#include <lib.h>
+#include <efi.h>
+#include <comus/efi.h>
+#include <comus/memory.h>
+
+struct memory_map efi_mmap = { 0 };
+
+EFI_STATUS efi_load_mmap(EFI_SYSTEM_TABLE *ST)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+
+ EFI_MEMORY_DESCRIPTOR *memory_map = NULL;
+ UINT32 version = 0;
+ UINTN map_key = 0;
+ UINTN descriptor_size = 0;
+ UINTN memory_map_size = 0;
+
+ status = ST->BootServices->GetMemoryMap(
+ &memory_map_size, memory_map, &map_key, &descriptor_size, &version);
+
+ assert(status != EFI_SUCCESS,
+ "GetMemoryMap should NEVER succeed the first time");
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return status;
+
+ UINTN encompassing_size = memory_map_size + (2 * descriptor_size);
+ void *buffer = NULL;
+ status = ST->BootServices->AllocatePool(EfiLoaderData, encompassing_size,
+ &buffer);
+
+ if (EFI_ERROR(status))
+ return status;
+
+ memory_map = (EFI_MEMORY_DESCRIPTOR *)buffer;
+ memory_map_size = encompassing_size;
+ status = ST->BootServices->GetMemoryMap(
+ &memory_map_size, memory_map, &map_key, &descriptor_size, &version);
+
+ if (EFI_ERROR(status))
+ return status;
+
+ uint32_t idx = 0;
+ for (size_t i = 0; i < (memory_map_size / descriptor_size); i++) {
+ EFI_MEMORY_DESCRIPTOR *seg =
+ (EFI_MEMORY_DESCRIPTOR *)((char *)memory_map +
+ (descriptor_size * i));
+ if (idx >= N_MMAP_ENTRY)
+ panic("Too many mmap entries: limit is %d", N_MMAP_ENTRY);
+ efi_mmap.entries[idx].addr = seg->PhysicalStart;
+ efi_mmap.entries[idx].len = seg->NumberOfPages * PAGE_SIZE;
+ switch (seg->Type) {
+ case EfiReservedMemoryType:
+ case EfiMemoryMappedIO:
+ case EfiMemoryMappedIOPortSpace:
+ efi_mmap.entries[idx].type = SEG_TYPE_RESERVED;
+ break;
+ case EfiConventionalMemory:
+ efi_mmap.entries[idx].type = SEG_TYPE_FREE;
+ break;
+ case EfiACPIReclaimMemory:
+ case EfiACPIMemoryNVS:
+ efi_mmap.entries[idx].type = SEG_TYPE_ACPI;
+ break;
+ case EfiUnusableMemory:
+ efi_mmap.entries[idx].type = SEG_TYPE_DEFECTIVE;
+ break;
+ default:
+ efi_mmap.entries[idx].type = SEG_TYPE_EFI;
+ break;
+ }
+ idx++;
+ }
+ efi_mmap.entry_count = idx;
+
+ ST->BootServices->FreePool(buffer);
+
+ return status;
+}
+
+int efi_get_mmap(struct memory_map *map)
+{
+ if (efi_mmap.entry_count) {
+ *map = efi_mmap;
+ return 0;
+ }
+ return 1;
+}
diff --git a/kernel/entry.S b/kernel/entry.S
index 0610495..fdb8a5a 100644
--- a/kernel/entry.S
+++ b/kernel/entry.S
@@ -12,24 +12,47 @@
# multiboot header
mb_start:
- .align 8
# magic
+ .align 8
.long 0xe85250d6
.long 0
.long mb_end - mb_start
.long 0x100000000 - (0xe85250d6 + (mb_end - mb_start))
-mbi_start:
- .align 8
# info request
+ .align 8
.short 1
.short 1
- .long mbi_end - mbi_start
- .long 1 # cmdline
- .long 6 # mmap
- .long 9 # elf section
-mbi_end:
+ .long 20
+ .long 1 # cmdline
+ .long 6 # mmap
+ .long 9 # elf section
+ # bios entry
+ .align 8
+ .short 3
+ .short 0
+ .long 12
+ .long _start
+ # framebuffer
+ .align 8
+ .short 5
+ .short 1
+ .long 20
+ .long 720 # width
+ .long 480 # height
+ .long 32 # bpp
+ # efi boot services
.align 8
+ .short 7
+ .short 0
+ .long 8
+ # efi amd64 entry
+ .align 8
+ .short 9
+ .short 0
+ .long 12
+ .long _start_efi
# null
+ .align 8
.short 0
.short 0
.long 8
@@ -131,7 +154,7 @@ GDT:
.code32
_start:
- # enable interrupts
+ # disable interrupts
cli
# setup stack
@@ -203,8 +226,36 @@ code64:
pop %rsi
call main
+ jmp halt
+
+_start_efi:
+ # disable interrupts
cli
+ # setup stack
+ movq $kern_stack_end, %rsp
+ movq $kern_stack_end, %rbp
+
+ # load gdt
+ lgdt GDT.Pointer
+
+ # set segment registers
+ movw $GDT.Code, %dx
+ movw %dx, %cs
+ movw %dx, %es
+ movw $GDT.Data, %dx
+ movw %dx, %ds
+ movw %dx, %ss
+
+ xorq %rbp, %rbp # set ebp to 0 so we know where to end stack traces
+
+ movq %rax, %rdi
+ movq %rbx, %rsi
+
+ call main
+ jmp halt
+
halt:
+ cli
hlt
jmp halt
diff --git a/kernel/include/comus/drivers/gpu.h b/kernel/include/comus/drivers/gpu.h
index d6b4266..39c633f 100644
--- a/kernel/include/comus/drivers/gpu.h
+++ b/kernel/include/comus/drivers/gpu.h
@@ -11,26 +11,34 @@
#include <stdint.h>
-/**
- * Loads any gpu graphics driver
- * @returns 0 on success
- */
-int gpu_init(void);
+struct gpu {
+ const char *name;
+ uint16_t width;
+ uint16_t height;
+ uint16_t bit_depth;
+ volatile void *framebuffer;
+};
-/**
- * @returns the width of the framebuffer
- */
-uint32_t gpu_width(void);
+struct psf2_font {
+ uint8_t magic[4];
+ uint32_t version;
+ uint32_t header_size;
+ uint32_t flags;
+ uint32_t length;
+ uint32_t glyph_size;
+ uint32_t height;
+ uint32_t width;
+ uint8_t data[];
+};
-/**
- * @returns the height of the framebuffer
- */
-uint32_t gpu_height(void);
+extern struct gpu *gpu_dev;
+extern struct psf2_font en_font;
/**
- * @returns the bit depth of the framebuffer
+ * Loads any gpu graphics driver
+ * @returns 0 on success
*/
-uint8_t gpu_bit_depth(void);
+int gpu_init(void);
/**
* Sets the pixel at a given position
diff --git a/kernel/include/comus/drivers/gpu/bochs.h b/kernel/include/comus/drivers/gpu/bochs.h
index 31aa740..7d26b60 100644
--- a/kernel/include/comus/drivers/gpu/bochs.h
+++ b/kernel/include/comus/drivers/gpu/bochs.h
@@ -9,33 +9,12 @@
#ifndef BOCHS_H_
#define BOCHS_H_
-#include <stdint.h>
+#include <comus/drivers/gpu.h>
/**
* Loads the bochs graphics driver
- * @returns 0 on success
+ * @returns 0 on success, NULL on error
*/
-int bochs_init(void);
-
-/**
- * @returns the width of the framebuffer
- */
-uint32_t bochs_width(void);
-
-/**
- * @returns the height of the framebuffer
- */
-uint32_t bochs_height(void);
-
-/**
- * @returns the bit depth of the framebuffer
- */
-uint8_t bochs_bit_depth(void);
-
-/**
- * Sets the pixel at a given position
- */
-void bochs_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g,
- uint32_t b);
+int bochs_init(struct gpu **gpu_dev);
#endif /* bochs.h */
diff --git a/kernel/include/comus/drivers/gpu/gop.h b/kernel/include/comus/drivers/gpu/gop.h
new file mode 100644
index 0000000..6475f05
--- /dev/null
+++ b/kernel/include/comus/drivers/gpu/gop.h
@@ -0,0 +1,20 @@
+/**
+ * @file gop.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * UEFI Graphics Output Protocol Driver
+ */
+
+#ifndef GOP_H_
+#define GOP_H_
+
+#include <comus/drivers/gpu.h>
+
+/**
+ * Loads the uefi gop graphics driver
+ * @returns 0 on success, NULL on error
+ */
+int gop_init(struct gpu **gpu_dev);
+
+#endif /* gop.h */
diff --git a/kernel/include/comus/drivers/vga.h b/kernel/include/comus/drivers/gpu/vga_text.h
index 71906f6..26fbe41 100644
--- a/kernel/include/comus/drivers/vga.h
+++ b/kernel/include/comus/drivers/gpu/vga_text.h
@@ -9,14 +9,11 @@
#ifndef VGA_H_
#define VGA_H_
-#define VGA_WIDTH 80
-#define VGA_HEIGHT 25
-
#include <stdint.h>
/**
* Draw a character to the vga text mode at a given position
*/
-void vga_draw_char(char c, uint16_t x, uint16_t y);
+void vga_text_draw_char(char c, uint16_t x, uint16_t y);
#endif /* vga.h */
diff --git a/kernel/include/comus/efi.h b/kernel/include/comus/efi.h
new file mode 100644
index 0000000..bbb87f9
--- /dev/null
+++ b/kernel/include/comus/efi.h
@@ -0,0 +1,35 @@
+/**
+ * @file efi.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * EFI functions
+ */
+
+#ifndef EFI_H_
+#define EFI_H_
+
+#include <comus/memory.h>
+#include <efi.h>
+
+/**
+ * Initalize EFI structures
+ */
+void efi_init(EFI_HANDLE IH, EFI_SYSTEM_TABLE *ST);
+
+/**
+ * Get the memory map from multiboot
+ */
+int efi_get_mmap(struct memory_map *map);
+
+/**
+ * Get graphics output protocol
+ */
+EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(void);
+
+/**
+ * Report EFI system status
+ */
+void efi_report(void);
+
+#endif /* efi.h */
diff --git a/kernel/include/comus/limits.h b/kernel/include/comus/limits.h
index 58cc9cb..93cf8dd 100644
--- a/kernel/include/comus/limits.h
+++ b/kernel/include/comus/limits.h
@@ -13,7 +13,7 @@
#define N_PCI_DEV 256
/// max memory entires
-#define N_MMAP_ENTRY 64
+#define N_MMAP_ENTRY 256
/// length of terminal buffer
#define TERM_MAX_WIDTH 480
diff --git a/kernel/include/comus/mboot.h b/kernel/include/comus/mboot.h
index 59d2d12..036cc40 100644
--- a/kernel/include/comus/mboot.h
+++ b/kernel/include/comus/mboot.h
@@ -10,6 +10,7 @@
#define MBOOT_H_
#include <comus/memory.h>
+#include <efi.h>
/**
* Load the multiboot information passed from the bootloader
@@ -31,4 +32,14 @@ void *mboot_get_rsdp(void);
*/
const char *mboot_get_elf_sym(uint64_t addr);
+/**
+ * Returns EFI64 system table
+ */
+EFI_SYSTEM_TABLE *mboot_get_efi_st(void);
+
+/**
+ * Returns EFI64 image handle
+ */
+EFI_HANDLE mboot_get_efi_hdl(void);
+
#endif /* mboot.h */
diff --git a/kernel/include/comus/memory.h b/kernel/include/comus/memory.h
index ad049ec..3b57324 100644
--- a/kernel/include/comus/memory.h
+++ b/kernel/include/comus/memory.h
@@ -26,6 +26,13 @@
#define F_MEGABYTE 0x080
#define F_GLOBAL 0x100
+#define SEG_TYPE_FREE 0
+#define SEG_TYPE_RESERVED 1
+#define SEG_TYPE_ACPI 2
+#define SEG_TYPE_HIBERNATION 3
+#define SEG_TYPE_DEFECTIVE 4
+#define SEG_TYPE_EFI 5
+
struct memory_segment {
uint64_t addr;
uint64_t len;
diff --git a/kernel/include/comus/term.h b/kernel/include/comus/term.h
index 6ac77e4..53c5a9e 100644
--- a/kernel/include/comus/term.h
+++ b/kernel/include/comus/term.h
@@ -11,22 +11,6 @@
#include <stdint.h>
-/// vtable structure for terminal handlers
-///
-/// required:
-/// out_at - put out char at position
-/// scroll - scroll the terminal count lines
-///
-/// optional:
-/// clear - clear terminal
-/// clear_line - clear a specific line on the terminal
-///
-struct terminal {
- uint16_t width;
- uint16_t height;
- void (*draw_char)(char c, uint16_t x, uint16_t y);
-};
-
/**
* Get the character width of the terminal
*/
@@ -78,9 +62,8 @@ void term_redraw(void);
void term_scroll(uint16_t lines);
/**
- * Switch terminal handler
+ * Resize terminal
*/
-void term_switch_handler(uint16_t width, uint16_t height,
- void (*draw_char)(char c, uint16_t x, uint16_t y));
+void term_resize(uint16_t width, uint16_t height);
#endif /* term.h */
diff --git a/kernel/include/efi.h b/kernel/include/efi.h
new file mode 100644
index 0000000..784b5fb
--- /dev/null
+++ b/kernel/include/efi.h
@@ -0,0 +1,1457 @@
+#pragma once
+
+/*
+As per UEFI Specification, version 2.8
+
+You may use this code for any purpose.
+
+This code is provided as-is and includes no claims, warranties, or
+representations whether express, implied, or otherwise for
+merchantability, fitness for a particular purpose, non-infringement,
+absence of latent or other defects, accuracy, or the presence or
+absence of errors, whether or not known or discoverable.
+
+*/
+
+// PE32+ Subsystem type for EFI images
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+
+// PE32+ Machine type for EFI images
+#define EFI_IMAGE_MACHINE_IA32 0x014c
+#define EFI_IMAGE_MACHINE_IA64 0x0200
+#define EFI_IMAGE_MACHINE_EBC 0x0EBC
+#define EFI_IMAGE_MACHINE_x64 0x8664
+#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2
+#define EFI_IMAGE_MACHINE_AARCH64 0xAA64
+#define EFI_IMAGE_MACHINE_RISCV32 0x5032
+#define EFI_IMAGE_MACHINE_RISCV64 0x5064
+#define EFI_IMAGE_MACHINE_RISCV128 0x5128
+
+/******************/
+/* Status_Codes */
+/******************/
+#define EFI_SUCCESS 0x0000000000000000
+
+#define EFI_WARN_UNKNOWN_GLYPH 0x0000000000000001
+#define EFI_WARN_DELETE_FAILURE 0x0000000000000002
+#define EFI_WARN_WRITE_FAILURE 0x0000000000000003
+#define EFI_WARN_BUFFER_TOO_SMALL 0x0000000000000004
+#define EFI_WARN_STALE_DATA 0x0000000000000005
+#define EFI_WARN_FILE_SYSTEM 0x0000000000000006
+#define EFI_WARN_RESET_REQUIRED 0x0000000000000007
+
+#define EFI_LOAD_ERROR 0x8000000000000001
+#define EFI_INVALID_PARAMETER 0x8000000000000002
+#define EFI_UNSUPPORTED 0x8000000000000003
+#define EFI_BAD_BUFFER_SIZE 0x8000000000000004
+#define EFI_BUFFER_TOO_SMALL 0x8000000000000005
+#define EFI_NOT_READY 0x8000000000000006
+#define EFI_DEVICE_ERROR 0x8000000000000007
+#define EFI_WRITE_PROTECTED 0x8000000000000008
+#define EFI_OUT_OF_RESOURCES 0x8000000000000009
+#define EFI_VOLUME_CORRUPTED 0x800000000000000a
+#define EFI_VOLUME_FULL 0x800000000000000b
+#define EFI_NO_MEDIA 0x800000000000000c
+#define EFI_MEDIA_CHANGED 0x800000000000000d
+#define EFI_NOT_FOUND 0x800000000000000e
+#define EFI_ACCESS_DENIED 0x800000000000000f
+#define EFI_NO_RESPONSE 0x8000000000000010
+#define EFI_NO_MAPPING 0x8000000000000011
+#define EFI_TIMEOUT 0x8000000000000012
+#define EFI_NOT_STARTED 0x8000000000000013
+#define EFI_ALREADY_STARTED 0x8000000000000014
+#define EFI_ABORTED 0x8000000000000015
+#define EFI_ICMP_ERROR 0x8000000000000016
+#define EFI_TFTP_ERROR 0x8000000000000017
+#define EFI_PROTOCOL_ERROR 0x8000000000000018
+#define EFI_INCOMPATIBLE_VERSION 0x8000000000000019
+#define EFI_SECURITY_VIOLATION 0x800000000000001a
+#define EFI_CRC_ERROR 0x800000000000001b
+#define EFI_END_OF_MEDIA 0x800000000000001c
+#define EFI_END_OF_FILE 0x800000000000001f
+#define EFI_INVALID_LANGUAGE 0x8000000000000020
+#define EFI_COMPROMISED_DATA 0x8000000000000021
+#define EFI_IP_ADDRESS_CONFLICT 0x8000000000000022
+#define EFI_HTTP_ERROR 0x8000000000000023
+
+#define EFI_ERROR(status) ((status) & 0x8000000000000000)
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef uint8_t BOOLEAN;
+#define TRUE 1
+#define FALSE 0
+
+typedef uintmax_t UINTN;
+typedef intmax_t INTN;
+
+typedef uint64_t UINT64;
+typedef uint32_t UINT32;
+typedef uint16_t UINT16;
+typedef uint8_t UINT8;
+
+typedef int64_t INT64;
+typedef int32_t INT32;
+typedef int16_t INT16;
+typedef int8_t INT8;
+
+typedef uint8_t CHAR8;
+typedef uint16_t CHAR16;
+
+typedef void VOID;
+
+typedef UINTN EFI_STATUS;
+
+typedef VOID *EFI_HANDLE;
+typedef VOID *EFI_EVENT;
+typedef UINT64 EFI_LBA;
+typedef UINTN EFI_TPL;
+
+typedef UINT64 EFI_PHYSICAL_ADDRESS;
+
+typedef UINT8 EFI_MAC_ADDRESS[4];
+typedef UINT8 EFI_IPv4_ADDRESS[4];
+typedef UINT8 EFI_IPv6_ADDRESS[16];
+typedef UINT8 __attribute__((aligned(4))) EFI_IP_ADDRESS[16];
+
+#define IN
+#define OUT
+#define OPTIONAL
+#define CONST const
+
+// Only true for x64(as far as I know)
+#define EFIAPI __attribute__((ms_abi))
+
+/*******************/
+/* Boot_Services */
+/*******************/
+
+//
+// CreateEvent
+//
+typedef VOID *EFI_EVENT;
+// These types can be “ORed” together as needed – for example,
+// EVT_TIMER might be “ORed” with EVT_NOTIFY_WAIT or
+// EVT_NOTIFY_SIGNAL. For actual definitions check the specification.
+#define EVT_TIMER 0x80000000
+#define EVT_RUNTIME 0x40000000
+#define EVT_NOTIFY_WAIT 0x00000100
+
+#define EVT_NOTIFY_SIGNAL 0x00000200
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+typedef VOID(EFIAPI *EFI_EVENT_NOTIFY)(IN EFI_EVENT Event, IN VOID *Context);
+
+typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT)(
+ IN UINT32 Type, IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
+ IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *Event);
+
+//
+// CreateEventEx
+//
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT_EX)(
+ IN UINT32 Type, IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
+ IN CONST VOID *NotifyContext OPTIONAL,
+ IN CONST EFI_GUID *EventGroup OPTIONAL, OUT EFI_EVENT *Event);
+#define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \
+ { 0x27abf055, \
+ 0xb1b8, \
+ 0x4c26, \
+ { 0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf } }
+
+#define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \
+ { 0x13fa7698, \
+ 0xc831, \
+ 0x49c7, \
+ { 0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96 } }
+
+#define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \
+ { 0x78bee926, \
+ 0x692f, \
+ 0x48fd, \
+ { 0x9e, 0xdb, 0x1, 0x42, 0x2e, 0xf0, 0xd7, 0xab } }
+
+#define EFI_EVENT_GROUP_READY_TO_BOOT \
+ { 0x7ce88fb3, \
+ 0x4bd7, \
+ 0x4679, \
+ { 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0xd, 0x2b } }
+
+#define EFI_EVENT_GROUP_RESET_SYSTEM \
+ { 0x62da6a56, \
+ 0x13fb, \
+ 0x485a, \
+ { 0xa8, 0xda, 0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b } }
+
+//
+// CloseEvent
+//
+typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(IN EFI_EVENT Event);
+
+//
+// SignalEvent
+//
+typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(IN EFI_EVENT Event);
+
+//
+// WaitForEvent
+//
+typedef EFI_STATUS(EFIAPI *EFI_WAIT_FOR_EVENT)(IN UINTN NumberOfEvents,
+ IN EFI_EVENT *Event,
+ OUT UINTN *Index);
+
+//
+// CheckEvent
+//
+typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(IN EFI_EVENT Event);
+
+//
+// SetTimer
+//
+typedef enum { TimerCancel, TimerPeriodic, TimerRelative } EFI_TIMER_DELAY;
+typedef EFI_STATUS(EFIAPI *EFI_SET_TIMER)(IN EFI_EVENT Event,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime);
+
+//
+// RaiseTPL
+//
+typedef EFI_TPL(EFIAPI *EFI_RAISE_TPL)(IN EFI_TPL NewTpl);
+typedef UINTN EFI_TPL;
+#define TPL_APPLICATION 4
+#define TPL_CALLBACK 8
+#define TPL_NOTIFY 16
+#define TPL_HIGH_LEVEL 31
+
+//
+// RestoreTPL
+//
+typedef VOID(EFIAPI *EFI_RESTORE_TPL)(IN EFI_TPL OldTpl);
+
+//
+// AllocatePages
+//
+typedef enum {
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ AllocateAddress,
+ MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+typedef enum {
+ EfiReservedMemoryType = 0,
+ EfiLoaderCode = 1,
+ EfiLoaderData = 2,
+ EfiBootServicesCode = 3,
+ EfiBootServicesData = 4,
+ EfiRuntimeServicesCode = 5,
+ EfiRuntimeServicesData = 6,
+ EfiConventionalMemory = 7,
+ EfiUnusableMemory = 8,
+ EfiACPIReclaimMemory = 9,
+ EfiACPIMemoryNVS = 10,
+ EfiMemoryMappedIO = 11,
+ EfiMemoryMappedIOPortSpace = 12,
+ EfiPalCode = 13,
+ EfiPersistentMemory = 14,
+ EfiMaxMemoryType = 15
+} EFI_MEMORY_TYPE;
+typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_PAGES)(
+ IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory);
+
+//
+// FreePages
+//
+typedef EFI_STATUS(EFIAPI *EFI_FREE_PAGES)(IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN Pages);
+
+//
+// GetMemoryMap
+//
+typedef UINT64 EFI_VIRTUAL_ADDRESS;
+typedef struct {
+ UINT32 Type;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ EFI_VIRTUAL_ADDRESS VirtualStart;
+ UINT64 NumberOfPages;
+ UINT64 Attribute;
+} EFI_MEMORY_DESCRIPTOR;
+typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)(
+ IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey, OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion);
+#define EFI_MEMORY_UC 0x0000000000000001
+#define EFI_MEMORY_WC 0x0000000000000002
+#define EFI_MEMORY_WT 0x0000000000000004
+#define EFI_MEMORY_WB 0x0000000000000008
+#define EFI_MEMORY_UCE 0x0000000000000010
+#define EFI_MEMORY_WP 0x0000000000001000
+#define EFI_MEMORY_RP 0x0000000000002000
+#define EFI_MEMORY_XP 0x0000000000004000
+#define EFI_MEMORY_NV 0x0000000000008000
+#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000
+#define EFI_MEMORY_RO 0x0000000000020000
+#define EFI_MEMORY_SP 0x0000000000040000
+#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000
+#define EFI_MEMORY_RUNTIME 0x8000000000000000
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+
+//
+// AllocatePool
+//
+typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_POOL)(IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size, OUT VOID **Buffer);
+
+//
+// FreePool
+//
+typedef EFI_STATUS(EFIAPI *EFI_FREE_POOL)(IN VOID *Buffer);
+
+//
+// InstallProtocolInterface
+//
+typedef enum { EFI_NATIVE_INTERFACE } EFI_INTERFACE_TYPE;
+typedef EFI_STATUS(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(
+ IN OUT EFI_HANDLE *Handle, IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface);
+
+//
+// UninstallProtocolInterface
+//
+typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(
+ IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, IN VOID *Interface);
+
+//
+// ReinstallProtocolInterface
+//
+typedef EFI_STATUS(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(
+ IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, IN VOID *OldInterface,
+ IN VOID *NewInterface);
+
+//
+// RegisterProtocolNotify
+//
+typedef EFI_STATUS(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(
+ IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration);
+
+//
+// LocateHandle
+//
+typedef enum {
+ AllHandles,
+ ByRegisterNotify,
+ ByProtocol
+} EFI_LOCATE_SEARCH_TYPE;
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE)(
+ IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL, IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer);
+
+//
+// HandleProtocol
+//
+typedef EFI_STATUS(EFIAPI *EFI_HANDLE_PROTOCOL)(IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface);
+
+//
+// LocateDevicePath
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 SubType;
+ UINT8 Length[2];
+} EFI_DEVICE_PATH_PROTOCOL;
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
+ IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Device);
+
+//
+// OpenProtocol
+//
+typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL)(IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **InterfaceOPTIONAL,
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT32 Attributes);
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+//
+// CloseProtocol
+//
+typedef EFI_STATUS(EFIAPI *EFI_CLOSE_PROTOCOL)(IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_HANDLE ControllerHandle);
+
+//
+// OpenProtocolInformation
+//
+typedef struct {
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)(
+ IN EFI_HANDLE Handle, IN EFI_GUID *Protocol,
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount);
+
+//
+// ConnectController
+//
+typedef EFI_STATUS(EFIAPI *EFI_CONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive);
+
+//
+// DisconnectController
+//
+typedef EFI_STATUS(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle OPTIONAL,
+ IN EFI_HANDLE ChildHandle OPTIONAL);
+
+//
+// ProtocolsPerHandle
+//
+typedef EFI_STATUS(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)(
+ IN EFI_HANDLE Handle, OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount);
+
+//
+// LocateHandleBuffer
+//
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
+ IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKeyOPTIONAL, IN OUT UINTN *NoHandles,
+ OUT EFI_HANDLE **Buffer);
+
+//
+// LocateProtocol
+//
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_PROTOCOL)(IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface);
+
+//
+// InstallMultipleProtocolInterfaces
+//
+typedef EFI_STATUS(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+ IN OUT EFI_HANDLE *Handle, ...);
+
+//
+// UninstallMultipleProtocolInterfaces
+//
+typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+ IN EFI_HANDLE Handle, ...);
+
+//
+// LoadImage
+//
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_LOAD)(
+ IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize, OUT EFI_HANDLE *ImageHandle);
+
+//
+// StartImage
+//
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_START)(IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL);
+
+//
+// UnloadImage
+//
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_UNLOAD)(IN EFI_HANDLE ImageHandle);
+
+//
+// Exit
+//
+typedef EFI_STATUS(EFIAPI *EFI_EXIT)(IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS ExitStatus,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL);
+
+//
+// ExitBootServices
+//
+typedef EFI_STATUS(EFIAPI *EFI_EXIT_BOOT_SERVICES)(IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey);
+
+//
+// SetWatchdogTimer
+//
+typedef EFI_STATUS(EFIAPI *EFI_SET_WATCHDOG_TIMER)(
+ IN UINTN Timeout, IN UINT64 WatchdogCode, IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL);
+
+//
+// Stall
+//
+typedef EFI_STATUS(EFIAPI *EFI_STALL)(IN UINTN Microseconds);
+
+//
+// CopyMem
+//
+typedef VOID(EFIAPI *EFI_COPY_MEM)(IN VOID *Destination, IN VOID *Source,
+ IN UINTN Length);
+
+//
+// SetMem
+//
+typedef VOID(EFIAPI *EFI_SET_MEM)(IN VOID *Buffer, IN UINTN Size,
+ IN UINT8 Value);
+
+//
+// GetNextMonotonicCount
+//
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(OUT UINT64 *Count);
+
+//
+// InstallConfigurationTable
+//
+typedef EFI_STATUS(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(IN EFI_GUID *Guid,
+ IN VOID *Table);
+
+//
+// CalculateCrc32
+//
+typedef EFI_STATUS(EFIAPI *EFI_CALCULATE_CRC32)(IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *Crc32);
+
+/**********************/
+/* Runtime_Services */
+/**********************/
+#define EFI_RT_SUPPORTED_GET_TIME 0x0001
+#define EFI_RT_SUPPORTED_SET_TIME 0x0002
+#define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004
+#define EFI_RT_SUPPORTED_SET_WAKEUP_TIME 0x0008
+#define EFI_RT_SUPPORTED_GET_VARIABLE 0x0010
+#define EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME 0x0020
+#define EFI_RT_SUPPORTED_SET_VARIABLE 0x0040
+#define EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP 0x0080
+#define EFI_RT_SUPPORTED_CONVERT_POINTER 0x0100
+#define EFI_RT_SUPPORTED_GET_NEXT_HIGH_MONOTONIC_COUNT 0x0200
+#define EFI_RT_SUPPORTED_RESET_SYSTEM 0x0400
+#define EFI_RT_SUPPORTED_UPDATE_CAPSULE 0x0800
+#define EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES 0x1000
+#define EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO 0x2000
+
+//
+// GetVariable
+//
+typedef EFI_STATUS(EFIAPI *EFI_GET_VARIABLE)(IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data OPTIONAL);
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+// NOTE: EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated
+// and should be considered reserved.
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS 0x00000080
+#define EFI_VARIABLE_AUTHENTICATION_3_CERT_ID_SHA256 1
+typedef struct {
+ UINT8 Type;
+ UINT32 IdSize;
+ // UINT8 Id[IdSize];
+} EFI_VARIABLE_AUTHENTICATION_3_CERT_ID;
+
+//
+// GetNextVariableName
+//
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(
+ IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid);
+
+//
+// SetVariable
+//
+typedef EFI_STATUS(EFIAPI *EFI_SET_VARIABLE)(IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize, IN VOID *Data);
+
+//
+// QueryVariableInfo
+//
+typedef EFI_STATUS(EFIAPI *EFI_QUERY_VARIABLE_INFO)(
+ IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize);
+
+//
+// GetTime
+//
+// This represents the current time information
+typedef struct {
+ UINT16 Year; // 1900 – 9999
+ UINT8 Month; // 1 – 12
+ UINT8 Day; // 1 – 31
+ UINT8 Hour; // 0 – 23
+ UINT8 Minute; // 0 – 59
+ UINT8 Second; // 0 – 59
+ UINT8 Pad1;
+ UINT32 Nanosecond; // 0 – 999,999,999
+ INT16 TimeZone; // -1440 to 1440 or 2047
+ UINT8 Daylight;
+ UINT8 Pad2;
+} EFI_TIME;
+// Bit Definitions for EFI_TIME.Daylight
+#define EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define EFI_TIME_IN_DAYLIGHT 0x02
+// Value Definition for EFI_TIME.TimeZone
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+// This provides the capabilities of the
+// real time clock device as exposed through the EFI interfaces.
+typedef struct {
+ UINT32 Resolution;
+ UINT32 Accuracy;
+ BOOLEAN SetsToZero;
+} EFI_TIME_CAPABILITIES;
+typedef EFI_STATUS(EFIAPI *EFI_GET_TIME)(
+ OUT EFI_TIME *Time, OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL);
+
+//
+// SetTime
+//
+typedef EFI_STATUS(EFIAPI *EFI_SET_TIME)(IN EFI_TIME *Time);
+
+//
+// GetWakeupTime
+//
+typedef EFI_STATUS(EFIAPI *EFI_GET_WAKEUP_TIME)(OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time);
+
+//
+// SetWakeupTime
+//
+typedef EFI_STATUS(EFIAPI *EFI_SET_WAKEUP_TIME)(IN BOOLEAN Enable,
+ IN EFI_TIME *Time OPTIONAL);
+
+//
+// SetVirtualAddressMap
+//
+typedef EFI_STATUS(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(
+ IN UINTN MemoryMapSize, IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap);
+
+//
+// ConvertPointer
+//
+typedef EFI_STATUS(EFIAPI *EFI_CONVERT_POINTER)(IN UINTN DebugDisposition,
+ IN VOID **Address);
+#define EFI_OPTIONAL_PTR 0x00000001
+
+//
+// ResetSystem
+//
+typedef enum {
+ EfiResetCold,
+ EfiResetWarm,
+ EfiResetShutdown,
+ EfiResetPlatformSpecific
+} EFI_RESET_TYPE;
+typedef VOID(EFIAPI *EFI_RESET_SYSTEM)(IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN VOID *ResetData OPTIONAL);
+
+//
+// GetNextHighMonotonicCount
+//
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_HIGH_MONOTONIC_COUNT)(
+ OUT UINT32 *HighCount);
+
+//
+// UpdateCapsule
+//
+typedef struct {
+ UINT64 Length;
+ union {
+ EFI_PHYSICAL_ADDRESS DataBlock;
+ EFI_PHYSICAL_ADDRESS ContinuationPointer;
+ } Union;
+} EFI_CAPSULE_BLOCK_DESCRIPTOR;
+typedef struct {
+ EFI_GUID CapsuleGuid;
+ UINT32 HeaderSize;
+ UINT32 Flags;
+ UINT32 CapsuleImageSize;
+} EFI_CAPSULE_HEADER;
+typedef EFI_STATUS(EFIAPI *EFI_UPDATE_CAPSULE)(
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount,
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL);
+
+//
+// QueryCapsuleCapabilities
+//
+typedef EFI_STATUS(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)(
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount,
+ OUT UINT64 *MaximumCapsuleSize, OUT EFI_RESET_TYPE *ResetType);
+
+/***********************/
+/* Simple_Text_Stuff */
+/***********************/
+
+//
+//
+// Input stuff
+//
+//
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+ { 0x387477c1, \
+ 0x69c7, \
+ 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } }
+
+//
+// InputReset
+//
+struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+typedef EFI_STATUS(EFIAPI *EFI_INPUT_RESET)(
+ IN struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+//
+// ReadKeyStroke
+//
+typedef struct {
+ UINT16 ScanCode;
+ CHAR16 UnicodeChar;
+} EFI_INPUT_KEY;
+typedef EFI_STATUS(EFIAPI *EFI_INPUT_READ_KEY)(
+ IN struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key);
+
+typedef struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
+ EFI_INPUT_RESET Reset;
+ EFI_INPUT_READ_KEY ReadKeyStroke;
+ EFI_EVENT WaitForKey;
+} EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+
+//
+//
+// Output stuff
+//
+//
+
+//*******************************************************
+// UNICODE DRAWING CHARACTERS
+//*******************************************************
+#define BOXDRAW_HORIZONTAL 0x2500
+#define BOXDRAW_VERTICAL 0x2502
+#define BOXDRAW_DOWN_RIGHT 0x250c
+#define BOXDRAW_DOWN_LEFT 0x2510
+#define BOXDRAW_UP_RIGHT 0x2514
+#define BOXDRAW_UP_LEFT 0x2518
+#define BOXDRAW_VERTICAL_RIGHT 0x251c
+#define BOXDRAW_VERTICAL_LEFT 0x2524
+#define BOXDRAW_DOWN_HORIZONTAL 0x252c
+#define BOXDRAW_UP_HORIZONTAL 0x2534
+#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c
+#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550
+#define BOXDRAW_DOUBLE_VERTICAL 0x2551
+#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552
+#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553
+#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554
+#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555
+#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556
+#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557
+#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558
+#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559
+#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a
+#define BOXDRAW_UP_LEFT_DOUBLE 0x255b
+#define BOXDRAW_UP_DOUBLE_LEFT 0x255c
+#define BOXDRAW_DOUBLE_UP_LEFT 0x255d
+#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e
+#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f
+#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560
+#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561
+#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562
+#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563
+#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564
+#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565
+#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566
+#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567
+#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568
+#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569
+#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a
+#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b
+#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c
+//*******************************************************
+// EFI Required Block Elements Code Chart
+//*******************************************************
+#define BLOCKELEMENT_FULL_BLOCK 0x2588
+#define BLOCKELEMENT_LIGHT_SHADE 0x2591
+//*******************************************************
+// EFI Required Geometric Shapes Code Chart
+//*******************************************************
+#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2
+#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba
+#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc
+#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4
+//*******************************************************
+// EFI Required Arrow shapes
+//*******************************************************
+#define ARROW_UP 0x2191
+#define ARROW_DOWN 0x2193
+
+#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
+ { 0x387477c2, \
+ 0x69c7, \
+ 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } }
+
+//
+// TestReset
+//
+struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_RESET)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+//
+// OutputString
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_STRING)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String);
+
+//
+// TestString
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_TEST_STRING)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String);
+
+//
+// QueryMode
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_QUERY_MODE)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber,
+ OUT UINTN *Columns, OUT UINTN *Rows);
+
+//
+// SetMode
+//
+typedef EFI_STATUS (*EFIAPI EFI_TEXT_SET_MODE)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber);
+
+//
+// SetAttribute
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_ATTRIBUTE)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute);
+//*******************************************************
+// Attributes
+//*******************************************************
+#define EFI_BLACK 0x00
+#define EFI_BLUE 0x01
+#define EFI_GREEN 0x02
+#define EFI_CYAN 0x03
+#define EFI_RED 0x04
+#define EFI_MAGENTA 0x05
+#define EFI_BROWN 0x06
+#define EFI_LIGHTGRAY 0x07
+#define EFI_BRIGHT 0x08
+#define EFI_DARKGRAY 0x08
+#define EFI_LIGHTBLUE 0x09
+#define EFI_LIGHTGREEN 0x0A
+#define EFI_LIGHTCYAN 0x0B
+#define EFI_LIGHTRED 0x0C
+#define EFI_LIGHTMAGENTA 0x0D
+#define EFI_YELLOW 0x0E
+#define EFI_WHITE 0x0F
+
+#define EFI_BACKGROUND_BLACK 0x00
+#define EFI_BACKGROUND_BLUE 0x10
+#define EFI_BACKGROUND_GREEN 0x20
+#define EFI_BACKGROUND_CYAN 0x30
+#define EFI_BACKGROUND_RED 0x40
+#define EFI_BACKGROUND_MAGENTA 0x50
+#define EFI_BACKGROUND_BROWN 0x60
+#define EFI_BACKGROUND_LIGHTGRAY 0x70
+// The foreground color and background color can
+// be OR-ed(|) together to set them both in one call.
+
+//
+// ClearScreen
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_CLEAR_SCREEN)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This);
+
+//
+// SetCursorPosition
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column,
+ IN UINTN Row);
+
+//
+// EnableCursor
+//
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)(
+ IN struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible);
+
+typedef struct {
+ INT32 MaxMode; // current settings
+ INT32 Mode;
+ INT32 Attribute;
+ INT32 CursorColumn;
+ INT32 CursorRow;
+ BOOLEAN CursorVisible;
+} SIMPLE_TEXT_OUTPUT_MODE;
+
+typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+ EFI_TEXT_RESET Reset;
+ EFI_TEXT_STRING OutputString;
+ EFI_TEXT_TEST_STRING TestString;
+ EFI_TEXT_QUERY_MODE QueryMode;
+ EFI_TEXT_SET_MODE SetMode;
+ EFI_TEXT_SET_ATTRIBUTE SetAttribute;
+ EFI_TEXT_CLEAR_SCREEN ClearScreen;
+ EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;
+ EFI_TEXT_ENABLE_CURSOR EnableCursor;
+ SIMPLE_TEXT_OUTPUT_MODE *Mode;
+} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+
+/***********************/
+/* Table_Definitions */
+/***********************/
+
+#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_REVISION EFI_2_8_SYSTEM_TABLE_REVISION
+
+typedef struct {
+ UINT64 Signature;
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 CRC32;
+ UINT32 Reserved;
+} EFI_TABLE_HEADER;
+
+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
+#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION
+typedef struct {
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Task Priority Services
+ //
+ EFI_RAISE_TPL RaiseTPL; // EFI 1.0+
+ EFI_RESTORE_TPL RestoreTPL; // EFI 1.0+
+
+ //
+ // Memory Services
+ //
+ EFI_ALLOCATE_PAGES AllocatePages; // EFI 1.0+
+ EFI_FREE_PAGES FreePages; // EFI 1.0+
+ EFI_GET_MEMORY_MAP GetMemoryMap; // EFI 1.0+
+ EFI_ALLOCATE_POOL AllocatePool; // EFI 1.0+
+ EFI_FREE_POOL FreePool; // EFI 1.0+
+
+ //
+ // Event & Timer Services
+ //
+ EFI_CREATE_EVENT CreateEvent; // EFI 1.0+
+ EFI_SET_TIMER SetTimer; // EFI 1.0+
+ EFI_WAIT_FOR_EVENT WaitForEvent; // EFI 1.0+
+ EFI_SIGNAL_EVENT SignalEvent; // EFI 1.0+
+ EFI_CLOSE_EVENT CloseEvent; // EFI 1.0+
+ EFI_CHECK_EVENT CheckEvent; // EFI 1.0+
+
+ //
+ // Protocol Handler Services
+ //
+ EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; // EFI 1.0+
+ EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; // EFI 1.0+
+ EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; // EFI 1.0+
+ EFI_HANDLE_PROTOCOL HandleProtocol; // EFI 1.0+
+ VOID *Reserved; // EFI 1.0+
+ EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; // EFI 1.0+
+ EFI_LOCATE_HANDLE LocateHandle; // EFI 1.0+
+ EFI_LOCATE_DEVICE_PATH LocateDevicePath; // EFI 1.0+
+ EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; // EFI 1.0+
+
+ //
+ // Image Services
+ //
+ EFI_IMAGE_LOAD LoadImage; // EFI 1.0+
+ EFI_IMAGE_START
+ StartImage; // EFI 1.0+UEFI Specification, Version 2.8 EFI System Table
+ EFI_EXIT Exit; // EFI 1.0+
+ EFI_IMAGE_UNLOAD UnloadImage; // EFI 1.0+
+ EFI_EXIT_BOOT_SERVICES ExitBootServices; // EFI 1.0+
+
+ //
+ // Miscellaneous Services
+ //
+ EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; // EFI 1.0+
+ EFI_STALL Stall; // EFI 1.0+
+ EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; // EFI 1.0+
+
+ //
+ // DriverSupport Services
+ //
+ EFI_CONNECT_CONTROLLER ConnectController; // EFI 1.1
+ EFI_DISCONNECT_CONTROLLER DisconnectController; // EFI 1.1+
+
+ //
+ // Open and Close Protocol Services
+ //
+ EFI_OPEN_PROTOCOL OpenProtocol; // EFI 1.1+
+ EFI_CLOSE_PROTOCOL CloseProtocol; // EFI 1.1+
+ EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; // EFI 1.1+
+
+ //
+ // Library Services
+ //
+ EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; // EFI 1.1+
+ EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; // EFI 1.1+
+ EFI_LOCATE_PROTOCOL LocateProtocol; // EFI 1.1+
+ EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES
+ InstallMultipleProtocolInterfaces; // EFI 1.1+
+ EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES
+ UninstallMultipleProtocolInterfaces; // EFI 1.1+
+
+ //
+ // 32-bit CRC Services
+ //
+ EFI_CALCULATE_CRC32 CalculateCrc32; // EFI 1.1+
+
+ //
+ // Miscellaneous Services
+ //
+ EFI_COPY_MEM CopyMem; // EFI 1.1+
+ EFI_SET_MEM
+ SetMem; // EFI 1.1+UEFI Specification, Version 2.8 EFI System Table
+ EFI_CREATE_EVENT_EX CreateEventEx; // UEFI 2.0+
+} EFI_BOOT_SERVICES;
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552
+#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION
+typedef struct {
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Time Services
+ //
+ EFI_GET_TIME GetTime;
+ EFI_SET_TIME SetTime;
+ EFI_GET_WAKEUP_TIME GetWakeupTime;
+ EFI_SET_WAKEUP_TIME SetWakeupTime;
+
+ //
+ // Virtual Memory Services
+ //
+ EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
+ EFI_CONVERT_POINTER ConvertPointer;
+
+ //
+ // Variable Services
+ //
+ EFI_GET_VARIABLE GetVariable;
+ EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
+ EFI_SET_VARIABLE SetVariable;
+
+ //
+ // Miscellaneous Services
+ //
+ EFI_GET_NEXT_HIGH_MONOTONIC_COUNT GetNextHighMonotonicCount;
+ EFI_RESET_SYSTEM ResetSystem;
+
+ //
+ // UEFI 2.0 Capsule Services
+ //
+ EFI_UPDATE_CAPSULE UpdateCapsule;
+ EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
+
+ //
+ // Miscellaneous UEFI 2.0 Service
+ //
+ EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
+} EFI_RUNTIME_SERVICES;
+
+typedef struct {
+ EFI_GUID VendorGuid;
+ VOID *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+#define ACPI_TABLE_GUID \
+ { 0xeb9d2d30, \
+ 0x2d88, \
+ 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define SAL_SYSTEM_TABLE_GUID \
+ { 0xeb9d2d32, \
+ 0x2d88, \
+ 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define SMBIOS_TABLE_GUID \
+ { 0xeb9d2d31, \
+ 0x2d88, \
+ 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define SMBIOS3_TABLE_GUID \
+ { 0xf2fd1544, \
+ 0x9794, \
+ 0x4a2c, \
+ { 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } }
+
+#define MPS_TABLE_GUID \
+ { 0xeb9d2d2f, \
+ 0x2d88, \
+ 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+//
+// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID
+//
+#define EFI_ACPI_TABLE_GUID \
+ { 0x8868e871, \
+ 0xe4f1, \
+ 0x11d3, \
+ { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID
+
+#define ACPI_TABLE_GUID \
+ { 0xeb9d2d30, \
+ 0x2d88, \
+ 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID
+
+#define EFI_JSON_CONFIG_DATA_TABLE_GUID \
+ { 0x87367f87, \
+ 0x1119, \
+ 0x41ce, \
+ { 0xaa, 0xec, 0x8b, 0xe0, 0x11, 0x1f, 0x55, 0x8a } }
+
+#define EFI_JSON_CAPSULE_DATA_TABLE_GUID \
+ { 0x35e7a725, \
+ 0x8dd2, \
+ 0x4cac, \
+ { 0x80, 0x11, 0x33, 0xcd, 0xa8, 0x10, 0x90, 0x56 } }
+
+#define EFI_JSON_CAPSULE_RESULT_TABLE_GUID \
+ { 0xdbc461c3, \
+ 0xb3de, \
+ 0x422a, \
+ { 0xb9, 0xb4, 0x98, 0x86, 0xfd, 0x49, 0xa1, 0xe5 } }
+
+#define EFI_PROPERTIES_TABLE_VERSION 0x00010000
+typedef struct {
+ UINT32 Version;
+ UINT32 Length;
+ UINT32 MemoryProtectionAttribute;
+} EFI_PROPERTIES_TABLE;
+//
+// Memory attribute (Non-defined bits are reserved)
+//
+#define EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA 0x1
+// BIT 0 - description - implies the runtime data is separated from the code
+
+#define EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { 0xffe06bdd, \
+ 0x6107, \
+ 0x46a6, \
+ { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c } }
+
+#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID \
+ { 0xdcfa911d, \
+ 0x26eb, \
+ 0x469f, \
+ { 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20 } }
+
+//
+// EFI_MEMORY_ATTRIBUTES_TABLE
+//
+typedef struct {
+ UINT32 Version;
+ UINT32 NumberOfEntries;
+ UINT32 DescriptorSize;
+ UINT32 Reserved;
+ // EFI_MEMORY_DESCRIPTOR Entry[1];
+} EFI_MEMORY_ATTRIBUTES_TABLE;
+
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
+#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
+#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
+#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
+#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
+#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
+#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
+#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
+typedef struct {
+ EFI_TABLE_HEADER Hdr;
+ CHAR16 *FirmwareVendor;
+ UINT32 FirmwareRevision;
+ EFI_HANDLE ConsoleInHandle;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
+ EFI_HANDLE ConsoleOutHandle;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
+ EFI_HANDLE StandardErrorHandle;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
+ EFI_RUNTIME_SERVICES *RuntimeServices;
+ EFI_BOOT_SERVICES *BootServices;
+ UINTN NumberOfTableEntries;
+ EFI_CONFIGURATION_TABLE *ConfigurationTable;
+} EFI_SYSTEM_TABLE;
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { 0x9042a9de, \
+ 0x23dc, \
+ 0x4a38, \
+ { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } }
+
+struct EFI_GRAPHICS_OUTPUT_PROTOCOL;
+
+typedef enum {
+ PixelRedGreenBlueReserved8BitPerColor,
+ PixelBlueGreenRedReserved8BitPerColor,
+ PixelBitMask,
+ PixelBltOnly,
+ PixelFormatMax
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+ UINT32 RedMask;
+ UINT32 GreenMask;
+ UINT32 BlueMask;
+ UINT32 ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef struct {
+ UINT32 Version;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ UINT32 PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+typedef EFI_STATUS(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)(
+ IN struct EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info);
+
+typedef EFI_STATUS(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)(
+ IN struct EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber);
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+typedef enum {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphicsOutputBltOperationMax
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+typedef EFI_STATUS(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)(
+ IN struct EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX,
+ IN UINTN DestinationY, IN UINTN Width, IN UINTN Height,
+ IN UINTN Delta OPTIONAL);
+
+typedef struct {
+ UINT32 MaxMode;
+ UINT32 Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+typedef struct EFI_GRAPHICS_OUTPUT_PROTOCOL {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL;
+
+//
+// ImageEntryPoint
+//
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_ENTRY_POINT)(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+ { 0x3fdda605, \
+ 0xa76e, \
+ 0x4f46, \
+ { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } }
+
+struct EFI_MP_SERVICES_PROTOCOL;
+
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors);
+
+typedef struct {
+ UINT32 Package;
+ UINT32 Core;
+ UINT32 Thread;
+} EFI_CPU_PHYSICAL_LOCATION;
+typedef struct {
+ UINT64 ProcessorId;
+ UINT32 StatusFlag;
+ EFI_CPU_PHYSICAL_LOCATION Location;
+} EFI_PROCESSOR_INFORMATION;
+#define PROCESSOR_AS_BSP_BIT 0x00000001
+#define PROCESSOR_ENABLED_BIT 0x00000002
+#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer);
+
+#define END_OF_CPU_LIST 0xffffffff
+typedef VOID(EFIAPI *EFI_AP_PROCEDURE)(IN VOID *ProcedureArgument);
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroSeconds, IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL);
+
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber, IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL);
+
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP);
+
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL);
+
+typedef EFI_STATUS(EFIAPI *EFI_MP_SERVICES_WHOAMI)(
+ IN struct EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *ProcessorNumber);
+
+typedef struct EFI_MP_SERVICES_PROTOCOL {
+ EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;
+ EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;
+ EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs;
+ EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;
+ EFI_MP_SERVICES_SWITCH_BSP SwitchBSP;
+ EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP;
+ EFI_MP_SERVICES_WHOAMI WhoAmI;
+} EFI_MP_SERVICES_PROTOCOL;
+
+#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \
+ { 0x31878c87, \
+ 0xb75, \
+ 0x11d5, \
+ { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+typedef struct {
+ UINT64 ResolutionX;
+ UINT64 ResolutionY;
+ UINT64 ResolutionZ;
+ BOOLEAN LeftButton;
+ BOOLEAN RightButton;
+} EFI_SIMPLE_POINTER_MODE;
+
+struct _EFI_SIMPLE_POINTER_PROTOCOL;
+
+typedef struct {
+ INT32 RelativeMovementX;
+ INT32 RelativeMovementY;
+ INT32 RelativeMovementZ;
+ BOOLEAN LeftButton;
+ BOOLEAN RightButton;
+} EFI_SIMPLE_POINTER_STATE;
+
+typedef EFI_STATUS(EFIAPI *EFI_SIMPLE_POINTER_RESET)(
+ IN struct _EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+typedef EFI_STATUS(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE)(
+ IN struct _EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State);
+
+typedef struct _EFI_SIMPLE_POINTER_PROTOCOL {
+ EFI_SIMPLE_POINTER_RESET Reset;
+ EFI_SIMPLE_POINTER_GET_STATE GetState;
+ EFI_EVENT WaitForInput;
+ EFI_SIMPLE_POINTER_MODE *Mode;
+} EFI_SIMPLE_POINTER_PROTOCOL;
+
+// ACPI tables
+
+typedef struct __attribute__((packed)) RSDP {
+ UINT64 signature; // Should be "RSD PTR "
+ UINT8 checksum; // Checksum for RSDP v1.0, all of v1.0 bytes added together should equal 0
+ UINT8 OEMID[6]; // OEM supplied string
+ UINT8 revision; // Revision of this structure
+ UINT32 rsdtAddress; // Physical address of RSDT table
+
+ // For revisions => 2
+ UINT32 length; // Length of the table
+ UINT64 xsdtAddress; // Physical address of XSDT table
+ UINT8 extendedChecksum; // Checksum for the entire table, sum of all bytes should equal 0
+ UINT8 reserves[3]; // Reserved field.
+} RSDP;
+
+typedef struct __attribute__((packed)) {
+ uint32_t signature;
+ uint32_t length;
+ uint8_t revision;
+ uint8_t checksum;
+ uint8_t OEMID[6];
+ uint8_t OEMTableID[8];
+ uint32_t OEMRevision;
+ uint32_t creatorID;
+ uint32_t creatorRevision;
+} SDTH; // System Description Table Header
+
+typedef struct __attribute__((packed)) {
+ SDTH header;
+ uint32_t entry
+ []; // 32 bit physical memory addresses, number of entries is based on the length in the header
+} RSDT;
+
+typedef struct __attribute__((packed)) {
+ SDTH header;
+ uint64_t entry
+ []; // 64 bit physical memory addresses, number of entries is based on the length in the header
+} XSDT;
diff --git a/kernel/main.c b/kernel/main.c
index 7ea47ad..8666511 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -1,6 +1,7 @@
#include <comus/cpu.h>
#include <comus/memory.h>
#include <comus/mboot.h>
+#include <comus/efi.h>
#include <comus/drivers.h>
#include <comus/drivers/acpi.h>
#include <comus/drivers/pci.h>
@@ -25,6 +26,9 @@ void main(long magic, volatile void *mboot)
// load multiboot information
mboot_init(magic, mboot);
+ // load efi structures
+ efi_init(mboot_get_efi_hdl(), mboot_get_efi_st());
+
// initalize memory
memory_init();
diff --git a/kernel/mboot/efi.c b/kernel/mboot/efi.c
new file mode 100644
index 0000000..75b869a
--- /dev/null
+++ b/kernel/mboot/efi.c
@@ -0,0 +1,38 @@
+#include <comus/mboot.h>
+
+#include "mboot.h"
+
+#define MULTIBOOT_TAG_TYPE_EFI64 12
+#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
+
+struct multiboot_tag_efi64 {
+ uint32_t type;
+ uint32_t size;
+ uint64_t pointer;
+};
+
+struct multiboot_tag_efi64_ih {
+ uint32_t type;
+ uint32_t size;
+ uint64_t pointer;
+};
+
+EFI_SYSTEM_TABLE *mboot_get_efi_st(void)
+{
+ void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_EFI64);
+ if (tag == NULL)
+ return NULL;
+
+ struct multiboot_tag_efi64 *efi = (struct multiboot_tag_efi64 *)tag;
+ return (void *)efi->pointer;
+}
+
+EFI_HANDLE mboot_get_efi_hdl(void)
+{
+ void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_EFI64_IH);
+ if (tag == NULL)
+ return NULL;
+
+ struct multiboot_tag_efi64_ih *ih = (struct multiboot_tag_efi64_ih *)tag;
+ return (void *)ih->pointer;
+}
diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c
index 949337d..e4547e7 100644
--- a/kernel/mboot/mboot.c
+++ b/kernel/mboot/mboot.c
@@ -8,7 +8,7 @@ static volatile void *mboot = NULL;
void mboot_init(long magic, volatile void *ptr)
{
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC)
- panic("invalid multiboot magic");
+ panic("invalid multiboot magic: %#08lx", magic);
mboot = ptr;
}
diff --git a/kernel/mboot/mmap.c b/kernel/mboot/mmap.c
index d1d3d9a..96dc54c 100644
--- a/kernel/mboot/mmap.c
+++ b/kernel/mboot/mmap.c
@@ -7,6 +7,12 @@
#define MULTIBOOT_TAG_TYPE_MMAP 6
+#define MULTIBOOT_SEG_TYPE_RESV 0
+#define MULTIBOOT_SEG_TYPE_FREE 1
+#define MULTIBOOT_SEG_TYPE_ACPI 3
+#define MULTIBOOT_SEG_TYPE_HIBR 4
+#define MULTIBOOT_SEG_TYPE_DEFC 5
+
struct multiboot_mmap_entry {
uint64_t addr;
uint64_t len;
@@ -32,14 +38,32 @@ int mboot_get_mmap(struct memory_map *res)
int idx = 0;
uintptr_t i = (uintptr_t)mmap->entries;
- for (; i < (uintptr_t)mmap->entries + mmap->size;
- i += mmap->entry_size, idx++) {
+ for (; i < (uintptr_t)mmap->entries + mmap->size; i += mmap->entry_size) {
if (idx >= N_MMAP_ENTRY)
panic("Too many mmap entries: limit is %d", N_MMAP_ENTRY);
struct multiboot_mmap_entry *seg = (struct multiboot_mmap_entry *)i;
res->entries[idx].addr = seg->addr;
res->entries[idx].len = seg->len;
- res->entries[idx].type = seg->type;
+ switch (seg->type) {
+ case MULTIBOOT_SEG_TYPE_RESV:
+ res->entries[idx].type = SEG_TYPE_RESERVED;
+ break;
+ case MULTIBOOT_SEG_TYPE_FREE:
+ res->entries[idx].type = SEG_TYPE_FREE;
+ break;
+ case MULTIBOOT_SEG_TYPE_ACPI:
+ res->entries[idx].type = SEG_TYPE_ACPI;
+ break;
+ case MULTIBOOT_SEG_TYPE_HIBR:
+ res->entries[idx].type = SEG_TYPE_HIBERNATION;
+ break;
+ case MULTIBOOT_SEG_TYPE_DEFC:
+ res->entries[idx].type = SEG_TYPE_DEFECTIVE;
+ break;
+ default:
+ continue;
+ }
+ idx++;
}
res->entry_count = idx;
diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c
index 2d560f4..6bdfe38 100644
--- a/kernel/memory/memory.c
+++ b/kernel/memory/memory.c
@@ -2,6 +2,7 @@
#include <comus/memory.h>
#include <comus/asm.h>
#include <comus/mboot.h>
+#include <comus/efi.h>
#include <lib.h>
#include "memory.h"
@@ -68,7 +69,8 @@ void memory_init(void)
{
struct memory_map mmap;
if (mboot_get_mmap(&mmap))
- panic("failed to load memory map");
+ if (efi_get_mmap(&mmap))
+ panic("failed to load memory map");
kernel_mem_ctx = &_kernel_mem_ctx;
kernel_mem_ctx->pml4 = kernel_pml4;
@@ -79,4 +81,12 @@ void memory_init(void)
virtaddr_init(kernel_mem_ctx->virtctx);
physalloc_init(&mmap);
sti();
+
+ // identiy map EFI functions
+ for (size_t i = 0; i < mmap.entry_count; i++) {
+ struct memory_segment *seg = &mmap.entries[i];
+ if (seg->type != SEG_TYPE_EFI)
+ continue;
+ kmapaddr((void *)seg->addr, (void *)seg->addr, seg->len, F_WRITEABLE);
+ }
}
diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c
index 5177928..3764abb 100644
--- a/kernel/memory/paging.c
+++ b/kernel/memory/paging.c
@@ -56,6 +56,7 @@ struct pte {
extern volatile struct pml4e kernel_pml4[512];
extern volatile struct pdpte kernel_pdpt_0[512];
extern volatile struct pde kernel_pd_0[512];
+extern volatile struct pte kernel_pt_0[512];
extern volatile struct pte bootstrap_pt[512];
extern volatile struct pte
paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say
@@ -502,49 +503,51 @@ void paging_init(void)
kernel_pdpt_0[0].flags = F_PRESENT | F_WRITEABLE;
kernel_pdpt_0[0].address = (uint64_t)(&kernel_pd_0) >> 12;
+ kernel_pd_0[0].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pd_0[0].address = (uint64_t)(&kernel_pt_0) >> 12;
kernel_pd_0[1].flags = F_PRESENT | F_WRITEABLE;
kernel_pd_0[1].address = (uint64_t)(&paging_pt) >> 12;
kernel_pd_0[2].flags = F_PRESENT | F_WRITEABLE;
kernel_pd_0[2].address = (uint64_t)(&bootstrap_pt) >> 12;
+ for (size_t i = 0; i < 512; i++) {
+ kernel_pt_0[i].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pt_0[i].address = (i * PAGE_SIZE) >> 12;
+ }
+
memsetv(&paging_pt, 0, 4096);
memsetv(&bootstrap_pt, 0, 4096);
-}
-static inline void *page_align(void *addr)
-{
- uintptr_t a = (uintptr_t)addr;
- a /= PAGE_SIZE;
- a *= PAGE_SIZE;
- return (void *)a;
+ // make sure we are using THESE pagetables
+ // EFI doesnt on boot
+ __asm__ volatile("mov %0, %%cr3" ::"r"(kernel_pml4) : "memory");
}
void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len,
unsigned int flags)
{
long pages;
- ptrdiff_t error;
- void *aligned_phys;
+ int alloc = 0;
- // get length and physical page aligned address
- aligned_phys = page_align(phys);
- error = (char *)phys - (char *)aligned_phys;
- len += error;
- pages = len / PAGE_SIZE + 1;
+ pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
+ len += (PAGE_SIZE - len) % PAGE_SIZE;
- // get page aligned (or allocate) vitural address
- if (virt == NULL)
+ if (virt == NULL) {
virt = virtaddr_alloc(ctx->virtctx, pages);
+ alloc = 1;
+ }
+
if (virt == NULL)
return NULL;
- if (map_pages((volatile struct pml4e *)ctx->pml4, virt, aligned_phys,
+ if (map_pages((volatile struct pml4e *)ctx->pml4, virt, phys,
F_WRITEABLE | flags, pages)) {
- virtaddr_free(ctx->virtctx, virt);
+ if (alloc)
+ virtaddr_free(ctx->virtctx, virt);
return NULL;
}
- return (char *)virt + error;
+ return (char *)virt;
}
void mem_unmapaddr(mem_ctx_t ctx, void *virt)
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 676e68e..87072c4 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -20,10 +20,11 @@ static uint64_t segment_count;
struct memory_map phys_mmap;
struct memory_segment *page_start;
-static const char *segment_type_str[] = { "Reserved", "Free",
- "Reserved", "ACPI Reserved",
- "Hibernation", "Defective",
- "Unknown" };
+static const char *segment_type_str[] = {
+ [SEG_TYPE_FREE] = "Free", [SEG_TYPE_RESERVED] = "Reserved",
+ [SEG_TYPE_ACPI] = "ACPI Reserved", [SEG_TYPE_HIBERNATION] = "Hibernation",
+ [SEG_TYPE_DEFECTIVE] = "Defective", [SEG_TYPE_EFI] = "EFI Reserved",
+};
static int n_pages(const struct memory_segment *m)
{
@@ -124,7 +125,7 @@ static bool segment_invalid(const struct memory_segment *segment)
{
if (segment->len < 1)
return true;
- if (segment->type != 1)
+ if (segment->type != SEG_TYPE_FREE)
return true;
if (segment->addr < kaddr(kernel_start))
return true;
@@ -245,16 +246,9 @@ void memory_report(void)
kprintf("MEMORY MAP\n");
for (uint32_t i = 0; i < phys_mmap.entry_count; i++) {
struct memory_segment *seg;
- const char *type_str;
-
seg = &phys_mmap.entries[i];
- if (seg->type > 6)
- type_str = segment_type_str[6];
- else
- type_str = segment_type_str[seg->type];
-
- kprintf("ADDR: %16p LEN: %4s TYPE: %s (%d)\n", (void *)seg->addr,
- btoa(seg->len, buf), type_str, seg->type);
+ kprintf("ADDR: %16p LEN: %4s TYPE: %s\n", (void *)seg->addr,
+ btoa(seg->len, buf), segment_type_str[seg->type]);
}
kprintf("\nMEMORY USAGE\n");
diff --git a/kernel/term.c b/kernel/term.c
index 101805f..b2b7134 100644
--- a/kernel/term.c
+++ b/kernel/term.c
@@ -1,20 +1,14 @@
-#include "lib/kio.h"
#include <lib.h>
#include <comus/term.h>
#include <comus/asm.h>
#include <comus/limits.h>
-#include <comus/memory.h>
-#include <comus/drivers/vga.h>
-#include <comus/drivers/uart.h>
-
-// draw function
-static void (*draw_char)(char c, uint16_t x, uint16_t y) = vga_draw_char;
+#include <comus/drivers/gpu.h>
// terminal data
static char buffer[TERM_MAX_WIDTH * TERM_MAX_HEIGHT];
static uint16_t buffer_line = UINT16_MAX;
-static uint16_t width = VGA_WIDTH;
-static uint16_t height = VGA_HEIGHT;
+static uint16_t width = 80; // baseline vga text mode until resized
+static uint16_t height = 25;
static uint16_t x = 0;
static uint16_t y = 0;
@@ -102,7 +96,7 @@ void term_out_at(char c, uint16_t x, uint16_t y)
return;
buffer[BUFIDX(x, y)] = c;
- draw_char(c, x, y);
+ gpu_draw_char(c, x, y);
}
void term_out_str(const char *str)
@@ -136,7 +130,7 @@ void term_clear_line(uint16_t line)
for (uint16_t x = 0; x < width; x++) {
buffer[BUFIDX(x, line)] = 0;
- draw_char(0, x, line);
+ gpu_draw_char(0, x, line);
}
}
@@ -147,7 +141,7 @@ void term_redraw(void)
for (uint16_t j = 0; j < height; j++) {
for (uint16_t i = 0; i < width; i++) {
char c = buffer[BUFIDX(i, j)];
- draw_char(c, i, j);
+ gpu_draw_char(c, i, j);
}
}
}
@@ -160,10 +154,8 @@ void term_scroll(uint16_t lines)
term_redraw();
}
-void term_switch_handler(uint16_t w, uint16_t h,
- void (*fn)(char c, uint16_t x, uint16_t y))
+void term_resize(uint16_t w, uint16_t h)
{
- draw_char = fn;
width = w % TERM_MAX_WIDTH;
height = h % TERM_MAX_HEIGHT;
term_redraw();