LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
efi.c
Go to the documentation of this file.
1#include <log.h>
2#include <string.h>
3#include <stdbool.h>
4#include <efi.h>
5#include <acpi.h>
6#include <vm.h>
7
8static EFI_GUID gVendorLFOSGuid = {
9 0x54a97f1c, 0x4828, 0x4bb0, { 0xaa, 0xa6, 0x95, 0x84, 0x5e, 0x2d, 0xb2, 0xee }
10};
11
12static EFI_SYSTEM_TABLE* gST = 0;
13
14struct vm_table* efi_setup_mapping(struct LoaderStruct* loaderStruct) {
15 struct vm_table* context = vm_context_new();
16
17 struct MemoryRegion* memoryRegions = (struct MemoryRegion*)((ptr_t)loaderStruct + loaderStruct->size);
18
19 for(size_t i = 0; i < loaderStruct->num_mem_desc; ++i) {
20 struct MemoryRegion* desc = memoryRegions + i;
21
22 if(desc->flags & MEMORY_REGION_FIRMWARE) {
23 // TODO: this is amd64 specific code, generify VM interface for that!
24 uint8_t pat = 0;
25
26 if(desc->flags & MEMORY_REGION_WB) {
27 pat = 0x06;
28 }
29 else if(desc->flags & MEMORY_REGION_WP) {
30 pat = 0x05;
31 }
32 else if(desc->flags & MEMORY_REGION_WT) {
33 pat = 0x04;
34 }
35 else if(desc->flags & MEMORY_REGION_WC) {
36 pat = 0x01;
37 }
38
39 logd(
40 "efi", "mapping runtime memory, %ld pages starting at 0x%lx with PAT %x",
41 desc->num_pages, desc->start_address, (unsigned)pat
42 );
43
44 for(ptr_t addr = desc->start_address; addr < desc->start_address + (desc->num_pages * 0x1000); addr += 0x1000) {
45 vm_context_map(context, addr, addr, pat);
46 }
47 }
48 }
49
50 return context;
51}
52
53void init_efi(struct LoaderStruct* loaderStruct) {
54 if(!loaderStruct->firmware_info) {
55 logw("efi", "No EFI system table provided by bootloader, runtime services not available");
56 return;
57 }
58
59 struct vm_table* efi_context = efi_setup_mapping(loaderStruct);
60 struct vm_table* original_context = vm_current_context();
61 vm_context_activate(efi_context);
62
63 gST = (EFI_SYSTEM_TABLE*)loaderStruct->firmware_info;
64 logi("efi", "firmware version %d by %ls", gST->FirmwareRevision, gST->FirmwareVendor);
65
66 uint64_t maxStorageSize, remainingStorageSize, maxVarSize;
67 EFI_STATUS status = gST->RuntimeServices->QueryVariableInfo(0x7, &maxStorageSize, &remainingStorageSize, &maxVarSize);
68
69 if(status == EFI_SUCCESS) {
70 logi("efi", "firmware reports maximum variable size of %B, with %B of %B available", maxVarSize, remainingStorageSize, maxStorageSize);
71 }
72 else {
73 loge("efi", "Could not query variable info: %d", status);
74 }
75
77 vm_context_activate(original_context);
78}
79
80void efi_append_log(char* msg) {
81 static bool no_log;
82 if(gST && !no_log) {
83 no_log = true;
84
85 EFI_STATUS status = gST->RuntimeServices->SetVariable(L"LFOS_LOG", &gVendorLFOSGuid, 0x47, strlen(msg), msg);
86 if(status != EFI_SUCCESS) {
87 loge("efi", "Could not log to EFI: %d", status);
88 }
89
90 no_log = false;
91 }
92}
93
94
void init_acpi_efi(EFI_SYSTEM_TABLE *efiST)
Definition acpi.c:136
uint64_t ptr_t
Definition arch.h:17
unsigned long uint64_t
Definition arch.h:14
unsigned char uint8_t
Definition arch.h:5
void init_efi(struct LoaderStruct *loaderStruct)
Definition efi.c:53
static EFI_SYSTEM_TABLE * gST
Definition efi.c:12
struct vm_table * efi_setup_mapping(struct LoaderStruct *loaderStruct)
Definition efi.c:14
static EFI_GUID gVendorLFOSGuid
Definition efi.c:8
void efi_append_log(char *msg)
Definition efi.c:80
size_t strlen(const char *str)
Definition string.c:30
ptr_t addr
Definition elf.h:3
uint64_t flags
Flags for the memory region. See MEMORY_REGION_ defines.
Definition loader.h:89
#define MEMORY_REGION_WT
supports write-through
Definition loader.h:30
ptr_t firmware_info
Firmware info data, e.g. EFI_SYSTEM_TABLE on UEFI.
Definition loader.h:77
#define MEMORY_REGION_WB
supports write-back
Definition loader.h:32
#define MEMORY_REGION_WP
Supports write-protected.
Definition loader.h:37
size_t num_pages
Number of pages, where page size is 4096 bytes.
Definition loader.h:86
#define MEMORY_REGION_FIRMWARE
memory is in use by the firmware
Definition loader.h:12
#define MEMORY_REGION_WC
supports write-combine
Definition loader.h:28
uint64_t num_mem_desc
Number of memory descriptors.
Definition loader.h:71
uint16_t size
Definition loader.h:50
ptr_t start_address
Start of the region as physical address.
Definition loader.h:83
Main interface between loader and kernel.
Definition loader.h:44
Describes a single memory region.
Definition loader.h:81
#define logd(component, fmt,...)
Definition log.h:28
#define logw(component, fmt,...)
Definition log.h:44
#define logi(component, fmt,...)
Definition log.h:36
#define loge(component, fmt,...)
Definition log.h:52
struct vm_table * vm_current_context(void)
Definition vm.c:743
void vm_context_map(struct vm_table *pml4, ptr_t virtual, ptr_t physical, uint8_t pat)
Definition vm.c:406
void vm_context_activate(struct vm_table *context)
Definition vm.c:388
struct vm_table * vm_context_new(void)
Definition vm.c:381
A paging table, when this is a PML4 it may also be called context.
Definition vm.c:42