diff --git a/src/central-execution-engine-spec.adoc b/src/central-execution-engine-spec.adoc index f73dc6b..38289cd 100644 --- a/src/central-execution-engine-spec.adoc +++ b/src/central-execution-engine-spec.adoc @@ -4,9 +4,9 @@ include::custom-attributes.adoc[] :preface-title: Preface This document presents the public interface of an _Execution Engine_ of the {central-arch-name}. -This means that the amount of information pertaining to the internals of an _Execution Engine_ hardware implementation are kept at a minimum except when a choice in the public interface is specifically made to simplify said implementation. +This means that the amount of information pertaining to the internals of an _Execution Engine_ hardware implementation are kept to a minimum except when a choice in the public interface is specifically made to simplify said implementation. include::execution-engine-spec/glossary.adoc[] include::execution-engine-spec/intro.adoc[] -include::execution-engine-spec/registers.adoc[] +include::execution-engine-spec/channel-io-overview.adoc[] include::execution-engine-spec/instructions.adoc[] \ No newline at end of file diff --git a/src/execution-engine-spec/channel-io-overview.adoc b/src/execution-engine-spec/channel-io-overview.adoc new file mode 100644 index 0000000..3346bd6 --- /dev/null +++ b/src/execution-engine-spec/channel-io-overview.adoc @@ -0,0 +1,10 @@ +== Channel I/O Overview +Input/Output operations are handled by channels. +Channels are coprocessors that offload from the _Execution Engine_ the task of interacting with device controllers. +Channel operations are programmed using "`channel programs`" that are stored in main memory. + +Data flow inside a channel is two-way. The _Execution Engine_ can initiate read or write operations targeting a device and a device controller can initiate read or write operations targeting main memory. +Device controllers can signal events to a channel and the channel may send an interrupt request to the _Execution Engine_ for it to handle it (e.g. receiving a network packet from a channel connected network adapter). + +Multiple channels can be connected to an _Execution Engine_. + diff --git a/src/execution-engine-spec/glossary.adoc b/src/execution-engine-spec/glossary.adoc index 14a590f..5785630 100644 --- a/src/execution-engine-spec/glossary.adoc +++ b/src/execution-engine-spec/glossary.adoc @@ -4,19 +4,19 @@ [glossary] [horizontal] Processing Complex:: - The hardware enclosure and the hardware inside said enclosure. - Composed of _Processing Units_, memory modules & controllers, an I/O subsystem, an _HMC_ communications controller and various other components. + Composed of a _Processing Unit_, memory modules and subsystems that are not located inside of the _Processing Unit_ (e.g. Channel I/O Subsytem, Hardware Management Subsystem). + The name applies both to the hardware enclosure and the hardware inside said enclosure. Processing Unit:: - An hardware unit containing one or more _Execution Engines_, cache controllers, an interrupt controller, ... + An hardware unit containing the _Execution Engine_ and various subsystems (cache, memory, debug, etc...). Execution Engine:: The hardware responsible for the execution of user-written code, be it kernel code or user program code. - An _Execution Engine_ contains a fetch unit, a decode unit, a micro-instruction sequencer, an Arithmetic & Logic Unit, various registers and subsystems. + An _Execution Engine_ contains an instruction fetch unit, an instruction decode unit, a micro-instruction sequencer, an Arithmetic & Logic Unit and various registers. An _Execution Engine_ is analogous to an _hart_ in a RISC-V processor or to a _core_ in other CPU specifications. -HMC:: - Stands for Hardware Management Console. - This is a console directly attached to the _Processor Complex_ that is used to manage the different aspects of the hardware. +Hardware Management Console:: + Also refered as _HMC_ for the sake of brevity. + It is both a circuit and a console that is directly attached to the _Processor Complex_ and that is used to manage the hardware. For example, the HMC is reponsible for loading the _Boot Code_ into main memory and instructing the _Processing Units_ to begin executing code at a given address. diff --git a/src/execution-engine-spec/images/instruction-formats.adoc b/src/execution-engine-spec/images/instruction-formats.adoc index c30f0de..b12af0d 100644 --- a/src/execution-engine-spec/images/instruction-formats.adoc +++ b/src/execution-engine-spec/images/instruction-formats.adoc @@ -14,7 +14,7 @@ {reg: [ {bits: 7, name: 'opcode'}, {bits: 5, name: 'rd'}, - {bits: 5, name: 'rs'}, + {bits: 5, name: 'rs1'}, {bits: 15, name: 'imm'} ], config: {label: {right: 'B-Type'}}} .... diff --git a/src/execution-engine-spec/instructions.adoc b/src/execution-engine-spec/instructions.adoc index 46ac711..fa1e1f7 100644 --- a/src/execution-engine-spec/instructions.adoc +++ b/src/execution-engine-spec/instructions.adoc @@ -3,5 +3,30 @@ Multiple instruction encoding formats are used to encode multiple kinds of instructions. The source (rs1 and rs2) and destination (rd) registers are kept at the same position in all formats to simplify decoding. +For instruction encoding formats that contain an immediate value, not all immediate bits are used by all instructions sharing the format. The actual relevant bits are specified for these instructions. + include::images/instruction-formats.adoc[] +.Bit ranges legend +opcode:: + The operation to carry on. +rd:: + Destination register. +rs1:: + Source register 1. +rs2:: + Source register 2. +imm:: + Immediate value. +reg:: + Source/destination register on the _Execution Engine_ side. +sid:: + Subsystem ID. +sre:: + Source/destination register on the subsystem side. +cmd:: + Subsystem command. + +=== Instruction list +#TODO: List instructions# + diff --git a/src/execution-engine-spec/intro.adoc b/src/execution-engine-spec/intro.adoc index b697c54..bba388d 100644 --- a/src/execution-engine-spec/intro.adoc +++ b/src/execution-engine-spec/intro.adoc @@ -1,10 +1,10 @@ == Introduction === Overview -The {central-arch-name} is a 32-bits architecture meaning that most of the registers present in an _execution engine_ are 32-bits wide. +The {central-arch-name} is a 32-bits architecture meaning that most of the registers present in an _Execution engine_ are 32-bits wide. === Memory The {central-arch-name} uses byte-addressable memory. -While an _execution engine_ handles data 32-bits wide, memory addresses are only 24-bits wide. +While an _Execution engine_ handles data 32-bits wide, memory addresses are only 24-bits wide. An _Execution Engine_ can thus address up to 16MB of main memory. NOTE: We use the terms "`memory`" and "`main memory`" interchangably. Main memory refers to the RAM while we use the term "`secondary memory`" to refer to HDD or SSD storage. @@ -17,11 +17,11 @@ NOTE: The term "`memory accesses`" encompasses both read and write operations. Data is encoded in memory with the little endian scheme. For a given value, the least significant byte (LSB) is stored in the lowest address and the most significant byte (MSB) in the highest. -=== System modes and privilege levels +=== System Modes and Privilege Levels There are three system modes divided into two privilege levels. The privilege levels are `privileged` and `unprivileged`. -Some instructions can only be executed and some registers can only be accessed while running under a system mode belonging to the `privileged` privilege level. +Some instructions can only be executed, and some registers can only be accessed, while running under a `privileged` system mode. .System modes [cols="1,1"] @@ -52,41 +52,49 @@ Fault-mode:: Code executing under this mode can be used to log/report double faults and then reset/halt the system. Debug exceptions generated in supervisor-mode code are also handled in this mode, in which case control is passed back to supervisor-mode after handling. +include::registers.adoc[] + === Exceptions Exceptions are events that need to be acknowledged and handled by the system. -Exceptions change the state of the _execution engine_ so that privileged software can be executed to handle them. +Exceptions change the state of the _Execution engine_ so that privileged software can be executed to handle them. Exceptions thus always suspend user code for the duration of their handling. Exceptions can be of two types: *synchronous* and *asynchronous*. -==== Synchronous exceptions -Synchronous exceptions are generated from inside an _execution engine_. +==== Synchronous Exceptions +Synchronous exceptions are generated from events originating from inside of the _Execution engine_. They are a conditional or unconditional response to the execution of an instruction. SVC:: Supervisor call exceptions are generated when a user program calls the `svc` instruction. - Supervisor calls are used to perform privileged actions in a secure manner. + Supervisor calls are used to perform privileged actions in a secure manner as the kernel consistently performs security checks whenever it processes requests from user-mode software. -DataFault:: - A data fault is generated when an instruction references a memory address that is not mapped in virtual memory or that does not exist. - This exception is generated when read or writing memory as well as fetching an instruction. +MemFault:: + A memory fault is generated when an instruction references a memory address that is not mapped in virtual memory or is invalid (e.g. does not exist virtually and physically). + This exception can be generated when attempting to read or write memory as well as when attempting to fetch an instruction. SysTick:: This exception is generated each time a system programed timer ticks at regular intervals. This exception is used to implement context switching. Debug:: - TODO + This exception is generated when debug events are encountered. + + Such events can be: + * Executing a `bkpt` instruction, + * Fetching an instruction located at an address matching a configured _Hardware Breakpoint_, + * Accessing a memory address matching a configured _Hardware Watchpoint_ -==== Asynchronous exceptions -Asynchronous exceptions are generated from outside an _execution engine_. +==== Asynchronous Exceptions +Asynchronous exceptions are generated from events originating from outside of the _Execution engine_. These exceptions enable the system to react to its environment. -HMC:: - This exception is generated when the _hardware management console_ communicates with a _Processing Unit_ and that the _Processing Unit_ relays the event to an _Execution Engine_. +HardMgmt:: + This exception is generated when the _Hardware Management Console_ communicates with the _Processing Unit_ and that the _Processing Unit_ relays the event to the _Execution Engine_. Data can be passed alongside the exception and would be stored in main memory by the _Processing Unit_ communications controller. -IO:: - This exception is generated when an I/O device communicates with the _Execution Engine_. - Data can be passed alongside the exception and would be stored in main memory by the I/O system. +Channel:: + This exception is generated when an I/O device communicates with the _Execution Engine_ through a channel. + If data is passed alongside the exception then it is stored in main memory and ready to be read by the time this exception is generated. + +include::subsystems.adoc[] diff --git a/src/execution-engine-spec/registers.adoc b/src/execution-engine-spec/registers.adoc index b9870dd..c84c2e8 100644 --- a/src/execution-engine-spec/registers.adoc +++ b/src/execution-engine-spec/registers.adoc @@ -1,9 +1,9 @@ -== Registers -=== General Purpose Registers +=== Registers +==== General Purpose Registers General purpose registers (GPRs) are used to perform calculations and store intermediate values. There are 8 GPRs in an Execution Engine. These registers are named *_r0_* through *_r7_*. -=== Special Purpose Registers +==== Special Purpose Registers .Special purpose registers [cols="1,1,1,1,3"] @@ -65,5 +65,6 @@ There are 8 GPRs in an Execution Engine. These registers are named *_r0_* throug |Fault-mode stack pointer. |=== -#Add a Program Status Register (ALU flags C, Z, N, V and processor modes U, S, F), an Exception Status Register and a Channel Status Register. --> Or do we put it in subsystems?# +Other notable registers are accessible through <>. + +#TODO: Add the Program Status Register (ALU flags C, Z, N, V and processor modes U, S, F), Exception Status Register and the Channel Status Register in the Execution Engine State Subsystem.# diff --git a/src/execution-engine-spec/subsystems.adoc b/src/execution-engine-spec/subsystems.adoc new file mode 100644 index 0000000..4e59301 --- /dev/null +++ b/src/execution-engine-spec/subsystems.adoc @@ -0,0 +1,14 @@ +[id=subsystems-intro] +=== Subsystems +Subsystems are extra components interacting with an _Execution Engine_. + +.Examples of subsystems +* Execution Engine State Sybsystem +* Memory Management Subsystem +* Cache Control Subsystem +* Channel I/O Subsystem +* Debugging Subsystem +* Hardware Management Subsystem + +A generic interface is provided to interact with the subsystems through the use of the `ssr` and `ssw` instructions. +