-
Notifications
You must be signed in to change notification settings - Fork 144
Aviron features #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Aviron features #683
Conversation
88e66b0
to
1632125
Compare
5ed6544
to
41ae681
Compare
sim/aviron/src/main.zig
Outdated
|
||
const addr_masked: u24 = @intCast(phdr.p_paddr & 0x007F_FFFF); | ||
const target_addr: u24 = if (phdr.p_paddr >= 0x0080_0000) | ||
addr_masked - sram.base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❯ avr-readelf -s test.elf
Symbol table '.symtab' contains 396 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00800100 0 SECTION LOCAL DEFAULT 1 .data
.data is at 0x00800100, but it should start at 0 in the array, so we mask off the top 8, then adjust by the base (0x100)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here is flawed as two LOAD headers at 00800100
and 00800200
would both be offset, while the third LOAD header at 00800000
would not.
You have to basically go through cpu.data_write
for this instead of hijacking the data in a conditional here.
With a proper mapped SRAM object instead of a single "Static" this would not be a problem.
I think we should introduce a real mapper object here already, as we're piling up workarounds on workarounds just to not have a mapper and introduce more complexity than necessary by that.
The branch would not be necessary if we could just do ram.write(addr_masked, data)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've written a mapper, but it only supports writing individual bytes. I could extend it to add a method to write a slice, but with the changes to this part (take a look at new commits) I think this is probably fine.
In your example case, though: How would there be a load at 0x00800000 if SRAM starts at 0x100?
sim/aviron/src/main.zig
Outdated
.m = "mcu", | ||
.I = "info", | ||
.f = "format", | ||
.B = "break_pc", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be lower case?
sim/aviron/src/main.zig
Outdated
.mcu = "Selects the emulated MCU.", | ||
.info = "Prints information about the given MCUs memory.", | ||
.format = "Specify file format.", | ||
.break_pc = "Break when PC reaches this address (hex or dec)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You wanted to call this 'breakpoint'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd go with either aviron --break-at 0x1000
or aviron --breakpoint 0x1000
sim/aviron/src/main.zig
Outdated
.sreg => write_masked(@ptrCast(io.sreg), mask, value), | ||
|
||
_ => std.debug.panic("illegal i/o write to undefined register 0x{X:0>2} with value=0x{X:0>2}, mask=0x{X:0>2}", .{ addr, value, mask }), | ||
_ => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably restore the panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitly crash/stop here in any case, and not silently ignoring it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the main pain point is that we should introduce a proper memory mapper instead of doing all of these workarounds, as it will actually simplify the code a lot
KEEP(*(.vectors)) | ||
|
||
/* Ensure _start comes first */ | ||
KEEP(*(.text._start)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't always hold true as .text._start
will only be present with -ffunction-sections
compile flag (which is on in default for Zig code, but not for C and definitly not for Asm)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is _start
not exported normally for gcc? If not, what can we add here as an alternative?
// Some AVR families (e.g., XMEGA) expose extended I/O up to 0xFFF (12 bits). | ||
pub const Address = u12; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which instructions would use these? Afaik the 1024 byte I/O is only usable via the RAM interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not for io instructions, it's for MCUs with IO mapped and read/writable with normal load and stores.
checkExitFn: *const fn (ctx: ?*anyopaque) ?u8, | ||
translateAddressFn: *const fn (ctx: ?*anyopaque, data_addr: u24) ?Address, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add default implementations for these two, where both functions will return null
by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a empty()
function to return an IO with dummy functions. Would you prefer that the vtable have default values so an empty version can be initialized with.{}
instead? I find this more expressive but I don't mind either way.
sim/aviron/src/main.zig
Outdated
|
||
const addr_masked: u24 = @intCast(phdr.p_paddr & 0x007F_FFFF); | ||
const target_addr: u24 = if (phdr.p_paddr >= 0x0080_0000) | ||
addr_masked - sram.base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here is flawed as two LOAD headers at 00800100
and 00800200
would both be offset, while the third LOAD header at 00800000
would not.
You have to basically go through cpu.data_write
for this instead of hijacking the data in a conditional here.
With a proper mapped SRAM object instead of a single "Static" this would not be a problem.
I think we should introduce a real mapper object here already, as we're piling up workarounds on workarounds just to not have a mapper and introduce more complexity than necessary by that.
The branch would not be necessary if we could just do ram.write(addr_masked, data)
sim/aviron/src/main.zig
Outdated
.mcu = "Selects the emulated MCU.", | ||
.info = "Prints information about the given MCUs memory.", | ||
.format = "Specify file format.", | ||
.break_pc = "Break when PC reaches this address (hex or dec)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd go with either aviron --break-at 0x1000
or aviron --breakpoint 0x1000
sim/aviron/src/main.zig
Outdated
.sreg => write_masked(@ptrCast(io.sreg), mask, value), | ||
|
||
_ => std.debug.panic("illegal i/o write to undefined register 0x{X:0>2} with value=0x{X:0>2}, mask=0x{X:0>2}", .{ addr, value, mask }), | ||
_ => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitly crash/stop here in any case, and not silently ignoring it
41ae681
to
65393d1
Compare
5240640
to
fd54e9b
Compare
RAMEND - 1
(though gcc-compiled binaries will set this for us)Mapper
to the CPU struct. All reads and writes go through it. It will properly delegate to SRAM or IO.in