diff --git a/memorymap.md b/memorymap.md index 67889dc..327af6a 100644 --- a/memorymap.md +++ b/memorymap.md @@ -7,7 +7,7 @@ 1F800000h 9F800000h -- 1K Scratchpad (D-Cache used as Fast RAM) 1F801000h 9F801000h BF801000h 8K I/O Ports 1F802000h 9F802000h BF802000h 8K Expansion Region 2 (I/O Ports) - 1FA00000h 9FA00000h BFA00000h 2048K Expansion Region 3 (whatever purpose) + 1FA00000h 9FA00000h BFA00000h 2048K Expansion Region 3 (SRAM BIOS region for DTL cards) 1FC00000h 9FC00000h BFC00000h 512K BIOS ROM (Kernel) (4096K max) FFFE0000h (KSEG2) 0.5K I/O Ports (Cache Control) ``` @@ -25,11 +25,11 @@ Additionally, there are a number of memory mirrors.
#### KUSEG,KSEG0,KSEG1,KSEG2 Memory Regions ``` - Address Name Size Privilege Code-Cache Data-Cache - 00000000h KUSEG 2048M Kernel/User Yes (Scratchpad) - 80000000h KSEG0 512M Kernel Yes (Scratchpad) - A0000000h KSEG1 512M Kernel No No - C0000000h KSEG2 1024M Kernel (No code) No + Address Name i-Cache Write-Queue + 00000000h KUSEG Yes Yes + 80000000h KSEG0 Yes Yes + A0000000h KSEG1 No No + C0000000h KSEG2 (No code) No ``` Kernel Memory: KSEG1 is the normal physical memory (uncached), KSEG0 is a mirror thereof (but with cache enabled). KSEG2 is usually intended to contain @@ -39,22 +39,29 @@ processors), the PSX doesn't support virtual memory, and KUSEG simply contains a mirror of KSEG0/KSEG1 (in the first 512MB) (trying to access memory in the remaining 1.5GB causes an exception).
-#### Code Cache -Works in the cached regions (KUSEG and KSEG0).
+#### i-Cache +The i-Cache can hold 4096 bytes, or 1024 instructions.
+It is only active in the cached regions (KUSEG and KSEG0).
There are reportedly some restrictions... not sure there... eventually it is using the LSBs of the address as cache-line number... so, for example, it couldn't simultaneously memorize opcodes at BOTH address 80001234h, AND at address 800F1234h (?)
-#### Data Cache aka Scratchpad -The MIPS CPU usually have a Data Cache, but, in the PSX, Sony has misused it as -"Scratchpad", that is, the "Data Cache" is mapped to a fixed memory location at -1F800000h..1F8003FFh (ie. it's used as Fast RAM, rather than as cache).
-There \ be a way to disable that behaviour (via Port FFFE0130h or +#### Scratchpad +MIPS CPUs usually have a d-Cache, but, in the PSX, Sony has assigned it as +what's referenced as the "Scratchpad", mapped to a fixed memory location at +1F800000h..1F8003FFh, ie. it's used as Fast RAM, rather than as cache.
+There \ be a way to disable that behavior (via Port FFFE0130h or so), but, the Kernel is accessing I/O ports via KUSEG, so activating Data Cache would cause the Kernel to access cached I/O ports.
-Not tested yet, but most probably the Scratchpad can be used only for Data (ie. -NOT for program Code?).
+The purpose of the scratchpad is to have a more flexible cache system available +to the programmer. Neither the kernel nor the Sony libraries will try to make use +of it, so it is therefore completely up for grabs to the programmer. A good example +would be if you were to write a piece of code that's doing a lot of CRC computation, +to use the 1KB scratchpad to initially load the CRC lookup tables, which incidentally, +is exactly 1KB large. Doing this will relieve SDRAM page changes overhead while reading +the data to checksum linearly, while also keeping the whole CRC code in the i-Cache, +hence being more optimal than what you'd get with an automatic d-Cache system. #### Memory Mirrors As described above, the 512Mbyte KUSEG, KSEG0, and KSEG1 regions are mirrors of @@ -78,6 +85,60 @@ The Scratchpad is mirrored only in KUSEG and KSEG0, but not in KSEG1.
(unless RAM/BIOS/Expansion mirrors are mapped to "unused" area) ``` +#### Write queue +The MIPS CPU has a 4-words deep pass-through write queue, in order to relieve +some bus contention when writing to memory. If reading the same memory location +that just got written into the write queue, it will first be flushed before +being read back from memory.
+It is important to realize that the write queue's mechanism is only viable for +normal memory attached to the main CPU, and that any hardware register state machine +will get messed up by it.
+The typical example is the typical JEDEC standard to access flash, which usually does +the following sequence to read the ID of a flash chip: +```C + base[0xAAA] = 0xAA; + base[0x555] = 0x55; + base[0xAAA] = 0x90; + uint8_t mnfctrID = base[0x000]; + uint8_t deviceId = base[0x002]; +``` + +In this example above, if `base` is located in a memory segment that has the write queue +enabled, even if the low level assembly code will do the first 3 stores before doing 2 loads, +the physical signals sent to that device through the CPU bus will be seen in the sequence: +``` +store(0xaaa, 0xaa) +load(0x000) +store(0x555, 0x55) +load(0x002) +store(0xaaa, 0x90) +``` + +Therefore, using KSEG1 that disables the write queue is the only way to ensure that the +operations are done in the proper way. + +The above is valid for most of the hardware connected to the main CPU, such as the CDROM +controller, exp1, exp2, the SPU, or the GPU. Therefore, using BF80180xh to access the +CDROM registers is more correct than using 1F80180xh. + +It is noteworthy that the Sony code will still incorrectly use KUSEG as the memory map +for all hardware registers, and they then spend a lot of time writing 4 dummy values +somewhere, in order to ensure the write queue has been flushed. + +The SN debugger in contrast is properly using the KSEG1 memory map for all the hardware +registers, nullifying the need to flush the write queue when accessing it. + +It's also noteworthy that doing ANY KSEG1 access (read OR write) will automatically stall +the CPU in order to flush the whole write queue before proceeding with the operation. +Therefore, all BIOS ROM operations will naturally and effectively have the write queue +disabled, as this code requires the CPU to read from KSEG1 constantly. + +This also means that if using KUSEG for the hardware registers, another method to flush +the write queue, albeit potentially slightly less efficient, would be to simply read +the first byte located at BFC00000h. The latter is what is effectively described as the +official method to flush the write queue in the MIPS handbook. This could be potentially +useful to flush the write queue all at once, instead of flushing it word by word. + #### More Memory Info For Info on Exception vectors, Unused/Garbage memory locations, I/O Ports, Expansion ROM Headers, and Memory Waitstate Control, etc. see: