Skip to content
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

Route MMU through RAM access methods, caching? #26

Open
onnokort opened this issue Aug 21, 2023 · 6 comments
Open

Route MMU through RAM access methods, caching? #26

onnokort opened this issue Aug 21, 2023 · 6 comments
Assignees

Comments

@onnokort
Copy link
Contributor

Hi,

I just ported your great little emu to a very unlikely architecture and whilst doing so, I had to tweak the MMU code to go through the RAM access methods as well. I propose the code would be a lot more portable if MMU RAM access calls corresponding methods/functions as well, so that RAM access can really be anything. The current way of having a pointer into emu RAM is a bit of a breach of abstraction IMO.

I further noticed that every CPU instruction fetch goes through the MMU page walk and a very simple "1-entry-1-page" cache (one for INSN fetch, load & store) speeds up the emulation considerably. For the standard PC build, I got from about 10s to boot the emulated Linux to about 7s just by caching the current page for mmu_fetch.

As my code to do so is quite peculiar and adapted to the odd target architecture, I don't think it really fits well as an upstream patch. Still, I like to raise the issue of the MMU being direct-access here.

@jserv
Copy link
Collaborator

jserv commented Aug 22, 2023

@RinHizakura, Could you provide a comment on the MMU issue mentioned above, drawing from your past experience in developing the riscv-emulator?

@RinHizakura
Copy link

For the part of the instruction cache, it can really help a lot for system emulators. In my experience, I have icache.c on my risc-v emulator, and it improves performance even though the implementation is super naive as you can see. riscv-rust has a better implementation of page cache if we want one to reference.

In conclusion, the instruction cache would be an important component for optimization, but it is also worth mentioning that the timing to invalidate the cache for system emulator should be considered carefully for correctness.

@jserv
Copy link
Collaborator

jserv commented Aug 24, 2023

I further noticed that every CPU instruction fetch goes through the MMU page walk and a very simple "1-entry-1-page" cache (one for INSN fetch, load & store) speeds up the emulation considerably. For the standard PC build, I got from about 10s to boot the emulated Linux to about 7s just by caching the current page for mmu_fetch.

As my code to do so is quite peculiar and adapted to the odd target architecture, I don't think it really fits well as an upstream patch. Still, I like to raise the issue of the MMU being direct-access here.

I appreciate the outstanding C64 porting work carried out by @onnokort! Introducing a cache for MMU manipulation is a logical step towards enhancing performance.

Furthermore, uc-rv32ima has reported the following:

To improve the performance, a simple cache is implemented, it turns out we achieved 95.1% cache hit during linux booting.

The cache implementation in uc-rv32ima is both straightforward and effective. We may consider employing a similar technique in this project.

@onnokort
Copy link
Contributor Author

onnokort commented Aug 24, 2023 via email

@jserv
Copy link
Collaborator

jserv commented Aug 24, 2023

I would also like that to be modular enough to be able to either configure a MMU or RAM cache (or not!) during runtime or at least with a couple #defines in code. Maybe modularizing the code so that all the MMU functions go into their own exchangeable module is already most of what would be needed. Does that make sense?

Certainly, modularization and refactoring efforts are greatly appreciated. Feel free to submit pull requests for these changes.

What I really like about this project is the minimalism and simplicity, I like simple and being able to understand stuff but still being able to deal with applications of any complexity on the guest side. As far as I looked, this is the simplest emulator that can still run a full Linux with virtual memory.

As a university faculty member teaching RISC-V and system programming, I was searching for pre-existing implementations that could facilitate the execution of (almost) unmodified Linux images with an active MMU. Unfortunately, I couldn't find an exact match for my requirements. As a result, my students and I have taken on this project. While it might not have the level of polish seen in professional solutions, it is reasonably functional and serves its purpose effectively.

Once again, contributions are always welcomed. I believe that maintaining a minimalist approach will be beneficial for adaptive development, facilitated by effective code reviewing.

@jserv
Copy link
Collaborator

jserv commented Sep 4, 2024

arv32-opt s a port of mini-rv32ima on atmega328p (the core of Arduino UNO, a 8-bit AVR microcontroller). So basically, this code is for booting Linux on Arduino UNO. It has 3 512-bytes cache (1 icache and 2 dcache interchangeable) and lazy/delayed cache write system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants