Talea

The Central Processing Unit

This chapter discusses the nucleus of the Taleä Computer System. The Central Processing Unit is the component wich captains the machine, the piece that performs almost all calculations and manages the data flows of the system. I’ts understanding in depth is utterly necessary to achieve mastery over the computer.

Registers

The first step to understand Sirius (the Central Processing Unit) is to understand its basic component: the registers.

The registers are cells of quick access memory, and hold the data on wich the machine is operating in the moment. There are varius type of registers inside Sirius:

General purpose registers: there are 32 of these registers, labeled x0 to x31, or by the names in the Appendix A. They hold 32-bit integer values, and are the source or the destination of the majority of the operations that the machine can perform. However, it’s worth to notice that x0 is special: it behaves as a constant zero, wirtes do not affect this register, which always reads as 0.

Program Counter: it is a single 24-bit register, that keeps track of the memory location that Sirius will execute in the next cycle.

Stack Pointer: though the stack pointer corresponds to x2, it should be noticed that this register is different at different privilege modes.

Processor Status Register: this is a 32-bit register that keeps track of varius states of the processor and some system settings:

╭────┬───────┬───────┬─────┬───────┬───────┬────────╮
│s: 1│ irq: 1│ mmu: 1│ p: 3│ ivt: 6│ pdt: 8│ res: 12│
╰────┴───────┴───────┴─────┴───────┴───────┴────────╯
s: supervisor, irq: interrupt enable, mmu: mmu enable,
p: priority, ivt: interrupt vector table (value*1024),
pdt: page directory table (value*256), res: reserved

Memory

To perform task and complex calculations, a machine needs to manage data. As the registers are few, the system provides memory, a file of 8-bit wide cells (bytes), that can be read and written at will, though slower than registers. Memory also serves another main purpose in this machine: it provides itself the instructions to execute.

The Taleä Computer System provides two different types of memory: main memory, that can be read, written, and executed; and data memory, that can only be read or written and is only accesible in supervisor or privileged mode. It is possible to address up to 24 bits of addresses in main memory (roughly sixteen million seven hundred and fifty thousand bytes, 16 Mib), and 16 bits of addresses in data (sixty five thousand five hundred thirty six bytes, 64 Kib). Data memory serves thus as a way of tidily managing the system: many important structures, such as the interrupt vector table, input buffers, paging structures and I/O ports sit in this memory. This is the default memory map for the system:

╭───────────────────╮
│╭────────╮╭───────╮│
││Teletype││ 0x0000││ 6  bytes DEVICE 0x0
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Timer   ││ 0x0006││ 6  bytes DEVICE 0x0
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Keyboard││ 0x000c││ 4  bytes DEVICE 0x0
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Video   ││ 0x0010││ 16 bytes DEVICE 0x1
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││TPS     ││ 0x0020││ 6  bytes DEVICE 0x2
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Disk    ││ 0x0026││ 8  bytes DEVICE 0x2 
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Custom  ││ 0x0030││
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││........││.......││
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││System  ││ 0x00f0││ DEVICE 0xF
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││Dev Map ││ 0x0100││ DEVICE 0x10 (16)
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││........││.......││
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││IVT     ││ 0xf800││
│╰────────╯╰───────╯│
│╭────────╮╭───────╮│
││PDT     ││ 0xff00││
│╰────────╯╰───────╯│
╰───────────────────╯

The Taleä System default configuration reserves data memory from 0x0000 to 0x00ff for i/o devices, and provides three different coupled devices. Hardware devices contain up to 16 byte-size accessible registers for interface with the machine.

It’s worth noticing that devides 15 and 16 correspond to pseudo devices that provide information about the system and it’s configuration:

The system device is comprised by the following registers:

The device map (device 0x10) stores the device id for each device or 0 if it’s not installed.

Instruction Set

The instruction set for sirius is somewhat simple and reduced: it supports 70 instructions divided in 8 groups. All instructions are 32 bits long and encoded in big endian format. The binary representation of the instructions can be one of five forms:

╭────────┬──────────┬───────┬───────────────────────────────────┬──────────────╮
│group: 3│ opcode: 4│ reg: 5│ imm: 20                           │ ENCODING   I │
├────────┼──────────┼───────┼───────┬───────────────────────────┼──────────────╮
│group: 3│ opcode: 4│ reg: 5│ reg: 5│ imm: 15                   │ ENCODING  II │
├────────┼──────────┼───────┼───────┼───────┬───────────────────┼──────────────╮
│group: 3│ opcode: 4│ reg: 5│ reg: 5│ reg: 5│zero: 10           │ ENCODING III │
├────────┼──────────┼───────┼───────┼───────┼────────┬──────────┼──────────────╮
│group: 3│ opcode: 4│ reg: 5│ reg: 5│ reg: 5│ reg: 5 │ zero: 5  │ ENCODING  IV │
├────────┼──────────┼───────┼───────┴───────┴─────┬──┴──────────┼──────────────╮
│group: 3│ opcode: 4│ reg: 5│ zero: 12            │ vector: 8   │ ENCODING   V │
╰────────┴──────────┴───────┴─────────────────────┴─────────────┴──────────────╯

U instructions

Its group code is 0b010, and take ENCODING I.

J instructions

There is only a J instruction. Its group code is also 0b010, and takes ENCODING I.

B instructions

B instructions are conditional branches. Its group code is 0b011, and take ENCODING II. Its relative jump argument is also a signed two’s complement integer, must be 4 byte aligned, and makes thus the range effectively 17 bits.

I instructions

