| ... | @@ -799,44 +799,53 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr | ... | @@ -799,44 +799,53 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr |
| 799 | .uefi => { | 799 | .uefi => { |
| 800 | const uefi = std.os.uefi; | 800 | const uefi = std.os.uefi; |
| 801 | | 801 | |
| | 802 | const Formatter = struct { |
| | 803 | pub fn fmt(exit_msg: []const u8, out: []u16) ![:0]u16 { |
| | 804 | var u8_buf: [256]u8 = undefined; |
| | 805 | const slice = try std.fmt.bufPrint(&u8_buf, "err: {s}\r\n", .{exit_msg}); |
| | 806 | // We pass len - 1 because we need to add a null terminator after |
| | 807 | const len = try std.unicode.utf8ToUtf16Le(out[0 .. out.len - 1], slice); |
| | 808 | |
| | 809 | out[len] = 0; |
| | 810 | |
| | 811 | return out[0..len :0]; |
| | 812 | } |
| | 813 | }; |
| | 814 | |
| 802 | const ExitData = struct { | 815 | const ExitData = struct { |
| 803 | pub fn create_exit_data(exit_msg: []const u8, exit_size: *usize) ![*:0]u16 { | 816 | pub fn create_exit_data(exit_msg: [:0]u16, exit_size: *usize) ![*:0]u16 { |
| 804 | // Need boot services for pool allocation | 817 | // Need boot services for pool allocation |
| 805 | if (uefi.system_table.boot_services == null) { | 818 | if (uefi.system_table.boot_services == null) { |
| 806 | return error.BootServicesUnavailable; | 819 | return error.BootServicesUnavailable; |
| 807 | } | 820 | } |
| 808 | | 821 | |
| 809 | // ExitData buffer must be allocated using boot_services.allocatePool | 822 | // ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220) |
| 810 | var utf16: []u16 = try uefi.raw_pool_allocator.alloc(u16, 256); | 823 | const exit_data: []u16 = try uefi.raw_pool_allocator.alloc(u16, exit_msg.len + 1); |
| 811 | errdefer uefi.raw_pool_allocator.free(utf16); | | |
| 812 | | 824 | |
| 813 | if (exit_msg.len > 255) { | 825 | @memcpy(exit_data[0 .. exit_msg.len + 1], exit_msg[0 .. exit_msg.len + 1]); |
| 814 | return error.MessageTooLong; | 826 | exit_size.* = exit_msg.len + 1; |
| 815 | } | | |
| 816 | | | |
| 817 | var fmt: [256]u8 = undefined; | | |
| 818 | const slice = try std.fmt.bufPrint(&fmt, "\r\nerr: {s}\r\n", .{exit_msg}); | | |
| 819 | const len = try std.unicode.utf8ToUtf16Le(utf16, slice); | | |
| 820 | | | |
| 821 | utf16[len] = 0; | | |
| 822 | | 827 | |
| 823 | exit_size.* = 256; | 828 | return @as([*:0]u16, @ptrCast(exit_data.ptr)); |
| 824 | | | |
| 825 | return @as([*:0]u16, @ptrCast(utf16.ptr)); | | |
| 826 | } | 829 | } |
| 827 | }; | 830 | }; |
| 828 | | 831 | |
| | 832 | var buf: [256]u16 = undefined; |
| | 833 | const utf16 = Formatter.fmt(msg, &buf) catch null; |
| | 834 | |
| 829 | var exit_size: usize = 0; | 835 | var exit_size: usize = 0; |
| 830 | const exit_data = ExitData.create_exit_data(msg, &exit_size) catch null; | 836 | const exit_data = if (utf16) |u| |
| | 837 | ExitData.create_exit_data(u, &exit_size) catch null |
| | 838 | else |
| | 839 | null; |
| 831 | | 840 | |
| 832 | if (exit_data) |data| { | 841 | if (utf16) |str| { |
| 833 | // Output to both std_err and con_out, as std_err is easier | 842 | // Output to both std_err and con_out, as std_err is easier |
| 834 | // to read in stuff like QEMU at times, but, unlike con_out, | 843 | // to read in stuff like QEMU at times, but, unlike con_out, |
| 835 | // isn't visible on actual hardware if directly booted into | 844 | // isn't visible on actual hardware if directly booted into |
| 836 | inline for ([_]?*uefi.protocol.SimpleTextOutput{ uefi.system_table.std_err, uefi.system_table.con_out }) |o| { | 845 | inline for ([_]?*uefi.protocol.SimpleTextOutput{ uefi.system_table.std_err, uefi.system_table.con_out }) |o| { |
| 837 | if (o) |out| { | 846 | if (o) |out| { |
| 838 | _ = out.setAttribute(uefi.protocol.SimpleTextOutput.red); | 847 | _ = out.setAttribute(uefi.protocol.SimpleTextOutput.red); |
| 839 | _ = out.outputString(data); | 848 | _ = out.outputString(str); |
| 840 | _ = out.setAttribute(uefi.protocol.SimpleTextOutput.white); | 849 | _ = out.setAttribute(uefi.protocol.SimpleTextOutput.white); |
| 841 | } | 850 | } |
| 842 | } | 851 | } |