Coding vWii 3-core support - everything you need to know.

Discussion in 'Wii U - Hacking & Backup Loaders' started by Maxternal, May 9, 2013.

  1. Maxternal
    OP

    Maxternal Peanut Gallery Spokesman

    Member
    5,210
    2,073
    Nov 15, 2011
    Deep in GBAtemp addiction
    First off, for anyone who wants to download our teaser release, miscellaneous tools or just look at the code, the GoogleCode page can be found here : https://code.google.com/p/gbadev/

    . . .

    The title is what I hoped this thread will EVENTUALLY become
    (although now I realize it, at best, will become a place to post 3-core Linux development updates and, maybe, eventually, a 3-core library of sorts to try to add minimal ASMP 3-core support to libogc homebrew)

    I just thought I'd make a place where everyone who knows anything about this can contribute and compare notes with discoveries, code spinets, further detail on the process, etc.




    I'll start with what little I've found / come up with so far (Haven't found TOO much time between different day to day activities so if it seems too limited, don't complain about it, just add to it :) )


    First is Marcan's blog entry.
    http://fail0verflow.com/blog/2013/espresso.html
    Here's a summary of the process as I understood it
    1. Load your app into memory. It either needs to be loaded into memory areas that won't be overwritten with 1-200 when it's loaded and running or be prepared to load the rest of it later from a drive or NAND.
    2. The 1-200 title needs to be loaded into memory (1-200 that Marcan mentioned in the blog is a name based off hex values. This might be more commonly recognized as 1-512 or, more incorrectly, IOS512)
    3. Starting from PPC, work some magic to load some ARM code into memory and get it running.
    4. wait for and replace the right instruction with a link to your PPC code (this should already be in memory before or as part of step 3 since I'm not sure if you'll have time to load it at once 1-200 has started doing it's thing.)
    5. The PPC binary loaded at this point can either be the Linux kernel or you're traditional homebrew app. Either way, one of the first things it needs to do is init the cores
    #1, #2 : loading 1-512 into memory

    Since Mini didn't really have NAND file system support and we didn't really want to write that support into it, the above code also includes code to preload the 1-512 title into memory from the PPC side before running the ARM code. We were lucky that none of the memory addresses clashed so our Linux kernel, the 1-512 title AND the nSwitch code can all coexist at once in memory. To get access to this, we used AHBPROT access and patched out NAND access. (see code from #3 below)

    #3 : getting custom ARM code running to reset and watch PPC

    We used Mini as a base for ARM code and nSwitch as a base to get it running since it was already loading a version of Mini into memory and running it.
    Here's that code :
    https://code.google.com/p/gbadev/source/browse/nswitch/source/main.c
    Since the HackMii installer for Wii U doesn't install the BootMii IOS (which nSwitch depends on) We also included a WAD for that IOS in our repository. Crediar was also nice enough to hand us some code that could be used to load Mini WITHOUT using the BootMii IOS ... but since the IOS's built-in method of reloading an IOS (such as the BootMii IOS) shuts everything down nicely to make it ready for the new IOS being loaded ... with this new code WE had to do that part. We've only recently figured out how to do that and it now works fine for the v2.6 Linux Kernel (previously, it would get stuck when we used that loading method because it couldn't get access to Bluetooth or USB. The latter was needed for a keyboard and mouse to login with.) The v3.X Linux kernels, though, do NOT work with this loading method yet so we still have both code options in there.

    #4 : the actual race attack

    most of the code for that is to be found here ... as well as a lot of garbage I need to get rid of
    https://code.google.com/p/gbadev/source/browse/armboot/powerpc_elf.c

    #5 : Initializing the new cores

    I tried taking the pseudo-C code he had down there and converting it into Assembly like it should be. I don't have a lot of experience with assembly so it's obviously not complete (and may not have good syntax) but it's what I've got.
    - I put parenthesis after the SPR register numbers in his original code and then commented them out when replacing them with ASM.

    <original assembly moved to googlecode page. See link below>

    https://code.google.com/p/gbadev/source/browse/armboot/stubsb1/stub_sb_on.s
    This is on our GoogleCode page. I basically copied and pasted the assembly from here into that and then went through and figured out which lines I had to remove to make Linux not crash on me.

    (They're still there, just commented out or bypassed.)
    The
    bcr |= 0x08000000;
    in the global init and the
    if(pvr & 0xFFFF == 0x101)
    section had Linux getting stuck while the Linux kernel started up (and I can't remember if there was something else, too)

    and while with a few variations to make Linux run on core1 or core2 DID execute, their state coming out of a fresh reset (unlike core0 that comes out of the bootROM execution) also made them get stuck in the middle of the Linux kernel startup process.
    Also, in the above code, I mostly assumed on my first tests that Linux would already contain a lot of the "standard, boring init" sequences mentioned by Marcan so I left that out. It was good enough to get things running for now but all this code will eventually have to be unified to make sure everything is REALLY happening as it should



    - - - - - - - - - - - - - - - - - - - - - - - - -




    Alternate course of action
    My original idea was to just make a library that could be compiled into an app (creating a single DOL for each app that could be run from HBC) and be used to unlock and kickstart the extra cores and provide a simple means to run code on them. The problem with this is that we would need to get the IOS back in place in order to run any liboGC code. Without Boot2, Mini finds that difficult so we would need to patch the unlocking code into the IOS. THIS poses a problem because that process needs to invalidate the ARM cache which can only be done, to my knowledge, from the kernel and the kernel code for the IOS is in a memory location that PPC just CAN'T access even with AHBPROT disabled.

    This doesn't mean it's impossible ... it's just complicated.

    additional note : I was looking through this page http://wiibrew.org/wiki/IOS/Syscalls and it looks like syscalls 0x3F and 0x40 are to invalidate and flush the cache respectively. This is EXACTLY what I was looking for to be able to patch the race attack into the IOS. libogc number crunching here we come!!! (just as soon as I brush up a bit on my ARM assembly :P )

    Yet another note: while the syscalls to flush/invalidate the cache work just fine, it looks like the ones to reset PPC don't return until much after PPC has already finished running the bootROM (at which point it's too late for the race attack) so that means I'd either need to perform the race attack and the PPC reset in separate processes (assuming the ARM kernel doesn't just stop all userland processes while it's running) or patch the race attack into the IOS kernel itself. Now, the IOS kernel can't be edited from userland so we'd need to load a new kernel from NAND, pre-patch it and then get it to load reload into it. The thing here is that getting it to manually reload an IOS like that would make it a lot easier to just temporarily load MINI to do the race attack with the new IOS preloaded into memory and have MINI exit to the new IOS kernel when it's done. I've only made a couple of attempts at this but they've failed so that's where my next step lies.

    Current course of action
    What we're currently doing is taking advantage of the ELF loader built into the mini to make a kind of ELF forwarder DOL that unlocks and inits the cores with 1-200 and then run a second ELF file. I'll try to pack it up and post a link when I can but the code can be found at http://gbadev.googlecode.com/


    Links that might help


    Datasheets
    http://www.raidenii.net/files/datasheets/cpu/ppc_750cl.pdf
    https://www-01.ibm.com/chips/techli...9B20050FF778525699600719DF2/$file/6xx_pem.pdf

    assembly tutorials and references
    http://www.freescale.com/files/32bit/doc/app_note/AN1809.pdf
    a nice, basic, little tutorial on PowerPC assembly at WiiBrew : http://wiibrew.org/wiki/Assembler_Tutorial
    and another one from IBM http://www.ibm.com/developerworks/linux/library/l-powarch/
    aaand another one http://gchiesa.smos.org/pub/_documentation/ISA_PPC/


    SMP and Linux code
    http://lxr.free-electrons.com/source/arch/powerpc/kernel/smp.c?v=3.6;a=powerpc
    http://www.tldp.org/HOWTO/pdf/SMP-HOWTO.pdf
    https://launchpad.net/ubuntu/precise/ package/linux-image-3.2.0-23-powerpc-smp
    https://launchpad.net/ubuntu/quantal/ package/linux-image-3.5.0-37-powerpc-smp
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-Archive
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-3.4.y
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-2.6.32.y
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-2.6.34.y-POC
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-3.6.11-POC
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-3.0.y
    https://github.com/DeltaResero/GC-Wii-Linux-Kernel-3.10.y
    https://github.com/DeltaResero/GC-Wii-xf86-video-cube
    http://wiibrew.org/wiki/Linux
    http://wiibrew.org/wiki/WiiToo!
    http://www.gc-linux.org/wiki/MINI:KernelPreviewFive
    http://forum.wiibrew.org/list.php?29
    http://penguinppc.org/
    http://gbatemp.net/threads/linux-help-please.347856/

    http://forum.wiibrew.org/read.php?29,68339,68339 (Easy Wii Linux)

    Thanks to everyone helping me put these pieces together. (in particular, [user]comex[/user], [user]Crewman[/user] and [user]cory1492[/user] so far ... (and of course, Marcan for the blog post and some clarifying posts here) ) (this thank you list REALLY needs to be amplified)

    This OP still needs LOTS of updating and cleanup ... on my (rather lengthy) to-do list.
     


  2. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Continuing to edit myself out, lol
     
  3. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Continuing to edit myself out, lol
     
  4. comex

    comex Advanced Member

    Newcomer
    56
    59
    Jan 21, 2007
    United States
    C is unlikely to work here, because you don't have a stack. Just use a .s file, you already practically wrote the whole thing in assembly (which is, incidentally, unnecessary with asm(), since you can do the math and such in C, edit: and you shouldn't be using explicit registers with asm()).

    This is unlikely to work unless your assembler is magic, because andi is not an instruction and the operand is out of range. rlwinm is the best option if the mask you want is just bit A to bit B, otherwise load the mask into a register.

    just a variable.

    just copy libogc's init code.
     
  5. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Continuing to edit myself out, lol ol.
     
  6. Andy A

    Andy A Advanced Member

    Newcomer
    57
    8
    Feb 22, 2013
    Quick question to comex or anyone else who can answer, can messing with these registers cause a possibility to brick the wii U? If not I think I need to get off my arse and get a TV so I can start porting linux (If I ever get the time). Interesting stuff going on finally.
     
    Ray Lewis likes this.
  7. Maxternal
    OP

    Maxternal Peanut Gallery Spokesman

    Member
    5,210
    2,073
    Nov 15, 2011
    Deep in GBAtemp addiction
    I think all registers are reset when you turn the console off so there's no permanent changes this would do to the Wii U and nothing that could brick or damage it.
     
  8. Andy A

    Andy A Advanced Member

    Newcomer
    57
    8
    Feb 22, 2013
    The problem comes when it isn't expecting to run at 3 cores so it may turn the fans down or something like that, you are right in saying that all registers are reset on reboot as that is the nature or registers.
     
  9. Maxternal
    OP

    Maxternal Peanut Gallery Spokesman

    Member
    5,210
    2,073
    Nov 15, 2011
    Deep in GBAtemp addiction
    Hmm, that's a good point with the fans ... I would guess you might be able to hear the difference if it did but I don't know about that.
     
  10. Crewman

    Crewman Member

    Newcomer
    42
    20
    May 9, 2013
    Gambia, The
    Try it with:

    if (/*upir(1007) == 0*/ r3) //////////////////////////////////////////////////////
    cmp 0,r3,0x00
    bc 0x04,2,ENDIF

    asm("mfspr %r3,947");
    asm("andi %r3,%r3,0xBFFFFFFF");
    //scr(947) &= ~0x40000000; // scr, car, and bcr are global SPRs
    asm("mtspr 947,%r3");

    asm("mfspr %r3,947");
    asm("ori %r3,%r3,0x80000000");
    //scr(947) |= 0x80000000;
    asm("mtspr 947,%r3");

    asm("mfspr %r3,948");
    asm("ori %r3,%r3,0xfc100000");
    //car(948) |= 0xfc100000; // these bit assignments are unknown
    asm("mtspr 948,%r3");

    asm("mfspr %r3,949");
    asm("ori %r3,%r3,0x08000000");
    //bcr(949) |= 0x08000000;
    asm("mtspr 949,%r3");


    ENDIF


    This could be totally wrong, last time I programmed something in assembly was long time ago.
     
    Maxternal likes this.
  11. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Continuing to edit myself out, lol
     
  12. the_randomizer

    the_randomizer The Temp's official fox whisperer

    Member
    20,764
    9,762
    Apr 29, 2011
    United States
    Dr. Wahwee's castle
    Wow, ASM makes my eyes bleed, but it is something I want to learn for sure; I've yet to find useful info on getting started. Glad to see people rolling things into motion.
     
    filfat and Maxternal like this.
  13. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Continuing to edit myself out, lol
     
  14. the_randomizer

    the_randomizer The Temp's official fox whisperer

    Member
    20,764
    9,762
    Apr 29, 2011
    United States
    Dr. Wahwee's castle
    Don't worry, you will get the support.
     
  15. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Useless babbling of an idiot; edited (per Sven, Marcan et al)
     
    Maxternal likes this.
  16. Ray Lewis

    Ray Lewis Banned

    Banned
    1,518
    386
    Dec 30, 2012
    United States
    Useless babbling of an idiot; edited (per Sven, Marcan et al)
     
    Maxternal likes this.
  17. the_randomizer

    the_randomizer The Temp's official fox whisperer

    Member
    20,764
    9,762
    Apr 29, 2011
    United States
    Dr. Wahwee's castle
  18. Maxternal
    OP

    Maxternal Peanut Gallery Spokesman

    Member
    5,210
    2,073
    Nov 15, 2011
    Deep in GBAtemp addiction
    it says it's been updated much more recently than the stuff on wiibrew. that could prove useful.
     
    the_randomizer likes this.
  19. the_randomizer

    the_randomizer The Temp's official fox whisperer

    Member
    20,764
    9,762
    Apr 29, 2011
    United States
    Dr. Wahwee's castle
    Me gusta. That is all. :P
     
  20. comex

    comex Advanced Member

    Newcomer
    56
    59
    Jan 21, 2007
    United States
    I wouldn't worry about bricking unless I was messing with the NAND. Or messing willy-nilly with IOS-U, the way I bricked my first Wii U :(