some predefined registers for Cortex M (#190)

wch-ch32v003
Matt Knight 4 months ago committed by GitHub
parent 095630e1d1
commit ea809c6b7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -130,6 +130,7 @@ pub fn add_firmware(
.target = mz.host_build.resolveTargetQuery(chip.cpu.target),
.linkage = .static,
.root_source_file = .{ .cwd_relative = mz.microzig_core.builder.pathFromRoot("src/start.zig") },
.strip = options.strip,
}),
.target = options.target,
.output_files = Firmware.OutputFileMap.init(host_build.allocator),
@ -358,6 +359,8 @@ pub const FirmwareOptions = struct {
/// If set, overrides the `linker_script` property of the target.
linker_script: ?LazyPath = null,
strip: bool = false,
};
/// Configuration options for firmware installation.

@ -29,7 +29,7 @@ pub const cpus = struct {
pub const cortex_m0 = MicroZig.Cpu{
.name = "ARM Cortex-M0",
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex-m.zig" },
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex_m.zig" },
.target = std.zig.CrossTarget{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m0 },
@ -40,7 +40,7 @@ pub const cpus = struct {
pub const cortex_m0plus = MicroZig.Cpu{
.name = "ARM Cortex-M0+",
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex-m.zig" },
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex_m.zig" },
.target = std.zig.CrossTarget{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m0plus },
@ -51,7 +51,7 @@ pub const cpus = struct {
pub const cortex_m3 = MicroZig.Cpu{
.name = "ARM Cortex-M3",
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex-m.zig" },
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex_m.zig" },
.target = std.zig.CrossTarget{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m3 },
@ -62,7 +62,7 @@ pub const cpus = struct {
pub const cortex_m4 = MicroZig.Cpu{
.name = "ARM Cortex-M4",
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex-m.zig" },
.root_source_file = .{ .path = build_root ++ "/src/cpus/cortex_m.zig" },
.target = std.zig.CrossTarget{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },

@ -3,28 +3,49 @@ const microzig = @import("microzig");
const mmio = microzig.mmio;
const root = @import("root");
pub const regs = struct {
// Interrupt Control and State Register
pub const ICSR: *volatile mmio.Mmio(packed struct {
VECTACTIVE: u9,
reserved0: u2,
RETTOBASE: u1,
VECTPENDING: u9,
reserved1: u1,
ISRPENDING: u1,
ISRPREEMPT: u1,
reserved2: u1,
PENDSTCLR: u1,
PENDSTSET: u1,
PENDSVCLR: u1,
PENDSVSET: u1,
reserved3: u2,
NMIPENDSET: u1,
}) = @ptrFromInt(0xE000ED04);
const scs_base = 0xE000E000;
const itm_base = 0xE0000000;
const dwt_base = 0xE0001000;
const tpi_base = 0xE0040000;
const coredebug_base = 0xE000EDF0;
const systick_base = scs_base + 0x0010;
const nvic_base = scs_base + 0x0100;
const scb_base = scs_base + 0x0D00;
const mpu_base = scs_base + 0x0D90;
const Core = enum {
@"ARM Cortex-M0",
@"ARM Cortex-M0+",
@"ARM Cortex-M3",
@"ARM Cortex-M4",
};
const core: type = blk: {
const cortex_m = std.meta.stringToEnum(microzig.config.cpu_name) orelse @panic(std.fmt.comptimePrint("Unrecognized Cortex-M core name: {s}", .{microzig.config.cpu_name}));
break :blk switch (cortex_m) {
.@"ARM Cortex-M0" => @import("cortex_m/m0"),
.@"ARM Cortex-M0+" => @import("cortex_m/m0plus.zig"),
.@"ARM Cortex-M3" => @import("cortex_m/m3.zig"),
.@"ARM Cortex-M4" => @import("cortex_m/m4.zig"),
};
};
const properties = microzig.chip.properties;
// TODO: will have to standardize this with regz code generation
const mpu_present = @hasDecl(properties, "__MPU_PRESENT") and std.mem.eql(u8, properties.__MPU_PRESENT, "1");
/// System Control Block (SCB)
pub const scb: *volatile core.SystemControlBlock = @ptrFromInt(scb_base);
/// Nested Vector Interrupt Controller (NVIC)
pub const nvic: *volatile core.NestedVectorInterruptController = @ptrFromInt(nvic_base);
/// Memory Protection Unit (MPU)
pub const mpu: *volatile core.MemoryProtectionUnit = if (mpu_present)
@ptrFromInt(mpu_base)
else
@compileError("Cortex-M does not have an MPU");
pub fn executing_isr() bool {
return regs.ICSR.read().VECTACTIVE != 0;
return scb.ICSR.read().VECTACTIVE != 0;
}
pub fn enable_interrupts() void {

@ -0,0 +1,3 @@
pub const SystemControlBlock = @compileError("TODO");
pub const NestedVectorInterruptController = @compileError("TODO");
pub const MemoryProtectionUnit = @compileError("TODO");

@ -0,0 +1,3 @@
pub const SystemControlBlock = @compileError("TODO");
pub const NestedVectorInterruptController = @compileError("TODO");
pub const MemoryProtectionUnit = @compileError("TODO");

@ -0,0 +1,3 @@
pub const SystemControlBlock = @compileError("TODO");
pub const NestedVectorInterruptController = @compileError("TODO");
pub const MemoryProtectionUnit = @compileError("TODO");

@ -0,0 +1,156 @@
const microzig = @import("microzig");
const mmio = microzig.mmio;
pub const SystemControlBlock = extern struct {
/// CPUID Base Register
CPUID: u32,
/// Interrupt Control and State Register
ICSR: mmio.Mmio(packed struct(u32) {
VECTACTIVE: u9,
reserved0: u2 = 0,
RETTOBASE: u1,
VECTPENDING: u9,
reserved1: u1 = 0,
ISRPENDING: u1,
ISRPREEMPT: u1,
reserved2: u1 = 0,
PENDSTCLR: u1,
PENDSTSET: u1,
PENDSVCLR: u1,
PENDSVSET: u1,
reserved3: u2 = 0,
NMIPENDSET: u1,
}),
/// Vector Table Offset Register
VTOR: u32,
/// Application Interrupt and Reset Control Register
AIRCR: u32,
/// System Control Register
SCR: u32,
/// Configuration Control Register
CCR: mmio.Mmio(packed struct(u32) {
NONBASETHRDENA: u1,
USERSETMPEND: u1,
_reserved0: u1 = 0,
UNALIGN_TRP: u1,
DIV_0_TRP: u1,
_reserved1: u3 = 0,
BFHFNMIGN: u1,
STKALIGN: u1,
_padding: u22 = 0,
}),
/// System Handlers Priority Registers
SHP: [12]u8,
/// System Handler Contol and State Register
SHCSR: u32,
/// Configurable Fault Status Register
CFSR: u32,
/// HardFault Status Register
HFSR: u32,
/// Debug Fault Status Register
DFSR: u32,
/// MemManage Fault Address Register
MMFAR: u32,
/// BusFault Address Register
BFAR: u32,
/// Auxilary Feature Register
AFSR: u32,
/// Processor Feature Register
PFR: [2]u32,
/// Debug Feature Register
DFR: u32,
/// Auxilary Feature Register
ADR: u32,
/// Memory Model Feature Register
MMFR: [4]u32,
/// Instruction Set Attributes Register
ISAR: [5]u32,
RESERVED0: [5]u32,
/// Coprocessor Access Control Register
CPACR: u32,
};
pub const NestedVectorInterruptController = extern struct {
ISER: [8]u32,
_reserved0: [24]u32,
ICER: [8]u32,
_reserved1: [24]u32,
ISPR: [8]u32,
_reserved2: [24]u32,
ICPR: [8]u32,
_reserved3: [24]u32,
IABR: [8]u32,
_reserved4: [56]u32,
IP: [240]u8,
_reserved5: [644]u32,
STIR: u32,
};
pub const MemoryProtectionUnit = extern struct {
/// MPU Type Register
TYPE: mmio.Mmio(packed struct(u32) {
SEPARATE: u1,
_reserved0: u7,
DREGION: u8,
IREGION: u8,
_reserved1: u8,
}),
/// MPU Control Register
CTRL: mmio.Mmio(packed struct(u32) {
ENABLE: u1,
HFNMIENA: u1,
PRIVDEFENA: u1,
padding: u29,
}),
/// MPU RNRber Register
RNR: mmio.Mmio(packed struct(u32) {
REGION: u8,
padding: u24,
}),
/// MPU Region Base Address Register
RBAR: RBAR,
/// MPU Region Attribute and Size Register
RASR: RASR,
/// MPU Alias 1 Region Base Address Register
RBAR_A1: RBAR,
/// MPU Alias 1 Region Attribute and Size Register
RASR_A1: RASR,
/// MPU Alias 2 Region Base Address Register
RBAR_A2: RBAR,
/// MPU Alias 2 Region Attribute and Size Register
RASR_A2: RASR,
/// MPU Alias 3 Region Base Address Register
RBAR_A3: RBAR,
/// MPU Alias 3 Region Attribute and Size Register
RASR_A3: RASR,
pub const RBAR = mmio.Mmio(packed struct(u32) {
REGION: u4,
VALID: u1,
ADDR: u27,
});
pub const RASR = mmio.Mmio(packed struct(u32) {
/// Region enable bit
ENABLE: u1,
/// Region Size
SIZE: u5,
_reserved0: u2,
/// Sub-Region Disable
SRD: u8,
/// ATTRS.B
B: u1,
/// ATTRS.C
C: u1,
/// ATTRS.S
S: u1,
/// ATTRS.TEX
TEX: u3,
_reserved1: u2,
/// ATTRS.AP
AP: u3,
/// ATTRS.XN
XN: u1,
padding: u4,
});
};

@ -84,6 +84,10 @@ fn load_device(ctx: *Context, node: xml.Node) !void {
if (node.find_child(&.{"interrupts"})) |interrupts_node|
try load_interrupts(ctx, interrupts_node, id);
var param_it = node.iterate(&.{"parameters"}, &.{"param"});
while (param_it.next()) |param_node|
try load_param(ctx, param_node, id);
try infer_peripheral_offsets(ctx);
try infer_enum_sizes(ctx);
@ -98,11 +102,26 @@ fn load_device(ctx: *Context, node: xml.Node) !void {
// events.generators.generator
// events.users.user
// interfaces.interface.parameters.param
// parameters.param
// property-groups.property-group.property
}
fn load_param(ctx: *Context, node: xml.Node, device_id: EntityId) !void {
const db = ctx.db;
assert(db.entity_is("instance.device", device_id));
validate_attrs(node, &.{
"name",
"value",
});
const name = node.get_attribute("name") orelse return error.MissingParamName;
const value = node.get_attribute("value") orelse return error.MissingParamName;
// TODO: do something with caption
_ = node.get_attribute("caption");
try db.add_device_property(device_id, name, value);
}
fn load_interrupts(ctx: *Context, node: xml.Node, device_id: EntityId) !void {
var interrupt_it = node.iterate(&.{}, &.{"interrupt"});
while (interrupt_it.next()) |interrupt_node|

Loading…
Cancel
Save