Skip to content

Commit b979fc1

Browse files
committed
initial work torwards std lib support for uefi
1 parent 6e8ef5b commit b979fc1

21 files changed

+963
-10
lines changed

src/codegen.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -8540,10 +8540,6 @@ static bool want_startup_code(CodeGen *g) {
85408540
if (g->is_test_build)
85418541
return false;
85428542

8543-
// start code does not handle UEFI target
8544-
if (g->zig_target->os == OsUefi)
8545-
return false;
8546-
85478543
// WASM freestanding can still have an entry point but other freestanding targets do not.
85488544
if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target))
85498545
return false;
@@ -8553,8 +8549,12 @@ static bool want_startup_code(CodeGen *g) {
85538549
return false;
85548550

85558551
// 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) {
85578553
return true;
8554+
} else {
8555+
if (g->zig_target->os == OsUefi)
8556+
return false;
8557+
}
85588558

85598559
if (g->out_type == OutTypeExe) {
85608560
// For build-exe, we might add start code even though there is no pub main, so that the

std/os.zig

+10-2
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ pub fn abort() noreturn {
155155
system.abort();
156156
}
157157
if (builtin.os == .uefi) {
158-
// TODO there must be a better thing to do here than loop forever
159-
while (true) {}
158+
exit(0); // TODO choose appropriate exit code
160159
}
161160

162161
raise(SIGABRT) catch {};
@@ -228,6 +227,15 @@ pub fn exit(status: u8) noreturn {
228227
if (linux.is_the_target and !builtin.single_threaded) {
229228
linux.exit_group(status);
230229
}
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+
}
231239
system.exit(status);
232240
}
233241

std/os/uefi.zig

+40-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
1-
// TODO this is where the extern declarations go. For example, see
2-
// inc/efilib.h in gnu-efi-code
1+
pub const protocols = @import("uefi/protocols.zig");
2+
pub const status = @import("uefi/status.zig");
3+
pub const tables = @import("uefi/tables.zig");
34

45
const builtin = @import("builtin");
5-
66
pub const is_the_target = builtin.os == .uefi;
7+
8+
pub var handle: *Handle = undefined;
9+
pub var system_table: *tables.SystemTable = undefined;
10+
11+
pub const Event = @OpaqueType();
12+
// GUIDs must be align(8)
13+
pub 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+
};
21+
pub const Handle = @OpaqueType();
22+
pub 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+
};
39+
pub const TimeCapabilities = extern struct {
40+
resolution: u32,
41+
accuracy: u32,
42+
sets_to_zero: bool,
43+
};

std/os/uefi/protocols.zig

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
2+
pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
3+
pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;
4+
pub const SimpleTextInputExProtocol = @import("protocols/simple_text_input_ex_protocol.zig").SimpleTextInputExProtocol;
5+
6+
pub const SimpleTextOutputMode = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputMode;
7+
pub const SimpleTextOutputProtocol = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputProtocol;
8+
9+
pub const SimplePointerMode = @import("protocols/simple_pointer_protocol.zig").SimplePointerMode;
10+
pub const SimplePointerProtocol = @import("protocols/simple_pointer_protocol.zig").SimplePointerProtocol;
11+
pub const SimplePointerState = @import("protocols/simple_pointer_protocol.zig").SimplePointerState;
12+
13+
pub const AbsolutePointerMode = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerMode;
14+
pub const AbsolutePointerProtocol = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerProtocol;
15+
pub const AbsolutePointerState = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerState;
16+
17+
pub const GraphicsOutputBltPixel = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltPixel;
18+
pub const GraphicsOutputBltOperation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltOperation;
19+
pub const GraphicsOutputModeInformation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputModeInformation;
20+
pub const GraphicsOutputProtocol = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocol;
21+
pub const GraphicsOutputProtocolMode = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocolMode;
22+
pub const GraphicsPixelFormat = @import("protocols/graphics_output_protocol.zig").GraphicsPixelFormat;
23+
pub const PixelBitmask = @import("protocols/graphics_output_protocol.zig").PixelBitmask;
24+
25+
pub const EdidDiscoveredProtocol = @import("protocols/edid_discovered_protocol.zig").EdidDiscoveredProtocol;
26+
27+
pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").EdidActiveProtocol;
28+
29+
pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;
30+
31+
pub const RNGProtocol = @import("protocols/rng_protocol.zig").RNGProtocol;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const uefi = @import("std").os.uefi;
2+
const Event = uefi.Event;
3+
const Guid = uefi.Guid;
4+
5+
/// UEFI Specification, Version 2.8, 12.7
6+
pub 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+
30+
pub 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+
43+
pub 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+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const uefi = @import("std").os.uefi;
2+
const Guid = uefi.Guid;
3+
4+
/// UEFI Specification, Version 2.8, 12.9
5+
pub 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+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const uefi = @import("std").os.uefi;
2+
const Guid = uefi.Guid;
3+
4+
/// UEFI Specification, Version 2.8, 12.9
5+
pub 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+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const uefi = @import("std").os.uefi;
2+
const Guid = uefi.Guid;
3+
const Handle = uefi.Handle;
4+
5+
/// UEFI Specification, Version 2.8, 12.9
6+
pub 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+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const uefi = @import("std").os.uefi;
2+
const Guid = uefi.Guid;
3+
4+
/// UEFI Specification, Version 2.8, 12.9
5+
pub 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+
33+
pub 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+
42+
pub 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+
62+
pub const GraphicsPixelFormat = extern enum(u32) {
63+
PixelRedGreenBlueReserved8BitPerColor,
64+
PixelBlueGreenRedReserved8BitPerColor,
65+
PixelBitMask,
66+
PixelBltOnly,
67+
PixelFormatMax,
68+
};
69+
70+
pub const PixelBitmask = extern struct {
71+
red_mask: u32,
72+
green_mask: u32,
73+
blue_mask: u32,
74+
reserved_mask: u32,
75+
};
76+
77+
pub const GraphicsOutputBltPixel = extern struct {
78+
blue: u8,
79+
green: u8,
80+
red: u8,
81+
reserved: u8 = undefined,
82+
};
83+
84+
pub const GraphicsOutputBltOperation = extern enum(u32) {
85+
BltVideoFill,
86+
BltVideoToBltBuffer,
87+
BltBufferToVideo,
88+
BltVideoToVideo,
89+
GraphicsOutputBltOperationMax,
90+
};

0 commit comments

Comments
 (0)