psx.wiki
Log in
Main page
Hardware
Hardware tests
System software
SDKs
File formats
Games
Tools
History
All pages
page
view source
history
View source for Central Processing Unit (CPU)
← Central Processing Unit (CPU)
You do not have permission to edit this page.
Log in
to edit.
--- title: Central Processing Unit (CPU) type: component summary: 32-bit RISC processor at the center of the PlayStation. category: Hardware --- ## Overview The PlayStation uses a customized CPU based on the R3000A, which is a 32-bit RISC CPU. Its D-cache is used as a scratchpad, and fixed address areas are accessed with the same block number as cache memory. The specifications are as below:[^hw23] Table: CPU specifications | Item | Specification | | --- | --- | | System Clock | 33.8688 MHz | | Bus Width | 32 bit | | I cache | 4KB | | D cache | 1KB (Scratch Pad) | | Endian | Little | The basic part of the PlayStation is composed of the CPU with a main memory and an interrupt controller. The CPU contains an instruction cache and the scratchpad memory and manages the actual memory. The GTE (Geometry Transformation Engine) is a coprocessor of the CPU that performs coordinate transformation and light source calculation.[^hw14] The R3000 TLB, the virtual memory management device, is not mounted. The relationship between the physical address and the logical address of the memory space is therefore always fixed, as the [memory map](/hardware/memory-map/) shows.[^hw23] The following pages describe the CPU in detail: Table: CPU reference pages | Page | Content | | --- | --- | | [Instruction set](/hardware/cpu/instruction-set/) | Encoding, operation and timing of every instruction | | [COP0](/hardware/cpu/cop0/) | Exception, status, cache and debug registers | | [Memory map](/hardware/memory-map/) | Segments, mirrors and memory exceptions | | [I/O map](/hardware/io-map/) | Addresses of all hardware registers | | [Memory control](/hardware/memory-control/) | Bus timing, RAM and cache configuration registers | | [Interrupt controller](/hardware/interrupts/) | I_STAT, I_MASK and the interrupt sources | | [DMA controller](/hardware/dma/) | The 7 DMA channels | | [Root counters](/hardware/timers/) | The hardware timers | ## Memory There is 2 MB of main memory installed in the PlayStation, and a 512KB OS ROM holds the OS kernel and the boot loader. Sony prohibits access to the ROM and does not disclose its addresses.[^hw23] The kernel uses the first 64K bytes of main memory. Addresses for the application therefore begin at 0x00010000.[^ovr27] ## I-Cache The top 4 bits of a logical address determine whether the instruction cache (I-cache) is effective. Of the segments that correspond to memory devices, the I-cache is effective with A, B, P and Q but not with C and R. When it is effective, instruction codes are read into the I-cache in units, and an instruction found there needs no memory access over the bus.[^hw24][^hw25] The I-cache holds 1K words (4K bytes) and is 1-way mapped. Logical space is therefore divided into 4K-byte units, and these units are mapped onto the I-cache in multiplex.[^hw25] The I-cache is divided into 256 lines of 16 bytes, and each line holds the equivalent of 4 instructions. Each line has a tag that records whether its instructions have been read and stores the upper 20 bits of their memory address. When an instruction is fetched, the line is selected by the address, and the CPU reads the instruction from the line in 1 cycle if the tag matches.[^hw28] Sony's manual gives bits 5 to 12 of the address as the line number. psx-spx gives bits 4 to 11, so that 80001234h and 800F1234h both use line 23h and cannot be cached at the same time.[^hw28][^ic] On a miss the CPU reads the line from memory starting with the next cycle. If the target instruction is not on a line boundary, the instructions below it in the line are not read. The fill then takes 4 to 7 cycles into the R-buffer, plus one cycle to pass the line to the CPU.[^hw28] ### Tags and Valid Bits psx-spx gives the tag in more detail. Each tag holds bits 12 to 31 of the physical address and one valid bit for each of the 4 words. Because the tag holds the physical address, KUSEG and KSEG0 accesses to one location share a cache entry, while KSEG1 accesses bypass the cache.[^ic] A miss fills the line from the accessed word to the end of the line without wrapping. A fill entered at word 0 sets all four valid bits (0Fh), one entered at word 2 sets only those of words 2 and 3 (0Ch), and later fills of the same line add their valid bits. A tag that matches with the word's valid bit clear counts as a miss and refills the whole line.[^ic] Table: I-cache fill by entry word | Entry word | Words filled | Valid bits | | --- | --- | --- | | 0 | 0, 1, 2, 3 | 0Fh | | 1 | 1, 2, 3 | 0Eh | | 2 | 2, 3 | 0Ch | | 3 | 3 | 08h | The IBLKSZ field of the BCC register limits the burst length. With IBLKSZ = 0 a fill entered at word 0 reads only words 0 and 1 (valid bits 03h), while fills entered at words 1 to 3 are unaffected.[^ic] ### Self-Modifying Code Stores to RAM do not affect the I-cache, which is independent of the data write path. Code written over a cached address through either KSEG0 or KSEG1 therefore leaves the cached instructions in place, and the CPU runs the old instructions until the cache is flushed. Formula One 2001 loads new code over itself and relies on this behavior until it calls the FlushCache system call.[^ic] The I-cache is flushed by isolating the cache in COP0 SR and writing the tag memory through the BCC register. The [memory control](/hardware/memory-control/) page gives the BIOS sequence.[^bcc] ## Scratchpad The D-cache is composed of a high-speed memory housed in the CPU. It has a scratchpad structure and is mapped in the memory space as segment S, so that game programmers can access it. Both data and programs can be stored in this segment, but it is not a subject for DMA transmission.[^hw25] The scratchpad can read and write at high speed (once per cycle). Sony suggests the S segment as a way to raise execution speed.[^hw29][^os44] psx-spx adds the following. The scratchpad occupies 1F800000h to 1F8003FFh and is mirrored in KUSEG and KSEG0 only. Neither the kernel nor the Sony libraries use it, so the whole 1K is free for the program. However, it cannot execute code, and a jump into it raises a bus error on the first instruction fetch even with the swapped cache bit set in SR.[^sp] The hardware manual states that programs can be stored in the scratchpad, while psx-spx states that code there cannot run.[^hw25][^sp] ## Read and Write Buffers Three high-speed memories sit between the CPU and main memory to reduce access time: the I-cache and two buffer memories. The buffers are transparent to a running program. Their side effect is that the exact timing of a program cannot be predicted.[^hw27] The R-buffer is a single 4-byte register that buffers read data. Loading data from memory into the R-buffer takes 4 cycles and reading it from the R-buffer to the CPU takes 1 cycle, so a pure data read takes 5 cycles. The R-buffer cannot be accessed by bytes or halfwords. Reading one word as several bytes or halfwords therefore takes 5 cycles for each read instruction.[^hw28] The W-buffer is a FIFO of 4 registers of 4 bytes, and each write takes one register whatever its length. A write to the W-buffer takes 1 cycle, so the CPU does not wait for main memory. When all 4 registers are full the next write waits until the oldest is written to main memory. Writing one word from the W-buffer to main memory takes 4 cycles. Continuous writes to the same 1K-byte page take 2 more cycles for each further word, as the access timing table shows.[^hw28][^hw29] A write pending in the W-buffer completes before the CPU reads the same address. The read therefore always obtains the newest data, although write timing is otherwise not guaranteed.[^hw28] ### The Write Queue and I/O Registers psx-spx calls the W-buffer the write queue. It is meant for normal memory, and a device with an internal state machine can see its accesses in the wrong order. For example, the three writes of a JEDEC flash ID sequence followed by two reads reach the bus interleaved in the order store load store load store.[^wq] KSEG1 does not use the write queue, and any KSEG1 access stalls the CPU until the queue is empty. psx-spx therefore recommends the KSEG1 addresses for hardware registers (BF80180xh for the CD-ROM, for example). Sony's code uses the KUSEG addresses and writes 4 dummy values to flush the queue, while a single read of BFC00000h also flushes it.[^wq] ## Access Timing The cache and buffers are managed by the CPU and cannot be controlled from a program. It is therefore not possible to predict the exact number of cycles a segment of code needs. However, best and worst case times can be computed from the access timing below:[^hw29] Table: Memory access timing | Contents | Number of Words | Penalty Cycles | Required Number of Cycles | | --- | --- | --- | --- | | I-Cache to CPU | 1 | 0 | 0 | | ScratchPad to CPU | 1 | 0 | 0 | | Main Memory to I-Cache | 1 | 5 | 4 | | Main Memory to I-Cache | 2 | 6 | 5 | | Main Memory to I-Cache | 3 | 7 | 6 | | Main Memory to I-Cache | 4 | 8 | 7 | | Main Memory to CPU | 1 | 5 | 4 | | CPU to W Buffer | 1 | 0 | 0 | | CPU to ScratchPad | 1 | 0 | 0 | | W-Buffer to Main Memory | 1 | 0 | 4 | | W-Buffer to Main Memory (same page) | 2 | 0 | 6 | | W-Buffer to Main Memory (same page) | 3 | 0 | 8 | | W-Buffer to Main Memory (same page) | 4 | 0 | 10 | ## Address Alignment The R3000 requires strict address alignment. Word-length (4-byte) data must start at a multiple of 4, and halfword-length (2-byte) data at a multiple of 2. A data store, data load or instruction fetch that does not comply causes an address error.[^hw25] ## Registers The R3000 has 32 general-purpose registers of 32 bits and a program counter. The compiler assigns each register a use, and threaded code or assembler code must use the registers in the same way. The macros in the table are defined in asm.h.[^hw25] Table: R3000 general-purpose registers | Register # | Macro (1) | Macro (2) | Assembler | Assignment | | --- | --- | --- | --- | --- | | 0 | R_ZERO | R_R0 | Zero | 0 fixed | | 1 | R_AT | R_R1 | AT | Assembler reserves | | 2 | R_V0 | R_R2 | v0 | Function return value | | 3 | R_V1 | R_R3 | v1 | Return value (for double type) | | 4 to 7 | R_A0 to R_A3 | R_R4 to R_R7 | a0 to a3 | Arguments #0 to #3 | | 8 to 15 | R_T0 to R_T7 | R_R8 to R_R15 | t0 to t7 | Destroyed in function | | 16 to 23 | R_S0 to R_S7 | R_R16 to R_R23 | s0 to s7 | Saved in function | | 24 to 25 | R_T8 to R_T9 | R_R24 to R_R25 | t8 to t9 | Saved in function | | 26 to 27 | R_K0 to R_K1 | R_R26 to R_R27 | k0 to k1 | Kernel reserves | | 28 | R_GP | R_R28 | gp | Global pointer | | 29 | R_SP | R_R29 | sp | Stack pointer | | 30 | R_FP | R_R30 | fp | Frame pointer | | 31 | R_RA | R_R31 | ra | Return address | The hardware manual lists t8 and t9 as saved in a function. The PlayStation Operating System manual lists them as temporaries, and psx-spx agrees that a subroutine may change them. The same OS manual table lists R_T7 as a saved temporary.[^hw26][^os27][^reg] ### Register Conventions The assembler uses AT as a work area, and the C compiler and assembler programmers may not use it. The R3000 has no subroutine call. A jump instruction holds the return address in a register instead, and the compiler always uses RA for it.[^hw26] A C function receives up to 4 arguments in A0 to A3 in order from the left. With 5 or more arguments the rest are stored on the stack, where space is also reserved for the first 4 although their values travel in registers. A return value of 32 bits or less is stored in V0, and for a 64-bit double the high 32 bits are stored in V1.[^hw26][^os28] The R3000 has no stack either. The compiler keeps a stack pointer in SP and stores the head address of the function frame in FP, which is set to SP when a module starts.[^hw27] Memory access uses register indirect addressing with a signed 16-bit offset. The compiler therefore gathers up to 64K bytes of variables in a block called the bss section and keeps the center address of the block in GP. Any variable in the block is then reached by one instruction, and this global pointer does not change within the module.[^hw27] K0 and K1 are reserved for the kernel. An exception handler cannot preserve every register because it must load its return address into one (conventionally K0). Code that uses K0 must therefore be sure no interrupt or exception can occur, while the PlayStation kernel leaves K1 unchanged.[^reg][^rp] ## Program Counter The program counter cannot be accessed directly. It takes the following values:[^hw27] Table: Program counter values | Timing | Program Counter | | --- | --- | | Immediately after power on reset | 0xbfc00000 fixed | | When an external interrupt is generated | 0x00000080 fixed | | When an exception interrupt is generated | 0x00000080 fixed | ## Exceptions An error such as a bus error or a reserved instruction execution generates an exception. An exception jumps to 0x00000080 in the same way as an interrupt from a device, but it cannot be masked. The [COP0](/hardware/cpu/cop0/) page describes the exception codes, the status register and the return from an exception.[^hw27] ## References [^hw14]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 1-4. [^hw23]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-3, Table 2-1. [^hw24]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-4. [^hw25]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-5. [^hw26]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-6, Table 2-3. [^hw27]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-7, Figure 2-3, Table 2-4. [^hw28]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-8. [^hw29]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 2-9, Table 2-5. [^os27]: Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 2-7, Table 2-4. [^os28]: Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 2-8. [^os44]: Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 4-4. [^ovr27]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-7. [^ic]: psx-spx. Memory Map, i-Cache. https://psx-spx.consoledev.net/memorymap/ [^sp]: psx-spx. Memory Map, Scratchpad. https://psx-spx.consoledev.net/memorymap/ [^wq]: psx-spx. Memory Map, Write queue. https://psx-spx.consoledev.net/memorymap/ [^bcc]: psx-spx. Memory Control, FFFE0130h - BCC, BIU/Cache Configuration Register. https://psx-spx.consoledev.net/memorycontrol/ [^reg]: psx-spx. CPU Specifications, CPU Registers. https://psx-spx.consoledev.net/cpuspecifications/ [^rp]: psx-spx. Unpredictable Things, CPU Register Problems - R1 (AT), R26 (K0), R29 (SP). https://psx-spx.consoledev.net/unpredictablethings/