Code Monkey home page Code Monkey logo

Comments (6)

rafalcieslak avatar rafalcieslak commented on September 17, 2024

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.

rafalcieslak avatar rafalcieslak commented on September 17, 2024

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.

rafalcieslak avatar rafalcieslak commented on September 17, 2024

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.

cahirwpz avatar cahirwpz commented on September 17, 2024

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.

rafalcieslak avatar rafalcieslak commented on September 17, 2024

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.

cahirwpz avatar cahirwpz commented on September 17, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.