-
Notifications
You must be signed in to change notification settings - Fork 2
(DEPRECATED) VM design document (WIP)
Address size: 19bit? (=512K addresses) Inputs:
- 7 bit opcode
- 4 bit phase
- 8 flags!
- 8 registers in total
- General purpose: A, B, C, D, E
- Instruction Pointer IP
- Stack Pointer: SP
- Address Register: AR
- Control Registers
- Interrupt vector
- Flags (8)
- Supervisor or User mode
- Carry flag
- Overflow flag
- Zero flag
- Sign flag
- Interupts enabled
- Memory management enabled
- Compare
- 2^32 bytes total memory addressable
- 2^16 bytes accessible simultaneously (pointer size = 16bits)
- If MMU disabled, only 2^16 bytes available
- Page Table
- Vector Table
- 7bit opcodes
- 9bit arguments
- Input 1, input 2, output registers
- 8bit a
- 8bit b
- 1bit 8mode
- 2bit function
- 16bit out
- 4bit flags out
- Interrupts enabled flag
- Init data flag
- Interrupt request flag
- Data input - 16bit
- Power
- Ground
- Interrupt line
- Interrupt ID - 8 bit
- Data output - 16bit
Function called based on interrupt line and ID
Start - power connected Init data flag high - send device ID, 48bit id, unique to the device type (i.e. all devices with that ID should be able to use the same device drivers) Interrupt request flag - read data input, then process data provided
Data input used as address Data output used as data Interrupt
More than one phase? Some operations will take longer ie memory access through memory management system and disk access - how is mmu clocked? How long will it take to access ram? More than one microcode phase probably. What should be done during this time? Disconnect clock from system until data is provided? Should the microcode have to deal with it, ie by having multiple blank phases or phases where other work is happening? Multiple places will be requesting memory access, not necessarily at the same time (system, dma, …?) What should take priority? Round-robbin aproach? Could increase delay for data to be read and written. DMA and system could both be running simultaneously. Could the mmu be clocked twice as fast and have dma run 180deg out of phase from system?
Some of these are very long term / possibly/probably will not happen
- Build TTL circuit to implement a custom CPU.
- Write a simulator that can also run the programs for the CPU.
- Write an assembler and a (C Language? Something else?) compiler so programs can be written for this architecture.
- Write a custom kernel and operating system.
- Write a custom microcode assembler so the microcode can be expressed in text, rather than binary.
- HARD - other devices that might be possible
- VGA video
- ethernet/ internet connection
- Audio output
- GPIO
- Internal X and Internal Y - only accessible from microcode
- Process Register - current process running, used in memory management
- Fault ID register - identification for triggered fault.
- Shared Stack Top - the top of the shared stack
Microcode EEPROMs 10 bits - instruction 4 bits - phase 6 bits - flags ALU Flags Supervisor mode flag Interrupts and faults enabled flag Upper 4 bits of each instruction are unread. This makes it easier (possible?) to find the correct size eeproms to hold the microcode.
- 64 possible processes at one time
- 64 kiB maximum memory per process
- Default private memory pages
- Can have shared memory pages
- Process 0 is the kernel/OS
- Switching to process 0 turns on supervisor mode flag
- Leaving device 0 turns off supervisor mode
- A process does not have to run in a loop, it could instead provide a function table instead - eg the kernel
- Process 0's last page is accessible from every process for a shared stack, etc. This page is only writable by shared stack push/pop instructions but can be read like a normal, readonly page. This page should always be the last page in any process so interrupt returns from handlers defined in the process can return.
- A process can call functions defined in a table in the page used by the shared stack in order to call into the kernel - eg write to disk.
This is a page that each process can swap in, it is unique for each process though. It can be accessed by the kernel to transfer larger sections of data than could fit on the shared stack - useful for writing files to disk. IDK?
- 2kiB pages
- 32 pages per process
- 0th page for the process is process information and used for storing processor context - if processor context switches, register content is stored and read from here.
- All pages in process are in RAM, they do not have to exist - heap and stack memory etc is in process and only pages for the program source are initially allocated.
- If memory management is disabled - initially disabled, has to be enabled by os, only 2^16 bits of memory are accessible
- A process can ask the kernel to swap out pages - each process can have up to 64 pages including any pages shared to the process by other processes, however only 32 pages are accessible at any one time.
- Section 1 - process page table - sort of not a translation lookaside buffer
- Associative memory - maps virtual process memory to real memory - upper 5 bits of memory address are equal to page id
- 31 bit real address
- 1 bit - does page exist
- 64 entries per page * 32 pages
- Section 2 - real page table - all pages in system
- List of pages
- 1 bit - is page present in system
- 1 bit - is page a device or is it RAM
- 1 bit - is page writable - false for some devices and ROM
- 64 bits - one per process - processes that have permission to write to the page. Devices and ROM only have process 0 true, all others are false.
- Page table only writable in supervisor mode.
- If a page is requested that does not exist, eg a process trying to increase its heap size, then a page fault is triggered.
- In supervisor mode long (32 bit) addresses are enabled, to allow access to all memory
- Writing to the page table is enabled
- Memory management is disabled
- Supervisor mode is on by default.
- 16 Hardware interrupt lines
- 16 Interrupt handled lines
- Devices should turn on their interrupt line to signal an interrupt and only turn it off when there has been a signal on the device's interrupt handled line.
- Device 0 has the highest priority so its handler will run before any other interrupts triggered on same clock pulse. Device 1 is next highest, device 7 has the lowest priority, etc.
- If the phase counter is 0, interrupts are enabled and an interrupt line is active, the interrupt handler for that interrupt line is called. The interrupt handler is process 0, page 1. The interrupt handler can read from the interrupt lines and push that value onto the stack to identify which interrupt was called.
- A process can ask the kernel to register an interrupt handler which will be called by the interrupt handler in the kernel when the interrupt happens.
- First: Disable interrupts and faults
- Second: Save current context to current process's context store
- Third: Call registered handlers which will process stuff, set flags, etc
- Fourth: Reload a context from a process
- Fifth: Interrupts and faults are both automatically enabled by a microcode instruction inside the reload context instruction.
- In handlers faults and interrupts are disabled, so reads from/writes to non existent memory will be ignored, divide by 0 will silently fail, etc.
- Triggering a fault switches execution to page 2, process 0, which handles the fault. This handler works identically to an interrupt handler. Examples: Page fault, divide by 0.
- The fault handler can read from the fault ID register and push that value onto the stack to identify which fault occurred.
- Purpose of having both interrupts and faults? IDK? Faults could just use an interrupt line
- Real time clock - used to generate timer interrupts for process switching and to tell the time!
- UART/Serial computer connection to connect to a terminal
- Keyboard - main input method
- LCD panel - text output
- Hard Disk Drive / SD card / some non volatile writable storage
- Supervisor Call User - Push instruction pointer to shared stack, jump to userspace code.
- Handler Return - If interrupts and faults disabled, take value from top of shared stack and jump to that address in process 0 - kernel. This is used for interrupt handler and fault handler returns.
- Instruction set
- Schematic
- Software
- Block diagram
- Microcode instructions - how wide does the microcode need to be (32 bits?)