I'm trying to understand the Wii memory architecture so I can better grasp how Dolphin works, but I've hit a stumbling block.
I'm using the following as references:
* User manual for PPC 740/750 (https://www-01.ibm.com/chips/techlib/tec...96006C28E2)
* Programming Environments Manual for 32-Bit Implementations of the. PowerPC™ Architecture (http://www.freescale.com/files/product/d...FPE32B.pdf)
(As best as I can tell, these datasheets correspond to the CPU codenamed "Broadway" that the Wii uses.)
As I understand it, when address translation is enabled, there are three types of addresses that are in use:
* 32-bit CPU Virtual addresses (those used by all memory accesses generated within the CPU proper, including load/store, instruction fetch, etc.)
* 52-bit(!) MMU Virtual addresses (those used by the MMU to do page-table lookups for virtual->physical mapping)
* 32-bit Real/physical addresses (those that show up on the memory bus connecting the MMU to RAM and memory-mapped devices and whatnot)
Furthermore, my understanding is this:
* Point 1: The upper 4 bits of CPU virtual addresses specify one of sixteen segment registers. The low-order 24 bits of that segment register are combined with the low-order 28 bits of the CPU virtual address to get the MMU virtual address
I jailbroke a Wii and wrote a little Homebrew program to dump out the sixteen segment registers. The results were not what I expected: I see 0x80000000 for all SRs!
That would indicate that all segments are direct-store segments, except that my docs say that the 750 doesn't support direct-store segments.
I then modified my program to print the MSR. The output is: 0x0000b032, which according to my docs is:
EE=1 PR=0 FP=1 ME=1 IR=1 DR=1 RI=1
In particular, DR=1 and IR=1 means that address translation is, in fact, enabled for both loads/stores and for instruction fetches.
I then tried this:
* Create a global variable and set it to 42.
* Take the address of that variable (0x80034c60)
* Set the upper 4 bits to 0111 (0x70034c60)
* Read the value at that address.
Source: http://www.klozoff.org/wii/hwinfo/
(Main file: http://www.klozoff.org/wii/hwinfo/source/hwinfo.c
If SR7 and SR8 contain the same data, then 0x70034c60 and 0x80034c60 should generate the same virtual addresses, and thus generate the same physical adddresses. Therefore, they should reference exactly the same memory, and the answer should be 42.
What I actually see happen is:
* On Dolphin (4.0-5099), the value printed for *(int*)0x70034c60 is 0, instead of 42.
* On a real Wii, the program crashes with a DSI exception at the point where it attempts to dereference the mangled pointer.
Obviously, I am missing something. But what?
I'm using the following as references:
* User manual for PPC 740/750 (https://www-01.ibm.com/chips/techlib/tec...96006C28E2)
* Programming Environments Manual for 32-Bit Implementations of the. PowerPC™ Architecture (http://www.freescale.com/files/product/d...FPE32B.pdf)
(As best as I can tell, these datasheets correspond to the CPU codenamed "Broadway" that the Wii uses.)
As I understand it, when address translation is enabled, there are three types of addresses that are in use:
* 32-bit CPU Virtual addresses (those used by all memory accesses generated within the CPU proper, including load/store, instruction fetch, etc.)
* 52-bit(!) MMU Virtual addresses (those used by the MMU to do page-table lookups for virtual->physical mapping)
* 32-bit Real/physical addresses (those that show up on the memory bus connecting the MMU to RAM and memory-mapped devices and whatnot)
Furthermore, my understanding is this:
* Point 1: The upper 4 bits of CPU virtual addresses specify one of sixteen segment registers. The low-order 24 bits of that segment register are combined with the low-order 28 bits of the CPU virtual address to get the MMU virtual address
I jailbroke a Wii and wrote a little Homebrew program to dump out the sixteen segment registers. The results were not what I expected: I see 0x80000000 for all SRs!
That would indicate that all segments are direct-store segments, except that my docs say that the 750 doesn't support direct-store segments.
I then modified my program to print the MSR. The output is: 0x0000b032, which according to my docs is:
EE=1 PR=0 FP=1 ME=1 IR=1 DR=1 RI=1
In particular, DR=1 and IR=1 means that address translation is, in fact, enabled for both loads/stores and for instruction fetches.
I then tried this:
* Create a global variable and set it to 42.
* Take the address of that variable (0x80034c60)
* Set the upper 4 bits to 0111 (0x70034c60)
* Read the value at that address.
Source: http://www.klozoff.org/wii/hwinfo/
(Main file: http://www.klozoff.org/wii/hwinfo/source/hwinfo.c
If SR7 and SR8 contain the same data, then 0x70034c60 and 0x80034c60 should generate the same virtual addresses, and thus generate the same physical adddresses. Therefore, they should reference exactly the same memory, and the answer should be 42.
What I actually see happen is:
* On Dolphin (4.0-5099), the value printed for *(int*)0x70034c60 is 0, instead of 42.
* On a real Wii, the program crashes with a DSI exception at the point where it attempts to dereference the mangled pointer.
Obviously, I am missing something. But what?