From 5543589b3f2447b1ee7b22740aefe8fce6008ae6 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 10 Feb 2025 06:07:06 +0100 Subject: [PATCH] remove unnecessary casts and modify rp2040-only rom func control flow --- port/raspberrypi/rp2xxx/src/hal/rom.zig | 166 ++++++++++++------------ 1 file changed, 81 insertions(+), 85 deletions(-) diff --git a/port/raspberrypi/rp2xxx/src/hal/rom.zig b/port/raspberrypi/rp2xxx/src/hal/rom.zig index b3e012b4..ee53e146 100644 --- a/port/raspberrypi/rp2xxx/src/hal/rom.zig +++ b/port/raspberrypi/rp2xxx/src/hal/rom.zig @@ -16,15 +16,15 @@ const microzig = @import("microzig"); const chip = microzig.hal.compatibility.chip; /// Function codes to lookup public functions that provide useful RP2040 functionality -pub const Code = enum(u32) { - popcount32 = rom_table_code('P', '3'), // Only avaiable on: RP2040 - reverse32 = rom_table_code('R', '3'), // Only avaiable on: RP2040 - clz32 = rom_table_code('L', '3'), // Only avaiable on: RP2040 - ctz32 = rom_table_code('T', '3'), // Only avaiable on: RP2040 - memset = rom_table_code('M', 'S'), // Only avaiable on: RP2040 - memset4 = rom_table_code('S', '4'), // Only avaiable on: RP2040 - memcpy = rom_table_code('M', 'C'), // Only avaiable on: RP2040 - memcpy44 = rom_table_code('C', '4'), // Only avaiable on: RP2040 +pub const Code = enum(u16) { + popcount32 = rom_table_code('P', '3'), // Only avaiable on: RP2040 + reverse32 = rom_table_code('R', '3'), // Only avaiable on: RP2040 + clz32 = rom_table_code('L', '3'), // Only avaiable on: RP2040 + ctz32 = rom_table_code('T', '3'), // Only avaiable on: RP2040 + memset = rom_table_code('M', 'S'), // Only avaiable on: RP2040 + memset4 = rom_table_code('S', '4'), // Only avaiable on: RP2040 + memcpy = rom_table_code('M', 'C'), // Only avaiable on: RP2040 + memcpy44 = rom_table_code('C', '4'), // Only avaiable on: RP2040 connect_internal_flash = rom_table_code('I', 'F'), flash_exit_xip = rom_table_code('E', 'X'), flash_range_erase = rom_table_code('R', 'E'), @@ -36,7 +36,7 @@ pub const Code = enum(u32) { /// Signatures of all public bootrom functions pub const signatures = struct { /// Returns the 32 bit pointer into the ROM if found or NULL otherwise - const rom_table_lookup = fn (table: *u16, code: u32) *anyopaque; + const rom_table_lookup = fn (table: [*]u16, code: u32) *anyopaque; /// Signature for popcount32: Return a count of the number of 1 bits in value const popcount32 = fn (value: u32) u32; /// Signature for reverse32: Return the bits of value in the reverse order @@ -90,8 +90,8 @@ pub const signatures = struct { /// # Returns /// /// A 32 bit address pointing into bootrom -pub fn rom_table_code(c1: u8, c2: u8) u32 { - return @as(u32, @intCast(c1)) | (@as(u32, @intCast(c2)) << 8); +pub fn rom_table_code(c1: u8, c2: u8) u16 { + return @as(u32, c1) | (@as(u32, c2) << 8); } /// Convert a 16 bit pointer stored at the given rom address into a pointer @@ -103,8 +103,8 @@ pub fn rom_table_code(c1: u8, c2: u8) u32 { /// /// The converted pointer pub inline fn rom_hword_as_ptr(rom_addr: u32) *anyopaque { - const ptr_to_ptr = @as(*u16, @ptrFromInt(rom_addr)); - return @as(*anyopaque, @ptrFromInt(@as(usize, @intCast(ptr_to_ptr.*)))); + const ptr_to_ptr: *u16 = @ptrFromInt(rom_addr); + return @ptrFromInt(ptr_to_ptr.*); } /// Lookup a bootrom function by code (inline) @@ -116,8 +116,8 @@ pub inline fn rom_hword_as_ptr(rom_addr: u32) *anyopaque { /// /// A anyopaque pointer to the function; must be cast by the caller pub inline fn _rom_func_lookup(code: Code) *anyopaque { - const rom_table_lookup = @as(*signatures.rom_table_lookup, @ptrCast(rom_hword_as_ptr(0x18))); - const func_table = @as(*u16, @ptrCast(@alignCast(rom_hword_as_ptr(0x14)))); + const rom_table_lookup: *signatures.rom_table_lookup = @ptrCast(rom_hword_as_ptr(0x18)); + const func_table: [*]u16 = @ptrCast(@alignCast(rom_hword_as_ptr(0x14))); return rom_table_lookup(func_table, @intFromEnum(code)); } @@ -139,62 +139,69 @@ pub fn rom_func_lookup(code: Code) *anyopaque { /// Return a count of the number of 1 bits in value pub fn popcount32(value: u32) u32 { - if (chip == .RP2350) { - // RP2350, supports fast assembly version - return @popCount(value); - } - const S = struct { var f: ?*signatures.popcount32 = null; }; - if (S.f == null) S.f = @as(*signatures.popcount32, @ptrCast(_rom_func_lookup(Code.popcount32))); - return S.f.?(value); + switch (chip) { + .RP2040 => { + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.popcount32)); + return S.f.?(value); + }, + .RP2350 => return @popCount(value), + } } /// Return a count of the number of 1 bits in value pub fn reverse32(value: u32) u32 { - if (chip == .RP2350) { - // RP2350, supports fast assembly version - return @bitReverse(value); - } - const S = struct { var f: ?*signatures.reverse32 = null; }; - if (S.f == null) S.f = @as(*signatures.reverse32, @ptrCast(_rom_func_lookup(Code.reverse32))); - return S.f.?(value); + switch (chip) { + .RP2040 => { + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.reverse32)); + return S.f.?(value); + }, + // RP2350, supports fast assembly version + .RP2350 => return @bitReverse(value), + } } /// Return the number of consecutive high order 0 bits of value pub fn clz32(value: u32) u32 { - if (chip == .RP2350) { - // RP2350, supports fast assembly version - return @clz(value); - } - const S = struct { var f: ?*signatures.clz32 = null; }; - if (S.f == null) S.f = @as(*signatures.clz32, @ptrCast(_rom_func_lookup(Code.clz32))); - return S.f.?(value); + switch (chip) { + .RP2040 => { + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.clz32)); + return S.f.?(value); + }, + // RP2350, supports fast assembly version + .RP2350 => return @clz(value), + } } /// Return the number of consecutive low order 0 bits of value pub fn ctz32(value: u32) u32 { - if (chip == .RP2350) { - // RP2350, supports fast assembly version - return @ctz(value); - } - const S = struct { var f: ?*signatures.ctz32 = null; }; - if (S.f == null) S.f = @as(*signatures.ctz32, @ptrCast(_rom_func_lookup(Code.ctz32))); - return S.f.?(value); + switch (chip) { + .RP2040 => { + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.ctz32)); + return S.f.?(value); + }, + // RP2350, supports fast assembly version + .RP2350 => return @ctz(value), + } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -203,35 +210,42 @@ pub fn ctz32(value: u32) u32 { /// Sets all bytes of dest to the value c and returns ptr pub fn memset(dest: []u8, c: u8) []u8 { - if (chip == .RP2350) { - @memset(dest, c); - return dest; - } - const S = struct { var f: ?*signatures.memset = null; }; - if (S.f == null) S.f = @as(*signatures.memset, @ptrCast(_rom_func_lookup(Code.memset))); - return S.f.?(dest.ptr, c, dest.len)[0..dest.len]; + switch (chip) { + .RP2040 => { + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.memset)); + return S.f.?(dest.ptr, c, dest.len)[0..dest.len]; + }, + .RP2350 => { + @memset(dest, c); + return dest; + }, + } } /// Copies n bytes from src to dest; The number of bytes copied is the size of the smaller slice pub fn memcpy(dest: []u8, src: []const u8) []u8 { - if (chip == .RP2350) { - // For some reason @memcpy crash chip with HardFault interrupt (UNALIGNED) - std.mem.copyForwards(u8, dest, src); - return dest; - } - const S = struct { var f: ?*signatures.memcpy = null; }; - const n = if (dest.len <= src.len) dest.len else src.len; - - if (S.f == null) S.f = @as(*signatures.memcpy, @ptrCast(_rom_func_lookup(Code.memcpy))); - return S.f.?(dest.ptr, src.ptr, n)[0..n]; + switch (chip) { + .RP2040 => { + const n = @min(dest.len, src.len); + if (S.f == null) + S.f = @ptrCast(_rom_func_lookup(Code.memcpy)); + return S.f.?(dest.ptr, src.ptr, n)[0..n]; + }, + // For some reason @memcpy crash chip with HardFault interrupt (UNALIGNED) + .RP2350 => { + std.mem.copyForwards(u8, dest, src); + return dest; + }, + } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -240,10 +254,7 @@ pub fn memcpy(dest: []u8, src: []const u8) []u8 { /// Restore all QSPI pad controls to their default state, and connect the SSI to the QSPI pads pub inline fn connect_internal_flash() *signatures.connect_internal_flash { - return @as( - *signatures.connect_internal_flash, - @ptrCast(_rom_func_lookup(Code.connect_internal_flash)), - ); + return @ptrCast(_rom_func_lookup(Code.connect_internal_flash)); } /// First set up the SSI for serial-mode operations, then issue the fixed XIP exit @@ -252,10 +263,7 @@ pub inline fn connect_internal_flash() *signatures.connect_internal_flash { /// SSI to XIP mode (e.g. by a call to _flash_flush_cache). This function configures /// the SSI with a fixed SCK clock divisor of /6. pub inline fn flash_exit_xip() *signatures.flash_exit_xip { - return @as( - *signatures.flash_exit_xip, - @ptrCast(_rom_func_lookup(Code.flash_exit_xip)), - ); + return @ptrCast(_rom_func_lookup(Code.flash_exit_xip)); } /// Erase a count bytes, starting at addr (offset from start of flash). Optionally, @@ -264,29 +272,20 @@ pub inline fn flash_exit_xip() *signatures.flash_exit_xip { /// possible, for much higher erase speed. addr must be aligned to a 4096-byte sector, /// and count must be a multiple of 4096 bytes. pub inline fn flash_range_erase() *signatures.flash_range_erase { - return @as( - *signatures.flash_range_erase, - @ptrCast(_rom_func_lookup(Code.flash_range_erase)), - ); + return @ptrCast(_rom_func_lookup(Code.flash_range_erase)); } /// Program data to a range of flash addresses starting at addr (offset from the /// start of flash) and count bytes in size. addr must be aligned to a 256-byte /// boundary, and the length of data must be a multiple of 256. pub inline fn flash_range_program() *signatures.flash_range_program { - return @as( - *signatures.flash_range_program, - @ptrCast(_rom_func_lookup(Code.flash_range_program)), - ); + return @ptrCast(_rom_func_lookup(Code.flash_range_program)); } /// Flush and enable the XIP cache. Also clears the IO forcing on QSPI CSn, so that /// the SSI can drive the flash chip select as normal. pub inline fn flash_flush_cache() *signatures.flash_flush_cache { - return @as( - *signatures.flash_flush_cache, - @ptrCast(_rom_func_lookup(Code.flash_flush_cache)), - ); + return @ptrCast(_rom_func_lookup(Code.flash_flush_cache)); } /// Configure the SSI to generate a standard 03h serial read command, with 24 address @@ -296,8 +295,5 @@ pub inline fn flash_flush_cache() *signatures.flash_flush_cache { /// visible to the debug host, without having to know exactly what kind of flash /// device is connected. pub inline fn flash_enter_cmd_xip() *signatures.flash_enter_cmd_xip { - return @as( - *signatures.flash_enter_cmd_xip, - @ptrCast(_rom_func_lookup(Code.flash_enter_cmd_xip)), - ); + return @ptrCast(_rom_func_lookup(Code.flash_enter_cmd_xip)); }