I instructions are loads and arithmetic operations, they involve several groups and take ECODING II. Its immediate argument need not be aligned, so the range remains 15 bit.

For this instruction, the relative offset must be 4 byte aligned. Group 0b100.

Load operations

Load operations use the group code 0b100, and load the value pointed to rs1 ± imm into rd. Loads from data memory are restricted to supervisor mode.

Artimetic operations with immediate values

These operations use the group code 0b101, and load the result of the operation between rs1 and imm into rd. imm is taken here as a two’s complement 15 bit integer, and thus, sign extended.

S instructions

S instructions are store operations, their group code is 0b111 and take ECODING II. Its immediate argument need not be aligned, so the range remains 15 bit. They store values into memory taking a base location in rs2 and an offset ±imm.

R instructions

R instructions are analogous to the I ones: they perform arithmetic operations, but over registers. They take thus ENCODING III and ENCODING IV. Their group code is 0b110.

M instructions

M instructions deal with data in bulk and data structures like stacks or buffers. Their group code is 0b001, and use ENCODING II and ENCODING III.

T instructions

T instructions are system management instructions. They use the group code 0b000 and take ENCODING V.

Interrupts and Exceptions

Interrupts are a mechanism that allow certain events in the system to interrupt Sirius’ normal processing in response to them. Exceptions arise from the program itself, be it as errors in it, wrong privilege level or other exceptional cause. Interrupts come from the outside and represent requests to the processor to respond to events.

The general workings are alike for both of them: a request is sent to Sirius with a priority level. If this priority level is strictly higher than the current’s cp priority (stored in psr), Sirius will acknowledge the interrupt. In doing so, it shall raise the privilege level to supervisor, save the state of the machine by pushing psr and pc onto the stack, equate the priority level of the request to its own, and proceed to process the handler requested (a byte that indexes into a vector table of 32-bit values, index = request * 4. The process for exceptios is the same, though they are always acknowledged. After an interrupt, Sirius shall restore the state of the machine as it was. After an exception, it will depend of the type: if it is a trap, it will continue after the instruction that caused it. If it is a fault, it will retry to execte the instruction that triggered it. If while processing a fault another fault occurs, a double fault shall arise, and most likely the system will shut down.

The interrupt vector table (IVT), sits in data memory, at location 0xf800 by default, and can be rearranged to 64 different points by writing the 6 bit psr field ivt. The hardware exception indexes cannot be rearranged, and are the following:

╭───────────────────┬─────╮
│Reset              │ 0x00│
├───────────────────┼─────┤
│Bus Error          │ 0x02│
├───────────────────┼─────┤
│Address Error      │ 0x03│
├───────────────────┼─────┤
│Illegal Instruction│ 0x04│
├───────────────────┼─────┤
│Division by Zero   │ 0x05│
├───────────────────┼─────┤
│Privilege Violation│ 0x06│
├───────────────────┼─────┤
│Page Fault         │ 0x07│
├───────────────────┼─────┤
│Access Violation   │ 0x08│
╰───────────────────┴─────╯

The different peripherals of the system define also their interrupts, their default indexes being:

╭──────────────────┬─────╮
│TTY Transmit      │ 0x0a│
├──────────────────┼─────┤
│KBD Character     │ 0x0b│
├──────────────────┼─────┤
│KBD Scancode      │ 0x0c│
├──────────────────┼─────┤
│TPS Load Finished │ 0x0d│
├──────────────────┼─────┤
│DISK Load Finished│ 0x0e│
├──────────────────┼─────┤
│TIMER Timeout     │ 0x0f│ 
├──────────────────┼─────┤     
│TIMER Interval    │ 0x10│
├──────────────────┼─────┤ 
│VIDEO Refresh     │ 0x11│
╰──────────────────┴─────╯

Memory Mapping Unit

The memory mamping unit (MMU) is a special part of Sirius. It can be enabled by writing to psr mmu_enable field, and it’s purpose is that of providing virtual memory: it provides a mapping between virtual, that is, arbitrary addresses, to physical ones, actual locations in memory. It only affects main memory, and its reason of existence is to provide a cleaner and more organized address space to programs.

When enabled, every read, write, or instruction fetch that Sirius executes, will undergo a translating process:

  1. The virtual address will be decomposed in various parts: a prefix to a page table directory (PDT), that lies in Data memory, and whose address is configurable by writing to psr pdt field (pdt_address = pdt * 256), a page table index, and and offset within tat page.
  2. The entry in the PDT shall contain a page table address, a real address pointing to another table in main memory.
  3. This page table will contain entries that indicate the physical locations of pages and their status at the index indicated by the virtual address (page_table[page_table_index] = page_real_address).
  4. The physical address shall then be the page’s real address plus the offset supplied.

The actual sizes of PDT, page tables and pages can be configured in hardware, but Sirius accounts for some status bits: w, wether the page is writable or not, x, wether it is executable, d, wether it has been written, and p, wether it is present and mapped to a frame in main memory. Trying to perform operations on pages that are not configured accordinly may raise exceptions, though none except p apply in supervisor mode.

Entries in the page table must be 2 bytes long, (a halfword) and contain this fields:

╭────────────────┬────────────────────────┬───┬───┬───────┬─────────╮
│Page Table Entry│Physical page address:12│w:1│x:1│dirty:1│present:1│
╰────────────────┴────────────────────────┴───┴───┴───────┴─────────╯
╭──────────────────────────┬─────────────────────────────────┬──────────╮
│Page Directory Table Entry│Physical address of Page Table:12│reserved:4│
╰──────────────────────────┴─────────────────────────────────┴──────────╯

The values for entries, and sizes, in bytes, are the following: