summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlendi <slendi@socopon.com>2023-10-03 17:19:30 +0300
committerSlendi <slendi@socopon.com>2023-10-03 17:19:30 +0300
commit01da7b0a8d1b069c68d309237403c969f693e0b4 (patch)
treee6742635316447f8e7c371a583f80429f1b71014
parent4d318bda3f14a3f67aa9214349d0149426e5f8ed (diff)
Add EFI_LOAD_FILE support.HEADmaster
Signed-off-by: Slendi <slendi@socopon.com>
-rw-r--r--efi_media_access.odin50
-rw-r--r--main.odin3
-rw-r--r--std.odin73
-rw-r--r--stub.c2
4 files changed, 125 insertions, 3 deletions
diff --git a/efi_media_access.odin b/efi_media_access.odin
new file mode 100644
index 0000000..7e820fe
--- /dev/null
+++ b/efi_media_access.odin
@@ -0,0 +1,50 @@
+package main
+
+EFI_LOAD_FILE_PROTOCOL_GUID: GUID : {
+ 0x56EC3091,
+ 0x954C,
+ 0x11d2,
+ {0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b},
+}
+
+// Causes the driver to load a specified file.
+//
+// Inputs:
+// - this: Indicates a pointer to the calling context. Type
+// EFI_LOAD_FILE_PROTOCOL is defined in Load File Protocol.
+// - file_path: The device specific path of the file to load. Type
+// EFI_DEVICE_PATH_PROTOCOL is defined in EFI Device Path Protocol.
+// - boot_policy: If TRUE, indicates that the request originates from the boot
+// manager, and that the boot manager is attempting to load FilePath as a
+// boot selection. If FALSE, then FilePath must match an exact file to be
+// loaded.
+// - buffer: The memory buffer to transfer the file to. If Buffer is NULL, then
+// the size of the requested file is returned in BufferSize.
+//
+// Inputs/Outputs:
+// - buffer_size: On input the size of Buffer in bytes. On output with a return
+// code of EFI_SUCCESS, the amount of data transferred to Buffer. On output
+// with a return code of EFI_BUFFER_TOO_SMALL, the size of Buffer required to
+// retrieve the requested file.
+EfiLoadFile :: proc "c" (
+ this: ^EfiLoadFileProtocol,
+ file_path: ^EfiDevicePathProtocol,
+ boot_policy: bool,
+ buffer_size: uint,
+ buffer: rawptr,
+)
+
+// Used to obtain files, that are primarily boot options, from arbitrary devices.
+EfiLoadFileProtocol :: struct {
+ load_file: EfiLoadFile,
+}
+
+EFI_LOAD_FILE2_PROTOCOL_GUID: GUID : {
+ 0x4006c0c1,
+ 0xfcb3,
+ 0x403e,
+ {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d},
+}
+
+// Used to obtain files from arbitrary devices but are not used as boot options.
+EfiLoadFile2Protocol :: EfiLoadFileProtocol
diff --git a/main.odin b/main.odin
index c763572..b50c51d 100644
--- a/main.odin
+++ b/main.odin
@@ -47,8 +47,9 @@ main_ :: proc(efi_handle: rawptr, system_table: ^EfiSystemTable) -> u64 {
printf(
&buffer[0],
1024,
- L("Hello from Odin! Firmware vendor: %s\r\n"),
+ L("Hello from Odin! Firmware vendor: %s Revision: %i\r\n"),
system_table.firmware_vendor,
+ int(system_table.firmware_revision),
)
system_table.console_out.output_string(system_table.console_out, &buffer[0])
system_table.console_out.output_string(
diff --git a/std.odin b/std.odin
index 1cdb585..9009382 100644
--- a/std.odin
+++ b/std.odin
@@ -1,6 +1,7 @@
package main
import "core:mem"
+import "core:strconv"
strlen :: proc(string: [^]u16) -> uint {
len: uint = 0
@@ -10,6 +11,54 @@ strlen :: proc(string: [^]u16) -> uint {
return len
}
+reverse :: proc(str: [^]u16, length: int) {
+ start := 0
+ end := length - 1
+ for start < end {
+ temp := str[start]
+ str[start] = str[end]
+ str[end] = temp
+ end -= 1
+ start += 1
+ }
+}
+
+citoa :: proc(num_: int, str: [^]u16, base: int) -> [^]u16 {
+ i := 0
+ isNegative := false
+ num := num_
+
+ if (num == 0) {
+ str[i] = '0'
+ i += 1
+ str[i] = 0
+ return str
+ }
+
+ if (num < 0 && base == 10) {
+ isNegative = true
+ num = -num
+ }
+
+ for (num != 0) {
+ rem: int = num % base
+ str[i] = (rem > 9) ? (auto_cast (rem - 10) + 'a') : auto_cast rem + '0'
+ i += 1
+ num = num / base
+ }
+
+ if (isNegative) {
+ str[i] = '-'
+ i += 1
+ }
+
+ str[i] = 0
+
+ reverse(str, i)
+
+ return str
+}
+
printf :: proc(buffer: [^]u16, buffer_len: uint, format: [^]u16, args: ..any) -> [^]u16 {
format_len := strlen(format)
idx: uint = 0
@@ -27,13 +76,33 @@ printf :: proc(buffer: [^]u16, buffer_len: uint, format: [^]u16, args: ..any) ->
idx += 1
case 's':
arg := args[idx_args].([^]u16)
- str_len := strlen(arg)
idx_args += 1
+ str_len := strlen(arg)
for i2 in 0 ..< str_len {
buffer[idx] = arg[i2]
idx += 1
if idx >= buffer_len {break}
}
+ case 'd':
+ fallthrough
+ case 'i':
+ arg := args[idx_args].(int)
+ idx_args += 1
+ tmp: [21]byte
+ //mem.set(raw_data(tmp[:]), 0, 21)
+ //strconv.itoa(tmp[:], arg)
+ ////big.int_itoa_raw(auto_cast &arg, 10, tmp[:], 20, true)
+ tmp_u16: [21]u16
+ //for i2 in 0 ..< 21 {
+ // tmp_u16[i2] = u16(tmp[i2])
+ //}
+ citoa(arg, raw_data(tmp_u16[:]), 10)
+ str_len := strlen(raw_data(tmp_u16[:]))
+ for i2 in 0 ..< str_len {
+ buffer[idx] = tmp_u16[i2]
+ idx += 1
+ if idx >= buffer_len {break}
+ }
}
} else {
buffer[idx] = format[i]
@@ -43,7 +112,7 @@ printf :: proc(buffer: [^]u16, buffer_len: uint, format: [^]u16, args: ..any) ->
if idx >= buffer_len {break}
}
- //printf_buffer[idx + 1] = 0
+ buffer[idx + 1] = 0
return buffer
}
diff --git a/stub.c b/stub.c
index 67b7232..d006929 100644
--- a/stub.c
+++ b/stub.c
@@ -1,3 +1,4 @@
+#include <stddef.h>
void RaiseException() {}
void GetStdHandle() {}
void SetHandleInformation() {}
@@ -10,3 +11,4 @@ void HeapFree() {}
void RtlFillMemory() {}
void RtlMoveMemory() {}
void _fltused() {}
+size_t __chkstk(size_t a) { return a; }