diff options
author | Slendi <slendi@socopon.com> | 2023-10-03 17:19:30 +0300 |
---|---|---|
committer | Slendi <slendi@socopon.com> | 2023-10-03 17:19:30 +0300 |
commit | 01da7b0a8d1b069c68d309237403c969f693e0b4 (patch) | |
tree | e6742635316447f8e7c371a583f80429f1b71014 | |
parent | 4d318bda3f14a3f67aa9214349d0149426e5f8ed (diff) |
Signed-off-by: Slendi <slendi@socopon.com>
-rw-r--r-- | efi_media_access.odin | 50 | ||||
-rw-r--r-- | main.odin | 3 | ||||
-rw-r--r-- | std.odin | 73 | ||||
-rw-r--r-- | stub.c | 2 |
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 @@ -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( @@ -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 } @@ -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; } |