Get osreport.c linked

This commit is contained in:
Cuyler36
2023-03-15 16:46:43 -04:00
parent 2252184a87
commit 3b150d408d
19 changed files with 976 additions and 93 deletions
+7 -1
View File
@@ -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}"
]
+1 -1
View File
@@ -352,7 +352,7 @@ forced_types:
0x80078fcc: ENTRY
0x8007ac24: ENTRY
0x8007ac34: ENTRY
0x8007db20: ENTRY
# 0x8007db20: ENTRY
0x8007db3c: ENTRY
0x8009ae2c: ENTRY
0x8009ae34: ENTRY
+4 -1
View File
@@ -1 +1,4 @@
trim_ctors: true
trim_ctors: true
symbol_aligns:
0x80207458: 8 # align RunQueue to 0x001251d8
+8 -5
View File
@@ -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
View File
@@ -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,
+1
View File
@@ -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"
+3 -3
View File
@@ -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
View File
@@ -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
+12 -12
View File
@@ -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);
+9
View File
@@ -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
+72
View File
@@ -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
+120 -6
View File
@@ -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
View File
@@ -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
+30 -10
View File
@@ -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
+12
View File
@@ -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))
+230
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+52
View File
@@ -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)