wiiu-nanddumper-payload/ios_bsp/source/seeprom.c

157 lines
4.1 KiB
C

/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "svc.h"
#include "fsa.h"
#define SD_SEEPROM_SECTOR 0x4FF
#define BSP_MEMCPY ((void * (*)(void *, void *, unsigned int size))0xE600EA18)
static int writeEnabled = 0;
static int dirty = 0;
unsigned char seeprom_buffer[512] __attribute__((section(".seeprom_buffer")));
extern int orig_EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf);
static int SD_EEPROM_WriteAll(void)
{
int fsa = svcOpen("/dev/fsa", 0);
if(fsa < 0)
return fsa;
int fd;
int res = FSA_RawOpen(fsa, "/dev/sdcard01", &fd);
if(res >= 0)
{
void *buffer = svcAllocAlign(0xCAFF, 0x200, 0x40);
if(buffer)
{
// user global buffer for FSA to be able to access it
BSP_MEMCPY(buffer, seeprom_buffer, 0x200);
res = FSA_RawWrite(fsa, buffer, 0x200, 1, SD_SEEPROM_SECTOR, fd);
svcFree(0xCAFF, buffer);
}
else
res = -1;
FSA_RawClose(fsa, fd);
}
svcClose(fsa);
return res;
}
static void EEPROM_InitializeCache(int handle_index)
{
int i;
for(i = 0; i < 0x100; i++)
{
orig_EEPROM_SPI_ReadWord(handle_index, i, (unsigned short*)(seeprom_buffer + (i << 1)));
}
}
int EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf)
{
unsigned int offset = ((unsigned int)index) << 1;
// check for valid eeprom dump and initialize if none was on sd card
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
{
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
dirty = 1;
}
// don't redirect the drive key as it is specific for the drive on the wii u
// the seeprom key is the same for all wiiu's it seems so nothing to re-encrypt here
if(offset >= 0x80 && offset < 0x90)
{
return orig_EEPROM_SPI_ReadWord(handle_index, index, outbuf);
}
if(!outbuf || (offset >= 512))
{
return -5;
}
*outbuf = *(unsigned short*)(seeprom_buffer + offset);
if(dirty && SD_EEPROM_WriteAll() == 0)
{
dirty = 0;
}
return 0;
}
int EEPROM_SPI_WriteWord(int handle_index, unsigned char index, unsigned short data)
{
if(writeEnabled == 0)
{
return -5;
}
// check for valid eeprom dump and initialize if none was on sd card
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
{
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
}
unsigned int offset = ((unsigned int)index) << 1;
if(offset >= 512)
{
return -5;
}
*(unsigned short*)(seeprom_buffer + offset) = data;
dirty = 1;
if(SD_EEPROM_WriteAll() == 0)
{
dirty = 0;
}
return 0;
}
int EEPROM_WriteControl(int handle_index, int type)
{
if(type == 1)
{
writeEnabled = 0;
}
else if(type == 2)
{
writeEnabled = 1;
}
else if(type == 3)
{
// erase all -> skip that part...its actually never used but would be only a memset with 0xFF
}
else
{
return -4;
}
return 0;
}