[PS2] POPS stuff & POPStarter

Discussion in 'Sony Programming and Development' started by krHACKen, Apr 9, 2013.

  1. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    While the version number in the module should be reflected in ROMIMG, I remember giving all modules version 99.99 in ROMIMG. There is no problem.

    We replace EESYNC to save on space (newer versions of EESYNC allocate memory, for some reason that I never found). If I remember right, EESYNC from DNAS games also contain a module that quietly does a memory wipe.
     
    Last edited: Jan 12, 2018
    AlGollan84 and ps2netbox like this.
  2. brian patrick mahoney

    brian patrick mahoney Newly Registered

    Joined:
    Jan 12, 2018
    Messages:
    1
    Likes Received:
    0
    Hello sp193. I would very much like to connect with you over email or some other way. I have sent an email to you on your yahoo email account that is listed on your geocities. Is that a good way to contact you? If not please reach out to me at brian.pat.mahoney@gmail.com thank you.
     
  3. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    After test , eesync version number of 0x101( use eesync from POPS ) and 0x303( use eesync of OPL's ) get same result in PCSX2.
    I will test on a real machine .
    These codes are both at ee side .After some debug , I think this is what popstarter have done .
    My goal is make an always resident ( even after reboot) iop side irx .
    So I can provide fake usbd.irx / usbdhsfsd.irx to popstarter ,and mc0:/boot/boot.elf after POPS igr 。
    This is easier for me , than hack POPS or POPstarter .

    Yes it is !
     
    Last edited: Jan 12, 2018
  4. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    In OPL, an IOPRP image is generated. As you observed, the version numbers of the modules must be higher than the one supplied by the game (and the ROM).

    IOPRP image generation: https://github.com/ifcaro/Open-PS2-Loader/blob/master/src/ioprp.c
    Location within system.c where patch_IOPRP_image is called: https://github.com/ifcaro/Open-PS2-Loader/blob/master/src/system.c#L450
    Base IOPRP file (this is not a complete IOPRP image on its own): https://github.com/ifcaro/Open-PS2-Loader/blob/master/modules/iopcore/IOPRP.img

    patch_IOPRP_image() will generate a IOPRP image, with the supplied the IOPRP image (ioprp_image), and the supplied modules: CDVDMAN, CDVDFSV and EESYNC.

    If you extracted the IOPRP image after generation, you will find that the IOPRP image contains CDVDMAN, CDVDFSV and EESYNC. All 3 of these files will have a version number of 99.99 in EXTINFO, even if their actual version numbers are different. UDNL will select the modules based on the version number identified from EXTINFO.

    ***

    But I think you may have some problem because POPStarter may not just call sceSifIopReboot() like retail games.

    Since POPStarter does not reboot with an IOPRP image from CD/DVD, it will have to use a method like this one (UDNL can only access IOPRP images from known devices): https://github.com/ps2dev/ps2sdk/blob/master/ee/iopreboot/src/SifIopRebootBuffer.c#L121

    So if you try to replace the custom IOP reboot process with your own version by intercepting an IOP reboot SIFCMD packet, it may not allow you to actually load your modules.
     
    AlGollan84 and kHn like this.
  5. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    POPS(tarter ) realy do something like :
    Code:
    SifLoadModuleSpecial("rom0:UDNL", 11, "img0:\0img1:", 1);
    
    because I get log :
    Code:
    loadmodule: fname rom0:UDNL args 5 arg crap:
    Hook_StartModule rom0:UDNL crap:
    
    After catch that , I do
    Code:
    StartModule("rom0:UDNL",..., "img0\0crap");
    
    In img0 , is my ioprp image , containe eesync of my self version .

    By using a version number 0x303 , custom eesync really loaded by udnl.
     
  6. kHn

    kHn Rising Member

    Joined:
    Oct 11, 2017
    Messages:
    56
    Likes Received:
    189
    Not sure when SifIopRebootBuffer was added to the PS2SDK, but yeah, that is what POPStarter does. As seen on $ONYs' utility discs, dnasload and stuff...
    I've been re-using this code in all my programs that need to reset the IOP with an embedded/buffered IOP replacement image. In things like my standalone DVD player ELFs, repacked DNAS HDD apps, and POPS-00001 which is based on the same code as my DVD players lol.
    And very lately, sp193's UDNL IRX solution in my System2x6 productions:):):).
     
  7. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    Popstarter related work is done , and there is bonus, IOP side only game loader core .
    When I am free ,I will try to test some game.
     
    kHn likes this.
  8. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    It was added not too long ago. I was thinking about how it should have been used to get modules into the IOP, even though we (homebrew developers) generally do not do it.
    I standardized this because there are some projects that use it.

    Thank you. :D

    This deserves a mention: all PlayStation 2 consoles have rom0:UDNL, which is also known as the updater module. An updater module selects modules for the final phase of the IOP reboot process, based on version number. Modules are selected out of a list of IOPRP images that specified (from the last one specified to the first, before checking rom0) from the arguments list.

    The module list is IOPBTCONF. UDNL will choose the first one it encounters. It is also possible for IOPBTCONF to include another file.
    However, due to the design of its parsing, it will only choose modules that are present in the image after the one that contains the file that IOPBTCONF includes. I wrote an explanation for this in the README file for my UDNL module, but it isn't a major issue unless one does use this function.

    UDNL modules may have an IOPRP image embedded within them. rom0:UDNL does not, although it has (broken code) for supporting one. The DVD player UDNL module does not allow an image list to be specified, and so it only reboots with the internal IOPRP image.

    The difference between the UDNL module that I put into OPL and rom0:UDNL (as well as the one used in FMCB), is to disable all DMA channels before loadcore is booted. While MODLOAD's ReBootStart function will always terminate resident libraries (and hence DMACMAN will disable all DMA channels) before doing anything further, MODLOAD doesn't do that before booting UDNL... and neither does UDNL itself. As a result, it is implied that all devices that UDNL would have officially supported, will not act on their own. Unfortunately, that does not work for at least USB, since the USB OHCI controller can access IOP RAM on its own. In early versions of the current OPL EE core design, some games would fail to boot because the USB OHCI controller would corrupt IOP RAM during the IOP reboot.
     
    uyjulian, svotib, kHn and 1 other person like this.
  9. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    How ? why not udnl use this method instead of simple disable dma channel ?

    I am not sure what will happed if :
    1) atad transfer data using dma eg , a large size 16KB.
    2) some bytes are transfered . eg , 1024+32.
    3) udnl is called .
    4) dma channel is disabled.
    this may be a problem . since hardware is request dma ( eg . #DRQ is asserted ).
    5) atad is reloaded .
     
  10. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    No, they are different things.

    I should write an article about the IOP reboot process. The original information I got was from a Chinese (?) user known as Tiamo, I think. That was in 2009 and I cannot seem to find his write-up anymore.

    The IOP reboot steps (IOP side only) are something like:
    1. REBOOT receives reboot SIFCMD command (contains command line).
    2. REBOOT thread calls MODLOAD's ReBootStart.
    3. ReBootStart() will terminate all resident modules and pass the command line to IOPBOOT..
    4. IOPBOOT will handle the boot up of the IOP.
      • If there is an updater module specified, then it will enter boot mode 2 and load the modules listed in IOPBTCON2.
      • If there is no updater module specified, then it will jump to boot mode 3 (update complete). The modules listed in IOPBTCONF are loaded and the boot process ends here.
      • SYSMEM and LOADCORE are always the first two modules loaded. LOADCORE will carry on with the boot process, from either IOPBOOT or UDNL.
    5. If it is boot mode 2, then MODLOAD will load the specified UDNL module and pass the command line to it.
    6. UDNL will handle the final part of the IOP reboot process. However, UDNL is booted without terminating loaded modules. UDNL will not terminate modules either, before loading SYSMEM and LOADCORE.
    As IOPBTCON2 only supports devices like CD/DVD and Memory Card, it is not possible to issue a SifIopReboot/SifIopReset with a device that the boot ROM does not support.

    Won't the reset function fix this?
     
    Last edited: Jan 21, 2018
    AlGollan84 and svotib like this.
  11. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    If before modload ,LOADCORE is loaded ,usbd's stop is called .
    It is a bug in usbd's stop function , so we should fix it here not by udnl module .
    If udnl do really load DMACMAN, we should no need to do anything ...

    This code may be have a bug , it should wait any pending io transfer to be done .
    Code:
    static int ata_bus_reset(void)
    {
    USE_SPD_REGS;
    SPD_REG16(SPD_R_IF_CTRL) = SPD_IF_ATA_RESET;
    DelayThread(100);
    SPD_REG16(SPD_R_IF_CTRL) = 0; //Not present in v1.04.
    SPD_REG16(SPD_R_IF_CTRL) = 0x48;
    DelayThread(3000);
    return ata_wait_busy();
    }
    
     
  12. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    No, LOADCORE will not unload any modules. In fact, when LOADCORE is loaded by IOPBOOT/UDNL, it does not know of any other module (except for SYSMEM).

    There is no code in USBD to disable the USB DMA channel, but DMACMAN does disable all DMA channels upon shutdown. Given that no other Sony module seems to disable the DMA channel upon unload, perhaps they intended the DMACMAN shutdown process to shut down all DMA channels.
    Even if you added code to USBD to disable the DMA channel upon module unload (_exit), UDNL will not call the module's _exit function.

    Of all DMA channels, only USB (channel 'U') and the i.Link DMA channels can access IOP RAM on their own. However, the PlayStation 2 doesn't support these devices for IOP reboot. It is also possible that they intended specific devices to be used for storing IOPRP images - and USB/i.Link are not included.

    ReBootStart() terminates all modules. But that is at the very start. I have updated my earlier post to show the step numbers.

    This is a copy of the original code. Isn't a reset good enough? Setting SPD_R_IF_CTRL to 0 probably also disables DMA transfers.
     
    AlGollan84 likes this.
  13. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    Let us talk it more clearly:( opl load game in usb mode ) .
    Code:
    // copy from ee_core iopmgr.c
    int New_Reset_Iop(const char *arg, int arglen)
    {
      ....
      while (!Reset_Iop(NULL, 0)) {
            ;
        }
        while (!SifIopSync()) {
            ; }
        ResetIopSpecial(NULL, 0);
    }
    
    0)at start , usbd is active at iop.
    1)New_Reset_Iop is called
    2)Reset_Iop called
    3)
    3.1) so usbd _stop will be called ( this will do nothing )
    3.2) DMACMAN _stop will be called ( this will disable all dma channel)
    4) ResetIopSpecial is called
    5) udnl get control
    5.1) udnl disable dma channel before call loadcore 's entry.
    6) usbd module reload by loadcore

    ---------------------------------------------------------------------------------
    so , 3.2) have no any effact , but 5.1) works .
    This is very strange .
     
    Last edited: Jan 21, 2018
  14. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    No, both do work.

    There are two calls to ResetIopSpecial. The first one is to get the USBD module + CDVDMAN + CDVDFSV into the IOP. The second one is to reboot the IOP with the game's IOPRP image (stored within the disc image, on the USB disk).

    After the first time USBD is loaded by ResetIopSpecial, the 2nd call to ResetIopSpecial will end with the USB DMA channel enabled. This was done because UDNL can only access IOPRP images on the USB disk, if it can access the USB disk.

    In normal homebrew software, we do not have to resort to such hacks because we usually embed the IOPRP image with the ELF itself (and we can use code like SifIopRebootBuffer). In the case of OPL, the code (EE core) exists without the IOPRP image (which belongs to the game).
     
    ps2netbox and AlGollan84 like this.
  15. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    I get it.
    It is not bug of Sony . Sony always call udnl after full reset. This is not a work around usbd.
    Even if usbd has a _exit function and really stop dma channel ,udnl do not call it .
    So perhaps , after get game's irprp , do a full reset maybe better.
    eg : read game's ioprp to iop , use ResetIopSpecial to replace ResetIopSpecial.
    this will reset all things not only disable channel .

    有句中国话说 "如数家珍”。

    Another question about opl igr :

    Code:
    // copy from ee_core pad_hook.c
    static void IGR_Thread()
    {
       
      // Execute home loader
            if (ExitPath[0] != '\0')
                ExecPS2(t_loadElf, &_gp, 0, NULL);
    
    }
    static void t_loadElf(void)
    {
    
            // Execute BOOT.ELF
            ret = LoadElf(argv[0], &elf);
            ExecPS2((void *)elf.epc, (void *)elf.gp, 1, argv);
    }
    
    This seems very strange to me . Why need ExecPS2(t_loadElf,).

    We can simple do in IGR_Thread.
    Code:
    LoadElf(argv[0], &elf);
    ExecPS2((void *)elf.epc, (void *)elf.gp, 1, argv);
    
    Why need t_loadElf ?
     
  16. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    "Full reset" should be done by initializing the hardware, regardless of the previous state. At least, that should be the logic...

    Unlike the POPS IGR, OPL has to hijack control of the PlayStation 2 from the game. POPS has full control of the PS2, unlike OPL.

    So if we do not do that, then the game could crash the console because we are loading a new ELF; this may overwrite the game executable. We will also sever connection of the game to the IOP side, since we have to reboot the IOP.

    The ExecPS2 is there to save code, as there is code to reset the state of the EE kernel (i.e. delete all threads, semaphores, remove all handlers, reset peripherals).
     
    AlGollan84 likes this.
  17. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    In ee_core Igr_thread.
    ExecPS2 is called twice , not one . Everything is restarted with one call to ExecPS2.
    I mean call sifiopreset.

    Code:
    // code from ee_core iopmgr.c
    int New_Reset_Iop() {
        Reset_Iop(NULL, 0);
        ResetIopSpecial(NULL, 0);
        if (arglen > 0) {
            ResetIopSpecial(&arg[10], arglen - 10);
        }
    }
    
    change to :
    Code:
    int New_Reset_Iop() {
        Reset_Iop(NULL, 0);
        ResetIopSpecial(NULL, 0);
        if (arglen > 0) {
             copy  IOPRP somewhere
            Reset_Iop(NULL, 0);
            //
            SifIopRebootBuffer()
        }
    }
    
    Or just to
    Code:
    int New_Reset_Iop() {
     
        if (arglen > 0) {
             copy  IOPRP somewhere
            Reset_Iop(NULL, 0);
            //
            SifIopRebootBuffer()
        }else{
          Reset_Iop(NULL, 0);
          ResetIopSpecial(NULL, 0);
        }
    }
    
     
  18. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    Yes! The moment we return from the interrupt, the game would continue running. So if we do not kill it, it can cause a crash if SifLoadElf overwrites it.
    For example, the game has a V-sync handler. It gets overwritten by instructions from the new ELF. Then at 1/60th a second, the EE will try to execute that handler... but the handler is no longer a valid, proper interrupt handler. So the EE can crash or get stuck.

    The first call to ExecPS2 is to allow the loader code to run. The second call to ExecPS2 is to execute the ELF.

    We cannot get the IOPRP image without getting access to the disk. There is also a lack of EE memory.

    Anyway, this lack of deinitialization is not a new problem, so it was probably by Sony's design. Even in normal IOP reboots (i.e. just a normal call to SifIopReset), UDNL will just overwrite all modules without deinitialization.
    Even though we added code to disable all DMA channels, it is only meant to target the USB DMA channel because only the USB OHCI controller can start transfers on its own. Normally, Sony doesn't use USB to retrieve IOPRP images, so there is no problem.
     
    AlGollan84 likes this.
  19. ps2netbox

    ps2netbox Spirited Member

    Joined:
    Dec 26, 2017
    Messages:
    116
    Likes Received:
    93
    Code:
    // from padhook.c
    static int IGR_Intc_Handler(int cause){
    if ( Pad_Data.combo_type != 0x00 )
        {
            // Disable Interrupts
           iDisableIntc()
         // Suspend all threads
         iSuspendThread(i);
         //WakeUp IGR thread
         iWakeupThread(IGR_Thread_ID);
    }
    
    Before wakeup IGR thread , all interrupts are disalbed , threads are suspend .
    Why need twice execps2 to cleanup somthing ?
     
  20. sp193

    sp193 Site Soldier

    Joined:
    Mar 28, 2012
    Messages:
    2,217
    Likes Received:
    1,052
    By the documentation, we cannot issue ExecPS2 from the interrupt handler, so the next best thing is to disable interrupts and suspend running threads, before calling ExecPS2 later. There are also some parts of the IGR process (i.e. IOP reset) that cannot be done from the interrupt handler. Simply disabling the external interrupts and suspending all threads doesn't totally make the EE kernel clean (there are other handlers, like DMAC and PGIF).

    The 2nd call to ExecPS2 is to also execute the target ELF properly, after cleaning up after the loader (t_LoadElf).
     
    AlGollan84 likes this.
sonicdude10
Draft saved Draft deleted
Insert every image as a...
  1.  0%

Share This Page