示例#1
0
bool CBoot::BootNANDTitle(const u64 title_id)
{
  UpdateStateFlags([](StateFlags* state) {
    state->type = 0x04;  // TYPE_NANDBOOT
  });

  auto es = IOS::HLE::GetIOS()->GetES();
  const IOS::ES::TicketReader ticket = es->FindSignedTicket(title_id);
  auto console_type = IOS::HLE::IOSC::ConsoleType::Retail;
  if (ticket.IsValid())
    console_type = ticket.GetConsoleType();
  else
    ERROR_LOG(BOOT, "No ticket was found for %016" PRIx64, title_id);
  SetupWiiMemory(console_type);
  return es->LaunchTitle(title_id);
}
示例#2
0
文件: Boot.cpp 项目: Tinob/Ishiiruka
    bool operator()(const BootParameters::Executable& executable) const
    {
      NOTICE_LOG(BOOT, "Booting from executable: %s", executable.path.c_str());

      if (!executable.reader->IsValid())
        return false;

      if (!executable.reader->LoadIntoMemory())
      {
        PanicAlertT("Failed to load the executable to memory.");
        return false;
      }

      SetDefaultDisc();

      SetupMSR();
      SetupBAT(config.bWii);
      CopyDefaultExceptionHandlers();

      if (config.bWii)
      {
        PowerPC::ppcState.spr[SPR_HID0] = 0x0011c464;
        PowerPC::ppcState.spr[SPR_HID4] = 0x82000000;

        // Set a value for the SP. It doesn't matter where this points to,
        // as long as it is a valid location. This value is taken from a homebrew binary.
        PowerPC::ppcState.gpr[1] = 0x8004d4bc;

        // Because there is no TMD to get the requested system (IOS) version from,
        // we default to IOS58, which is the version used by the Homebrew Channel.
        SetupWiiMemory();
        IOS::HLE::GetIOS()->BootIOS(Titles::IOS(58));
      }
      else
      {
        SetupGCMemory();
      }

      PC = executable.reader->GetEntryPoint();

      if (executable.reader->LoadSymbols() || LoadMapFromFilename())
      {
        UpdateDebugger_MapLoaded();
        HLE::PatchFunctions();
      }
      return true;
    }
