I've been implementing firmware for an ARMv8 processor recently and have been studying open-source tools along the way. I looked into the ARM virtual model in QEMU and came across something it refers to as Secure Memory. The code can be found in the memory map definition for the virtual device (defined as VIRT_SECURE_MEM):


static const MemMapEntry base_memmap[] = {
    /* 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 },
    [VIRT_GIC_HYP] =            { 0x08030000, 0x00010000 },
    [VIRT_GIC_VCPU] =           { 0x08040000, 0x00010000 },
    /* 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 },
    /* Actual RAM size depends on initial RAM and device memory settings */
    [VIRT_MEM] =                { GiB, LEGACY_RAMLIMIT_BYTES },

Note that there is also just VIRT_MEM, which is "regular", presumably non-secure, memory. They also have a VIRT_SECURE_UART.

I know that regions of memory, including MMIO devices, can be reserved for Secure World via setting the appropriate bit in the page mappings. However, this appears to be a totally different thing. What is 'secure memory' as a feature otherwise? Is this common across other devices?

I've searched around a bit and could not find any ARM devices that have any secure memory at reset; they just have regular memory that can be made secure by configuring the platform.

tl;dr Are there some devices that have 'secure memory' at reset that only the Secure World context can access? Or is this just a one-off feature of QEMU?

  • 1
    \$\begingroup\$ Isn't this what ARM call "TrustZone"? \$\endgroup\$ – pjc50 Apr 27 at 20:45
  • \$\begingroup\$ @pjc50, Maybe. TrustZone is the separation from resources into two domains: Normal World and Secure World. One can reserve memory for the SW by setting bits in the page table of EL3. In this way you can effectively reserve access to ranges of MMIO by reserving their addresses as SW-only. My question was specifically asking about POR Secure-Only peripherals, which I was not sure existed in the wild or was just a feature of QEMU. I was not sure if this sort of thing existed in the specification or was an implementation feature. \$\endgroup\$ – sherrellbc Apr 28 at 19:36

I am less familiar with the software side of things or QEMU, but I have dropped a number of ARM cores on silicon.

It is possible in hardware to check the AXI bus protection bits prot[2:0] and refuse access if cycle does not have enough rights or is of the wrong type.

Here is an abstract of the AXI standard:

Normal or privileged, ARPROT[0] and AWPROT[0]
• LOW indicates a normal access
• HIGH indicates a privileged access.
This is used by some masters to indicate their processing mode. A privileged processing mode typically has a greater level of access within a system.

Secure or non-secure, ARPROT[1] and AWPROT[1]
• LOW indicates a secure access
• HIGH indicates a non-secure access.
This is used in systems where a greater degree of differentiation between processing modes is required.

Note This bit is configured so that when it is HIGH then the transaction is considered non-secure and when LOW, the transaction is considered as secure.

Instruction or data, ARPROT[2] and AWPROT[2]
• LOW indicates a data access
• HIGH indicates an instruction access.
This bit gives an indication if the transaction is an instruction or a data access.
Note This indication is provided as a hint and is not accurate in all cases. For example, where a transaction contains a mix of instruction and data items. It is recommended that, by default, an access is marked as a data access unless it is specifically known to be an instruction access.

A prime example would be an en/decryption block which can only be access in privileged, secure, data mode PROT[2:0] = 3'b001

Note that this would be a feature of the system as the protection is build using the logic which does the address decoding, all of which is outside the processor core.

  • \$\begingroup\$ Interesting to know how it might be done. I suppose QEMU is just providing an this feature in the virt platform. I am familiar with things like OTP, like mentioned by Rajesh below, that might be privileged limited, I've just never seen it on whole swaths of memory. \$\endgroup\$ – sherrellbc Apr 28 at 19:59

Yes, devices can have certain memories that are always secure (block non-secure) by default depending on the usecase. For example: OTP memory in modern SoC's!

The secure or non-secure characteristic basically relates to which master interfaces in the system can have access (read/write) to memory. There can be different methods to implement this in hardware. Oldfart's answer captures the mechanism used in AXI interfaces, PROT signal denoted the type of access but a system may also use AXI ID to restrict access to a specific set of masters because it's possible that an adversary tries to electrically change the signal state of PROT and pretend to be secure.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.