Skip to content

Commit 187a6d1

Browse files
committed
Merge branch 'nrdmn-uefi'
closes #2944
2 parents eb7d36a + c15e464 commit 187a6d1

23 files changed

+1028
-16
lines changed

src/codegen.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,9 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
516516
}
517517
}
518518
if (g->have_stack_probing && !fn->def_scope->safety_off) {
519-
addLLVMFnAttrStr(llvm_fn, "probe-stack", "__zig_probe_stack");
519+
addLLVMFnAttrStr(fn->llvm_value, "probe-stack", "__zig_probe_stack");
520+
} else {
521+
addLLVMFnAttrStr(fn->llvm_value, "no-stack-arg-probe", "");
520522
}
521523
} else {
522524
maybe_import_dll(g, llvm_fn, linkage);
@@ -9081,10 +9083,6 @@ static bool want_startup_code(CodeGen *g) {
90819083
if (g->is_test_build)
90829084
return false;
90839085

9084-
// start code does not handle UEFI target
9085-
if (g->zig_target->os == OsUefi)
9086-
return false;
9087-
90889086
// WASM freestanding can still have an entry point but other freestanding targets do not.
90899087
if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target))
90909088
return false;
@@ -9094,8 +9092,12 @@ static bool want_startup_code(CodeGen *g) {
90949092
return false;
90959093

90969094
// If there is a pub main in the root source file, that means we need start code.
9097-
if (g->have_pub_main)
9095+
if (g->have_pub_main) {
90989096
return true;
9097+
} else {
9098+
if (g->zig_target->os == OsUefi)
9099+
return false;
9100+
}
90999101

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

src/target.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
11101110
}
11111111

11121112
bool target_allows_addr_zero(const ZigTarget *target) {
1113-
return target->os == OsFreestanding;
1113+
return target->os == OsFreestanding || target->os == OsUefi;
11141114
}
11151115

11161116
const char *target_o_file_ext(const ZigTarget *target) {
@@ -1535,12 +1535,12 @@ bool target_supports_fpic(const ZigTarget *target) {
15351535
}
15361536

15371537
bool target_supports_stack_probing(const ZigTarget *target) {
1538-
return target->os != OsWindows && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64);
1538+
return target->os != OsWindows && target->os != OsUefi && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64);
15391539
}
15401540

15411541
bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
15421542
// This function returns whether non-pic code is completely invalid on the given target.
1543-
return target->os == OsWindows || target_os_requires_libc(target->os) ||
1543+
return target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) ||
15441544
(linking_libc && target_is_glibc(target));
15451545
}
15461546

std/build.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,13 @@ pub const Target = union(enum) {
11751175
};
11761176
}
11771177