示例#3
0
bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
{
    std::string state_filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_STATE);

    if (File::Exists(state_filename))
    {
        File::IOFile state_file(state_filename, "r+b");
        StateFlags state;
        state_file.ReadBytes(&state, sizeof(StateFlags));

        state.type = 0x03; // TYPE_RETURN
        state.checksum = state_checksum((u32*)&state.flags, sizeof(StateFlags)-4);

        state_file.Seek(0, SEEK_SET);
        state_file.WriteBytes(&state, sizeof(StateFlags));
    }
    else
    {
        File::CreateFullPath(state_filename);
        File::IOFile state_file(state_filename, "a+b");
        StateFlags state;
        memset(&state,0,sizeof(StateFlags));
        state.type = 0x03; // TYPE_RETURN
        state.discstate = 0x01; // DISCSTATE_WII
        state.checksum = state_checksum((u32*)&state.flags, sizeof(StateFlags)-4);
        state_file.WriteBytes(&state, sizeof(StateFlags));
    }

    const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename);
    if (!ContentLoader.IsValid())
        return false;

    u64 titleID = ContentLoader.GetTitleID();
    // create data directory
    File::CreateFullPath(Common::GetTitleDataPath(titleID));

    if (titleID == TITLEID_SYSMENU)
        HLE_IPC_CreateVirtualFATFilesystem();
    // setup wii mem
    if (!SetupWiiMemory(ContentLoader.GetCountry()))
        return false;

    // DOL
    const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex());
    if (pContent == nullptr)
        return false;

    WII_IPC_HLE_Interface::SetDefaultContentFile(_pFilename);

    std::unique_ptr<CDolLoader> pDolLoader;
    if (pContent->m_pData)
    {
        pDolLoader.reset(new CDolLoader(pContent->m_pData, pContent->m_Size));
    }
    else
    {
        pDolLoader.reset(new CDolLoader(pContent->m_Filename));
    }
    pDolLoader->Load();
    PC = pDolLoader->GetEntryPoint() | 0x80000000;

    // Pass the "#002 check"
    // Apploader should write the IOS version and revision to 0x3140, and compare it
    // to 0x3188 to pass the check, but we don't do it, and i don't know where to read the IOS rev...
    // Currently we just write 0xFFFF for the revision, copy manually and it works fine :p

    // TODO : figure it correctly : where should we read the IOS rev that the wad "needs" ?
    Memory::Write_U16(ContentLoader.GetIosVersion(), 0x00003140);
    Memory::Write_U16(0xFFFF, 0x00003142);
    Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188);

    // Load patches and run startup patches
    const DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(_pFilename);
    if (pVolume != nullptr)
        PatchEngine::LoadPatches();

    return true;
}
示例#4
0
// __________________________________________________________________________________________________
// Wii Bootstrap 2 HLE:
// copy the apploader to 0x81200000
// execute the apploader
bool CBoot::EmulatedBS2_Wii()
{
  INFO_LOG(BOOT, "Faking Wii BS2...");

  // Setup Wii memory
  DiscIO::Country country_code = DiscIO::Country::COUNTRY_UNKNOWN;
  if (DVDInterface::VolumeIsValid())
    country_code = DVDInterface::GetVolume().GetCountry();
  if (SetupWiiMemory(country_code) == false)
    return false;

  // Execute the apploader
  bool apploaderRan = false;
  if (DVDInterface::VolumeIsValid() &&
      DVDInterface::GetVolume().GetVolumeType() == DiscIO::Platform::WII_DISC)
  {
    // This is some kind of consistency check that is compared to the 0x00
    // values as the game boots. This location keeps the 4 byte ID for as long
    // as the game is running. The 6 byte ID at 0x00 is overwritten sometime
    // after this check during booting.
    DVDRead(0, 0x3180, 4, true);

    // Set up MSR and the BAT SPR registers.
    UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
    m_MSR.FP = 1;
    m_MSR.DR = 1;
    m_MSR.IR = 1;
    m_MSR.EE = 1;
    PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
    PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
    PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
    PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
    PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
    PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
    PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
    PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
    PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
    PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
    PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
    PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;

    Memory::Write_U32(0x4c000064, 0x00000300);  // Write default DSI Handler:     rfi
    Memory::Write_U32(0x4c000064, 0x00000800);  // Write default FPU Handler:     rfi
    Memory::Write_U32(0x4c000064, 0x00000C00);  // Write default Syscall Handler: rfi

    HLE::Patch(0x81300000, "OSReport");  // HLE OSReport for Apploader

    PowerPC::ppcState.gpr[1] = 0x816ffff0;  // StackPointer

    const u32 apploader_offset = 0x2440;  // 0x1c40;

    // Load Apploader to Memory
    const DiscIO::IVolume& volume = DVDInterface::GetVolume();
    u32 apploader_entry, apploader_size;
    if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, true) ||
        !volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, true) ||
        apploader_entry == (u32)-1 || apploader_size == (u32)-1)
    {
      ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
      return false;
    }
    DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size, true);

    // call iAppLoaderEntry
    DEBUG_LOG(BOOT, "Call iAppLoaderEntry");

    u32 iAppLoaderFuncAddr = 0x80004000;
    PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
    PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
    PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
    RunFunction(apploader_entry);
    u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
    u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
    u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);

    // iAppLoaderInit
    DEBUG_LOG(BOOT, "Run iAppLoaderInit");
    PowerPC::ppcState.gpr[3] = 0x81300000;
    RunFunction(iAppLoaderInit);

    // Let the apploader load the exe to memory. At this point I get an unknown IPC command
    // (command zero) when I load Wii Sports or other games a second time. I don't notice
    // any side effects however. It's a little disconcerting however that Start after Stop
    // behaves differently than the first Start after starting Dolphin. It means something
    // was not reset correctly.
    DEBUG_LOG(BOOT, "Run iAppLoaderMain");
    do
    {
      PowerPC::ppcState.gpr[3] = 0x81300004;
      PowerPC::ppcState.gpr[4] = 0x81300008;
      PowerPC::ppcState.gpr[5] = 0x8130000c;

      RunFunction(iAppLoaderMain);

      u32 iRamAddress = PowerPC::Read_U32(0x81300004);
      u32 iLength = PowerPC::Read_U32(0x81300008);
      u32 iDVDOffset = PowerPC::Read_U32(0x8130000c) << 2;

      INFO_LOG(BOOT, "DVDRead: offset: %08x   memOffset: %08x   length: %i", iDVDOffset,
               iRamAddress, iLength);
      DVDRead(iDVDOffset, iRamAddress, iLength, true);
    } while (PowerPC::ppcState.gpr[3] != 0x00);

    // iAppLoaderClose
    DEBUG_LOG(BOOT, "Run iAppLoaderClose");
    RunFunction(iAppLoaderClose);

    apploaderRan = true;

    // Pass the "#002 check"
    // Apploader writes the IOS version and revision here, we copy it
    // Fake IOSv9 r2.4 if no version is found (elf loading)
    u32 firmwareVer = PowerPC::Read_U32(0x80003188);
    PowerPC::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x80003140);

    // Load patches and run startup patches
    PatchEngine::LoadPatches();

    // return
    PC = PowerPC::ppcState.gpr[3];
  }

  return apploaderRan;
}