2.13 still not working :/
This commit is contained in:
parent
55fd6db5a5
commit
ba7fa5bbda
8 changed files with 136 additions and 14 deletions
|
|
@ -11,7 +11,8 @@ IOP_OBJDUMP = iop-objdump
|
||||||
|
|
||||||
IOP_SYMBOLS = -DREAD_SECTORS_210=$(IOP_READ_SECTORS_210) -DORIGINAL_RETURN_ADDRESS_210=$(IOP_ORIGINAL_RETURN_ADDRESS_210) -DRETURN_ADDRESS_LOCATION_210=$(IOP_RETURN_ADDRESS_LOCATION_210) \
|
IOP_SYMBOLS = -DREAD_SECTORS_210=$(IOP_READ_SECTORS_210) -DORIGINAL_RETURN_ADDRESS_210=$(IOP_ORIGINAL_RETURN_ADDRESS_210) -DRETURN_ADDRESS_LOCATION_210=$(IOP_RETURN_ADDRESS_LOCATION_210) \
|
||||||
-DREAD_SECTORS_212=$(IOP_READ_SECTORS_212) -DORIGINAL_RETURN_ADDRESS_212=$(IOP_ORIGINAL_RETURN_ADDRESS_212) -DRETURN_ADDRESS_LOCATION_212=$(IOP_RETURN_ADDRESS_LOCATION_212) \
|
-DREAD_SECTORS_212=$(IOP_READ_SECTORS_212) -DORIGINAL_RETURN_ADDRESS_212=$(IOP_ORIGINAL_RETURN_ADDRESS_212) -DRETURN_ADDRESS_LOCATION_212=$(IOP_RETURN_ADDRESS_LOCATION_212) \
|
||||||
-DREAD_SECTORS_213=$(IOP_READ_SECTORS_213) -DORIGINAL_RETURN_ADDRESS_213=$(IOP_ORIGINAL_RETURN_ADDRESS_213) -DRETURN_ADDRESS_LOCATION_213=$(IOP_RETURN_ADDRESS_LOCATION_213)
|
-DREAD_SECTORS_213=$(IOP_READ_SECTORS_213) -DORIGINAL_RETURN_ADDRESS_213=$(IOP_ORIGINAL_RETURN_ADDRESS_213) -DRETURN_ADDRESS_LOCATION_213=$(IOP_RETURN_ADDRESS_LOCATION_213) \
|
||||||
|
-DREAD_SECTORS_110=$(IOP_READ_SECTORS_110) -DORIGINAL_RETURN_ADDRESS_110=$(IOP_ORIGINAL_RETURN_ADDRESS_110) -DRETURN_ADDRESS_LOCATION_110=$(IOP_RETURN_ADDRESS_LOCATION_110)
|
||||||
|
|
||||||
IOP_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -g $(IOP_SYMBOLS)
|
IOP_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -g $(IOP_SYMBOLS)
|
||||||
|
|
||||||
|
|
@ -30,9 +31,12 @@ dvd.iso: dvd.base.iso stage1_210_212.iop.bin stage1_213.iop.bin ioppayload.iop.b
|
||||||
# For now it's easier to just use a base dvd rather than attempting to generate an image and patch it
|
# For now it's easier to just use a base dvd rather than attempting to generate an image and patch it
|
||||||
cp dvd.base.iso dvd.iso
|
cp dvd.base.iso dvd.iso
|
||||||
|
|
||||||
# Return address 0x00818f4 = 530676
|
# Return address (2.10 - 2.13) 0x00818f4 = 530676
|
||||||
printf $(STAGE1_LOAD_ADDRESS_STRING_210_212) | dd of=dvd.iso bs=1 seek=530676 count=4 conv=notrunc
|
printf $(STAGE1_LOAD_ADDRESS_STRING_210_212) | dd of=dvd.iso bs=1 seek=530676 count=4 conv=notrunc
|
||||||
|
|
||||||
|
# Return address 1.10 (0x000818bc = 530620)
|
||||||
|
printf $(STAGE1_LOAD_ADDRESS_STRING_110) | dd of=dvd.iso bs=1 seek=530620 count=4 conv=notrunc
|
||||||
|
|
||||||
# Old toolchains don't support this option, so just copy byte-by-byte...
|
# Old toolchains don't support this option, so just copy byte-by-byte...
|
||||||
# bs=4096 iflag=skip_bytes,count_bytes
|
# bs=4096 iflag=skip_bytes,count_bytes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ _start:
|
||||||
|
|
||||||
jr $a0
|
jr $a0
|
||||||
|
|
||||||
|
# Don't use on phat PS2... completely broken syscall
|
||||||
#ExecPS2:
|
#ExecPS2:
|
||||||
# la $v1, 0x07
|
# la $v1, 0x07
|
||||||
# syscall 0x07 # ExecPS2
|
# syscall 0x07 # ExecPS2
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,44 @@ extern void SifWriteBackDCache(void *ptr, int size);
|
||||||
extern int SifSetReg(unsigned int register_num, unsigned int register_value);
|
extern int SifSetReg(unsigned int register_num, unsigned int register_value);
|
||||||
extern int SifGetReg(unsigned int register_num);
|
extern int SifGetReg(unsigned int register_num);
|
||||||
|
|
||||||
//static int SifIopSync(void) {
|
static int SifIopSync(void) {
|
||||||
// #define SIF_REG_SMFLAG 4
|
#define SIF_REG_SMFLAG 4
|
||||||
// #define SIF_STAT_BOOTEND 0x40000
|
#define SIF_STAT_BOOTEND 0x40000
|
||||||
// return((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
|
return((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
|
||||||
//}
|
}
|
||||||
|
|
||||||
static void flush(void) {
|
static void flush(void) {
|
||||||
asm volatile("la $v1, 0x64; la $a0, 0; syscall 0x64"); // FlushCache data writeback
|
asm volatile("la $v1, 0x64; la $a0, 0; syscall 0x64"); // FlushCache data writeback
|
||||||
asm volatile("la $v1, 0x64; la $a0, 2; syscall 0x64"); // FlushCache instruction invalidate
|
asm volatile("la $v1, 0x64; la $a0, 2; syscall 0x64"); // FlushCache instruction invalidate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetThreadId(void);
|
||||||
|
void ChangeThreadPriority(int thread_id, int priority);
|
||||||
|
int CancelWakeupThread(int thread_id);
|
||||||
|
void TerminateThread(int thread_id);
|
||||||
|
void DeleteThread(int thread_id);
|
||||||
|
|
||||||
|
static void TerminateAllThreads(void) {
|
||||||
|
int i, ThreadID;
|
||||||
|
|
||||||
|
ThreadID=GetThreadId();
|
||||||
|
ChangeThreadPriority(ThreadID, 0);
|
||||||
|
CancelWakeupThread(ThreadID);
|
||||||
|
for(i=1; i<256; i++){ //Skip idle thread.
|
||||||
|
if(i!=ThreadID){
|
||||||
|
TerminateThread(i);
|
||||||
|
DeleteThread(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
// ExecPS2 is broken on Phat PS2... manually kill other threads instead
|
||||||
|
TerminateAllThreads();
|
||||||
|
|
||||||
|
// Signal IOP that EE is Ready, willing, and fully enabled!
|
||||||
|
SifSetReg(3, 1);
|
||||||
|
|
||||||
volatile int *waitAddress = (void *)0x21FFF7F0;
|
volatile int *waitAddress = (void *)0x21FFF7F0;
|
||||||
while(!*waitAddress);
|
while(!*waitAddress);
|
||||||
|
|
||||||
|
|
@ -33,6 +59,9 @@ int main(void) {
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
|
//SifIopReset("rom0:UDNL rom0:EELOADCNF", 0);
|
||||||
|
//while(!SifIopSync());
|
||||||
|
|
||||||
//ExecPS2(*entry_point_address, 0, 0, 0);
|
//ExecPS2(*entry_point_address, 0, 0, 0);
|
||||||
ExecPS2(*entry_point_address, 0, 1, argument); // kHn: arg == cdrom0:
|
ExecPS2(*entry_point_address, 0, 1, argument); // kHn: arg == cdrom0:
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
#STAGE1_LOAD_ADDRESS_110 = 0xa00b66a8
|
||||||
|
#STAGE1_LOAD_ADDRESS_STRING_110 = '\xa8\x66\x0b\xa0'
|
||||||
|
|
||||||
STAGE1_LOAD_ADDRESS_210_212 = 0xa00b7548
|
STAGE1_LOAD_ADDRESS_210_212 = 0xa00b7548
|
||||||
STAGE1_LOAD_ADDRESS_STRING_210_212 = '\x48\x75\x0b\xa0'
|
STAGE1_LOAD_ADDRESS_STRING_210_212 = '\x48\x75\x0b\xa0'
|
||||||
|
|
||||||
|
|
@ -7,6 +10,7 @@ STAGE1_LOAD_ADDRESS_STRING_213 = '\xc8\x6f\x0b\xa0'
|
||||||
STAGE1_ISO_210_212 = 532728 # 0x820f8
|
STAGE1_ISO_210_212 = 532728 # 0x820f8
|
||||||
STAGE1_ISO_213 = 534136 # 0x82678
|
STAGE1_ISO_213 = 534136 # 0x82678
|
||||||
|
|
||||||
|
IOP_READ_SECTORS_110 = 0xb19e4
|
||||||
IOP_READ_SECTORS_210 = 0xb260c
|
IOP_READ_SECTORS_210 = 0xb260c
|
||||||
IOP_READ_SECTORS_212 = 0xb25f8
|
IOP_READ_SECTORS_212 = 0xb25f8
|
||||||
IOP_READ_SECTORS_213 = 0xb21f8
|
IOP_READ_SECTORS_213 = 0xb21f8
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
STAGE1_LOAD_ADDRESS_210_212 = 0xa0062C48
|
STAGE1_LOAD_ADDRESS_210_212 = 0xa0062C48
|
||||||
STAGE1_LOAD_ADDRESS_STRING_210_212 = '\x48\x2c\x06\xa0'
|
STAGE1_LOAD_ADDRESS_STRING_210_212 = '\x48\x2c\x06\xa0'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ static void memset_ee(void *s, int c, unsigned int n);
|
||||||
|
|
||||||
//#include "iopresolve.h"
|
//#include "iopresolve.h"
|
||||||
|
|
||||||
|
#define BD2 (*(volatile int *)0xBD000020) //msflag
|
||||||
|
|
||||||
static void readData(void *dest, unsigned int offset, size_t n) {
|
static void readData(void *dest, unsigned int offset, size_t n) {
|
||||||
//unsigned char buffer[SECTOR_SIZE];
|
//unsigned char buffer[SECTOR_SIZE];
|
||||||
//unsigned char *buffer = (void *)0xfd000;
|
//unsigned char *buffer = (void *)0xfd000;
|
||||||
|
|
@ -121,6 +123,7 @@ void _start(void) {
|
||||||
sceSifDmaStat = (void *)0x17170;
|
sceSifDmaStat = (void *)0x17170;
|
||||||
|
|
||||||
unsigned int addiu_magic = 0x27bdffc8; // addiu $sp, $sp, -0x38
|
unsigned int addiu_magic = 0x27bdffc8; // addiu $sp, $sp, -0x38
|
||||||
|
//if(*(unsigned int *)READ_SECTORS_110 == addiu_magic) readSectors = (void *)READ_SECTORS_110;
|
||||||
if(*(unsigned int *)READ_SECTORS_210 == addiu_magic) readSectors = (void *)READ_SECTORS_210;
|
if(*(unsigned int *)READ_SECTORS_210 == addiu_magic) readSectors = (void *)READ_SECTORS_210;
|
||||||
else if(*(unsigned int *)READ_SECTORS_212 == addiu_magic) readSectors = (void *)READ_SECTORS_212;
|
else if(*(unsigned int *)READ_SECTORS_212 == addiu_magic) readSectors = (void *)READ_SECTORS_212;
|
||||||
else if(*(unsigned int *)READ_SECTORS_213 == addiu_magic) readSectors = (void *)READ_SECTORS_213;
|
else if(*(unsigned int *)READ_SECTORS_213 == addiu_magic) readSectors = (void *)READ_SECTORS_213;
|
||||||
|
|
@ -139,9 +142,13 @@ void _start(void) {
|
||||||
transfer_to_ee((void *)0x01477B80, &return_address, sizeof(return_address)); // 2.13E/A
|
transfer_to_ee((void *)0x01477B80, &return_address, sizeof(return_address)); // 2.13E/A
|
||||||
|
|
||||||
// Clear bit 0 of 0x208bb710 to make EE exit loop waiting for IOP, and return to our above payload
|
// Clear bit 0 of 0x208bb710 to make EE exit loop waiting for IOP, and return to our above payload
|
||||||
//unsigned int loopValue = 0x010004;
|
unsigned int loopValue = 0x010004;
|
||||||
//transfer_to_ee((void *)0x208bb710, &loopValue, sizeof(loopValue)); // 2.10E
|
//transfer_to_ee((void *)0x208bb710, &loopValue, sizeof(loopValue)); // 2.10E
|
||||||
|
transfer_to_ee((void *)0x2087d110, &loopValue, sizeof(loopValue)); // 2.13E
|
||||||
|
|
||||||
|
// We wait for EE side to be ready before sending ELF.
|
||||||
|
while(!(SifGetMSFlag() & 1));
|
||||||
|
SifSetMSFlag(3);
|
||||||
|
|
||||||
//unsigned char *buffer = (void *)0xfe000;
|
//unsigned char *buffer = (void *)0xfe000;
|
||||||
unsigned char *buffer = (void *)0xBB800;
|
unsigned char *buffer = (void *)0xBB800;
|
||||||
|
|
@ -246,6 +253,34 @@ static void *memset(void *s, int c, unsigned int n)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int SifGetMSFlag()
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
b = BD2;
|
||||||
|
do {
|
||||||
|
a=b;
|
||||||
|
b=BD2;
|
||||||
|
} while(a != b);
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SifSetMSFlag(unsigned int value)
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
BD2 = value;
|
||||||
|
|
||||||
|
b = BD2;
|
||||||
|
do {
|
||||||
|
a=b;
|
||||||
|
b=BD2;
|
||||||
|
} while(a != b);
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
asm("\n\
|
asm("\n\
|
||||||
.global ee_crt0\n\
|
.global ee_crt0\n\
|
||||||
ee_crt0:\n\
|
ee_crt0:\n\
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,14 @@ iop_payload_address = 0xa00fd000
|
||||||
_start:
|
_start:
|
||||||
move $fp, $sp # We need to reset $fp as it gets trashed by memcpy
|
move $fp, $sp # We need to reset $fp as it gets trashed by memcpy
|
||||||
|
|
||||||
check_210:
|
|
||||||
la $v1, 0x27bdffc8 # addiu $sp, $sp, -0x38
|
la $v1, 0x27bdffc8 # addiu $sp, $sp, -0x38
|
||||||
|
|
||||||
|
check_110:
|
||||||
|
#la $v0, READ_SECTORS_110
|
||||||
|
#lw $t0, 0($v0)
|
||||||
|
#beq $t0, $v1, read_iop_payload
|
||||||
|
|
||||||
|
check_210:
|
||||||
la $v0, READ_SECTORS_210
|
la $v0, READ_SECTORS_210
|
||||||
lw $t0, 0($v0)
|
lw $t0, 0($v0)
|
||||||
beq $t0, $v1, read_iop_payload
|
beq $t0, $v1, read_iop_payload
|
||||||
|
|
@ -35,8 +41,12 @@ read_iop_payload:
|
||||||
la $v0, ENTRY
|
la $v0, ENTRY
|
||||||
jalr $v0
|
jalr $v0
|
||||||
|
|
||||||
check_210_again:
|
|
||||||
la $v1, 0x27bdffc8 # addiu $sp, $sp, -0x38
|
la $v1, 0x27bdffc8 # addiu $sp, $sp, -0x38
|
||||||
|
|
||||||
|
check_110_again:
|
||||||
|
|
||||||
|
|
||||||
|
check_210_again:
|
||||||
la $v0, READ_SECTORS_210
|
la $v0, READ_SECTORS_210
|
||||||
lw $v0, 0($v0)
|
lw $v0, 0($v0)
|
||||||
la $a0, RETURN_ADDRESS_LOCATION_210
|
la $a0, RETURN_ADDRESS_LOCATION_210
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,46 @@
|
||||||
# ElReino 2020
|
# ElReino and CTurt 2020
|
||||||
|
|
||||||
# Since GCC does something strange, we can't write syscall thunks directly in C
|
# Since GCC does something strange, we can't write syscall thunks directly in C
|
||||||
# as GCC adds move $v1, $v0 directly after jr $ra, effectively trashing $v0.
|
# as GCC adds move $v1, $v0 directly after jr $ra, effectively trashing $v0.
|
||||||
# I don't know why this happens, but I do know enough about GCC that this
|
# I don't know why this happens, but I do know enough about GCC that this
|
||||||
# approach will most probably be easier. But feel free to try fixing it.
|
# approach will most probably be easier. But feel free to try fixing it.
|
||||||
|
|
||||||
|
.global GetThreadId
|
||||||
|
GetThreadId:
|
||||||
|
la $v1, 0x2f
|
||||||
|
syscall 0x2f
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.global ChangeThreadPriority
|
||||||
|
ChangeThreadPriority:
|
||||||
|
la $v1, 0x29
|
||||||
|
syscall 0x29
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.global CancelWakeupThread
|
||||||
|
CancelWakeupThread:
|
||||||
|
la $v1, 0x35
|
||||||
|
syscall 0x35
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.global TerminateThread
|
||||||
|
TerminateThread:
|
||||||
|
la $v1, 0x25
|
||||||
|
syscall 0x25
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.global DeleteThread
|
||||||
|
DeleteThread:
|
||||||
|
la $v1, 0x21
|
||||||
|
syscall 0x21
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.global SifSetReg
|
||||||
|
SifSetReg:
|
||||||
|
la $v1, 0x79
|
||||||
|
syscall 0x79
|
||||||
|
jr $ra
|
||||||
|
|
||||||
.global SifGetReg
|
.global SifGetReg
|
||||||
SifGetReg:
|
SifGetReg:
|
||||||
la $v1, 0x7a
|
la $v1, 0x7a
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue