QCPU
  • Instruction set
  • CLI
  • Guide
  • Snippets

On this page

  • 1 Address alignment
  • 2 MMU: memory management unit
  • 3 I/O: input and output

Physical devices

memory
addressing
io
Physical mapping, I/O and memory devices.
Published

December 3, 2023

The benefit of using virtual addresses is that it allows management software, such as a kernel, to control the view of memory that is presented to software. The kernel can control what memory is visible, the virtual address at which that memory is visible, and what accesses are permitted to that memory. This allows the kernel to sandbox applications (hiding the resources of one application from another application) and to provide abstraction from the underlying hardware [1, Ch. 3].

*----------*             *----------*    +- devices interface -+
|          |             |          | ___ I/O 0 'boot' regfile |
|  64 KiB  |             |  64 KiB  | ___ I/O 1 'dmac' regfile | ___
|          | per-process |          | ___ I/O ... regfile      |    |
| virtual  | ___ MMU ___ | physical | ___ I/O 23 regfile       |    |
| memory   |   mapping   | memory   |                          |    |c
|          |             |          | ___ main memory          |   *------------*
|          |             |          | ___ (I/O references) ___ | _ | persistent |
|          |             |          |                          | d | storage    |
*----------*             *----------*    +-                   -+   *------------*

1 Address alignment

                16 bit
15                 7                  0
|------------------|------------------|
| physical address | page offset      |
  8 bit              8 bit
                     256 byte page size

A resolved address is the combination of a physical address and an offset [1, Ch. 5]. In this case, there’s an 8 bit physical address and an 8 bit offset, which means the minimum amount of space per physical page is 256 bytes. An offset is left out when passing around physical addresses. Memory is allocated in 256 byte blocks. Section 2 explains strategies for small allocations.

                16 bit
15                 7                  0
|------------------|------------------|
| physical address | page offset      |
|-------------------------------------|
| virtual address    offset           |

A translation of the upper virtual address byte is done to resolve to a 16 bit physical address. The lower byte of the virtual address, the offset, is the same offset in the resolved address in order to perform byte-specific operations on the designated memory page.

Contrary to physical resolved addresses, the 16 bit virtual address is passed around userland in its entirety.

2 MMU: memory management unit

A kernel can only map segments of 256 bytes to a process’ virtual memory. In order to handle multiple smaller allocations efficiently, like 24 byte arrays and a couple of small objects, an allocator layer in userland may be used. A system call is only done when more physical space is necessary for the allocation rather than with every single allocation [2].

The MMU holds a table of virtual segments and their physical address for the userspace. It also holds the flags belonging to the segment [3, Ch. 4] [1, Ch. 4].

  1. Flags
    • Cacheable
    • Readonly
    • Copy-on-write
    • Executable
    • Reserved
    • Reserved
    • Reserved
    • Dirty
  2. Physical address

Currently, the two-byte MMU stride is for a 16 bit physical address.

  • Cacheable: an indication that the data doesn’t change outside of write instructions, and can therefore be cached, unlike ever-changing dynamic data provided by I/O regfiles;
  • Readonly: a write operation will signal a segmentation fault to the processor;
  • Copy-on-write: a write operation will signal a copy-on-write to the processor;
  • Executable: a read operation through an execution mode will signal a segmentation fault to the processor;
  • Dirty: a read or write triggers a new lookup in physical memory.

3 I/O: input and output

There are 24 total pages mapped to I/O devices. Each page is a 256 byte register file to communicate with the device, and the rest is managed by the main memory port [1, Ch. 3]. Every one of the I/O devices has 4 interrupt pins each, resulting in 96 total external interrupts. There are 32 system calls for a grand total of 128 interrupts. It means exactly one page of 256 bytes are allocated for the interrupt map with a 16 bit address per interrupt. The I/O device address range is from 0x0000 to 0x1700 (6.144 bytes).

Two built-in I/O devices are present in the QCPU microcontroller:

  • ‘Boot’ sector ROM device [0],
  • ‘DMAC’ device [1].

Interrupts with a lower address have higher priority. An interrupt with address 0 can therefore interrupt the interrupt with address 11. Having two predetermined I/O devices give 8 CPU interrupts, mainly for maintenance and security:

address name description
0100000 reset reset pin active (highest priority)
0100001 reserved
0100010 reserved
0100011 reserved
0100100 segv on unmapped or unprivileged virtual memory access
0100101 cow a memory page is being written to with copy-on-write active
0100110 mmap a (physical) map request of an I/O device was received
0100111 timer system timer for preemptive multitasking (lowest system priority, higher than I/O)

System calls are addressed before the system interrupts. I/O devices are addressed after the system interrupts.

An interrupt can come with data depending on the I/O device, which can be read from the I/O register file, usually through a device driver. An I/O device can include multiple physical I/O devices to save register file space and/or manage dynamic devices with a register/unregister system.

Interrupt defers add a 242 cycle buffer in which it’s guaranteed no timer interrupt is fired. It’s used in critical sections. However, the dfr instruction can implicitly fire timer (before the next instruction is executed) if deemed necessary to prevent cyclic usage of this feature.

References

[1]
Memory management. arm, 2019. Available: https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/Learn%20the%20Architecture/LearnTheArchitecture-MemoryManagement-101811_0100_00_en.pdf?revision=01a01804-ca64-4e19-a55e-2af56afea5a5
[2]
“The GNU allocator.” GNU. Available: https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html
[3]
Learn the architecture - ARMv8-a memory systems. arm, 2022. Available: https://documentation-service.arm.com/static/62d6777531ea212bb6627683

Footnotes

  1. Feature is currently uncertain.↩︎

  2. Cycle buffer is system-dependent.↩︎