Skip to content

Commit fa13c6f

Browse files
committed
implement patching
1 parent a74054f commit fa13c6f

File tree

3 files changed

+171
-6
lines changed

3 files changed

+171
-6
lines changed

port/raspberrypi/rp2xxx/src/hal/random.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ pub const Ascon = struct {
2828

2929
pub fn init() @This() {
3030
// Ensure that the system clocks run from the XOSC and/or PLLs
31-
const ref_src = peripherals.CLOCKS.CLK_REF_CTRL.read().SRC.value;
32-
const sys_clk_src = peripherals.CLOCKS.CLK_SYS_CTRL.read().SRC.value;
33-
const aux_src = peripherals.CLOCKS.CLK_SYS_CTRL.read().AUXSRC.value;
31+
const ref_src = peripherals.CLOCKS.CLK_REF_CTRL.read().SRC;
32+
const sys_clk_src = peripherals.CLOCKS.CLK_SYS_CTRL.read().SRC;
33+
const aux_src = peripherals.CLOCKS.CLK_SYS_CTRL.read().AUXSRC;
3434
assert((ref_src != .rosc_clksrc_ph and sys_clk_src == .clk_ref) or
3535
(sys_clk_src == .clksrc_clk_sys_aux and aux_src != .rosc_clksrc));
3636

@@ -68,7 +68,7 @@ pub const Ascon = struct {
6868
/// for security systems because it can be compromised, but it may be useful
6969
/// in less critical applications.
7070
fn rosc(buffer: []u8) void {
71-
const rosc_state = peripherals.ROSC.CTRL.read().ENABLE.value;
71+
const rosc_state = peripherals.ROSC.CTRL.read().ENABLE;
7272
// Enable the ROSC so it generates random bits for us
7373
peripherals.ROSC.CTRL.modify(.{ .ENABLE = .ENABLE });
7474
defer peripherals.ROSC.CTRL.modify(.{ .ENABLE = rosc_state });

port/raspberrypi/rp2xxx/src/hal/usb.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ pub const vendor = usb.vendor;
1616
pub const templates = usb.templates.DescriptorsConfigTemplates;
1717
pub const utils = usb.UsbUtils;
1818

19-
const EndpointType = microzig.chip.types.USB_CTRL.EndpointType;
20-
2119
const rom = @import("rom.zig");
2220
const resets = @import("resets.zig");
2321

@@ -53,6 +51,7 @@ pub const utf8ToUtf16Le = usb.utf8Toutf16Le;
5351

5452
const BufferControlMmio = microzig.mmio.Mmio(@TypeOf(microzig.chip.peripherals.USB_DPRAM.EP0_IN_BUFFER_CONTROL).underlying_type);
5553
const EndpointControlMimo = microzig.mmio.Mmio(@TypeOf(peripherals.USB_DPRAM.EP1_IN_CONTROL).underlying_type);
54+
const EndpointType = microzig.chip.types.peripherals.USB_DPRAM.EndpointType;
5655

5756
const HardwareEndpoint = struct {
5857
configured: bool,

tools/regz/src/Database.zig

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,143 @@ pub fn create_struct(db: *Database, opts: CreateStructOptions) !StructID {
18391839
return struct_id;
18401840
}
18411841

1842+
/// Returns the last part of the reference, and the beginning part of the
1843+
/// reference
1844+
fn get_ref_last_component(ref: []const u8) !struct { []const u8, ?[]const u8 } {
1845+
var it = std.mem.splitScalar(u8, ref, '.');
1846+
var last: ?[]const u8 = null;
1847+
while (it.next()) |comp| {
1848+
last = comp;
1849+
}
1850+
1851+
log.debug(" last={?s}", .{last});
1852+
1853+
return if (last) |l|
1854+
if (l.len == ref.len)
1855+
.{ l, null }
1856+
else
1857+
.{ l, ref[0 .. ref.len - l.len - 1] }
1858+
else
1859+
error.EmptyRef;
1860+
}
1861+
1862+
fn strip_ref_prefix(expected_prefix: []const u8, ref: []const u8) ![]const u8 {
1863+
var prefix_it = std.mem.splitScalar(u8, expected_prefix, '.');
1864+
var ref_it = std.mem.splitScalar(u8, ref, '.');
1865+
1866+
while (prefix_it.next()) |prefix_comp| {
1867+
const ref_comp = ref_it.next() orelse return error.RefTooShort;
1868+
1869+
if (!std.mem.eql(u8, prefix_comp, ref_comp))
1870+
return error.RefPrefixNotExpected;
1871+
}
1872+
1873+
const index = ref_it.index orelse return error.RefTooShort;
1874+
return ref[index..];
1875+
}
1876+
1877+
pub fn get_struct_ref(db: *Database, ref: []const u8) !StructID {
1878+
log.debug("get_struct_ref: ref={s}", .{ref});
1879+
var arena = std.heap.ArenaAllocator.init(db.gpa);
1880+
defer arena.deinit();
1881+
1882+
const base_ref = try strip_ref_prefix("types.peripherals", ref);
1883+
log.debug(" base_ref={s}", .{base_ref});
1884+
const struct_name, const rest_ref = try get_ref_last_component(base_ref);
1885+
log.debug(" rest_ref={?s} struct_name={s}", .{ rest_ref, struct_name });
1886+
1887+
return if (rest_ref) |rest| blk: {
1888+
var it = std.mem.splitScalar(u8, rest, '.');
1889+
const peripheral_name = it.next() orelse return error.NoPeripheral;
1890+
log.debug(" peripheral_name={s}", .{peripheral_name});
1891+
const peripheral_id = try db.get_peripheral_by_name(peripheral_name) orelse return error.NoPeripheral;
1892+
var struct_id = try db.get_peripheral_struct(peripheral_id);
1893+
if (it.index == null) {
1894+
log.debug("struct_name={s}", .{struct_name});
1895+
return if (std.mem.eql(u8, struct_name, peripheral_name))
1896+
struct_id
1897+
else
1898+
error.NoPeripheral;
1899+
}
1900+
1901+
break :blk while (it.next()) |name| {
1902+
const struct_decl = try db.get_struct_decl_by_name(arena.allocator(), struct_id, name);
1903+
log.debug(" struct_decl.name={s}", .{struct_decl.name});
1904+
if (it.index == null and std.mem.eql(u8, struct_name, struct_decl.name))
1905+
break struct_decl.struct_id;
1906+
1907+
struct_id = struct_decl.struct_id;
1908+
} else error.RefNotFound;
1909+
} else blk: {
1910+
log.debug(" just getting peripheral struct: peripheral_name={s}", .{struct_name});
1911+
// just getting a peripheral
1912+
const peripheral_id = try db.get_peripheral_by_name(struct_name) orelse return error.NoPeripheral;
1913+
break :blk try db.get_peripheral_struct(peripheral_id);
1914+
};
1915+
}
1916+
1917+
pub fn get_enum_ref(db: *Database, ref: []const u8) !EnumID {
1918+
var arena = std.heap.ArenaAllocator.init(db.gpa);
1919+
defer arena.deinit();
1920+
1921+
log.debug("get_enum_ref: ref={s}", .{ref});
1922+
1923+
const enum_name, const struct_ref = try get_ref_last_component(ref);
1924+
1925+
// An enum that can be referenced has a struct as a parent
1926+
const struct_id = try db.get_struct_ref(struct_ref orelse return error.InvalidRef);
1927+
1928+
// TODO: create a `get_enum_id_by_name()` function
1929+
const e = try db.get_enum_by_name(arena.allocator(), struct_id, enum_name);
1930+
return e.id;
1931+
}
1932+
1933+
pub fn get_register_ref(db: *Database, ref: []const u8) !RegisterID {
1934+
var arena = std.heap.ArenaAllocator.init(db.gpa);
1935+
defer arena.deinit();
1936+
1937+
log.debug("get_register_ref: ref={s}", .{ref});
1938+
1939+
const register_name, const struct_ref = try get_ref_last_component(ref);
1940+
const struct_id = try db.get_struct_ref(struct_ref orelse return error.InvalidRef);
1941+
const register = try db.get_register_by_name(arena.allocator(), struct_id, register_name);
1942+
return register.id;
1943+
}
1944+
1945+
pub fn set_register_field_enum_id(db: *Database, register_id: RegisterID, field_name: []const u8, enum_id: EnumID) !void {
1946+
try db.exec(
1947+
\\UPDATE struct_fields
1948+
\\SET enum_id = ?
1949+
\\WHERE struct_id = (
1950+
\\ SELECT struct_id
1951+
\\ FROM registers
1952+
\\ WHERE id = ?
1953+
\\)
1954+
\\AND name = ?;
1955+
, .{
1956+
.enum_id = enum_id,
1957+
.register_id = register_id,
1958+
.name = field_name,
1959+
});
1960+
1961+
log.debug("set_register_field_enum_id: register_id={} field_name={s} enum_id={}", .{
1962+
register_id,
1963+
field_name,
1964+
enum_id,
1965+
});
1966+
}
1967+
1968+
pub fn cleanup_unused_enums(db: *Database) !void {
1969+
try db.exec(
1970+
\\DELETE FROM enums
1971+
\\WHERE id NOT IN (
1972+
\\ SELECT DISTINCT enum_id
1973+
\\ FROM struct_fields
1974+
\\ WHERE enum_id IS NOT NULL
1975+
\\)
1976+
, .{});
1977+
}
1978+
18421979
pub fn apply_patch(db: *Database, ndjson: []const u8) !void {
18431980
var list = std.ArrayList(std.json.Parsed(Patch)).init(db.gpa);
18441981
defer {
@@ -1852,6 +1989,35 @@ pub fn apply_patch(db: *Database, ndjson: []const u8) !void {
18521989
errdefer p.deinit();
18531990
try list.append(p);
18541991
}
1992+
1993+
for (list.items) |patch| {
1994+
switch (patch.value) {
1995+
.add_enum => |add_enum| {
1996+
const struct_id = try db.get_struct_ref(add_enum.parent);
1997+
1998+
const enum_id = try db.create_enum(struct_id, .{
1999+
.name = add_enum.@"enum".name,
2000+
.description = add_enum.@"enum".description,
2001+
.size_bits = add_enum.@"enum".bitsize,
2002+
});
2003+
2004+
for (add_enum.@"enum".fields) |enum_field| {
2005+
try db.add_enum_field(enum_id, .{
2006+
.name = enum_field.name,
2007+
.description = enum_field.description,
2008+
.value = enum_field.value,
2009+
});
2010+
}
2011+
},
2012+
.set_enum_type => |set_enum_type| {
2013+
const enum_id = try db.get_enum_ref(set_enum_type.to);
2014+
const field_name, const register_ref = try get_ref_last_component(set_enum_type.of);
2015+
const register_id = try db.get_register_ref(register_ref orelse return error.InvalidRef);
2016+
try db.set_register_field_enum_id(register_id, field_name, enum_id);
2017+
try db.cleanup_unused_enums();
2018+
},
2019+
}
2020+
}
18552021
}
18562022

18572023
pub fn to_zig(db: *Database, out_writer: anytype) !void {

0 commit comments

Comments
 (0)