mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Get osreport.c linked
This commit is contained in:
@@ -203,14 +203,20 @@ FORCEFILESGEN = f"{PYTHON} {PPCDIS}/forcefilesgen.py"
|
||||
TOOLS = "tools"
|
||||
CODEWARRIOR = os.path.join(TOOLS, "1.3.2")
|
||||
SDK_CW = os.path.join(TOOLS, "1.2.5")
|
||||
HOTFIX_CW = os.path.join(TOOLS, "1.2.5e")
|
||||
CC = os.path.join(CODEWARRIOR, "mwcceppc.exe")
|
||||
OCC = os.path.join(SDK_CW, "mwcceppc.exe")
|
||||
PROFILE = os.path.join(HOTFIX_CW, "mwcceppc.exe")
|
||||
LD = os.path.join(CODEWARRIOR, "mwldeppc.exe")
|
||||
if platform != "win32":
|
||||
CC = f"wibo {CC}"
|
||||
OCC = f"wibo {OCC}"
|
||||
LD = f"wibo {LD}"
|
||||
|
||||
# Frank
|
||||
FRANKLITE = "tools/franklite.py"
|
||||
FRANK = "tools/frank.py"
|
||||
|
||||
# DevkitPPC
|
||||
DEVKITPPC = os.environ.get("DEVKITPPC")
|
||||
AS = os.path.join(DEVKITPPC, "bin", "powerpc-eabi-as")
|
||||
@@ -306,7 +312,7 @@ CPLFLAGS =[
|
||||
"-O0"
|
||||
]
|
||||
BASE_DOL_CFLAGS = CFLAGS + [
|
||||
"-inline all",
|
||||
"-inline on",
|
||||
"-sdata 8",
|
||||
f"-sdata2 {DOL_SDATA2_SIZE}"
|
||||
]
|
||||
|
||||
@@ -352,7 +352,7 @@ forced_types:
|
||||
0x80078fcc: ENTRY
|
||||
0x8007ac24: ENTRY
|
||||
0x8007ac34: ENTRY
|
||||
0x8007db20: ENTRY
|
||||
# 0x8007db20: ENTRY
|
||||
0x8007db3c: ENTRY
|
||||
0x8009ae2c: ENTRY
|
||||
0x8009ae34: ENTRY
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
trim_ctors: true
|
||||
trim_ctors: true
|
||||
|
||||
symbol_aligns:
|
||||
0x80207458: 8 # align RunQueue to 0x001251d8
|
||||
|
||||
@@ -16,11 +16,11 @@ jaudio_NES/dummyprobe.c:
|
||||
#jaudio_NES/verysimple.c:
|
||||
# .text: [0x80008400, 0x80008480]
|
||||
# .sdata: [0x80217b80, 0x80217b88]
|
||||
#libforest/osreport.c: //see why it doesn't match
|
||||
# .text: [0x8005a654, 0x8005a92c]
|
||||
# .data: [0x800dc6d8, 0x800dc738]
|
||||
# .bss: [0x80206f08, 0x80206f20]
|
||||
# .sbss: [0x80218618, 0x80218628]
|
||||
libforest/osreport.c:
|
||||
.text: [0x8005a654, 0x8005a92c]
|
||||
.data: [0x800dc6d8, 0x800dc738]
|
||||
.bss: [0x80206f08, 0x80206f20]
|
||||
.sbss: [0x80218618, 0x80218628]
|
||||
#libforest/fault.c:
|
||||
# .text: [0x8005a92c, 0x8005adac]
|
||||
# .data: [0x800dc738, 0x800dc7c8]
|
||||
@@ -146,6 +146,9 @@ dolphin/os/OSEnableInterrupts.c:
|
||||
.text: [0x8007ac38, 0x8007ac4c]
|
||||
dolphin/os/OSRestoreInterrupts.c:
|
||||
.text: [0x8007ac4c, 0x8007ac70]
|
||||
dolphin/os/OSRtc.c:
|
||||
.text: [0x8007d050, 0x8007db20]
|
||||
.bss: [0x80207400, 0x80207458]
|
||||
MSL_C/rand.c:
|
||||
.text: [0x8009f46c, 0x8009f494]
|
||||
.sdata: [0x80218260, 0x80218268]
|
||||
|
||||
+51
-11
@@ -82,6 +82,8 @@ n.variable("elf2dol", c.ELF2DOL)
|
||||
n.variable("elf2rel", c.ELF2REL)
|
||||
n.variable("codewarrior", c.CODEWARRIOR)
|
||||
n.variable("cc", c.CC)
|
||||
n.variable("franklite", c.FRANKLITE)
|
||||
n.variable("frank", c.FRANK)
|
||||
n.variable("occ", c.OCC)
|
||||
n.variable("align16", c.ALIGN16)
|
||||
n.variable("ld", c.LD)
|
||||
@@ -109,6 +111,7 @@ n.newline()
|
||||
|
||||
# Windows can't use && without this statement
|
||||
ALLOW_CHAIN = "cmd /c " if os.name == "nt" else ""
|
||||
mwcc_cmd = ALLOW_CHAIN + f"$cpp -M $in -MF $out.d $cppflags && $cc $cflags -c $in -o $out"
|
||||
|
||||
n.rule(
|
||||
"relextern",
|
||||
@@ -204,11 +207,30 @@ n.rule(
|
||||
|
||||
n.rule(
|
||||
"cc",
|
||||
command = ALLOW_CHAIN + f"$cpp -M $in -MF $out.d $cppflags && $cc $cflags -c $in -o $out",
|
||||
command = mwcc_cmd,
|
||||
description = "CC $in",
|
||||
deps = "gcc",
|
||||
depfile = "$out.d"
|
||||
)
|
||||
|
||||
n.rule(
|
||||
"franklite",
|
||||
command = f"{mwcc_cmd} && $python $franklite $basefile $basefile",
|
||||
description = "FRANKLITE $out",
|
||||
deps = "gcc",
|
||||
depfile = "$basefile.d"
|
||||
)
|
||||
|
||||
n.rule(
|
||||
"frank",
|
||||
command = f"{mwcc_cmd} " +
|
||||
f"&& {c.PROFILE} $cflags -c $in -o $out.profile " +
|
||||
f"&& $python $frank $out $out.profile $out ",
|
||||
description = "FRANK $out",
|
||||
deps = "gcc",
|
||||
depfile = "$out.d"
|
||||
)
|
||||
|
||||
n.rule(
|
||||
"ccs",
|
||||
command = ALLOW_CHAIN + f"$cpp -M $in -MF $out.d $cppflags && $cc $cflags -S $in -o $out",
|
||||
@@ -609,15 +631,19 @@ class CSource(Source):
|
||||
if path.startswith("src/dolphin/"):
|
||||
self.cflags = c.SDK_FLAGS
|
||||
self.cc = c.OCC
|
||||
self.frank = True
|
||||
elif path.startswith("src/JSystem/"):
|
||||
self.cflags = c.JSYSTEM_CFLAGS
|
||||
self.cc = c.CC
|
||||
self.frank = False
|
||||
elif path.startswith("src/jaudio_NES"):
|
||||
self.cc = c.CC
|
||||
self.cflags = c.DOL_CPPFLAGS
|
||||
self.frank = False
|
||||
else:
|
||||
self.cflags = ctx.cflags
|
||||
self.cc = c.CC
|
||||
self.frank = False
|
||||
self.iconv_path = f"$builddir/iconv/{path}"
|
||||
|
||||
# Find generated includes
|
||||
@@ -645,16 +671,30 @@ class CSource(Source):
|
||||
#)
|
||||
#print(self.i_path)
|
||||
|
||||
n.build(
|
||||
self.o_path,
|
||||
rule = "cc",
|
||||
inputs = self.iconv_path,
|
||||
implicit = [inc.path for inc in self.gen_includes],
|
||||
variables = {
|
||||
"cc" : self.cc,
|
||||
"cflags" : self.cflags
|
||||
}
|
||||
)
|
||||
if self.frank == True:
|
||||
#print(f"python3 franklite.py {self.o_path} {self.o_path}")
|
||||
n.build(
|
||||
self.o_path,
|
||||
rule = "frank",
|
||||
inputs = self.iconv_path,
|
||||
implicit = [inc.path for inc in self.gen_includes],
|
||||
variables = {
|
||||
"cc" : self.cc,
|
||||
"cflags" : self.cflags,
|
||||
#"basefile" : self.o_path
|
||||
}
|
||||
)
|
||||
else:
|
||||
n.build(
|
||||
self.o_path,
|
||||
rule = "cc",
|
||||
inputs = self.iconv_path,
|
||||
implicit = [inc.path for inc in self.gen_includes],
|
||||
variables = {
|
||||
"cc" : self.cc,
|
||||
"cflags" : self.cflags
|
||||
}
|
||||
)
|
||||
# Optional manual debug target
|
||||
n.build(
|
||||
self.s_path,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define JSYSTEM_H
|
||||
|
||||
#include "dolphin/os.h"
|
||||
#include "libforest/osreport.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
//#include "JSystem/JUtility/JUTException.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "va_args.h"
|
||||
|
||||
|
||||
void vprintf(const char*, va_list);
|
||||
void print(const char*, ...);
|
||||
extern void vprintf(const char*, va_list);
|
||||
extern void printf(const char*, ...);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+15
-3
@@ -3,8 +3,11 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSContext.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "libforest/osreport.h" /* OSReport funcs */
|
||||
#include "va_args.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -15,8 +18,8 @@ extern void __OSFPRInit();
|
||||
extern void __OSCacheInit();
|
||||
|
||||
void OSPanic(const char *file, int line, const char *message, ...);
|
||||
void OSReport(const char*, ...);
|
||||
void OSVReport(const char* format, va_list list);
|
||||
void OSVReport(const char* fmt, va_list list);
|
||||
void OSReport(const char* fmt, ...);
|
||||
|
||||
extern void __OSPSInit();
|
||||
extern void __OSCacheInit();
|
||||
@@ -24,6 +27,15 @@ extern void __OSCacheInit();
|
||||
#define OSErrorLine(line, ...) \
|
||||
OSPanic(__FILE__, line, __VA_ARGS__)
|
||||
|
||||
#ifdef DOLPHIN_DEBUG
|
||||
#define DOLPHIN_ASSERTLINE(assertion, line) \
|
||||
(void) ((assertion) || (OSErrorLine(line, "Failed assertion " #assertion), 0))
|
||||
#define DOLPHIN_ASSERT(assertion) \
|
||||
(void) ((assertion) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #assertion), 0))
|
||||
#else
|
||||
#define DOLPHIN_ASSERTLINE(assertion, line)
|
||||
#define DOLPHIN_ASSERT(assertion)
|
||||
#endif
|
||||
|
||||
void OSResetSystem(u32, u32, u32); // goes in reset, but eh
|
||||
void OSInit(void);
|
||||
@@ -33,6 +45,6 @@ typedef void (*OSExceptionHandler)(u8, OSContext*);
|
||||
OSExceptionHandler __OSSetExceptionHandler(u8, OSExceptionHandler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
asm void DCEnable(void);
|
||||
asm void DCInvalidateRange(void*, u32);
|
||||
asm void DCFlushRange(void*, u32);
|
||||
asm void DCStoreRange(void*, u32);
|
||||
asm void DCFlushRangeNoSync(void*, u32);
|
||||
asm void DCStoreRangeNoSync(void*, u32);
|
||||
asm void DCZeroRange(void*, u32);
|
||||
asm void DCTouchRange(void*, u32 len);
|
||||
asm void ICInvalidateRange(void*, u32);
|
||||
asm void ICFlashInvalidate(void);
|
||||
asm void ICEnable(void);
|
||||
asm void LCDisable(void);
|
||||
void DCEnable(void);
|
||||
void DCInvalidateRange(void*, u32);
|
||||
void DCFlushRange(void*, u32);
|
||||
void DCStoreRange(void*, u32);
|
||||
void DCFlushRangeNoSync(void*, u32);
|
||||
void DCStoreRangeNoSync(void*, u32);
|
||||
void DCZeroRange(void*, u32);
|
||||
void DCTouchRange(void*, u32 len);
|
||||
void ICInvalidateRange(void*, u32);
|
||||
void ICFlashInvalidate(void);
|
||||
void ICEnable(void);
|
||||
void LCDisable(void);
|
||||
|
||||
//void L2GlobalInvalidate(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef DOLPHIN_OSEXCEPTION_H
|
||||
#define DOLPHIN_OSEXCEPTION_H
|
||||
|
||||
typedef enum OSException {
|
||||
OS_EXCEPTION_FLOATING_POINT = 7,
|
||||
OS_EXCEPTION_COUNT = 15,
|
||||
} OSException;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifndef DOLPHIN_OSEXI_H
|
||||
#define DOLPHIN_OSEXI_H
|
||||
|
||||
#include "dolphin/os/OSContext.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
#include "types.h"
|
||||
|
||||
typedef enum {
|
||||
EXI_STATE_DMA_ACCESS = (1 << 0),
|
||||
EXI_STATE_IMM_ACCESS = (1 << 1),
|
||||
EXI_STATE_SELECTED = (1 << 2),
|
||||
EXI_STATE_ATTACHED = (1 << 3),
|
||||
EXI_STATE_LOCKED = (1 << 4),
|
||||
EXI_STATE_BUSY = EXI_STATE_DMA_ACCESS | EXI_STATE_IMM_ACCESS
|
||||
} EXIState;
|
||||
|
||||
typedef enum {
|
||||
EXI_CHAN_0,
|
||||
EXI_CHAN_1,
|
||||
EXI_CHAN_2,
|
||||
EXI_MAX_CHAN
|
||||
} EXIChannel;
|
||||
|
||||
typedef enum {
|
||||
EXI_READ,
|
||||
EXI_WRITE,
|
||||
EXI_TYPE_2,
|
||||
EXI_MAX_TYPE
|
||||
} EXIType;
|
||||
|
||||
typedef void (*EXICallback)(EXIChannel, OSContext*);
|
||||
|
||||
typedef struct EXIControl {
|
||||
EXICallback exiCallback;
|
||||
EXICallback tcCallback;
|
||||
EXICallback extCallback;
|
||||
vu32 state;
|
||||
int immLen;
|
||||
u8* immBuf;
|
||||
u32 dev;
|
||||
u32 id;
|
||||
s32 idTime;
|
||||
int items;
|
||||
struct {
|
||||
u32 dev;
|
||||
EXICallback callback;
|
||||
} queue[3];
|
||||
} EXIControl;
|
||||
|
||||
#define EXI_REG_MAX 5
|
||||
extern vu32 __EXIRegs[EXI_MAX_CHAN][EXI_REG_MAX] AT_ADDRESS(0xCC006800);
|
||||
|
||||
void SetExiInterruptMask(EXIChannel, volatile EXIControl*);
|
||||
BOOL EXIImm(EXIChannel, void* buf, s32 len, u32 type, EXICallback);
|
||||
BOOL EXIImmEx(EXIChannel, void* buf, s32 len, u32 mode);
|
||||
BOOL EXIDma(EXIChannel, void* buf, s32 len, u32 type, EXICallback);
|
||||
BOOL EXISync(EXIChannel);
|
||||
u32 EXIClearInterrupts(EXIChannel, BOOL exi, BOOL tc, BOOL ext);
|
||||
EXICallback EXISetExiCallback(EXIChannel, EXICallback exiCallback);
|
||||
BOOL EXIProbe(EXIChannel);
|
||||
s32 EXIProbeEx(EXIChannel);
|
||||
BOOL EXIAttach(EXIChannel, EXICallback);
|
||||
BOOL EXIDetach(EXIChannel);
|
||||
BOOL EXISelect(EXIChannel, u32 dev, u32 freq);
|
||||
BOOL EXIDeselect(EXIChannel);
|
||||
void EXIInit(void);
|
||||
BOOL EXILock(EXIChannel, u32 dev, EXICallback unlockedCallback);
|
||||
BOOL EXIUnlock(EXIChannel);
|
||||
u32 EXIGetState(EXIChannel);
|
||||
s32 EXIGetID(EXIChannel, u32 dev, u32* id);
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,127 @@
|
||||
#ifndef OS_INTERRUPT_H
|
||||
#define OS_INTERRUPT_H
|
||||
#ifndef DOLPHIN_OSINTERRUPT_H
|
||||
#define DOLPHIN_OSINTERRUPT_H
|
||||
|
||||
#include "dolphin/os/OSContext.h"
|
||||
#include "dolphin/os/OSException.h"
|
||||
#include "types.h"
|
||||
|
||||
typedef s16 __OSInterrupt;
|
||||
typedef u32 OSInterruptMask;
|
||||
|
||||
BOOL OSDisableInterrupts(void);
|
||||
BOOL OSEnableInterrupts(void);
|
||||
BOOL OSRestoreInterrupts(BOOL status);
|
||||
typedef enum OSInterruptType {
|
||||
OS_INTR_MEM_0,
|
||||
OS_INTR_MEM_1,
|
||||
OS_INTR_MEM_2,
|
||||
OS_INTR_MEM_3,
|
||||
OS_INTR_MEM_ADDRESS,
|
||||
OS_INTR_DSP_AI,
|
||||
OS_INTR_DSP_ARAM,
|
||||
OS_INTR_DSP_DSP,
|
||||
OS_INTR_AI_AI,
|
||||
OS_INTR_EXI_0_EXI,
|
||||
OS_INTR_EXI_0_TC,
|
||||
OS_INTR_EXI_0_EXT,
|
||||
OS_INTR_EXI_1_EXI,
|
||||
OS_INTR_EXI_1_TC,
|
||||
OS_INTR_EXI_1_EXT,
|
||||
OS_INTR_EXI_2_EXI,
|
||||
OS_INTR_EXI_2_TC,
|
||||
OS_INTR_PI_CP,
|
||||
OS_INTR_PI_PE_TOKEN,
|
||||
OS_INTR_PI_PE_FINISH,
|
||||
OS_INTR_PI_SI,
|
||||
OS_INTR_PI_DI,
|
||||
OS_INTR_PI_RSW,
|
||||
OS_INTR_PI_ERROR,
|
||||
OS_INTR_PI_VI,
|
||||
OS_INTR_PI_DEBUG,
|
||||
OS_INTR_PI_HSP,
|
||||
OS_INTR_PI_ACR,
|
||||
OS_INTR_28,
|
||||
OS_INTR_29,
|
||||
OS_INTR_30,
|
||||
OS_INTR_31,
|
||||
|
||||
OS_INTR_MAX
|
||||
} OSInterruptType;
|
||||
|
||||
#define OS_INTRMASK_MEM_0 (0x80000000U >> OS_INTR_MEM_0)
|
||||
#define OS_INTRMASK_MEM_1 (0x80000000U >> OS_INTR_MEM_1)
|
||||
#define OS_INTRMASK_MEM_2 (0x80000000U >> OS_INTR_MEM_2)
|
||||
#define OS_INTRMASK_MEM_3 (0x80000000U >> OS_INTR_MEM_3)
|
||||
#define OS_INTRMASK_MEM_ADDRESS (0x80000000U >> OS_INTR_MEM_ADDRESS)
|
||||
#define OS_INTRMASK_DSP_AI (0x80000000U >> OS_INTR_DSP_AI)
|
||||
#define OS_INTRMASK_DSP_ARAM (0x80000000U >> OS_INTR_DSP_ARAM)
|
||||
#define OS_INTRMASK_DSP_DSP (0x80000000U >> OS_INTR_DSP_DSP)
|
||||
#define OS_INTRMASK_AI_AI (0x80000000U >> OS_INTR_AI_AI)
|
||||
#define OS_INTRMASK_EXI_0_EXI (0x80000000U >> OS_INTR_EXI_0_EXI)
|
||||
#define OS_INTRMASK_EXI_0_TC (0x80000000U >> OS_INTR_EXI_0_TC)
|
||||
#define OS_INTRMASK_EXI_0_EXT (0x80000000U >> OS_INTR_EXI_0_EXT)
|
||||
#define OS_INTRMASK_EXI_1_EXI (0x80000000U >> OS_INTR_EXI_1_EXI)
|
||||
#define OS_INTRMASK_EXI_1_TC (0x80000000U >> OS_INTR_EXI_1_TC)
|
||||
#define OS_INTRMASK_EXI_1_EXT (0x80000000U >> OS_INTR_EXI_1_EXT)
|
||||
#define OS_INTRMASK_EXI_2_EXI (0x80000000U >> OS_INTR_EXI_2_EXI)
|
||||
#define OS_INTRMASK_EXI_2_TC (0x80000000U >> OS_INTR_EXI_2_TC)
|
||||
#define OS_INTRMASK_PI_CP (0x80000000U >> OS_INTR_PI_CP)
|
||||
#define OS_INTRMASK_PI_PE_TOKEN (0x80000000U >> OS_INTR_PI_PE_TOKEN)
|
||||
#define OS_INTRMASK_PI_PE_FINISH (0x80000000U >> OS_INTR_PI_PE_FINISH)
|
||||
#define OS_INTRMASK_PI_SI (0x80000000U >> OS_INTR_PI_SI)
|
||||
#define OS_INTRMASK_PI_DI (0x80000000U >> OS_INTR_PI_DI)
|
||||
#define OS_INTRMASK_PI_RSW (0x80000000U >> OS_INTR_PI_RSW)
|
||||
#define OS_INTRMASK_PI_ERROR (0x80000000U >> OS_INTR_PI_ERROR)
|
||||
#define OS_INTRMASK_PI_VI (0x80000000U >> OS_INTR_PI_VI)
|
||||
#define OS_INTRMASK_PI_DEBUG (0x80000000U >> OS_INTR_PI_DEBUG)
|
||||
#define OS_INTRMASK_PI_HSP (0x80000000U >> OS_INTR_PI_HSP)
|
||||
|
||||
#define OS_INTRMASK_MEM \
|
||||
(OS_INTRMASK_MEM_0 | OS_INTRMASK_MEM_1 | OS_INTRMASK_MEM_2 | \
|
||||
OS_INTRMASK_MEM_3 | OS_INTRMASK_MEM_ADDRESS)
|
||||
|
||||
#define OS_INTRMASK_AI (OS_INTRMASK_AI_AI)
|
||||
|
||||
#define OS_INTRMASK_DSP \
|
||||
(OS_INTRMASK_DSP_AI | OS_INTRMASK_DSP_ARAM | OS_INTRMASK_DSP_DSP)
|
||||
|
||||
#define OS_INTRMASK_EXI_0 \
|
||||
(OS_INTRMASK_EXI_0_EXI | OS_INTRMASK_EXI_0_TC | OS_INTRMASK_EXI_0_EXT)
|
||||
#define OS_INTRMASK_EXI_1 \
|
||||
(OS_INTRMASK_EXI_1_EXI | OS_INTRMASK_EXI_1_TC | OS_INTRMASK_EXI_1_EXT)
|
||||
#define OS_INTRMASK_EXI_2 (OS_INTRMASK_EXI_2_EXI | OS_INTRMASK_EXI_2_TC)
|
||||
#define OS_INTRMASK_EXI \
|
||||
(OS_INTRMASK_EXI_0_EXI | OS_INTRMASK_EXI_0_TC | OS_INTRMASK_EXI_0_EXT | \
|
||||
OS_INTRMASK_EXI_1_EXI | OS_INTRMASK_EXI_1_TC | OS_INTRMASK_EXI_1_EXT | \
|
||||
OS_INTRMASK_EXI_2_EXI | OS_INTRMASK_EXI_2_TC)
|
||||
|
||||
#define OS_INTRMASK_PI \
|
||||
(OS_INTRMASK_PI_CP | OS_INTRMASK_PI_SI | OS_INTRMASK_PI_DI | \
|
||||
OS_INTRMASK_PI_RSW | OS_INTRMASK_PI_ERROR | OS_INTRMASK_PI_VI | \
|
||||
OS_INTRMASK_PI_PE_TOKEN | OS_INTRMASK_PI_PE_FINISH | \
|
||||
OS_INTRMASK_PI_DEBUG | OS_INTRMASK_PI_HSP)
|
||||
|
||||
#define OS_INTRMASK_PI_PE (OS_INTRMASK_PI_PE_TOKEN | OS_INTRMASK_PI_PE_FINISH)
|
||||
|
||||
typedef void (*OSInterruptHandler)(__OSInterrupt, OSContext*);
|
||||
|
||||
extern volatile u32 __OSLastInterruptSrr0;
|
||||
extern volatile s16 __OSLastInterrupt;
|
||||
extern volatile s64 __OSLastInterruptTime;
|
||||
|
||||
void __RAS_OSDisableInterrupts_begin(void);
|
||||
void __RAS_OSDisableInterrupts_end(void);
|
||||
|
||||
#endif
|
||||
BOOL OSDisableInterrupts(void);
|
||||
BOOL OSEnableInterrupts(void);
|
||||
BOOL OSRestoreInterrupts(BOOL);
|
||||
|
||||
OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt, OSInterruptHandler);
|
||||
OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt);
|
||||
|
||||
void __OSInterruptInit(void);
|
||||
|
||||
u32 __OSMaskInterrupts(u32);
|
||||
u32 __OSUnmaskInterrupts(u32);
|
||||
|
||||
u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current);
|
||||
void __OSDispatchInterrupt(OSException exception, OSContext* context);
|
||||
|
||||
#endif
|
||||
|
||||
+107
-5
@@ -1,9 +1,111 @@
|
||||
#ifndef OS_RTC_H
|
||||
#define OS_RTC_H
|
||||
#ifndef DOLPHIN_OSRTC_H
|
||||
#define DOLPHIN_OSTRC_H
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSExi.h"
|
||||
|
||||
u32 __OSSyncSram(void);
|
||||
void __OSSetBootMode(u8);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#define OS_SOUND_MODE_MONO 0
|
||||
#define OS_SOUND_MODE_STEREO 1
|
||||
|
||||
#define OS_PROGRESSIVE_MODE_OFF 0
|
||||
#define OS_PROGRESSIVE_MODE_ON 1
|
||||
|
||||
#define OS_BOOT_MODE_DEBUG (0 << 7)
|
||||
#define OS_BOOT_MODE_RETAIL (1 << 7)
|
||||
|
||||
#define RTC_CMD_READ 0x20000000
|
||||
#define RTC_CMD_WRITE 0xA0000000
|
||||
|
||||
#define RTC_SRAM_ADDR 0x00000100
|
||||
#define RTC_SRAM_SIZE 64
|
||||
|
||||
#define RTC_CHAN EXI_CHAN_0
|
||||
#define RTC_DEVICE 1
|
||||
#define RTC_FREQUENCY 3
|
||||
|
||||
typedef struct OSSram_s {
|
||||
u16 checkSum;
|
||||
u16 checkSumInv;
|
||||
u32 ead0;
|
||||
u32 ead1;
|
||||
u32 counterBias;
|
||||
s8 displayOffsetH;
|
||||
u8 ntd;
|
||||
u8 language;
|
||||
u8 flags;
|
||||
} OSSram;
|
||||
|
||||
typedef struct OSSramEx_s {
|
||||
u8 flashID[2][12];
|
||||
u32 wirelessKeyboardID;
|
||||
u16 wirelessPadID[4];
|
||||
u8 dvdErrorCode;
|
||||
u8 pad0;
|
||||
u8 flashIDCheckSum[2];
|
||||
u16 gbs;
|
||||
u8 pad1[2];
|
||||
} OSSramEx;
|
||||
|
||||
typedef struct SramControlBlock_s {
|
||||
u8 sram[RTC_SRAM_SIZE];
|
||||
u32 offset;
|
||||
BOOL enabled;
|
||||
BOOL locked;
|
||||
BOOL sync;
|
||||
void (*callback)(void);
|
||||
} SramControlBlock;
|
||||
|
||||
// static void GetRTC();
|
||||
// extern void __OSGetRTC();
|
||||
// extern void __OSSetRTC();
|
||||
static inline BOOL ReadSram(void* buffer);
|
||||
static void WriteSramCallback(EXIChannel chan, OSContext* ctx);
|
||||
static BOOL WriteSram(void* buffer, u32 offset, u32 size);
|
||||
extern void __OSInitSram();
|
||||
static inline void* LockSram(u32 offset);
|
||||
extern OSSram* __OSLockSram();
|
||||
extern OSSramEx* __OSLockSramEx();
|
||||
static BOOL UnlockSram(BOOL commit, u32 offset);
|
||||
extern void __OSUnlockSram(BOOL commit);
|
||||
extern void __OSUnlockSramEx(BOOL commit);
|
||||
extern BOOL __OSSyncSram();
|
||||
// extern void __OSCheckSram();
|
||||
// extern void __OSReadROM();
|
||||
// extern void __OSReadROMCallback();
|
||||
// extern void __OSReadROMAsync();
|
||||
extern u32 OSGetSoundMode();
|
||||
extern void OSSetSoundMode(u32 mode);
|
||||
extern u32 OSGetProgressiveMode();
|
||||
extern void OSSetProgressiveMode(u32 on);
|
||||
// extern void OSGetVideoMode();
|
||||
// extern void OSSetVideoMode();
|
||||
// extern void OSGetLanguage();
|
||||
// extern void OSSetLanguage();
|
||||
// extern void __OSGetBootMode();
|
||||
extern void __OSSetBootMode(u8 mode);
|
||||
// extern void OSGetEuRgb60Mode();
|
||||
// extern void OSSetEuRgb60Mode();
|
||||
extern u16 OSGetWirelessID(u32 chan);
|
||||
extern void OSSetWirelessID(u32 chan, u16 id);
|
||||
|
||||
#define GET_SOUNDMODE(flags) ((flags) & (1 << 2))
|
||||
#define CLR_SOUNDMODE(flags) ((flags) & (~(1 << 2)))
|
||||
#define SET_SOUNDMODE(mode) (((mode) & 1) << 2)
|
||||
|
||||
#define GET_PROGMODE(flags) ((flags) & (1 << 7))
|
||||
#define CLR_PROGMODE(flags) ((flags) & (~(1 << 7)))
|
||||
#define SET_PROGMODE(mode) (((mode) & 1) << 7)
|
||||
|
||||
#define GET_BOOTMODE(flags) ((flags) & (1 << 7))
|
||||
#define CLR_BOOTMODE(flags) ((flags) & (~(1 << 7)))
|
||||
#define SET_BOOTMODE(mode) (mode)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,19 +1,39 @@
|
||||
#ifndef LIB_OS_REPORT_H
|
||||
#define LIB_OS_REPORT_H
|
||||
#ifndef OSREPORT_H
|
||||
#define OSREPORT_H
|
||||
|
||||
#include "types.h"
|
||||
#include "va_args.h"
|
||||
#include "dolphin/os/OSMutex.h"
|
||||
#include "dolphin/os/OSThread.h"
|
||||
|
||||
void OSReportDisable(void);
|
||||
void OSReportEnable(void);
|
||||
#define DEBUG_MODE 0
|
||||
#define RETAIL_MODE 1
|
||||
|
||||
void OSVReport(const char*, va_list);
|
||||
/* Causes DSI exception */
|
||||
#define OSThrow() (*(int*)0 = 0)
|
||||
|
||||
void OSReport(const char*,...);
|
||||
void OSPanic(const char*, u32, const char*,...);
|
||||
extern void my_fopen(); /* @unused */
|
||||
extern void my_fgets(); /* @unused */
|
||||
extern void my_fclose(); /* @unused */
|
||||
extern void print_section(); /* @unused */
|
||||
extern void* OSGetCallerPC(); /* @unused */
|
||||
extern void OSDumpStackTrace(); /* @unused */
|
||||
extern s32 OSGetActiveThreadID(); /* @unused */
|
||||
extern void OSReportMonopoly(); /* @unused */
|
||||
|
||||
void OSChangeBootMode(u32);
|
||||
extern void OSReportDisable();
|
||||
extern void OSReportEnable();
|
||||
//void OSVReport(const char* fmt, va_list list);
|
||||
//void OSReport(const char* fmt, ...);
|
||||
//void OSPanic(const char* file, u32 line, const char* fmt, ...);
|
||||
extern void OSChangeBootMode(u32 mode);
|
||||
extern void OSDVDFatalError();
|
||||
|
||||
void OSDVDFatalError(void);
|
||||
#define OSChangeToRetail() (OSChangeBootMode(RETAIL_MODE))
|
||||
#define OSChangeToDebug() (OSChangeBootMode(DEBUG_MODE))
|
||||
|
||||
#endif
|
||||
static BOOL __OSReport_disable;
|
||||
static OSThread* __OSReport_MonopolyThread;
|
||||
static u8 print_mutex_initialized;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,18 @@ typedef u32 unknown;
|
||||
#define NULL ((void*)0)
|
||||
#define nullptr 0
|
||||
|
||||
#define AT_ADDRESS(x) : (x)
|
||||
|
||||
#ifndef ATTRIBUTE_ALIGN
|
||||
#if defined(__MWERKS__) || defined(__GNUC__)
|
||||
#define ATTRIBUTE_ALIGN(num) __attribute__((aligned(num)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define ATTRIBUTE_ALIGN(num)
|
||||
#else
|
||||
#error unknown compiler
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
#include "dolphin/os/OSRtc.h"
|
||||
|
||||
#include "dolphin/os/OSCache.h"
|
||||
#include "dolphin/os/OSExi.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "types.h"
|
||||
|
||||
static SramControlBlock Scb ATTRIBUTE_ALIGN(32);
|
||||
|
||||
static inline BOOL ReadSram(void* buffer) {
|
||||
u32 cmd;
|
||||
BOOL err;
|
||||
|
||||
DCInvalidateRange(buffer, RTC_SRAM_SIZE);
|
||||
|
||||
if (!EXILock(RTC_CHAN, RTC_DEVICE, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!EXISelect(RTC_CHAN, RTC_DEVICE, RTC_FREQUENCY)) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cmd = RTC_CMD_READ | RTC_SRAM_ADDR;
|
||||
err = !EXIImm(RTC_CHAN, &cmd, sizeof(u32), EXI_WRITE, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, EXI_READ, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
|
||||
return !err;
|
||||
}
|
||||
|
||||
void WriteSramCallback(EXIChannel chan, OSContext* ctx) {
|
||||
DOLPHIN_ASSERTLINE(!Scb.locked, 258);
|
||||
Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
|
||||
DOLPHIN_ASSERTLINE(Scb.sync, 264);
|
||||
|
||||
if (Scb.sync) {
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL WriteSram(void* buffer, u32 offset, u32 size) {
|
||||
u32 cmd;
|
||||
BOOL err;
|
||||
|
||||
if (EXILock(RTC_CHAN, 1, WriteSramCallback) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (EXISelect(RTC_CHAN, RTC_DEVICE, RTC_FREQUENCY) == FALSE) {
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
offset *= RTC_SRAM_SIZE;
|
||||
cmd = offset + RTC_SRAM_ADDR | RTC_CMD_WRITE;
|
||||
err = !EXIImm(RTC_CHAN, &cmd, sizeof(u32), EXI_WRITE, NULL);
|
||||
err |= !EXISync(RTC_CHAN);
|
||||
err |= !EXIImmEx(RTC_CHAN, buffer, size, EXI_WRITE);
|
||||
err |= !EXIDeselect(RTC_CHAN);
|
||||
EXIUnlock(RTC_CHAN);
|
||||
return !err;
|
||||
}
|
||||
|
||||
extern void __OSInitSram() {
|
||||
Scb.enabled = FALSE;
|
||||
Scb.locked = FALSE;
|
||||
Scb.sync = ReadSram(Scb.sram);
|
||||
DOLPHIN_ASSERTLINE(Scb.sync, 318);
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
|
||||
static inline void* LockSram(u32 offset) {
|
||||
BOOL enabled = OSDisableInterrupts();
|
||||
|
||||
DOLPHIN_ASSERTLINE(Scb.locked, 341);
|
||||
if (Scb.locked != FALSE) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Scb.enabled = enabled;
|
||||
Scb.locked = TRUE;
|
||||
return Scb.sram + offset;
|
||||
}
|
||||
|
||||
extern OSSram* __OSLockSram() {
|
||||
return (OSSram*)LockSram(0);
|
||||
//return sram;
|
||||
}
|
||||
|
||||
extern OSSramEx* __OSLockSramEx() {
|
||||
return (OSSramEx*)LockSram(sizeof(OSSram));
|
||||
//return sramEx;
|
||||
}
|
||||
|
||||
static BOOL UnlockSram(BOOL commit, u32 offset) {
|
||||
u16* chksum_p;
|
||||
|
||||
DOLPHIN_ASSERTLINE(Scb.locked, 375);
|
||||
if (commit) {
|
||||
if (offset == 0) {
|
||||
OSSram* sram = (OSSram*)Scb.sram;
|
||||
if ((sram->flags & 3u) > 2u) {
|
||||
sram->flags &= (~3u);
|
||||
}
|
||||
|
||||
sram->checkSum = sram->checkSumInv = 0;
|
||||
for (chksum_p = (u16*)&sram->counterBias; chksum_p < (u16*)(Scb.sram + sizeof(OSSram)); chksum_p++) {
|
||||
sram->checkSum += *chksum_p;
|
||||
sram->checkSumInv += ~*chksum_p;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset < Scb.offset) {
|
||||
Scb.offset = offset;
|
||||
}
|
||||
|
||||
Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
|
||||
if (Scb.sync) {
|
||||
Scb.offset = RTC_SRAM_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
Scb.locked = FALSE;
|
||||
OSRestoreInterrupts(Scb.enabled);
|
||||
return Scb.sync;
|
||||
}
|
||||
|
||||
extern void __OSUnlockSram(BOOL commit) {
|
||||
UnlockSram(commit, 0);
|
||||
}
|
||||
|
||||
extern void __OSUnlockSramEx(BOOL commit) {
|
||||
UnlockSram(commit, sizeof(OSSram));
|
||||
}
|
||||
|
||||
extern BOOL __OSSyncSram() {
|
||||
return Scb.sync;
|
||||
}
|
||||
|
||||
extern u32 OSGetSoundMode() {
|
||||
OSSram* sram = __OSLockSram();
|
||||
u32 mode = GET_SOUNDMODE(sram->flags) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO;
|
||||
__OSUnlockSram(FALSE);
|
||||
return mode;
|
||||
}
|
||||
|
||||
extern void OSSetSoundMode(u32 mode) {
|
||||
u32 flag;
|
||||
OSSram* sram;
|
||||
u32 m;
|
||||
|
||||
DOLPHIN_ASSERTLINE(mode == OS_SOUND_MODE_MONO || mode == OS_SOUND_MODE_STEREO, 617);
|
||||
flag = SET_SOUNDMODE(mode);
|
||||
sram = (OSSram*)__OSLockSram();
|
||||
if (flag == GET_SOUNDMODE(sram->flags)) {
|
||||
__OSUnlockSram(FALSE);
|
||||
}
|
||||
else {
|
||||
sram->flags = CLR_SOUNDMODE(sram->flags);
|
||||
sram->flags |= flag;
|
||||
__OSUnlockSram(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
extern u32 OSGetProgressiveMode() {
|
||||
OSSram* sram = __OSLockSram();
|
||||
u32 mode = GET_PROGMODE(sram->flags) >> 7;
|
||||
__OSUnlockSram(FALSE);
|
||||
return mode;
|
||||
}
|
||||
|
||||
extern void OSSetProgressiveMode(u32 on) {
|
||||
u32 flag;
|
||||
OSSram* sram;
|
||||
u32 m;
|
||||
|
||||
DOLPHIN_ASSERTLINE(on == OS_PROGRESSIVE_MODE_OFF || on == OS_PROGRESSIVE_MODE_ON, 670);
|
||||
flag = SET_PROGMODE(on);
|
||||
sram = __OSLockSram();
|
||||
|
||||
if (flag == GET_PROGMODE(sram->flags)) {
|
||||
__OSUnlockSram(FALSE);
|
||||
}
|
||||
else {
|
||||
sram->flags = CLR_PROGMODE(sram->flags);
|
||||
sram->flags |= flag;
|
||||
__OSUnlockSram(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
extern void __OSSetBootMode(u8 mode) {
|
||||
OSSram* sram;
|
||||
u32 m;
|
||||
|
||||
mode &= OS_BOOT_MODE_RETAIL;
|
||||
sram = __OSLockSram();
|
||||
if (mode == (u32)GET_BOOTMODE(sram->ntd)) {
|
||||
__OSUnlockSram(FALSE);
|
||||
}
|
||||
else {
|
||||
sram->ntd = CLR_BOOTMODE(sram->ntd);
|
||||
sram->ntd |= mode;
|
||||
__OSUnlockSram(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
extern u16 OSGetWirelessID(u32 chan) {
|
||||
OSSramEx* sramEx = __OSLockSramEx();
|
||||
u16 id = sramEx->wirelessPadID[chan];
|
||||
__OSUnlockSramEx(FALSE);
|
||||
return id;
|
||||
}
|
||||
|
||||
extern void OSSetWirelessID(u32 chan, u16 id) {
|
||||
OSSramEx* sramEx = __OSLockSramEx();
|
||||
if (sramEx->wirelessPadID[chan] != id) {
|
||||
sramEx->wirelessPadID[chan] = id;
|
||||
__OSUnlockSramEx(TRUE);
|
||||
}
|
||||
else {
|
||||
__OSUnlockSramEx(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
+27
-35
@@ -1,60 +1,55 @@
|
||||
#include "libforest/osreport.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
#include "dolphin/os/OSThread.h"
|
||||
#include "dolphin/os/OSRtc.h"
|
||||
#include "dolphin/os/OSMutex.h"
|
||||
|
||||
#include "MSL_C/printf.h"
|
||||
|
||||
OSMutex print_mutex;
|
||||
u8 print_mutex_initialized;
|
||||
static void* __OSReport_MonopolyThread;
|
||||
static s32 __OSReport_disable;
|
||||
|
||||
|
||||
void OSReportDisable (void){
|
||||
__OSReport_disable = 1;
|
||||
extern void OSReportDisable() {
|
||||
__OSReport_disable = TRUE;
|
||||
}
|
||||
|
||||
void OSReportEnable (void){
|
||||
__OSReport_disable = 0;
|
||||
extern void OSReportEnable() {
|
||||
__OSReport_disable = FALSE;
|
||||
}
|
||||
|
||||
void OSVReport(const char* fmt, va_list list){
|
||||
|
||||
void OSVReport(const char* fmt, va_list list) {
|
||||
OSThread* cur_thread;
|
||||
u32 enable;
|
||||
if(__OSReport_disable == 0){
|
||||
|
||||
if (__OSReport_disable == FALSE) {
|
||||
cur_thread = OSGetCurrentThread();
|
||||
if((cur_thread != NULL) && (cur_thread->state !=2)) {
|
||||
if ((cur_thread != NULL) && (cur_thread->state != (u32)OS_THREAD_STATE_RUNNING)) {
|
||||
cur_thread = NULL;
|
||||
}
|
||||
if((__OSReport_MonopolyThread == NULL) || (__OSReport_MonopolyThread == cur_thread)){
|
||||
if ((__OSReport_MonopolyThread == NULL) || (__OSReport_MonopolyThread == cur_thread)) {
|
||||
enable = OSDisableInterrupts();
|
||||
if(print_mutex_initialized == 0){
|
||||
if (print_mutex_initialized == FALSE) {
|
||||
OSInitMutex(&print_mutex);
|
||||
print_mutex_initialized = 1;
|
||||
print_mutex_initialized = TRUE;
|
||||
printf("*** OSVReport - OSInitMutex ***");
|
||||
}
|
||||
OSRestoreInterrupts(enable);
|
||||
if(cur_thread != NULL){
|
||||
if (cur_thread != NULL) {
|
||||
OSLockMutex(&print_mutex);
|
||||
}
|
||||
vprintf(fmt, list);
|
||||
if(cur_thread != NULL){
|
||||
if (cur_thread != NULL) {
|
||||
OSUnlockMutex(&print_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSReport(const char* fmt,...){
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
OSVReport(fmt, list);
|
||||
va_end(list);
|
||||
void OSReport(const char* fmt, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
OSVReport(fmt, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
void OSPanic(const char* file, u32 line, const char* fmt, ...){
|
||||
void OSPanic(const char* file, int line, const char* fmt, ...) {
|
||||
va_list list;
|
||||
u32 enable;
|
||||
OSThread* thread;
|
||||
@@ -68,21 +63,18 @@ void OSPanic(const char* file, u32 line, const char* fmt, ...){
|
||||
|
||||
thread = OSGetCurrentThread();
|
||||
|
||||
OSSetThreadPriority(thread, 0x1f);
|
||||
OSSetThreadPriority(thread, OS_PRIORITY_IDLE);
|
||||
OSRestoreInterrupts(enable);
|
||||
*(int*)0 = 0; //why lol
|
||||
OSThrow(); /* Stop processor execution forcefully */
|
||||
}
|
||||
|
||||
void OSChangeBootMode(u32 mode){
|
||||
__OSSetBootMode(mode ? 0x80 : 0);
|
||||
|
||||
while(__OSSyncSram() == 0) { }
|
||||
extern void OSChangeBootMode(u32 mode) {
|
||||
__OSSetBootMode(mode ? OS_BOOT_MODE_RETAIL : OS_BOOT_MODE_DEBUG);
|
||||
|
||||
while(__OSSyncSram() == FALSE) { }
|
||||
}
|
||||
|
||||
void OSDVDFatalError(void){
|
||||
extern void OSDVDFatalError(void) {
|
||||
OSReport("OSDVDFatalError called.\nExitThread.\n");
|
||||
OSExitThread(0);
|
||||
OSExitThread(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# Written by Ethan Roseman (ethteck)
|
||||
# MIT License
|
||||
# Copyright 2021
|
||||
|
||||
# Modified by EpochFlame
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
# Byte sequence that marks code size
|
||||
CODESIZE_MAGIC = b"\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x34"
|
||||
BLR_BYTE_SEQ = b"\x4E\x80\x00\x20"
|
||||
MTLR_BYTE_SEQ = b"\x7C\x08\x03\xA6"
|
||||
PROFILE_EXTRA_BYTES = b"\x48\x00\x00\x01\x60\x00\x00\x00"
|
||||
|
||||
LWZ_BYTE = b"\x80"
|
||||
|
||||
# Byte sequence array for branches to link register
|
||||
BLR_BYTE_SEQ_ARRAY = [BLR_BYTE_SEQ,
|
||||
b"\x4D\x80\x00\x20", b"\x4D\x80\x00\x21", b"\x4C\x81\x00\x20", b"\x4C\x81\x00\x21",
|
||||
b"\x4D\x82\x00\x20", b"\x4D\x82\x00\x21", b"\x4C\x80\x00\x20", b"\x4C\x80\x00\x21",
|
||||
b"\x4D\x81\x00\x20", b"\x4D\x81\x00\x21", b"\x4C\x80\x00\x20", b"\x4C\x80\x00\x21",
|
||||
b"\x4C\x82\x00\x20", b"\x4C\x82\x00\x21", b"\x4C\x81\x00\x20", b"\x4C\x81\x00\x21",
|
||||
b"\x4D\x83\x00\x20", b"\x4D\x83\x00\x21", b"\x4C\x83\x00\x20", b"\x4C\x83\x00\x21",
|
||||
b"\x4D\x83\x00\x20", b"\x4D\x83\x00\x21", b"\x4C\x83\x00\x20", b"\x4C\x83\x00\x21"]
|
||||
|
||||
# Example invocation: ./frank.py vanilla.o profile.o output.o
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("vanilla", help="Path to the vanilla object", type=argparse.FileType('rb'))
|
||||
parser.add_argument("profile", help="Path to the profile object", type=argparse.FileType('rb'))
|
||||
parser.add_argument("target", help="Path to the target object (to write)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read contents into bytearrays and close files
|
||||
vanilla_bytes = args.vanilla.read()
|
||||
args.vanilla.close()
|
||||
|
||||
# If the file contains no code, the codesize magic will not be found.
|
||||
# The vanilla object requires no modification.
|
||||
code_size_magic_idx = vanilla_bytes.find(CODESIZE_MAGIC)
|
||||
if code_size_magic_idx == -1:
|
||||
with open(args.target, "wb") as f:
|
||||
f.write(vanilla_bytes)
|
||||
sys.exit(0)
|
||||
|
||||
profile_bytes = args.profile.read()
|
||||
args.profile.close()
|
||||
|
||||
# Peephole rescheduling
|
||||
#
|
||||
# This is the pattern we will detect:
|
||||
# (A) lwz <--. .--> (A) li
|
||||
# (B) li <---\-' bl
|
||||
# \ nop
|
||||
# '---> (B) lwz
|
||||
#
|
||||
# If the profiled schedule swaps the
|
||||
# instructions around the bl/nop, we
|
||||
# instead use the vanilla schedule.
|
||||
#
|
||||
idx = 8
|
||||
shift = 0 # difference between vanilla and profile code, due to bl/nops
|
||||
while idx < len(profile_bytes) - 16:
|
||||
# Find next epilogue
|
||||
epi_pos = profile_bytes.find(PROFILE_EXTRA_BYTES, idx)
|
||||
if epi_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if epi_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
|
||||
v_pos = epi_pos - shift
|
||||
shift += 8
|
||||
|
||||
vanilla_inst_a = vanilla_bytes[v_pos-4:v_pos]
|
||||
vanilla_inst_b = vanilla_bytes[v_pos:v_pos+4]
|
||||
vanilla_inst_c = vanilla_bytes[v_pos+4:v_pos+8]
|
||||
profile_inst_a = profile_bytes[epi_pos-4:epi_pos]
|
||||
profile_inst_b = profile_bytes[epi_pos+8:epi_pos+12]
|
||||
profile_inst_c = profile_bytes[epi_pos+12:epi_pos+16]
|
||||
|
||||
opcode_a = vanilla_inst_a[0] >> 2
|
||||
opcode_b = vanilla_inst_b[0] >> 2
|
||||
opcode_c = vanilla_inst_c[0] >> 2
|
||||
|
||||
LWZ = 0x80 >> 2
|
||||
LFS = 0xC0 >> 2
|
||||
ADDI = 0x38 >> 2
|
||||
LI = ADDI # an LI instruction is just an ADDI with RA=0
|
||||
LMW = 0xB8 >> 2
|
||||
FDIVS = 0xEC >> 2
|
||||
|
||||
# Adjust LWZ and LMW loading from r1.
|
||||
if opcode_a in [LWZ, LMW] and vanilla_inst_a[2] == 0x00 and \
|
||||
opcode_b in [LI, LFS, FDIVS] and \
|
||||
vanilla_inst_a == profile_inst_b and \
|
||||
vanilla_inst_b == profile_inst_a and \
|
||||
vanilla_inst_c == profile_inst_c and \
|
||||
opcode_c != ADDI: # <- don't reorder if at the very end of the epilogue
|
||||
|
||||
# Swap instructions (A) and (B)
|
||||
profile_bytes = profile_bytes[:epi_pos-4] \
|
||||
+ vanilla_inst_a \
|
||||
+ PROFILE_EXTRA_BYTES \
|
||||
+ vanilla_inst_b \
|
||||
+ profile_bytes[epi_pos+12:]
|
||||
|
||||
# Similar reordering for lwz/lmw, except both insns follow the bl/nop
|
||||
elif opcode_b == LWZ and \
|
||||
opcode_c == LMW and \
|
||||
vanilla_inst_b == profile_inst_c and \
|
||||
vanilla_inst_c == profile_inst_b:
|
||||
|
||||
profile_bytes = profile_bytes[:epi_pos+8] \
|
||||
+ vanilla_inst_b \
|
||||
+ vanilla_inst_c \
|
||||
+ profile_bytes[epi_pos+16:]
|
||||
|
||||
idx = epi_pos + 8
|
||||
|
||||
# Remove byte sequence
|
||||
stripped_bytes = profile_bytes.replace(PROFILE_EXTRA_BYTES, b"")
|
||||
|
||||
# Find end of code sections in vanilla and stripped bytes
|
||||
code_size_offset = code_size_magic_idx + len(CODESIZE_MAGIC)
|
||||
code_size_bytes = vanilla_bytes[code_size_offset:code_size_offset+4]
|
||||
code_size = int.from_bytes(code_size_bytes, byteorder='big')
|
||||
|
||||
eoc_offset = 0x34 + code_size
|
||||
|
||||
# Break if the eoc is not found
|
||||
assert(eoc_offset != len(vanilla_bytes))
|
||||
|
||||
# Replace 0x34 - eoc in vanilla with bytes from stripped
|
||||
final_bytes = vanilla_bytes[:0x34] + stripped_bytes[0x34:eoc_offset] + vanilla_bytes[eoc_offset:]
|
||||
|
||||
# Fix branches to link register
|
||||
for seq in BLR_BYTE_SEQ_ARRAY:
|
||||
idx = 0
|
||||
|
||||
while idx < len(vanilla_bytes):
|
||||
found_pos = vanilla_bytes.find(seq, idx)
|
||||
if found_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if found_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
final_bytes = final_bytes[:found_pos] + vanilla_bytes[found_pos:found_pos+4] + final_bytes[found_pos+4:]
|
||||
idx = found_pos + len(seq)
|
||||
|
||||
# Reunify mtlr/blr instructions, shifting intermediary instructions up
|
||||
idx = 0
|
||||
|
||||
while idx < len(final_bytes):
|
||||
# Find mtlr position
|
||||
mtlr_found_pos = final_bytes.find(MTLR_BYTE_SEQ, idx)
|
||||
if mtlr_found_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if mtlr_found_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
# Find paired blr position
|
||||
blr_found_pos = final_bytes.find(BLR_BYTE_SEQ, mtlr_found_pos)
|
||||
if blr_found_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if blr_found_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
if mtlr_found_pos + 4 == blr_found_pos:
|
||||
idx += 4
|
||||
continue # continue if mtlr is followed directly by blr
|
||||
|
||||
final_bytes = final_bytes[:mtlr_found_pos] + final_bytes[mtlr_found_pos+4:blr_found_pos] + final_bytes[mtlr_found_pos:mtlr_found_pos+4] + final_bytes[blr_found_pos:]
|
||||
idx = mtlr_found_pos + len(MTLR_BYTE_SEQ)
|
||||
|
||||
# Reorder lmw/lwz/lfd instructions, if needed (@Altafen)
|
||||
# Specifically, if this sequence shows up in the stripped profiler code: "LMW, LWZ, LFD*"
|
||||
# And this sequence shows up in the vanilla code: "LWZ, LFD*, LMW"
|
||||
# (LFD* = any number of LFDs, including zero)
|
||||
# If all bytes match between the two (except for the reordering), then use the vanilla ordering.
|
||||
# This could be written to anchor around the "BL, NOP" instructions in unstripped profiler code,
|
||||
# or to check for the presence of "ADDI, MTLR, BLR" soon after.
|
||||
# This also could be written to decode the operands of each instruction to make sure the reorder is harmless.
|
||||
# Neither of these safeguards are necessary at the moment.
|
||||
LWZ = 32
|
||||
LMW = 46
|
||||
LFD = 50
|
||||
idx = 0
|
||||
while idx+4 < len(final_bytes):
|
||||
if final_bytes[idx] >> 2 == LMW and final_bytes[idx+4] >> 2 == LWZ and vanilla_bytes[idx] >> 2 == LWZ:
|
||||
start_idx = idx
|
||||
lmw_bytes = final_bytes[idx:idx+4]
|
||||
lwz_bytes = final_bytes[idx+4:idx+8]
|
||||
if vanilla_bytes[idx:idx+4] != lwz_bytes:
|
||||
idx += 4
|
||||
continue
|
||||
lfd_bytes = b""
|
||||
idx += 4
|
||||
while vanilla_bytes[idx] >> 2 == LFD:
|
||||
lfd_bytes += vanilla_bytes[idx:idx+4]
|
||||
idx += 4
|
||||
if vanilla_bytes[idx:idx+4] != lmw_bytes:
|
||||
continue
|
||||
if final_bytes[start_idx+8:start_idx+8+len(lfd_bytes)] != lfd_bytes:
|
||||
continue
|
||||
idx += 4
|
||||
final_bytes = final_bytes[:start_idx] + lwz_bytes + lfd_bytes + lmw_bytes + final_bytes[idx:]
|
||||
continue
|
||||
idx += 4
|
||||
|
||||
with open(args.target, "wb") as f:
|
||||
f.write(final_bytes)
|
||||
@@ -0,0 +1,52 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# Written by Ethan Roseman (ethteck)
|
||||
# MIT License
|
||||
# Copyright 2021
|
||||
|
||||
# Modified by EpochFlame
|
||||
|
||||
import argparse
|
||||
|
||||
# Byte sequences
|
||||
BLR_BYTE_SEQ = b"\x4E\x80\x00\x20"
|
||||
MTLR_BYTE_SEQ = b"\x7C\x08\x03\xA6"
|
||||
|
||||
# Example invocation: ./frank.py vanilla.o profile.o output.o
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("vanilla", help="Path to the vanilla object", type=argparse.FileType('rb'))
|
||||
parser.add_argument("target", help="Path to the target object (to write)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read contents into bytearrays and close files
|
||||
vanilla_bytes = args.vanilla.read()
|
||||
args.vanilla.close()
|
||||
|
||||
# Reunify mtlr/blr instructions, shifting intermediary instructions up
|
||||
idx = 0
|
||||
|
||||
while idx < len(vanilla_bytes):
|
||||
# Find mtlr position
|
||||
mtlr_found_pos = vanilla_bytes.find(MTLR_BYTE_SEQ, idx)
|
||||
if mtlr_found_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if mtlr_found_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
# Find paired blr position
|
||||
blr_found_pos = vanilla_bytes.find(BLR_BYTE_SEQ, mtlr_found_pos)
|
||||
if blr_found_pos == -1:
|
||||
break # break while loop when no targets remain
|
||||
if blr_found_pos % 4 != 0: # check 4-byte alignment
|
||||
idx += 4
|
||||
continue
|
||||
if mtlr_found_pos + 4 == blr_found_pos:
|
||||
idx += 4
|
||||
continue # continue if mtlr is followed directly by blr
|
||||
|
||||
vanilla_bytes = vanilla_bytes[:mtlr_found_pos] + vanilla_bytes[mtlr_found_pos+4:blr_found_pos] + vanilla_bytes[mtlr_found_pos:mtlr_found_pos+4] + vanilla_bytes[blr_found_pos:]
|
||||
idx = mtlr_found_pos + len(MTLR_BYTE_SEQ)
|
||||
|
||||
with open(args.target, "wb") as f:
|
||||
f.write(vanilla_bytes)
|
||||
Reference in New Issue
Block a user