Douglas Fulton Shaw
Douglas Fulton Shaw

Reputation: 55

How to get PERIPHBASE of qemu machine "virt"?

qemu-system-aarch64 can be used to emulate aarch64, the specific command is as follows:

qemu-system-aarch64 -M virt -cpu cortex-a53 ...(other options)

and we can use -M virt,dumpdtb=DTBFILE to get the internal device tree blob.

My question is that, how can we get the PERIPHBASE of the virtual machine virt?

Can we do that from the device tree blob file using the dtc tool?

Upvotes: 2

Views: 1836

Answers (3)

NienFeng Yao
NienFeng Yao

Reputation: 61

Maybe this is what you want. https://github.com/qemu/qemu/blob/master/hw/arm/virt.c

static const MemMapEntry a15memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
[VIRT_FLASH] =              {          0, 0x08000000 },
[VIRT_CPUPERIPHS] =         { 0x08000000, 0x00020000 },
/* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
[VIRT_GIC_DIST] =           { 0x08000000, 0x00010000 },
[VIRT_GIC_CPU] =            { 0x08010000, 0x00010000 },
[VIRT_GIC_V2M] =            { 0x08020000, 0x00001000 },
/* The space in between here is reserved for GICv3 CPU/vCPU/HYP */
[VIRT_GIC_ITS] =            { 0x08080000, 0x00020000 },
/* This redistributor space allows up to 2*64kB*123 CPUs */
[VIRT_GIC_REDIST] =         { 0x080A0000, 0x00F60000 },
[VIRT_UART] =               { 0x09000000, 0x00001000 },
[VIRT_RTC] =                { 0x09010000, 0x00001000 },
[VIRT_FW_CFG] =             { 0x09020000, 0x00000018 },
[VIRT_GPIO] =               { 0x09030000, 0x00001000 },
[VIRT_SECURE_UART] =        { 0x09040000, 0x00001000 },
[VIRT_SMMU] =               { 0x09050000, 0x00020000 },
[VIRT_MMIO] =               { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] =       { 0x0c000000, 0x02000000 },
[VIRT_SECURE_MEM] =         { 0x0e000000, 0x01000000 },
[VIRT_PCIE_MMIO] =          { 0x10000000, 0x2eff0000 },
[VIRT_PCIE_PIO] =           { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] =          { 0x3f000000, 0x01000000 },
[VIRT_MEM] =                { 0x40000000, RAMLIMIT_BYTES },
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
[VIRT_GIC_REDIST2] =        { 0x4000000000ULL, 0x4000000 },
[VIRT_PCIE_ECAM_HIGH] =     { 0x4010000000ULL, 0x10000000 },
/* Second PCIe window, 512GB wide at the 512GB boundary */
[VIRT_PCIE_MMIO_HIGH] =   { 0x8000000000ULL, 0x8000000000ULL },
};

Upvotes: 1

Frant
Frant

Reputation: 5895

The dtc command would be:

dtc -I dtb -O dts virt.dtb > virt.dts

The node you are looking for should be /intc:

intc {
    phandle = <0x8001>;
    reg = <0x0 0x8000000 0x0 0x10000 0x0 0x8010000 0x0 0x10000>;
    compatible = "arm,cortex-a15-gic";
    ranges;
    #size-cells = <0x2>;
    #address-cells = <0x2>;
    interrupt-controller;
    #interrupt-cells = <0x3>;

    v2m {
        phandle = <0x8002>;
        reg = <0x0 0x8020000 0x0 0x1000>;
        msi-controller;
        compatible = "arm,gic-v2m-frame";
    };
};

A more straightforward option would be to use fdtget:

fdtget -t i -t x virt.dtb /intc reg
0 8000000 0 10000 0 8010000 0 10000

I agree with Peter Maydell that the DTB should preferably be used at run-time for retrieving the addresses for the GIC CPU and distributor interfaces if you are running Linux in QEMU.
But the non-DTB approach is still easier to implement in an emulated bare-metal environment - in my humble opinion.

Upvotes: 1

Peter Maydell
Peter Maydell

Reputation: 11393

PERIPHBASE will be the address of the GIC distributor register bank in the device tree blob.

That said, I'm not sure why you want to know this information. Guest code for the 'virt' board should only hard code the base address of RAM, and should get all other information from the dtb at runtime. Some day in the future we may rearrange the virt memory map, and if you have hardcoded addresses from it then your guest will stop working...

Upvotes: 0

Related Questions