Comments (6)
A Release 2 MIPS can be configured to use one of following three interrupt modes:
- Single-vector mode (AKA legacy mode), in which all interrupts are processed by a single handler procedure
- Vectored Interrupt mode, where interrupts are vectored to multiple handlers, can be prioritized and can be assigned a separate shadow register set
- Extrernal Interrupt Controller mode, in which an external chip manages interrupt priorities, jump addresses, generally providing more features.
Given that PIC32MZ has a quite powerful external interrupt controller (http://ww1.microchip.com/downloads/en/DeviceDoc/60001108H.pdf), so I hoped I could configure it to react on Core Timer interrupts, which are triggered when Count == Compare
.
Once again, the results I observed were inconsistent with specification, so I had to run qemu
within a debugger and investigate sources. Indeed it turns out that the support for external interrupt controllers with MIPS is not fully implemented. Generally, it works exactly as it should, except for the part where the exception handler offset is calculated. It ignores the fact that OFF registers (which specify the offset for each interrupt, and can be set to a custom value) are present in the device (see chapter 8.6.1 in the document linked above), and assumes the offset is encoded in Cause<15:8>
. This may be the case for other interrupt controllers, but for PIC32MZ it is not, as these bits store the current interrupt's requested priority. This obviously results in incorrectly calculated interrupt handler address, which results in a jump to a completely wrong address.
The comments nearby the incorrect calculation in qemu's sources target-mips/helper.c:587 suggest that developers are aware of the issue, as they specifically mention PIC32MZ as an example where their assumption is incorrect.
Possible workarounds:
- Fixing qemu. I expect this particular issue would be fairly easy to fix, but preparing the fix and getting it upstream are two different stories, and we probably wouldn't like to fork qemu :-)
- Exploiting the bug. We might use interrupt priorities to encode vector offsets. This is silly, because it renders them useless, and will only work on qemu and not on the real device.
- Not using qemu. We might use a different simulator, but the huge advantage of qemu are it's openly available sources, which makes debugging much easier, as they provide an example implementation of MIPS' and PIC32 specifications.
- Using a dumber interrupt mode instead. I did not test them, but I suspect the other modes will work correctly, because they are not chip-specific, and generally their implementation in qemu looks complete. I suspect this is the way we'll choose, as it is probably the most reasonable one, but I would appreciate some feedback anyway.
from mimiker.
Initially I had the impression that the software can freely switch the processor between the three interrupt modes. However, this is not the case. According to [1], the processor determines whether to use External Interrupt Controller mode or Vectored Interrupts mode by the state of the VEC
bit of Config3
register. However, [2] clearly states that that bit is read-only and preset by hardware.
This means we have no means of switching the processor to Vectored Interrupts mode in order to avoid EIC behaviour that is not implemented in qemu.
We should be able, however, to switch to Legacy Single-Vector mode, as we can set the BEV
bit of Status
register to 1 (see [1] for other ways of enabling this mode). This way we would have to use a single handler for all interrupts. Is this the right way to go?
[1] MIPS32® microAptiv™ UP Processor Core Family Software User’s Manual, table 5.2
[2] MIPS® Architecture For Programmers Volume III: The MIPS32® and microMIPS32™ Privileged Resource Architecture, chapter 9.44, table 9.60, position 6 (VEIC)
from mimiker.
This still won't work. The chipset-specific code in qemu for PIC32MZ always assumes that EIC mode is active, regardless of Status register (see hw/mips/mips_pic32mz.c:136), so we cannot fall back to Legacy mode.
Putting my observations together, it would seem there is strictly no way to get correctly working interrupts on PIC32MZ with qemu (except for workarounds like always using priority = 0, which - due to a bug - will behave similarly to single-vector mode).
@cahirwpz, you did mention that you were able to successfully run a BDS kernel on MIPS with qemu. Did you test it using particularly PIC32MZ chipset emulation (other chipsets are free from the qemu bugs I observed)? Could you please point me to such kernel image? I would like to investigate how is that kernel using timer interrupts, and why are they [not] working correctly there.
from mimiker.
That's a plenty of interesting observations you made. I'll give it another read to interrupt related documentation tomorrow. In the meantime please have a look at:
Note that pic32mz is based on OVPsim, which is enterprise grade generic simulator framework. Unfortunately, it requires access to non-free software, hence you have to register an account and apply for personal use license (tied to MAC address & host name).
from mimiker.
I was able to identify why does LiteBSD for PIC32MZ work correctly on qemu. It uses the EIC, but it explicitly sets vector spacing to 0 (see sys/mips/pic32/machdep.c:408, and therefore never has to set OFF registers, effectivelly using a single interrupt handler. Qemu completely ignores the requested vector spacing, and blindly assumes that it is 0 (see target-mips/helper.c:592), which happens to be correct.
The interesting part about this approach is that this solution is valid according to the specification. Also, it would appear that this is the only solution which both is specification-conforming, and happens to work correctly on qemu.
from mimiker.
I've asked a question Robert Owen from Imagination Technologies. He'll investigate if there're better options for accurate PIC32MZ simulator. Stay tuned.
from mimiker.
Related Issues (20)
- Counter overflow in arm_timer_gettime()
- Weird time jumps, probably due to icount being disabled in QEMU HOT 4
- No ordering between locks &p->p_lock and &tty->t_lock HOT 1
- KASAN flag is not honored HOT 1
- UVM virtual memory system
- initrd: wrong alignment of sp HOT 1
- physmem: interface is insufficient
- Data race on vm_page_t::flags
- AArch64: broken master
- Usage of pool allocator can cause vmem test to fail HOT 1
- Set of macros for accessing device registers
- Copying memory seems to be unreliable. HOT 5
- pathconf syscall HOT 4
- Use-after-free in device_add_resource HOT 2
- run_tests.py does not properly report kernel timeouts HOT 1
- Authorization system
- Bochs VGA driver is not attached HOT 1
- on_user_exc_leave() can lose pending signals. HOT 1
- Tests that don't work on AArch64.
- Deadlock between physmem_lock and pv_list_lock HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mimiker.