-
Notifications
You must be signed in to change notification settings - Fork 10
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
Add Newlib binary and allocator support #20
Conversation
Adds builds of newlib-3.3.0, and implement an allocator in n64lib which uses this. Newlib was configured as follows: CFLAGS_FOR_TARGET="-DPREFER_SIZE_OVER_SPEED=1 -Os -G0 -mabi=32 -mno-gpopt" \ ../configure --target=mips-elf libc.a and libm.a are bundled in the cargo-n64 executable, and written to the temp directory where the other temporary build artifacts are placed (linker script, for example). Since our sbrk() starts returning memory at the end of the .bss section, up the alignment of this in the linker script to 16 bytes. Also enable the 'noabicalls' feature in the target.json. This is the default in GCC with the mips-elf target, but not for LLVM. The linker will emit some warnings without this.
Clippy is pretty unhappy with this one. We have a couple of options:
|
I went with this, as it's the easiest option for the time being. |
Should return the previous pointer, rather than the incremented one.
Had to fix the sbrk implementation, turns out it was wrong. Reference implementation from newlib. |
Is this ready for review? |
Yes, it's ready. I tested it yesterday by modifying the hello world example to use a format!()'d string rather than a constant, and verifying that malloc was being called. |
Actually, just hold off on this for now... I'm seeing some strange behavior when I'm trying to allocate frame buffers using malloc. The _gp symbol is present (and points to something), despite newlib being compiled with -mno-gpopt. And what's weirder is I can't find the _gp symbol anywhere in libc.a. Maybe it's from llvm. |
unsafe { | ||
asm!(" | ||
mtc0 $0,$$12" | ||
// todo: Hazards? Two nops after this? ^ |
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.
Good question... I'd have to go back over the MIPS docs to answer this, myself. But IIRC the instruction pipeline will be stalled in the presence of hazards, but shouldn't cause undefined behavior?
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 docs say:
The hazard related to CP0 does not generate the interlock of the
pipeline. Therefore, control the number of required instructions
by program.
They also say:
The number of NOP instructions between the instructions related to the CP0
register and TLB, or the number of the instructions independent of the conflict can
be calculated from the following expression, using this table.
(Number of destination hazards of instruction A) - {(Number of source hazards of instruction B) +1}
And then they present an example:
As an example, to find the number of instructions required between an MTC0 and
a subsequent MFC0 instruction, this is:
(7) - (4 + 1) = 2 instructions
The table they refer to is on page 621 of this document: http://datasheets.chipdb.org/NEC/Vr-Series/Vr43xx/U10504EJ7V0UMJ1.pdf
So, maybe 2 nops would be enough?
@kskjer FWIW the Nintendo64 target compiles with static relocation model to workaround problems I had with the global pointer:
cargo-n64/cargo-n64/src/templates/linker.ld Lines 40 to 45 in 51a0c81
I suspect |
Yeah, turns out the _gp sym was a red herring, and it's always there (but not used) if an .sdata section is present. The issue was that the CRCs were wrong due to a bug in my padding PR. The ABI configured in the target.json and what newlib was compiled with should be the same. |
Hi! One alternate approach to an allocator is the one i built here: https://github.com/JoNil/loka-n64/tree/master/n64-alloc It is basically a copy of https://crates.io/crates/wee_alloc for webassembly but with only the static array backend. Cheers |
That's really cool! Thanks for sharing the link. I see you also have some other interesting stuff floating around in there... I am also interested in experimenting with drone. I don't think it's an exact fit, but there's a lot of interesting things in it already. As much as I love building kernels, I would like someone else to do the heavy lifting. 😂 |
Adds builds of newlib-3.3.0, and implement an allocator in n64lib which
uses this.
Newlib was built as follows:
libc.a and libm.a are bundled in the cargo-n64 executable, and written
to the temp directory where the other temporary build artifacts are
placed (linker script, for example).
Since our sbrk() starts returning memory at the end of the .bss section,
up the alignment of this in the linker script to 16 bytes.
Also enable the 'noabicalls' feature in the target.json. This is the
default in GCC with the mips-elf target, but not for LLVM. The linker
will emit some warnings without this.