authorgravatar for n@nirf.deNick Erdmann <n@nirf.de> 2019-07-28 23:51:51+02:00
committergravatar for n@nirf.deNick Erdmann <n@nirf.de> 2019-08-04 21:53:49+02:00
logb979fc1bcd6d1bdc19b7f518498fb8c9740d6dea
treed9b04d1e688dde7c08a50544a953042f369b7a9f
parent6e8ef5b6f2205ada3f2c1b4769aefdfc61aca39e
signaturelock-open Commit is signed but in an unrecognized format.

initial work torwards std lib support for uefi


21 files changed, 963 insertions(+), 10 deletions(-)

src/codegen.cpp+5-5
...@@ -8540,10 +8540,6 @@ static bool want_startup_code(CodeGen *g) {...@@ -8540,10 +8540,6 @@ static bool want_startup_code(CodeGen *g) {
8540 if (g->is_test_build)8540 if (g->is_test_build)
8541 return false;8541 return false;
85428542
8543 // start code does not handle UEFI target
8544 if (g->zig_target->os == OsUefi)
8545 return false;
8546
8547 // WASM freestanding can still have an entry point but other freestanding targets do not.8543 // WASM freestanding can still have an entry point but other freestanding targets do not.
8548 if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target))8544 if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target))
8549 return false;8545 return false;
...@@ -8553,8 +8549,12 @@ static bool want_startup_code(CodeGen *g) {...@@ -8553,8 +8549,12 @@ static bool want_startup_code(CodeGen *g) {
8553 return false;8549 return false;
85548550
8555 // If there is a pub main in the root source file, that means we need start code.8551 // If there is a pub main in the root source file, that means we need start code.
8556 if (g->have_pub_main)8552 if (g->have_pub_main) {
8557 return true;8553 return true;
8554 } else {
8555 if (g->zig_target->os == OsUefi)
8556 return false;
8557 }
85588558
8559 if (g->out_type == OutTypeExe) {8559 if (g->out_type == OutTypeExe) {
8560 // For build-exe, we might add start code even though there is no pub main, so that the8560 // For build-exe, we might add start code even though there is no pub main, so that the
std/os.zig+10-2
...@@ -155,8 +155,7 @@ pub fn abort() noreturn {...@@ -155,8 +155,7 @@ pub fn abort() noreturn {
155 system.abort();155 system.abort();
156 }156 }
157 if (builtin.os == .uefi) {157 if (builtin.os == .uefi) {
158 // TODO there must be a better thing to do here than loop forever158 exit(0); // TODO choose appropriate exit code
159 while (true) {}
160 }159 }
161160
162 raise(SIGABRT) catch {};161 raise(SIGABRT) catch {};
...@@ -228,6 +227,15 @@ pub fn exit(status: u8) noreturn {...@@ -228,6 +227,15 @@ pub fn exit(status: u8) noreturn {
228 if (linux.is_the_target and !builtin.single_threaded) {227 if (linux.is_the_target and !builtin.single_threaded) {
229 linux.exit_group(status);228 linux.exit_group(status);
230 }229 }
230 if (uefi.is_the_target) {
231 // exit() is only avaliable if exitBootServices() has not been called yet.
232 // This call to exit should not fail, so we don't care about its return value.
233 if (uefi.system_table.boot_services) |bs| {
234 _ = bs.exit(uefi.handle, status, 0, null);
235 }
236 // If we can't exit, reboot the system instead.
237 uefi.system_table.runtime_services.resetSystem(uefi.tables.ResetType.ResetCold, status, 0, null);
238 }
231 system.exit(status);239 system.exit(status);
232}240}
233241
std/os/uefi.zig+40-3
...@@ -1,6 +1,43 @@...@@ -1,6 +1,43 @@
1// TODO this is where the extern declarations go. For example, see1pub const protocols = @import("uefi/protocols.zig");
2// inc/efilib.h in gnu-efi-code2pub const status = @import("uefi/status.zig");
3pub const tables = @import("uefi/tables.zig");
34
4const builtin = @import("builtin");5const builtin = @import("builtin");
5
6pub const is_the_target = builtin.os == .uefi;6pub const is_the_target = builtin.os == .uefi;
7
8pub var handle: *Handle = undefined;
9pub var system_table: *tables.SystemTable = undefined;
10
11pub const Event = @OpaqueType();
12// GUIDs must be align(8)
13pub const Guid = extern struct {
14 time_low: u32,
15 time_mid: u16,
16 time_high_and_version: u16,
17 clock_seq_high_and_reserved: u8,
18 clock_seq_low: u8,
19 node: [6]u8,
20};
21pub const Handle = @OpaqueType();
22pub const Time = extern struct {
23 year: u16,
24 month: u8,
25 day: u8,
26 hour: u8,
27 minute: u8,
28 second: u8,
29 pad1: u8,
30 nanosecond: u32,
31 timezone: i16,
32 daylight: u8,
33 pad2: u8,
34
35 pub const adjust_daylight: u8 = 1;
36 pub const in_daylight: u8 = 2;
37 pub const unspecified_timezone: i16 = 0x7ff;
38};
39pub const TimeCapabilities = extern struct {
40 resolution: u32,
41 accuracy: u32,
42 sets_to_zero: bool,
43};
std/os/uefi/protocols.zig created+31
...@@ -0,0 +1,31 @@
1pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
2pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
3pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;
4pub const SimpleTextInputExProtocol = @import("protocols/simple_text_input_ex_protocol.zig").SimpleTextInputExProtocol;
5
6pub const SimpleTextOutputMode = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputMode;
7pub const SimpleTextOutputProtocol = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputProtocol;
8
9pub const SimplePointerMode = @import("protocols/simple_pointer_protocol.zig").SimplePointerMode;
10pub const SimplePointerProtocol = @import("protocols/simple_pointer_protocol.zig").SimplePointerProtocol;
11pub const SimplePointerState = @import("protocols/simple_pointer_protocol.zig").SimplePointerState;
12
13pub const AbsolutePointerMode = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerMode;
14pub const AbsolutePointerProtocol = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerProtocol;
15pub const AbsolutePointerState = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerState;
16
17pub const GraphicsOutputBltPixel = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltPixel;
18pub const GraphicsOutputBltOperation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltOperation;
19pub const GraphicsOutputModeInformation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputModeInformation;
20pub const GraphicsOutputProtocol = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocol;
21pub const GraphicsOutputProtocolMode = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocolMode;
22pub const GraphicsPixelFormat = @import("protocols/graphics_output_protocol.zig").GraphicsPixelFormat;
23pub const PixelBitmask = @import("protocols/graphics_output_protocol.zig").PixelBitmask;
24
25pub const EdidDiscoveredProtocol = @import("protocols/edid_discovered_protocol.zig").EdidDiscoveredProtocol;
26
27pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").EdidActiveProtocol;
28
29pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;
30
31pub const RNGProtocol = @import("protocols/rng_protocol.zig").RNGProtocol;
std/os/uefi/protocols/absolute_pointer_protocol.zig created+60
...@@ -0,0 +1,60 @@
1const uefi = @import("std").os.uefi;
2const Event = uefi.Event;
3const Guid = uefi.Guid;
4
5/// UEFI Specification, Version 2.8, 12.7
6pub const AbsolutePointerProtocol = extern struct {
7 _reset: extern fn (*const AbsolutePointerProtocol, bool) usize,
8 _get_state: extern fn (*const AbsolutePointerProtocol, *AbsolutePointerState) usize,
9 wait_for_input: *Event,
10 mode: *AbsolutePointerMode,
11
12 pub fn reset(self: *const AbsolutePointerProtocol, verify: bool) usize {
13 return self._reset(self, verify);
14 }
15
16 pub fn getState(self: *const AbsolutePointerProtocol, state: *AbsolutePointerState) usize {
17 return self._get_state(self, state);
18 }
19
20 pub const guid align(8) = Guid{
21 .time_low = 0x8d59d32b,
22 .time_mid = 0xc655,
23 .time_high_and_version = 0x4ae9,
24 .clock_seq_high_and_reserved = 0x9b,
25 .clock_seq_low = 0x15,
26 .node = [_]u8{ 0xf2, 0x59, 0x04, 0x99, 0x2a, 0x43 },
27 };
28};
29
30pub const AbsolutePointerMode = extern struct {
31 absolute_min_x: u64,
32 absolute_min_y: u64,
33 absolute_min_z: u64,
34 absolute_max_x: u64,
35 absolute_max_y: u64,
36 absolute_max_z: u64,
37 attributes: u32,
38
39 pub const supports_alt_active: u32 = 1;
40 pub const supports_pressure_as_z: u32 = 2;
41};
42
43pub const AbsolutePointerState = extern struct {
44 current_x: u64,
45 current_y: u64,
46 current_z: u64,
47 active_buttons: u32,
48
49 pub fn init() AbsolutePointerState {
50 return AbsolutePointerState{
51 .current_x = undefined,
52 .current_y = undefined,
53 .current_z = undefined,
54 .active_buttons = undefined,
55 };
56 }
57
58 pub const touch_active: u32 = 1;
59 pub const alt_active: u32 = 2;
60};
std/os/uefi/protocols/edid_active_protocol.zig created+17
...@@ -0,0 +1,17 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 12.9
5pub const EdidActiveProtocol = extern struct {
6 size_of_edid: u32,
7 edid: ?[*]u8,
8
9 pub const guid align(8) = Guid{
10 .time_low = 0xbd8c1056,
11 .time_mid = 0x9f36,
12 .time_high_and_version = 0x44ec,
13 .clock_seq_high_and_reserved = 0x92,
14 .clock_seq_low = 0xa8,
15 .node = [_]u8{ 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 },
16 };
17};
std/os/uefi/protocols/edid_discovered_protocol.zig created+17
...@@ -0,0 +1,17 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 12.9
5pub const EdidDiscoveredProtocol = extern struct {
6 size_of_edid: u32,
7 edid: ?[*]u8,
8
9 pub const guid align(8) = Guid{
10 .time_low = 0x1c0c34f6,
11 .time_mid = 0xd380,
12 .time_high_and_version = 0x41fa,
13 .clock_seq_high_and_reserved = 0xa0,
14 .clock_seq_low = 0x49,
15 .node = [_]u8{ 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa },
16 };
17};
std/os/uefi/protocols/edid_override_protocol.zig created+23
...@@ -0,0 +1,23 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Handle = uefi.Handle;
4
5/// UEFI Specification, Version 2.8, 12.9
6pub const EdidOverrideProtocol = extern struct {
7 _get_edid: extern fn (*const EdidOverrideProtocol, *const Handle, *u32, *usize, *?[*]u8) usize,
8
9 pub fn getEdid(self: *const EdidOverrideProtocol, handle: *const Handle, attributes: *u32, edid_size: *usize, edid: *?[*]u8) usize {
10 return self._get_edid(self, handle, attributes, edid_size, edid);
11 }
12
13 pub const guid align(8) = Guid{
14 .time_low = 0x48ecb431,
15 .time_mid = 0xfb72,
16 .time_high_and_version = 0x45c0,
17 .clock_seq_high_and_reserved = 0xa9,
18 .clock_seq_low = 0x22,
19 .node = [_]u8{ 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5 },
20 };
21 pub const dont_override: u32 = 1;
22 pub const enable_hot_plug: u32 = 2;
23};
std/os/uefi/protocols/graphics_output_protocol.zig created+90
...@@ -0,0 +1,90 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 12.9
5pub const GraphicsOutputProtocol = extern struct {
6 _query_mode: extern fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) usize,
7 _set_mode: extern fn (*const GraphicsOutputProtocol, u32) usize,
8 _blt: extern fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) usize,
9 mode: *GraphicsOutputProtocolMode,
10
11 pub fn queryMode(self: *const GraphicsOutputProtocol, mode: u32, size_of_info: *usize, info: **GraphicsOutputModeInformation) usize {
12 return self._query_mode(self, mode, size_of_info, info);
13 }
14
15 pub fn setMode(self: *const GraphicsOutputProtocol, mode: u32) usize {
16 return self._set_mode(self, mode);
17 }
18
19 pub fn blt(self: *const GraphicsOutputProtocol, blt_buffer: ?[*]GraphicsOutputBltPixel, blt_operation: GraphicsOutputBltOperation, source_x: usize, source_y: usize, destination_x: usize, destination_y: usize, width: usize, height: usize, delta: usize) usize {
20 return self._blt(self, blt_buffer, blt_operation, source_x, source_y, destination_x, destination_y, width, height, delta);
21 }
22
23 pub const guid align(8) = Guid{
24 .time_low = 0x9042a9de,
25 .time_mid = 0x23dc,
26 .time_high_and_version = 0x4a38,
27 .clock_seq_high_and_reserved = 0x96,
28 .clock_seq_low = 0xfb,
29 .node = [_]u8{ 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a },
30 };
31};
32
33pub const GraphicsOutputProtocolMode = extern struct {
34 max_mode: u32,
35 mode: u32,
36 info: *GraphicsOutputModeInformation,
37 size_of_info: usize,
38 frame_buffer_base: u64,
39 frame_buffer_size: usize,
40};
41
42pub const GraphicsOutputModeInformation = extern struct {
43 version: u32,
44 horizontal_resolution: u32,
45 vertical_resolution: u32,
46 pixel_format: GraphicsPixelFormat,
47 pixel_information: PixelBitmask,
48 pixels_per_scan_line: u32,
49
50 pub fn init() GraphicsOutputModeInformation {
51 return GraphicsOutputModeInformation{
52 .version = undefined,
53 .horizontal_resolution = undefined,
54 .vertical_resolution = undefined,
55 .pixel_format = undefined,
56 .pixel_information = undefined,
57 .pixels_per_scan_line = undefined,
58 };
59 }
60};
61
62pub const GraphicsPixelFormat = extern enum(u32) {
63 PixelRedGreenBlueReserved8BitPerColor,
64 PixelBlueGreenRedReserved8BitPerColor,
65 PixelBitMask,
66 PixelBltOnly,
67 PixelFormatMax,
68};
69
70pub const PixelBitmask = extern struct {
71 red_mask: u32,
72 green_mask: u32,
73 blue_mask: u32,
74 reserved_mask: u32,
75};
76
77pub const GraphicsOutputBltPixel = extern struct {
78 blue: u8,
79 green: u8,
80 red: u8,
81 reserved: u8 = undefined,
82};
83
84pub const GraphicsOutputBltOperation = extern enum(u32) {
85 BltVideoFill,
86 BltVideoToBltBuffer,
87 BltBufferToVideo,
88 BltVideoToVideo,
89 GraphicsOutputBltOperationMax,
90};
std/os/uefi/protocols/rng_protocol.zig created+73
...@@ -0,0 +1,73 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 37.5
5pub const RNGProtocol = extern struct {
6 _get_info: extern fn (*const RNGProtocol, *usize, [*]align(8) Guid) usize,
7 _get_rng: extern fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) usize,
8
9 pub fn getInfo(self: *const RNGProtocol, list_size: *usize, list: [*]align(8) Guid) usize {
10 return self._get_info(self, list_size, list);
11 }
12
13 pub fn getRNG(self: *const RNGProtocol, algo: ?*const Guid, value_length: usize, value: [*]u8) usize {
14 return self._get_rng(self, algo, value_length, value);
15 }
16
17 pub const guid align(8) = Guid{
18 .time_low = 0x3152bca5,
19 .time_mid = 0xeade,
20 .time_high_and_version = 0x433d,
21 .clock_seq_high_and_reserved = 0x86,
22 .clock_seq_low = 0x2e,
23 .node = [_]u8{ 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 },
24 };
25 pub const algorithm_sp800_90_hash_256 align(8) = Guid{
26 .time_low = 0xa7af67cb,
27 .time_mid = 0x603b,
28 .time_high_and_version = 0x4d42,
29 .clock_seq_high_and_reserved = 0xba,
30 .clock_seq_low = 0x21,
31 .node = [_]u8{ 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 },
32 };
33 pub const algorithm_sp800_90_hmac_256 align(8) = Guid{
34 .time_low = 0xc5149b43,
35 .time_mid = 0xae85,
36 .time_high_and_version = 0x4f53,
37 .clock_seq_high_and_reserved = 0x99,
38 .clock_seq_low = 0x82,
39 .node = [_]u8{ 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 },
40 };
41 pub const algorithm_sp800_90_ctr_256 align(8) = Guid{
42 .time_low = 0x44f0de6e,
43 .time_mid = 0x4d8c,
44 .time_high_and_version = 0x4045,
45 .clock_seq_high_and_reserved = 0xa8,
46 .clock_seq_low = 0xc7,
47 .node = [_]u8{ 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e },
48 };
49 pub const algorithm_x9_31_3des align(8) = Guid{
50 .time_low = 0x63c4785a,
51 .time_mid = 0xca34,
52 .time_high_and_version = 0x4012,
53 .clock_seq_high_and_reserved = 0xa3,
54 .clock_seq_low = 0xc8,
55 .node = [_]u8{ 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 },
56 };
57 pub const algorithm_x9_31_aes align(8) = Guid{
58 .time_low = 0xacd03321,
59 .time_mid = 0x777e,
60 .time_high_and_version = 0x4d3d,
61 .clock_seq_high_and_reserved = 0xb1,
62 .clock_seq_low = 0xc8,
63 .node = [_]u8{ 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 },
64 };
65 pub const algorithm_raw align(8) = Guid{
66 .time_low = 0xe43176d7,
67 .time_mid = 0xb6e8,
68 .time_high_and_version = 0x4827,
69 .clock_seq_high_and_reserved = 0xb7,
70 .clock_seq_low = 0x84,
71 .node = [_]u8{ 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 },
72 };
73};
std/os/uefi/protocols/simple_pointer_protocol.zig created+54
...@@ -0,0 +1,54 @@
1const uefi = @import("std").os.uefi;
2const Event = uefi.Event;
3const Guid = uefi.Guid;
4
5/// UEFI Specification, Version 2.8, 12.5
6pub const SimplePointerProtocol = struct {
7 _reset: extern fn (*const SimplePointerProtocol, bool) usize,
8 _get_state: extern fn (*const SimplePointerProtocol, *SimplePointerState) usize,
9 wait_for_input: *Event,
10 mode: *SimplePointerMode,
11
12 pub fn reset(self: *const SimplePointerProtocol, verify: bool) usize {
13 return self._reset(self, verify);
14 }
15
16 pub fn getState(self: *const SimplePointerProtocol, state: *SimplePointerState) usize {
17 return self._get_state(self, state);
18 }
19
20 pub const guid align(8) = Guid{
21 .time_low = 0x31878c87,
22 .time_mid = 0x0b75,
23 .time_high_and_version = 0x11d5,
24 .clock_seq_high_and_reserved = 0x9a,
25 .clock_seq_low = 0x4f,
26 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
27 };
28};
29
30pub const SimplePointerMode = struct {
31 resolution_x: u64,
32 resolution_y: u64,
33 resolution_z: u64,
34 left_button: bool,
35 right_button: bool,
36};
37
38pub const SimplePointerState = struct {
39 relative_movement_x: i32,
40 relative_movement_y: i32,
41 relative_movement_z: i32,
42 left_button: bool,
43 right_button: bool,
44
45 pub fn init() SimplePointerState {
46 return SimplePointerState{
47 .relative_movement_x = undefined,
48 .relative_movement_y = undefined,
49 .relative_movement_z = undefined,
50 .left_button = undefined,
51 .right_button = undefined,
52 };
53 }
54};
std/os/uefi/protocols/simple_text_input_ex_protocol.zig created+81
...@@ -0,0 +1,81 @@
1const uefi = @import("std").os.uefi;
2const Event = uefi.Event;
3const Guid = uefi.Guid;
4
5/// UEFI Specification, Version 2.8, 12.3
6pub const SimpleTextInputExProtocol = extern struct {
7 _reset: extern fn (*const SimpleTextInputExProtocol, bool) usize,
8 _read_key_stroke_ex: extern fn (*const SimpleTextInputExProtocol, *KeyData) usize,
9 wait_for_key_ex: *Event,
10 _set_state: extern fn (*const SimpleTextInputExProtocol, *const u8) usize,
11 _register_key_notify: extern fn (*const SimpleTextInputExProtocol, *const KeyData, extern fn (*const KeyData) usize, **c_void) usize,
12 _unregister_key_notify: extern fn (*const SimpleTextInputExProtocol, *const c_void) usize,
13
14 pub fn reset(self: *const SimpleTextInputExProtocol, verify: bool) usize {
15 return self._reset(self, verify);
16 }
17
18 pub fn readKeyStrokeEx(self: *const SimpleTextInputExProtocol, key_data: *KeyData) usize {
19 return self._read_key_stroke_ex(self, key_data);
20 }
21
22 pub fn setState(self: *const SimpleTextInputExProtocol, state: *const u8) usize {
23 return self._set_state(self, state);
24 }
25
26 pub fn registerKeyNotify(self: *const SimpleTextInputExProtocol, key_data: *const KeyData, notify: extern fn (*const KeyData) usize, handle: **c_void) usize {
27 return self._register_key_notify(self, key_data, notify, handle);
28 }
29
30 pub fn unregisterKeyNotify(self: *const SimpleTextInputExProtocol, handle: *const c_void) usize {
31 return self._unregister_key_notify(self, handle);
32 }
33
34 pub const guid align(8) = Guid{
35 .time_low = 0xdd9e7534,
36 .time_mid = 0x7762,
37 .time_high_and_version = 0x4698,
38 .clock_seq_high_and_reserved = 0x8c,
39 .clock_seq_low = 0x14,
40 .node = [_]u8{ 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa },
41 };
42};
43
44pub const KeyData = extern struct {
45 key: InputKey,
46 key_state: KeyState,
47
48 pub fn init() KeyData {
49 return KeyData{
50 .key = undefined,
51 .key_state = undefined,
52 };
53 }
54};
55
56pub const KeyState = extern struct {
57 key_shift_state: u32,
58 key_toggle_state: u8,
59
60 pub const shift_state_valid: u32 = 0x80000000;
61 pub const right_shift_pressed: u32 = 0x00000001;
62 pub const left_shift_pressed: u32 = 0x00000002;
63 pub const right_control_pressed: u32 = 0x00000004;
64 pub const left_control_pressed: u32 = 0x00000008;
65 pub const right_alt_pressed: u32 = 0x00000010;
66 pub const left_alt_pressed: u32 = 0x00000020;
67 pub const right_logo_pressed: u32 = 0x00000040;
68 pub const left_logo_pressed: u32 = 0x00000080;
69 pub const menu_key_pressed: u32 = 0x00000100;
70 pub const sys_req_pressed: u32 = 0x00000200;
71 pub const toggle_state_valid: u8 = 0x80;
72 pub const key_state_exposed: u8 = 0x40;
73 pub const scroll_lock_active: u8 = 0x01;
74 pub const num_lock_active: u8 = 0x02;
75 pub const caps_lock_active: u8 = 0x04;
76};
77
78pub const InputKey = extern struct {
79 scan_code: u16,
80 unicode_char: u16,
81};
std/os/uefi/protocols/simple_text_output_protocol.zig created+143
...@@ -0,0 +1,143 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 12.4
5pub const SimpleTextOutputProtocol = extern struct {
6 _reset: extern fn (*const SimpleTextOutputProtocol, bool) usize,
7 _output_string: extern fn (*const SimpleTextOutputProtocol, [*]const u16) usize,
8 _test_string: extern fn (*const SimpleTextOutputProtocol, [*]const u16) usize,
9 _query_mode: extern fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) usize,
10 _set_mode: extern fn (*const SimpleTextOutputProtocol, usize) usize,
11 _set_attribute: extern fn (*const SimpleTextOutputProtocol, usize) usize,
12 _clear_screen: extern fn (*const SimpleTextOutputProtocol) usize,
13 _set_cursor_position: extern fn (*const SimpleTextOutputProtocol, usize, usize) usize,
14 _enable_cursor: extern fn (*const SimpleTextOutputProtocol, bool) usize,
15 mode: *SimpleTextOutputMode,
16
17 pub fn reset(self: *const SimpleTextOutputProtocol, verify: bool) usize {
18 return self._reset(self, verify);
19 }
20
21 pub fn outputString(self: *const SimpleTextOutputProtocol, msg: [*]const u16) usize {
22 return self._output_string(self, msg);
23 }
24
25 pub fn testString(self: *const SimpleTextOutputProtocol, msg: [*]const u16) usize {
26 return self._test_string(self, msg);
27 }
28
29 pub fn queryMode(self: *const SimpleTextOutputProtocol, mode_number: usize, columns: *usize, rows: *usize) usize {
30 return self._query_mode(self, mode_number, columns, rows);
31 }
32
33 pub fn setMode(self: *const SimpleTextOutputProtocol, mode_number: usize) usize {
34 return self._set_mode(self, mode_number);
35 }
36
37 pub fn setAttribute(self: *const SimpleTextOutputProtocol, attribute: usize) usize {
38 return self._set_attribute(self, attribute);
39 }
40
41 pub fn clearScreen(self: *const SimpleTextOutputProtocol) usize {
42 return self._clear_screen(self);
43 }
44
45 pub fn setCursorPosition(self: *const SimpleTextOutputProtocol, column: usize, row: usize) usize {
46 return self._set_cursor_position(self, column, row);
47 }
48
49 pub fn enableCursor(self: *const SimpleTextOutputProtocol, visible: bool) usize {
50 return self._enable_cursor(self, visible);
51 }
52
53 pub const guid align(8) = Guid{
54 .time_low = 0x387477c2,
55 .time_mid = 0x69c7,
56 .time_high_and_version = 0x11d2,
57 .clock_seq_high_and_reserved = 0x8e,
58 .clock_seq_low = 0x39,
59 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
60 };
61 pub const boxdraw_horizontal: u16 = 0x2500;
62 pub const boxdraw_vertical: u16 = 0x2502;
63 pub const boxdraw_down_right: u16 = 0x250c;
64 pub const boxdraw_down_left: u16 = 0x2510;
65 pub const boxdraw_up_right: u16 = 0x2514;
66 pub const boxdraw_up_left: u16 = 0x2518;
67 pub const boxdraw_vertical_right: u16 = 0x251c;
68 pub const boxdraw_vertical_left: u16 = 0x2524;
69 pub const boxdraw_down_horizontal: u16 = 0x252c;
70 pub const boxdraw_up_horizontal: u16 = 0x2534;
71 pub const boxdraw_vertical_horizontal: u16 = 0x253c;
72 pub const boxdraw_double_horizontal: u16 = 0x2550;
73 pub const boxdraw_double_vertical: u16 = 0x2551;
74 pub const boxdraw_down_right_double: u16 = 0x2552;
75 pub const boxdraw_down_double_right: u16 = 0x2553;
76 pub const boxdraw_double_down_right: u16 = 0x2554;
77 pub const boxdraw_down_left_double: u16 = 0x2555;
78 pub const boxdraw_down_double_left: u16 = 0x2556;
79 pub const boxdraw_double_down_left: u16 = 0x2557;
80 pub const boxdraw_up_right_double: u16 = 0x2558;
81 pub const boxdraw_up_double_right: u16 = 0x2559;
82 pub const boxdraw_double_up_right: u16 = 0x255a;
83 pub const boxdraw_up_left_double: u16 = 0x255b;
84 pub const boxdraw_up_double_left: u16 = 0x255c;
85 pub const boxdraw_double_up_left: u16 = 0x255d;
86 pub const boxdraw_vertical_right_double: u16 = 0x255e;
87 pub const boxdraw_vertical_double_right: u16 = 0x255f;
88 pub const boxdraw_double_vertical_right: u16 = 0x2560;
89 pub const boxdraw_vertical_left_double: u16 = 0x2561;
90 pub const boxdraw_vertical_double_left: u16 = 0x2562;
91 pub const boxdraw_double_vertical_left: u16 = 0x2563;
92 pub const boxdraw_down_horizontal_double: u16 = 0x2564;
93 pub const boxdraw_down_double_horizontal: u16 = 0x2565;
94 pub const boxdraw_double_down_horizontal: u16 = 0x2566;
95 pub const boxdraw_up_horizontal_double: u16 = 0x2567;
96 pub const boxdraw_up_double_horizontal: u16 = 0x2568;
97 pub const boxdraw_double_up_horizontal: u16 = 0x2569;
98 pub const boxdraw_vertical_horizontal_double: u16 = 0x256a;
99 pub const boxdraw_vertical_double_horizontal: u16 = 0x256b;
100 pub const boxdraw_double_vertical_horizontal: u16 = 0x256c;
101 pub const blockelement_full_block: u16 = 0x2588;
102 pub const blockelement_light_shade: u16 = 0x2591;
103 pub const geometricshape_up_triangle: u16 = 0x25b2;
104 pub const geometricshape_right_triangle: u16 = 0x25ba;
105 pub const geometricshape_down_triangle: u16 = 0x25bc;
106 pub const geometricshape_left_triangle: u16 = 0x25c4;
107 pub const arrow_up: u16 = 0x2591;
108 pub const arrow_down: u16 = 0x2593;
109 pub const black: u8 = 0x00;
110 pub const blue: u8 = 0x01;
111 pub const green: u8 = 0x02;
112 pub const cyan: u8 = 0x03;
113 pub const red: u8 = 0x04;
114 pub const magenta: u8 = 0x05;
115 pub const brown: u8 = 0x06;
116 pub const lightgray: u8 = 0x07;
117 pub const bright: u8 = 0x08;
118 pub const darkgray: u8 = 0x08;
119 pub const lightblue: u8 = 0x09;
120 pub const lightgreen: u8 = 0x0a;
121 pub const lightcyan: u8 = 0x0b;
122 pub const lightred: u8 = 0x0c;
123 pub const lightmagenta: u8 = 0x0d;
124 pub const yellow: u8 = 0x0e;
125 pub const white: u8 = 0x0f;
126 pub const background_black: u8 = 0x00;
127 pub const background_blue: u8 = 0x10;
128 pub const background_green: u8 = 0x20;
129 pub const background_cyan: u8 = 0x30;
130 pub const background_red: u8 = 0x40;
131 pub const background_magenta: u8 = 0x50;
132 pub const background_brown: u8 = 0x60;
133 pub const background_lightgray: u8 = 0x70;
134};
135
136pub const SimpleTextOutputMode = extern struct {
137 max_mode: u32, // specified as signed
138 mode: u32, // specified as signed
139 attribute: i32,
140 cursor_column: i32,
141 cursor_row: i32,
142 cursor_visible: bool,
143};
std/os/uefi/status.zig created+46
...@@ -0,0 +1,46 @@
1const high_bit = 1 << @typeInfo(usize).Int.bits - 1;
2
3/// UEFI Specification, Version 2.8, Appendix D
4pub const success: usize = 0;
5
6pub const load_error: usize = high_bit | 1;
7pub const invalid_parameter: usize = high_bit | 2;
8pub const unsupported: usize = high_bit | 3;
9pub const bad_buffer_size: usize = high_bit | 4;
10pub const buffer_too_small: usize = high_bit | 5;
11pub const not_ready: usize = high_bit | 6;
12pub const device_error: usize = high_bit | 7;
13pub const write_protected: usize = high_bit | 8;
14pub const out_of_resources: usize = high_bit | 9;
15pub const volume_corrupted: usize = high_bit | 10;
16pub const volume_full: usize = high_bit | 11;
17pub const no_media: usize = high_bit | 12;
18pub const media_changed: usize = high_bit | 13;
19pub const not_found: usize = high_bit | 14;
20pub const access_denied: usize = high_bit | 15;
21pub const no_response: usize = high_bit | 16;
22pub const no_mapping: usize = high_bit | 17;
23pub const timeout: usize = high_bit | 18;
24pub const not_started: usize = high_bit | 19;
25pub const already_started: usize = high_bit | 20;
26pub const aborted: usize = high_bit | 21;
27pub const icmp_error: usize = high_bit | 22;
28pub const tftp_error: usize = high_bit | 23;
29pub const protocol_error: usize = high_bit | 24;
30pub const incompatible_version: usize = high_bit | 25;
31pub const security_violation: usize = high_bit | 26;
32pub const crc_error: usize = high_bit | 27;
33pub const end_of_media: usize = high_bit | 28;
34pub const end_of_file: usize = high_bit | 31;
35pub const invalid_language: usize = high_bit | 32;
36pub const compromised_data: usize = high_bit | 33;
37pub const ip_address_conflict: usize = high_bit | 34;
38pub const http_error: usize = high_bit | 35;
39
40pub const warn_unknown_glyph: usize = 1;
41pub const warn_delete_failure: usize = 2;
42pub const warn_write_failure: usize = 3;
43pub const warn_buffer_too_small: usize = 4;
44pub const warn_stale_data: usize = 5;
45pub const warn_file_system: usize = 6;
46pub const warn_reset_required: usize = 7;
std/os/uefi/tables.zig created+6
...@@ -0,0 +1,6 @@
1pub const BootServices = @import("tables/boot_services.zig").BootServices;
2pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;
3pub const ResetType = @import("tables/runtime_services.zig").ResetType;
4pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;
5pub const SystemTable = @import("tables/system_table.zig").SystemTable;
6pub const TableHeader = @import("tables/table_header.zig").TableHeader;
std/os/uefi/tables/boot_services.zig created+64
...@@ -0,0 +1,64 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Handle = uefi.Handle;
4const TableHeader = uefi.tables.TableHeader;
5
6/// UEFI Specification, Version 2.8, 4.4
7///
8/// As the boot_services table may grow with new UEFI versions, it is important to check hdr.header_size.
9///
10/// Boot Services must not be used after exitBootServices has been called. The only exception is
11/// getMemoryMap, which may be used after the first unsuccessful call to exitBootServices.
12/// After successfully calling exitBootServices, system_table.console_in_handle, system_table.con_in,
13/// system_table.console_out_handle, system_table.con_out, system_table.standard_error_handle,
14/// system_table.std_err, and system_table.boot_services should be set to null. After setting these
15/// attributes to null, system_table.hdr.crc32 must be recomputed. See UEFI Specification, Version 2.8, 7.4.
16pub const BootServices = extern struct {
17 hdr: TableHeader,
18 raiseTpl: usize, // TODO
19 restoreTpl: usize, // TODO
20 allocatePages: usize, // TODO
21 freePages: usize, // TODO
22 getMemoryMap: usize, // TODO
23 allocatePool: usize, // TODO
24 freePool: usize, // TODO
25 createEvent: usize, // TODO
26 setTimer: usize, // TODO
27 waitForEvent: usize, // TODO
28 signalEvent: usize, // TODO
29 closeEvent: usize, // TODO
30 checkEvent: usize, // TODO
31 installProtocolInterface: usize, // TODO
32 reinstallProtocolInterface: usize, // TODO
33 uninstallProtocolInterface: usize, // TODO
34 handleProtocol: usize, // TODO
35 reserved: *c_void,
36 registerProtocolNotify: usize, // TODO
37 locateHandle: usize, // TODO
38 locateDevicePath: usize, // TODO
39 installConfigurationTable: usize, // TODO
40 imageLoad: usize, // TODO
41 imageStart: usize, // TODO
42 exit: extern fn (*const Handle, usize, usize, ?*const c_void) usize,
43 imageUnload: usize, // TODO
44 exitBootServices: usize, // TODO
45 getNextMonotonicCount: usize, // TODO
46 stall: extern fn (usize) usize,
47 setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) usize,
48 connectController: usize, // TODO
49 disconnectController: usize, // TODO
50 openProtocol: usize, // TODO
51 closeProtocol: usize, // TODO
52 openProtocolInformation: usize, // TODO
53 protocolsPerHandle: usize, // TODO
54 locateHandleBuffer: usize, // TODO
55 locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) usize,
56 installMultipleProtocolInterfaces: usize, // TODO
57 uninstallMultipleProtocolInterfaces: usize, // TODO
58 calculateCrc32: usize, // TODO
59 copyMem: usize, // TODO
60 setMem: usize, // TODO
61 createEventEx: usize, // TODO
62
63 pub const signature: u64 = 0x56524553544f4f42;
64};
std/os/uefi/tables/configuration_table.zig created+82
...@@ -0,0 +1,82 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4/// UEFI Specification, Version 2.8, 4.6
5/// Because GUIDs must be align(8), structs of this type also must be align(8)
6pub const ConfigurationTable = extern struct {
7 vendor_guid: Guid,
8 vendor_table: *c_void,
9
10 pub const acpi_20_table_guid align(8) = Guid{
11 .time_low = 0x8868e871,
12 .time_mid = 0xe4f1,
13 .time_high_and_version = 0x11d3,
14 .clock_seq_high_and_reserved = 0xbc,
15 .clock_seq_low = 0x22,
16 .node = [_]u8{ 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 },
17 };
18 pub const acpi_10_table_guid align(8) = Guid{
19 .time_low = 0xeb9d2d30,
20 .time_mid = 0x2d88,
21 .time_high_and_version = 0x11d3,
22 .clock_seq_high_and_reserved = 0x9a,
23 .clock_seq_low = 0x16,
24 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
25 };
26 pub const sal_system_table_guid align(8) = Guid{
27 .time_low = 0xeb9d2d32,
28 .time_mid = 0x2d88,
29 .time_high_and_version = 0x113d,
30 .clock_seq_high_and_reserved = 0x9a,
31 .clock_seq_low = 0x16,
32 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
33 };
34 pub const smbios_table_guid align(8) = Guid{
35 .time_low = 0xeb9d2d31,
36 .time_mid = 0x2d88,
37 .time_high_and_version = 0x11d3,
38 .clock_seq_high_and_reserved = 0x9a,
39 .clock_seq_low = 0x16,
40 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
41 };
42 pub const smbios3_table_guid align(8) = Guid{
43 .time_low = 0xf2fd1544,
44 .time_mid = 0x9794,
45 .time_high_and_version = 0x4a2c,
46 .clock_seq_high_and_reserved = 0x99,
47 .clock_seq_low = 0x2e,
48 .node = [_]u8{ 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 },
49 };
50 pub const mps_table_guid align(8) = Guid{
51 .time_low = 0xeb9d2d2f,
52 .time_mid = 0x2d88,
53 .time_high_and_version = 0x11d3,
54 .clock_seq_high_and_reserved = 0x9a,
55 .clock_seq_low = 0x16,
56 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
57 };
58 pub const json_config_data_table_guid align(8) = Guid{
59 .time_low = 0x87367f87,
60 .time_mid = 0x1119,
61 .time_high_and_version = 0x41ce,
62 .clock_seq_high_and_reserved = 0xaa,
63 .clock_seq_low = 0xec,
64 .node = [_]u8{ 0x8b, 0xe0, 0x11, 0x1f, 0x55, 0x8a },
65 };
66 pub const json_capsule_data_table_guid align(8) = Guid{
67 .time_low = 0x35e7a725,
68 .time_mid = 0x8dd2,
69 .time_high_and_version = 0x4cac,
70 .clock_seq_high_and_reserved = 0x80,
71 .clock_seq_low = 0x11,
72 .node = [_]u8{ 0x33, 0xcd, 0xa8, 0x10, 0x90, 0x56 },
73 };
74 pub const json_capsule_result_table_guid align(8) = Guid{
75 .time_low = 0xdbc461c3,
76 .time_mid = 0xb3de,
77 .time_high_and_version = 0x422a,
78 .clock_seq_high_and_reserved = 0xb9,
79 .clock_seq_low = 0xb4,
80 .node = [_]u8{ 0x98, 0x86, 0xfd, 0x49, 0xa1, 0xe5 },
81 };
82};
std/os/uefi/tables/runtime_services.zig created+41
...@@ -0,0 +1,41 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const TableHeader = uefi.tables.TableHeader;
4const Time = uefi.Time;
5const TimeCapabilities = uefi.TimeCapabilities;
6
7/// UEFI Specification, Version 2.8, 4.5
8///
9/// As the runtime_services table may grow with new UEFI versions, it is important to check hdr.header_size.
10///
11/// Some functions may not be supported. Check the RuntimeServicesSupported variable using getVariable.
12/// getVariable is one of the functions that may not be supported. See UEFI Specification, Version 2.8, 8.1.
13///
14/// Some functions may not be called while other functions are running. See UEFI Specification, Version 2.8, 8.1.
15pub const RuntimeServices = extern struct {
16 hdr: TableHeader,
17 getTime: extern fn (*uefi.Time, ?*TimeCapabilities) usize,
18 setTime: usize, // TODO
19 getWakeupTime: usize, // TODO
20 setWakeupTime: usize, // TODO
21 setVirtualAddressMap: usize, // TODO
22 convertPointer: usize, // TODO
23 getVariable: extern fn ([*]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) usize,
24 getNextVariableName: extern fn (*usize, [*]u16, *align(8) Guid) usize,
25 setVariable: extern fn ([*]const u16, *align(8) const Guid, u32, usize, *c_void) usize,
26 getNextHighMonotonicCount: usize, // TODO
27 resetSystem: extern fn (ResetType, usize, usize, ?*const c_void) noreturn,
28 updateCapsule: usize, // TODO
29 queryCapsuleCapabilities: usize, // TODO
30 queryVariableInfo: usize, // TODO
31
32 pub const signature: u64 = 0x56524553544e5552;
33};
34
35/// UEFI Specification, Version 2.8, 8.5.1
36pub const ResetType = extern enum(u32) {
37 ResetCold,
38 ResetWarm,
39 ResetShutdown,
40 ResetPlatformSpecific,
41};
std/os/uefi/tables/system_table.zig created+46
...@@ -0,0 +1,46 @@
1const uefi = @import("std").os.uefi;
2const BootServices = uefi.tables.BootServices;
3const ConfigurationTable = uefi.tables.ConfigurationTable;
4const Handle = uefi.Handle;
5const RuntimeServices = uefi.tables.RuntimeServices;
6const SimpleTextInputExProtocol = uefi.protocols.SimpleTextInputExProtocol;
7const SimpleTextOutputProtocol = uefi.protocols.SimpleTextOutputProtocol;
8const TableHeader = uefi.tables.TableHeader;
9
10/// UEFI Specification, Version 2.8, 4.3
11///
12/// As the system_table may grow with new UEFI versions, it is important to check hdr.header_size.
13///
14/// After successfully calling boot_services.exitBootServices, console_in_handle,
15/// con_in, console_out_handle, con_out, standard_error_handle, std_err, and
16/// boot_services should be set to null. After setting these attributes to null,
17/// hdr.crc32 must be recomputed. See UEFI Specification, Version 2.8, 7.4.
18pub const SystemTable = extern struct {
19 hdr: TableHeader,
20 firmware_vendor: *u16,
21 firmware_revision: u32,
22 console_in_handle: ?*Handle,
23 con_in: ?*SimpleTextInputExProtocol,
24 console_out_handle: ?*Handle,
25 con_out: ?*SimpleTextOutputProtocol,
26 standard_error_handle: ?*Handle,
27 std_err: ?*SimpleTextOutputProtocol,
28 runtime_services: *RuntimeServices,
29 boot_services: ?*BootServices,
30 number_of_table_entries: usize,
31 configuration_table: *ConfigurationTable,
32
33 pub const signature: u64 = 0x5453595320494249;
34 pub const revision_1_02: u32 = (1 << 16) | 2;
35 pub const revision_1_10: u32 = (1 << 16) | 10;
36 pub const revision_2_00: u32 = (2 << 16);
37 pub const revision_2_10: u32 = (2 << 16) | 10;
38 pub const revision_2_20: u32 = (2 << 16) | 20;
39 pub const revision_2_30: u32 = (2 << 16) | 30;
40 pub const revision_2_31: u32 = (2 << 16) | 31;
41 pub const revision_2_40: u32 = (2 << 16) | 40;
42 pub const revision_2_50: u32 = (2 << 16) | 50;
43 pub const revision_2_60: u32 = (2 << 16) | 60;
44 pub const revision_2_70: u32 = (2 << 16) | 70;
45 pub const revision_2_80: u32 = (2 << 16) | 80;
46};
std/os/uefi/tables/table_header.zig created+8
...@@ -0,0 +1,8 @@
1/// UEFI Specification, Version 2.8, 4.2
2pub const TableHeader = extern struct {
3 signature: u64,
4 revision: u32,
5 header_size: u32,
6 crc32: u32,
7 reserved: u32,
8};
std/special/start.zig+26
...@@ -4,6 +4,7 @@ const root = @import("root");...@@ -4,6 +4,7 @@ const root = @import("root");
4const std = @import("std");4const std = @import("std");
5const builtin = @import("builtin");5const builtin = @import("builtin");
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const uefi = std.os.uefi;
78
8var argc_ptr: [*]usize = undefined;9var argc_ptr: [*]usize = undefined;
910
...@@ -19,6 +20,8 @@ comptime {...@@ -19,6 +20,8 @@ comptime {
19 @export("WinMainCRTStartup", WinMainCRTStartup, .Strong);20 @export("WinMainCRTStartup", WinMainCRTStartup, .Strong);
20 } else if (is_wasm and builtin.os == .freestanding) {21 } else if (is_wasm and builtin.os == .freestanding) {
21 @export("_start", wasm_freestanding_start, .Strong);22 @export("_start", wasm_freestanding_start, .Strong);
23 } else if (builtin.os == .uefi) {
24 @export("EfiMain", EfiMain, .Strong);
22 } else {25 } else {
23 @export("_start", _start, .Strong);26 @export("_start", _start, .Strong);
24 }27 }
...@@ -28,6 +31,29 @@ extern fn wasm_freestanding_start() void {...@@ -28,6 +31,29 @@ extern fn wasm_freestanding_start() void {
28 _ = callMain();31 _ = callMain();
29}32}
3033
34extern fn EfiMain(handle: *uefi.Handle, system_table: *uefi.tables.SystemTable) usize {
35 const bad_efi_main_ret = "expected return type of main to be 'void', 'noreturn', or 'usize'";
36 uefi.handle = handle;
37 uefi.system_table = system_table;
38
39 switch (@typeInfo(@typeOf(root.main).ReturnType)) {
40 .NoReturn => {
41 root.main();
42 },
43 .Void => {
44 root.main();
45 return 0;
46 },
47 .Int => |info| {
48 if (info.bits != @typeInfo(usize).Int.bits) {
49 @compileError(bad_efi_main_ret);
50 }
51 return root.main();
52 },
53 else => @compileError(bad_efi_main_ret),
54 }
55}
56
31nakedcc fn _start() noreturn {57nakedcc fn _start() noreturn {
32 if (builtin.os == builtin.Os.wasi) {58 if (builtin.os == builtin.Os.wasi) {
33 std.os.wasi.proc_exit(callMain());59 std.os.wasi.proc_exit(callMain());