From 7a40807e86aa0d16714a8bf854075c739d52ca40 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sat, 16 Mar 2019 21:18:48 +0100 Subject: Update readme - include how CACHE and SYNCI instructions are implemented. Signed-off-by: Pavel Pisa --- README.md | 121 ++++++++++++++++++++++++++--------------- docs/exec-formats-and-tools.md | 4 +- 2 files changed, 79 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index ab45b8c..31fc320 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ and a pipeline model matches lecture slides prepared by Michal Štepanovský for The course is based on the book [Computer Organization and Design, The HW/SW Interface](https://www.elsevier.com/books/computer-organization-and-design-mips-edition/patterson/978-0-12-407726-3) written by professors Paterson and Henessy. -Additional documentation can be found in subdirectory ['docs'](docs) +Additional documentation can be found in subdirectory [`docs`](docs) of the project. Build Dependencies @@ -43,7 +43,7 @@ Compilation for Local Execution Because simulator it self and operating system stub are implemented as libraries you need to have that libraries in path where loader can found them. Binary looks for library at system library paths (on Windows in actual directory as well) and on compiled in -RPATH which is `../lib` (i.e., install into 'bin' and 'lib' directory is assumed): +RPATH which is `../lib` (i.e., install into `bin` and `lib` directory is assumed): ``` qmake /path/to/qtmips "QMAKE_RPATHDIR += ../qtmips_machine ../qtmips_osemu" @@ -64,7 +64,13 @@ Alternatively, you can setup LD_LIBRARY_PATH=/path_to_QtMips/qtmips_machine /path_to_QtMips/qtmips_osemu ``` -Accepted binary formats +Download Binary Packages +------------------------ + +* [https://github.com/ppisa/QtMips/releases](https://github.com/ppisa/QtMips/releases) - archives with Windows and generic GNU/Linux binaries +* [https://launchpad.net/~ppisa/+archive/ubuntu/qtmips](https://launchpad.net/~ppisa/+archive/ubuntu/qtmips) - Ubuntu packages for Disco, Cosmic, Bionic and Xenial releases. + +Accepted Binary Formats ------------------------ The simulator accepts ELF statically linked executables compiled for 32-bit big-endian MISP target. @@ -72,7 +78,7 @@ compiled for 32-bit big-endian MISP target. Optimal is use of plain mips-elf GCC toolchain. For more refer to the [supported executable formats](docs/exec-formats-and-tools.md) -documentation in the ['docs'](docs) projects subdirectory. +documentation in the [`docs`](docs) projects subdirectory. Tests ----- @@ -88,17 +94,25 @@ Peripherals ----------- The simulator implements emulation of two peripherals for now. - -The firs is simple serial port (UART) which transmission -(Tx) support only for now. Actual version implements only -two registers, the 'SERP_TX_ST_REG' is trasmit status register. -Bit 0 signals by value 1 that UART is ready and can -accept next character to be sent. -The second register 'SERP_TX_DATA_REG' is actual Tx buffer. -The LSB byte of written word is transmitted to terminal +Base addresses are selected such way that they are accessible +by 16 immediate offset which uses register 0 (`zero`) as base. + +The first is simple serial port (UART). It support transmission +(Tx) and receiption (Rx). Receiver status register (`SERP_RX_ST_REG`) +implements two bits. Read-only bit 0 (`SERP_RX_ST_REG_READY`) +is set to one if there is unread character available in +the receiver data register (`SERP_RX_DATA_REG`). The bit 1 +(`SERP_RX_ST_REG_IE`) can be written to 1 to enable interrupt +request when unread character is available. +The transmitter status register (`SERP_TX_ST_REG`) bit 0 +(SERP_TX_ST_REG_READY) signals by value 1 that UART is ready +and can accept next character to be sent. The bit 1 +(`SERP_TX_ST_REG_IE`) enables generation of interrupt. +The register `SERP_TX_DATA_REG` is actual Tx buffer. +The LSB byte of written word is transmitted to the terminal window. Definition of peripheral base address and registers -offsets follows including reserve for the future Rx port -implementation. +offsets (`_o`) and individual fields masks (`_m`) follows + ``` #define SERIAL_PORT_BASE 0xffffc000 @@ -114,13 +128,16 @@ implementation. #define SERP_TX_DATA_REG_o 0x0c ``` +The UART registers region is mirrored on the address 0xffff0000 +to enable use of programs initially writtent for [SPIM](http://spimsimulator.sourceforge.net/) +or [MARS](http://courses.missouristate.edu/KenVollmar/MARS/) emulators. The another peripheral allows to set three byte values concatenated to single word (read-only KNOBS_8BIT register) from user panel set by knobs and display one word in hexadecimal, -decimal and binary format ('LED_LINE' register). There are two +decimal and binary format (`LED_LINE` register). There are two other words writable which control color of RGB LED 1 and 2 -(registers 'LED_RGB1' and 'LED_RGB2'). +(registers `LED_RGB1` and `LED_RGB2`). ``` #define SPILED_REG_BASE 0xffffc100 @@ -172,19 +189,19 @@ Hardware/special registers implemented: Sequence to enable serial port receive interrupt: Decide location of interrupt service routine the first. The default address -is 0x80000180. The base can be changed (EBase register) and then PC is set +is 0x80000180. The base can be changed (`EBase` register) and then PC is set to address EBase + 0x180. This is in accordance with MIPS release 1 and 2 manuals. Enable bit 10 (interrupt mask) in the Status register. Ensure that bit -1 (EXL) is zero and bit 0 (IE) is set to one. +1 (`EXL`) is zero and bit 0 (`IE`) is set to one. -Enable interrupt in the receiver status register (bit 1 of SERP_RX_ST_REG). +Enable interrupt in the receiver status register (bit 1 of `SERP_RX_ST_REG`). -Write character to the terminal It should be immediately consumed by -the serial port receiver if interrupt is enabled in SERP_RX_ST_REG. +Write character to the terminal. It should be immediately consumed by +the serial port receiver if interrupt is enabled in `SERP_RX_ST_REG`. CPU should report interrupt exception and when it propagates to -the execution phase PC is set to the interrupt routine start address. +the execution phase `PC` is set to the interrupt routine start address. Some hints how to direct linker to place interrupt handler routine at appropriate address. Implement interrupt routine in new section @@ -231,27 +248,27 @@ Stop/end execution of the program. The argument is exit status code, zero means OK, other values informs about error. #### ssize_t [read](http://man7.org/linux/man-pages/man2/read.2.html)(int fd, void *buf, size_t count) __NR_read (4003) -Read 'count' bytes from open file descriptor 'fd'. The emulator maps +Read `count` bytes from open file descriptor `fd`. The emulator maps file descriptors 0, 1 and 2 to the internal terminal/console emulator. -They can be used without 'open' call. If there are no more characters to read +They can be used without `open` call. If there are no more characters to read from the console, newline is appended. At most the count bytes read -are stored to the memory location specified by 'buf' argument. +are stored to the memory location specified by `buf` argument. Actual number of read bytes is returned. #### ssize_t [write](http://man7.org/linux/man-pages/man2/write.2.html)(int fd, const void *buf, size_t count) __NR_write (4004) -Write 'count' bytes from memory location 'buf' to the open file descriptor -'fd'. The same about console for file handles 0, 1 and 2 is valid as for 'read'. +Write `count` bytes from memory location `buf` to the open file descriptor +`fd`. The same about console for file handles 0, 1 and 2 is valid as for `read`. #### int [close](http://man7.org/linux/man-pages/man2/close.2.html)(int fd) __NR_close (4006) -Close file associated to descriptor 'fd' and release descriptor. +Close file associated to descriptor `fd` and release descriptor. #### int [open](http://man7.org/linux/man-pages/man2/open.2.html)(const char *pathname, int flags, mode_t mode) __NR_open (4005) Open file and associate it with the first unused file descriptor number -and return that number. If the option 'OS Emulation'->'Filesystem root' -is not empty then the file path 'pathname' received from emulated -environment is appended to the path specified by 'Filesystem root'. +and return that number. If the option `OS Emulation`->`Filesystem root` +is not empty then the file path `pathname` received from emulated +environment is appended to the path specified by `Filesystem root`. The host filesystem is protected against attempt to traverse to -random directory by use of '..' path elements. If the root is not specified +random directory by use of `..` path elements. If the root is not specified then all open files are targetted to the emulated terminal. #### void * [brk](http://man7.org/linux/man-pages/man2/brk.2.html)(void *addr) __NR_brk (4045) @@ -260,34 +277,50 @@ The syscall is emulated by dummy implementation. Whole address space up to 0xffff0000 is backuped by automatically attached RAM. #### int [ftruncate](http://man7.org/linux/man-pages/man2/ftruncate.2.html)(int fd, off_t length) __NR_truncate (4092) -Set length of the open file specified by 'fd' to the new 'length'. -The 'length' argument is 64-bit even on 32-bit system and for +Set length of the open file specified by `fd` to the new `length`. +The `length` argument is 64-bit even on 32-bit system and for big-endian MIPS it is apssed as higher part and the lower part in the second and third argument. #### ssize_t [readv](http://man7.org/linux/man-pages/man2/readv.2.html)(int fd, const struct iovec *iov, int iovcnt) __NR_Linux (4145) -The variant of 'read' system call where data to read are would be stored -to locations specified by 'iovcnt' pairs of base address, length pairs stored -in memory at address pass in 'iov'. +The variant of `read` system call where data to read are would be stored +to locations specified by `iovcnt` pairs of base address, length pairs stored +in memory at address pass in `iov`. #### ssize_t [writev](http://man7.org/linux/man-pages/man2/writev.2.html)(int fd, const struct iovec *iov, int iovcnt) __NR_Linux (4146) -The variant of 'write' system call where data to write are defined -by 'iovcnt' pairs of base address, length pairs stored in memory -at address pass in 'iov'. +The variant of `write` system call where data to write are defined +by `iovcnt` pairs of base address, length pairs stored in memory +at address pass in `iov`. #### int [set_thread_area](http://man7.org/linux/man-pages/man2/set_thread_area.2.html)(unsigned long addr) __NR_set_thread_area (4283) -Set TLS base into 'C0' 'user_local' register accessible by 'rdhwr' instruction.. +Set TLS base into `C0` `user_local` register accessible by `rdhwr` instruction.. + +Special instructions support +--------------------------------- + +#### RDHWR - read hardware registers +Supported registers described in Interrupts and Coprocessor 0 Support section + +#### SYNC - memory barrier between preceding and following reads/writes +It is implemented as NOP because memory access is processed in order and only in the memory stage. + +#### SYNCI - synchronize/propagate modification to the instruction cache memory and pipeline +The function codes for different modes nor address/cache line which should be synchronized +is recognized. Instruction is implemented as full instruction and data cache flush. + +#### CACHE - cache maintenance operations +Function is not decoded, full flush of data and instruction caches is performed. Limitations of the Implementation --------------------------------- * Only very minimal support for privileged instruction is implemented for now. - Only RDHWR and some coprocessor 0 registers implemented. TLB and virtual - memory and complete exception model not implemented. + Only RDHWR, SYNCI, CACHE and some coprocessor 0 registers implemented. TLB and virtual + memory and complete exception model are not implemented. * Coprocessors (so no floating point unit and only limited coprocessor 0) * Memory access stall (stalling execution because of cache miss would be pretty annoying for users so difference between cache and memory is just in collected statistics) -* Only limited support for interrupts and exceptions. When 'syscall' or 'break' +* Only limited support for interrupts and exceptions. When `syscall` or `break` instruction is recognized, emulation stops. Single step proceed after instruction. List of Actually Supported Instructions diff --git a/docs/exec-formats-and-tools.md b/docs/exec-formats-and-tools.md index 85367c5..e2f29f3 100644 --- a/docs/exec-formats-and-tools.md +++ b/docs/exec-formats-and-tools.md @@ -83,8 +83,8 @@ instructions in the pipeline are discarded and execution stops. PC is set to the address of instruction causing the exception or to the branch instruction address if the exception occurs in delay slot. When the single step or continuous execution -is requested again then the "hardware" breakpoint exception -in the fetch stage is masked for the first executed instruction which. +is requested again then the "hardware" breakpoint exception +in the fetch stage is masked for the first executed instruction. But then CPU accepts breakpoint exceptions again. This is why it is not a good idea to set up breakpoint to address of an instruction in the delay slot. -- cgit v1.2.3