Uh oh!
There was an error while loading. Please reload this page.
Improvements for UEFI - #19486
Conversation
c6294b0 to
7d817aaCompareCorrect me if I'm wrong, but my assumption would be that UEFI should be using WTF-16 <-> WTF-8 conversion instead of UTF-16 <-> UTF-8 (see #19005 for context). (links to any resources about these sorts of UEFI details would be appreciated if anyone has them handy) Either way, the doc comments of either the |
RossComputerGuy
commented
Mar 30, 2024
@squeek502 The UEFI spec mentions UTF-16 and UTF-8 but not WTF-8 or WTF-16. |
llogick
commented
Mar 30, 2024
https://uefi.org/specs/UEFI/2.10/02_Overview.html?highlight=char16#data-types |
RossComputerGuy
commented
Mar 30, 2024
https://www.ibm.com/docs/en/i/7.4?topic=unicode-ucs-2-its-relationship-utf-16
So should we implement UCS-2 specific functions in the Unicode module or stick with the UTF-16 methods? |
The situation with UEFI sounds like it is the same as the situation with Windows (arbitrary sequences of (WTF-16 is an informal name for potentially ill-formed UTF-16, or UTF-16 with potentially unpaired surrogates). See the motivation section of the WTF-8 spec: https://simonsapin.github.io/wtf-8/#motivation and the description of #19005 |
RossComputerGuy
commented
Mar 30, 2024
Yeah, well UEFI takes similarities from Windows so no surprise there.
Has anyone tried WTF-8/16 encodings on UEFI? I've only seen UTF-8/16. |
From the linked specs, UEFI uses UCS-2 which is essentially just sequences of WTF-16 is functionally equivalent to UCS-2 for our purposes, and WTF-8 is a superset of UTF-8 that allows the codepoints If you'd like to test whether or not WTF-16 is needed, the way to go would be to create a file with any value from |
RossComputerGuy
commented
Mar 30, 2024
Well, I can give it a try. I'm currently porting over @truemedian's UEFI stuff from their own fork so this PR will include file system operations. |
RossComputerGuy
commented
Mar 31, 2024
I've merged @truemedian's Zig branch for the uefi-rework into this one and added a couple of improvements along the way. |
3b55c17 to
23d4f64CompareRossComputerGuy
commented
Mar 31, 2024
44da3f7 to
17a8713Compare| } | ||
| /// Returns the time in nanoseconds since 1900-01-01 00:00:00. | ||
| pub fn toEpochNanoseconds(self: Time) u128 { |
There was a problem hiding this comment.
This method is causing an integer overflow panic.
conststd=@import("std");
pubfnmain() !void {
conststat=trystd.posix.fstat(std.fs.cwd().fd);
std.debug.print("{} ", .{stat.atim});
std.debug.print("{}\n", .{stat.atime()});
std.debug.print("{} ", .{stat.mtim});
std.debug.print("{}\n", .{stat.mtime()});
std.debug.print("{} ", .{stat.ctim});
std.debug.print("{}\n", .{stat.ctime()});
}os.uefi.bits.Time{ .year = 2024, .month = 3, .day = 31, .hour = 0, .minute = 0, .second = 0, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1282{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } } 3920832000
os.uefi.bits.Time{ .year = 2024, .month = 3, .day = 31, .hour = 22, .minute = 28, .second = 8, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1282{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } } 3920912888
os.uefi.bits.Time{ .year = 1980, .month = 0, .day = 0, .hour = 0, .minute = 0, .second = 0, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1282{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } } panic: integer overflow 3186494919
There was a problem hiding this comment.
Correction: this is with toEpochSeconds and not toEpochNanoseconds
There was a problem hiding this comment.
My suspicion would be days += self.day - 1;. Based on the doc comment for day, it should be between 1 and 31, but you're passing a struct with .day = 0, so something looks to be out of sync.
There was a problem hiding this comment.
Yeah, I am not sure why it is like that. My implementation didn't do this (the one currently in upstream). This comes from @truemedian's branch which I incorporated.
There was a problem hiding this comment.
Going further with this test program, I get this output:
os.uefi.bits.Time{ .year = 2024, .month = 3, .day = 31, .hour = 0, .minute = 0, .second = 0, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1283{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } } 3920832000
os.uefi.bits.Time{ .year = 2024, .month = 3, .day = 31, .hour = 22, .minute = 51, .second = 46, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1283{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } } 3920914306
os.uefi.bits.Time{ .year = 1980, .month = 0, .day = 0, .hour = 0, .minute = 0, .second = 0, .nanosecond = 0, .timezone = 2047, .daylight = os.uefi.bits.Time.Time__struct_1283{ ._pad1 = 0, .in_daylight = false, .adjust_daylight = false } }
Days in years: 29219
Days in months: 29219
panic: integer overflow 3186465173
Panicked during a panic. Aborting
conststd=@import("std");
fntoEpochSeconds(self: std.os.uefi.bits.Time) u64 {
varyear: u16=1900;
vardays: u32=0;
while (year<self.year) : (year+=1) {
days+=std.time.epoch.getDaysInYear(year);
}
std.debug.print("\nDays in years: {}\n", .{days});
varmonth: u8=1;
while (month<self.month) : (month+=1) {
constleap_kind: std.time.epoch.YearLeapKind=if (std.time.epoch.isLeapYear(self.year)) .leapelse.not_leap;
days+=std.time.epoch.getDaysInMonth(leap_kind, @enumFromInt(month));
}
std.debug.print("\nDays in months: {}\n", .{days});
days+=self.day-1;
std.debug.print("Days: {}\n", .{days});
consthours=@as(u32, self.hour) *std.time.s_per_hour;
std.debug.print("Hours: {}\n", .{hours});
constminutes=@as(u16, self.minute) *std.time.s_per_min;
std.debug.print("Minutes: {}\n", .{minutes});
constdays_as_sec=days*std.time.s_per_day;
std.debug.print("Days as seconds: {}\n", .{days_as_sec});
returndays_as_sec+hours+minutes+self.second;
}
pubfnmain() !void {
conststat=trystd.posix.fstat(std.fs.cwd().fd);
std.debug.print("{} ", .{stat.atim});
std.debug.print("{}\n", .{stat.atime()});
std.debug.print("{} ", .{stat.mtim});
std.debug.print("{}\n", .{stat.mtime()});
std.debug.print("{} ", .{stat.ctim});
std.debug.print("{}\n", .{toEpochSeconds(stat.ctim)});
}So I think @ianprime0509 is right on this one.
There was a problem hiding this comment.
@RossComputerGuy You don't even have to @intCast() to convert from u64 to u128:
pubfnmain() void {
constv: u64=std.math.maxInt(u64);
std.debug.print("{d}\n", .{ @as(u128, v) });
}If you give a full stack trace I can help debug.
You may be able to avoid some integer casts if you refactor all your second and subsecond methods to be in terms of nanoseconds.
There was a problem hiding this comment.
If you give a full stack trace I can help debug.
Word of warning: we still cannot produce stack traces on UEFI, we're missing the information required to walk the stack backwards.
There was a problem hiding this comment.
I'm not even int casting. @nektro has tried helping me with this problem as well on Discord. I traced the issue to the @as(u128, v) call with print calls.
There was a problem hiding this comment.
Hm, that's very strange. Is there a way to run behavior and stdlib tests on UEFI?
There was a problem hiding this comment.
Kinda, however there are more important issues we need to get through first. Like zig actually being able to find itself in UEFI.
a9bc276 to
d877e8aCompare…ports and move to bits.zig
* don't even attempt stack unwinding on UEFI, no unwinding information is available yet. std.pdb: include the address *after* the last instruction as part of the function. This is required when using `@returnAddress` on a tailcall function. This is possible with panics.
d877e8a to
ca28a79Compared1723fc to
4ec3b02Compare7b079e7 to
471889cCompareRossComputerGuy
commented
Apr 19, 2024
Some progress has been made. |
d7dfe19 to
b3a24d5Compareb3a24d5 to
6473f74Compare6473f74 to
ab302cbCompareandrewrk
commented
Jun 8, 2024
draft status for > 30 days |

Just run:
zig build -Dtarget=x86_64-uefi -Dsingle-threaded --zig-lib-dir libThis PR introduces several improvements for UEFI, so far:
std.process.ArgvIteratorsupportstd.process.totalSystemMemorysupportPlanned:
std.process.EnvMapsupport