1178+
pub fn isUefi(self: Target) bool {
1179+
return switch (self.getOs()) {
1180+
.uefi => true,
1181+
else => false,
1182+
};
1183+
}
1184+
11781185
pub fn isWasm(self: Target) bool {
11791186
return switch (self.getArch()) {
11801187
.wasm32, .wasm64 => true,
@@ -1490,7 +1497,7 @@ pub const LibExeObjStep = struct {
14901497
}
14911498

14921499
pub fn producesPdbFile(self: *LibExeObjStep) bool {
1493-
if (!self.target.isWindows()) return false;
1500+
if (!self.target.isWindows() and !self.target.isUefi()) return false;
14941501
if (self.strip) return false;
14951502
return self.isDynamicLibrary() or self.kind == .Exe;
14961503
}
@@ -1587,7 +1594,7 @@ pub const LibExeObjStep = struct {
15871594
/// Unless setOutputDir was called, this function must be called only in
15881595
/// the make step, from a step that has declared a dependency on this one.
15891596
pub fn getOutputPdbPath(self: *LibExeObjStep) []const u8 {
1590-
assert(self.target.isWindows());
1597+
assert(self.target.isWindows() or self.target.isUefi());
15911598
return fs.path.join(
15921599
self.builder.allocator,
15931600
[_][]const u8{ self.output_dir.?, self.out_pdb_filename },

std/os.zig

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ pub fn abort() noreturn {
172172
system.abort();
173173
}
174174
if (builtin.os == .uefi) {
175-
// TODO there must be a better thing to do here than loop forever
176-
while (true) {}
175+
exit(0); // TODO choose appropriate exit code
177176
}
178177

179178
raise(SIGABRT) catch {};
@@ -245,6 +244,15 @@ pub fn exit(status: u8) noreturn {
245244
if (linux.is_the_target and !builtin.single_threaded) {
246245
linux.exit_group(status);
247246
}
247+
if (uefi.is_the_target) {
248+
// exit() is only avaliable if exitBootServices() has not been called yet.
249+
// This call to exit should not fail, so we don't care about its return value.
250+
if (uefi.system_table.boot_services) |bs| {
251+
_ = bs.exit(uefi.handle, status, 0, null);
252+
}
253+
// If we can't exit, reboot the system instead.
254+
uefi.system_table.runtime_services.resetSystem(uefi.tables.ResetType.ResetCold, status, 0, null);
255+
}
248256
system.exit(status);
249257
}
250258

std/os/uefi.zig

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,45 @@
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: packed struct {
33+
_pad1: u6,
34+
in_daylight: bool,
35+
adjust_daylight: bool,
36+
},
37+
_pad2: u8,
38+
39+
pub const unspecified_timezone: i16 = 0x7ff;
40+
};
41+
pub const TimeCapabilities = extern struct {
42+
resolution: u32,
43+
accuracy: u32,
44+
sets_to_zero: bool,
45+
};

std/os/uefi/protocols.zig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
pub const EdidOverrideProtocolAttributes = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocolAttributes;
31+
32+
pub const RNGProtocol = @import("protocols/rng_protocol.zig").RNGProtocol;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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: packed struct {
38+
supports_alt_active: bool,
39+
supports_pressure_as_z: bool,
40+
_pad1: u30,
41+
},
42+
};
43+
44+
pub const AbsolutePointerState = extern struct {
45+
current_x: u64 = undefined,
46+
current_y: u64 = undefined,
47+
current_z: u64 = undefined,
48+
active_buttons: packed struct {
49+
touch_active: bool,
50+
alt_active: bool,
51+
_pad1: u30,
52+
} = undefined,
53+
};
Lines changed: 17 additions & 0 deletions
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+
};
Lines changed: 17 additions & 0 deletions
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+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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, Handle, *u32, *usize, *?[*]u8) usize,
8+
9+
/// attributes must be align(4)
10+
pub fn getEdid(self: *const EdidOverrideProtocol, handle: Handle, attributes: *EdidOverrideProtocolAttributes, edid_size: *usize, edid: *?[*]u8) usize {
11+
return self._get_edid(self, handle, attributes, edid_size, edid);
12+
}
13+
14+
pub const guid align(8) = Guid{
15+
.time_low = 0x48ecb431,
16+
.time_mid = 0xfb72,
17+
.time_high_and_version = 0x45c0,
18+
.clock_seq_high_and_reserved = 0xa9,
19+
.clock_seq_low = 0x22,
20+
.node = [_]u8{ 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5 },
21+
};
22+
};
23+
24+
pub const EdidOverrideProtocolAttributes = packed struct {
25+
dont_override: bool,
26+
enable_hot_plug: bool,
27+
_pad1: u30,
28+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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 = undefined,
44+
horizontal_resolution: u32 = undefined,
45+
vertical_resolution: u32 = undefined,
46+
pixel_format: GraphicsPixelFormat = undefined,
47+
pixel_information: PixelBitmask = undefined,
48+
pixels_per_scan_line: u32 = undefined,
49+
};
50+
51+
pub const GraphicsPixelFormat = extern enum(u32) {
52+
PixelRedGreenBlueReserved8BitPerColor,
53+
PixelBlueGreenRedReserved8BitPerColor,
54+
PixelBitMask,
55+
PixelBltOnly,
56+
PixelFormatMax,
57+
};
58+
59+
pub const PixelBitmask = extern struct {
60+
red_mask: u32,
61+
green_mask: u32,
62+
blue_mask: u32,
63+
reserved_mask: u32,
64+
};
65+
66+
pub const GraphicsOutputBltPixel = extern struct {
67+
blue: u8,
68+
green: u8,
69+
red: u8,
70+
reserved: u8 = undefined,
71+
};
72+
73+
pub const GraphicsOutputBltOperation = extern enum(u32) {
74+
BltVideoFill,
75+
BltVideoToBltBuffer,
76+
BltBufferToVideo,
77+
BltVideoToVideo,
78+
GraphicsOutputBltOperationMax,
79+
};

0 commit comments

Comments
 (0)