[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Cortex M0 emulation tasks

From: Stefan Hajnoczi
Subject: [Qemu-devel] Cortex M0 emulation tasks
Date: Mon, 28 May 2018 15:26:05 +0100

I took a look at what's required for ARM Cortex M0 emulation that we
need for the micro:bit ARM board.  The following notes are based on
Appendix D3 of the ARMv6-M Architecture Reference Manual that Peter
Maydell recommended.

Several people can work on this since there are many smaller tasks.

The general approach for each task:
1. Look at Appendix D3 to understand the architecture differences.
2. Look at QEMU source code (mainly target/arm/translate.c) to
understand the current status.
3. Implement a ARMv6-M-specific code path, if necessary.
4. Implement a test case that exercises the instruction or register to
prove it works.

Before we can tackle these tasks a Cortex M0 CPU needs to be defined.
Adding the Cortex M0 involves a new element in
target/arm/cpu.c:arm_cpus[].  The CPU needs ARM_FEATURE_V6 and
ARM_FEATURE_M.  Once that is in place most of these tasks can be done
independently and by multiple people.

How to collaborate:
Pick something you want to do from this list and reply-all to announce
you are working on it.


D3.3 Instruction Support
Each of the listed instructions needs to be audited.  For example,
"32-bit DMB, DSB and ISB barrier instructions" will not work because
disas_thumb2_insn() won't run for ARM_FEATURE_V6 without

    /* The only 32 bit insn that's allowed for Thumb1 is the combined
     * BL/BLX prefix and suffix.
    if ((insn & 0xf800e800) != 0xf000e800) {
        ARCH(6T2);  <-- this will fail on ARMv6-M

The 32-bit Thumb2 DMB, DSB, and ISB instructions need to be added as
special cases for ARMv6-M.

And there is a second check that will fail:

  case 3: /* Special control operations.  */
    ARCH(7);  <-- this is too restrictive!
    op = (insn >> 4) & 0xf;
    switch (op) {
    case 2: /* clrex */
        gen_clrex(s);  <--- not supported on ARMv6-M
    case 4: /* dsb */  <--- supported on ARMv6-M
    case 5: /* dmb */  <--- supported on ARMv6-M
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
    case 6: /* isb */  <--- supported on ARMv6-M
        /* We need to break the TB after this insn
         * to execute self-modifying code correctly
         * and also to take any pending interrupts
         * immediately.
        gen_goto_tb(s, 0, s->pc & ~1);
        goto illegal_op;

These instructions must be tested to prove they do not fault and
behave properly.  I recommend a similar approach to
tests/boot-serial-test.c consisting of a tiny instruction sequence.

D3.4 Programmer's model
Lot's of details to check here.  I haven't investigated it.  Comments

D3.5 Memory model
This can probably be ignored, it's very similar to ARMv7-M.

D3.5.1 Alignment support
ARMv7-M supports unaligned accesses but ARMv6-M does not.  Check code
to ensure alignment checks are being made.

D3.5.2 Endian support
Nothing to do here.

D3.5.3 Exclusive access support
Each of the listed instructions must be checked.  For example, STREX
is not supported ARMv6-M but QEMU seems to allow it.

D3.5.4 Cache support
Nothing to do here.

D3.5.5 PMSA support
I think we can ignore this.  QEMU implements PMSA.  It would be best
to check if Cortex M0 wants PMSAv6.

D3.6.1 Reserved registers in ARMv6-M
Listed registers must be emulated "Read-as-Zero, Write Ignored" for
ARMv6-M.  This means guest memory load instructions produce 0 and
store instructions have no effect.

D3.6.2 General Fault Status Registers
ARMv6-M has a coarser fault handling architecture, the code needs to
be audited to check that HardFault is raised under all conditions.

D3.6.3 System timer support
No changes necessary.  My interpretation is that SysTick is optional
for Cortex M0 but the nRF51 implements it.  It is mandatory for
ARMv7-M, so let's just keep it.

D3.6.4 NVIC support
Some registers are reserved on ARMv6-M and there are fewer priority levels.

D3.7 Debug support
I think we can ignore this because debugging is handled by QEMU via the gdbstub.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]