Le Hoang Long
Le Hoang Long

Reputation: 500

Does QEMU emulate ARM coprocessor

I need to implement a kernel module that involves reading the ARM Cortex-A9 coprocessor's register:

register int reg asm ("r6");
reg = -2;
volatile printk(KERN_INFO "reg: %d\n", reg);
volatile  asm("MRC p15, 0,r6, c1, c0, 2;"); //Read Coprocessor Access Control Register
volatile  printk(KERN_INFO "reg: %d\n", reg);

However, when i run this on QEMU, it always print out:

reg: -2
reg: -2

Is this because of my code or is it because of QEMU?

Thanks in advance.

Upvotes: 0

Views: 635

Answers (1)

Sam Protsenko
Sam Protsenko

Reputation: 14743

Your code should work fine (though you need to remove volatile from printk lines, and ASM command should be asm volatile, not the other way around). Try to check next things:

  1. QEMU version. I'm using 2.12 and your code works. So if you're using older version, try 2.12 too.
  2. Emulated machine and cpu. Not sure if it affects CP registers, but I'm using "virt" machine with no CPU specified, you can try this configuration too.
  3. If this doesn't help, check more details about my configuration below.

My configuration

I'm using next command to run QEMU:

$ qemu-system-arm -kernel $zimage -initrd $rootfs \
    -machine virt -nographic -m 512 \
    --append "root=/dev/ram0 rw console=ttyAMA0,115200 mem=512M"

where:

  • $zimage is path to zImage file (my kernel is linux-mainline on tag v4.18, built with multi_v7_defconfig configuration)
  • $rootfs is path to CPIO archive with minimal BusyBox rootfs

My kernel module code is next:

#include <linux/module.h>

static int __init mrc_init(void)
{
    u32 acr;

    /*
     * Read Coprocessor Access Control Register.
     * See Cortex-A9 TRM for details.
     */
    asm volatile ("mrc p15, 0, %0, c1, c0, 2\n" : "=r" (acr));

    pr_info("ACR = 0x%x\n", acr);

    return 0;
}

static void __exit mrc_exit(void)
{
}

module_init(mrc_init);
module_exit(mrc_exit);

MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Test MRC on QEMU");
MODULE_LICENSE("GPL");

After loading this module I can see next output in dmesg:

ACR = 0xf00000

Upvotes: 1

Related Questions