Skip to content

Commit

Permalink
Work towards generic modchip patch
Browse files Browse the repository at this point in the history
  • Loading branch information
socram8888 committed May 23, 2021
1 parent 5bbb09c commit 52bc378
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ SC*
*.elf
*.bin
*.o
bios-patches.inc
orca.inc
BES*
BAS*
Expand Down
17 changes: 13 additions & 4 deletions loader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@

include ../variables.mk

LOADER_HEADERS := $(wildcard *.h) orca.inc
LOADER_OBJECTS := $(patsubst %.c, %.o, $(patsubst %.s, %.o, $(wildcard *.c *.s)))
LOADER_AUTOGEN := orca.inc bios-patches.inc
LOADER_HEADERS := $(wildcard *.h) $(LOADER_AUTOGEN)
LOADER_OBJECTS := $(patsubst %.c, %.o, $(patsubst %.S, %.o, $(wildcard *.c *.S)))

all: $(LOADER_FILES)

clean:
$(RM) $(LOADER_FILES) *.o *.elf orca.inc
$(RM) $(LOADER_FILES) *.o *.elf $(LOADER_AUTOGEN)

# BIOS patches

bios-patches.elf: bios-patches.S
$(CC) $(CFLAGS) bios-patches.S -o bios-patches.elf

bios-patches.inc: bios-patches.elf
bash ../util/elf2h.sh BIOS_PATCHES bios-patches.elf bios-patches.inc

# Intermediate objects

%.o: %.c $(LOADER_HEADERS)
$(CC) $(CFLAGS) -c $<

%.o: %.s $(LOADER_HEADERS)
%.o: %.S $(LOADER_HEADERS)
$(CC) $(CFLAGS) -c $<

orca.inc: orca.img
Expand Down
39 changes: 39 additions & 0 deletions loader/bios-patcher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

#include "bios.h"
#include "bios-patcher.h"
#include "debugscreen.h"
#include <string.h>

#include "bios-patches.inc"

/*
* 0xA00 is empty (null) space in the B table. This was never used by any official BIOS patches
* so we should be safe.
*/
static uint8_t * const PATCH_START_ADDR = (uint8_t *) 0xA00;

inline uint32_t encode_jal(const void * addr) {
return 0x08000000 | (((uint32_t) addr >> 4) & 0x3FFFFFF);
}

void install_modchip_patch() {
debug_write("Installing modchip patch (TODO!)");
}

void install_fpx_patch() {
if (bios_is_ps1()) {
return;
}

debug_write("Installing FreePSXBoot patch");
*((uint32_t *) 0x5B40) = encode_jal(PATCH_START_ADDR + BIOS_PATCHES_ANTIFPXPATCH);
}

void bios_patcher_apply(void) {
// Copy patches
memcpy(PATCH_START_ADDR, BIOS_PATCHES_BLOB, sizeof(BIOS_PATCHES_BLOB));

// Install patches
install_modchip_patch();
install_fpx_patch();
}
7 changes: 7 additions & 0 deletions loader/bios-patcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#pragma once

/**
* Install and apply suitable BIOS patches.
*/
void bios_patcher_apply(void);
34 changes: 34 additions & 0 deletions loader/bios-patches.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

#include <regdef.h>

.text
.globl __start
__start:

/*
* The anti-FreePSXBoot patch.
*
* This patch is called right at the very end of the last step in the read sector finite state
* machine:
* https://github.com/grumpycoders/pcsx-redux/blob/f6484e8010a40a81e4019d9bfa1a9d408637b614/src/mips/openbios/sio0/card.c#L194
*
* When this code is executed, the registers are as follows:
* - v0 contains 1, or "success".
* - a1 contains the read buffer
* - a2 contains the current sector number
*
* If the sector being read is sector 0 and it contains "FPBZ" at +0x7C, we modify the read data
* so it is detected as corrupted and the game skips reading from it
*
* The offsets have been checked against BIOSes 2.2, 3.0, 4.1 and 4.4
*/
.globl antifpxpatch
antifpxpatch:
lw t0, 0x7C(a1)
li t1, 0x5A425046
bne a2, 0, fpxret
bne t0, t1, fpxret

sw zero, 0(a1)
fpxret:
j 0x5B54
50 changes: 0 additions & 50 deletions loader/freepsxpatch.c

This file was deleted.

15 changes: 0 additions & 15 deletions loader/freepsxpatch.h

This file was deleted.

3 changes: 1 addition & 2 deletions loader/secondary.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "patcher.h"
#include "integrity.h"
#include "io.h"
#include "freepsxpatch.h"

// Loading address of tonyhax, provided by the secondary.ld linker script
extern uint8_t __BSS_START__, __BSS_END__;
Expand Down Expand Up @@ -315,7 +314,7 @@ void main() {
}

while (1) {
freepsxpatch_apply();
bios_patcher_apply();
try_boot_cd();

debug_write("Reinitializing kernel");
Expand Down
2 changes: 1 addition & 1 deletion util/bin2h.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ cat <<EOF >"${header_file}"
#pragma once
static const uint8_t ${constant_name}[] = {
$(od -v -tx1 -An <orca.img | sed -r "s/\b(..)\b/0x\1,/g")
$(od -v -tx1 -An <${binary_file} | sed -r "s/\b(..)\b/0x\1,/g")
};
EOF
30 changes: 30 additions & 0 deletions util/elf2h.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

set -euo pipefail

if [ $# -ne 3 ]; then
echo "Usage: $0 var_prefix elf_file header_file"
exit 1
fi

var_prefix="${1}"
elf_file="${2}"
header_file="${3}"

startaddr=$(mips-linux-gnu-nm "${elf_file}" | egrep "\b__start\b" | cut -d ' ' -f 1)

cat <<EOF >"${header_file}"
/*
* Automatically generated from ${elf_file}.
* Do not edit
*/
#include <stdint.h>
#pragma once
$(mips-linux-gnu-nm "${elf_file}" | sed -nr "s/^(\S*) T ([^_]\S*)/static const uint32_t ${var_prefix}_\U\2\E = 0x\1 - 0x${startaddr};/p")
static const uint8_t ${var_prefix}_BLOB[] = {
$(mips-linux-gnu-objcopy -O binary -j .text "${elf_file}" /dev/stdout | od -v -tx1 -An | sed -r "s/\b(..)\b/0x\1,/g")
};
EOF

0 comments on commit 52bc378

Please sign in to comment.