Skip to content

Commit

Permalink
__start OK, OSReboot almost
Browse files Browse the repository at this point in the history
  • Loading branch information
LagoLunatic committed Jul 7, 2024
1 parent cc0649f commit 42d942d
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 100 deletions.
4 changes: 2 additions & 2 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -962,10 +962,10 @@ def JSystemLib(lib_name, objects):
DolphinLib(
"os",
[
Object(NonMatching, "dolphin/os/__start.c"),
Object(Matching, "dolphin/os/__start.c"),
Object(Matching, "dolphin/os/OS.c"),
Object(Matching, "dolphin/os/OSAlarm.c"),
Object(NonMatching, "dolphin/os/OSAlloc.c"),
Object(Matching, "dolphin/os/OSAlloc.c"),
Object(Matching, "dolphin/os/OSArena.c"),
Object(Matching, "dolphin/os/OSAudioSystem.c"),
Object(Matching, "dolphin/os/OSCache.c"),
Expand Down
8 changes: 4 additions & 4 deletions include/dolphin/os/OSAlloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ extern "C" {

typedef struct OSHeapDescriptor {
/* 0x0 */ s32 size;
/* 0x4 */ struct OSHeapCell* freeList;
/* 0x8 */ struct OSHeapCell* usedList;
/* 0x4 */ struct OSHeapCell* free;
/* 0x8 */ struct OSHeapCell* allocated;
} OSHeapDescriptor;

typedef struct OSHeapCell {
/* 0x00 */ struct OSHeapCell* prev;
/* 0x04 */ struct OSHeapCell* next;
/* 0x08 */ s32 size;
/* 0x08 */ u32 size;
/* 0x0C */ struct OSHeapDescriptor* hd;
/* 0x10 */ s32 usedSize;
/* 0x10 */ u32 usedSize;
/* 0x14 */ char field_0x14[0x20 - 0x14];
} OSHeapCell;

Expand Down
4 changes: 2 additions & 2 deletions include/dolphin/os/OSExec.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ typedef struct {
} OSExecParams;

static s32 PackArgs(void* param_0, u32 param_1, void* param_2);
static void Run(int param_0);
static void Run(u32 param_0);
static void ReadDisc(void* param_0, s32 param_1, s32 param_2);
static void Callback(void);
static void Callback(s32 result, struct DVDCommandBlock* block);
void __OSGetExecParams(OSExecParams* param_0);
void __OSBootDolSimple(u32 param_0, u32 param_1, void* param_2, void* param_3, s32 param_4, u32 param_5, void* param_6);
void __OSBootDol(s32 param_0, u32 param_1, char** param_2);
Expand Down
65 changes: 65 additions & 0 deletions include/dolphin/os/__start.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef __START_H
#define __START_H

#include "global.h"

#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus

#define PAD3_BUTTON_ADDR 0x800030E4
#define OS_RESET_RESTART 0
#define FALSE 0
#define TRUE 1
#define EXCEPTIONMASK_ADDR 0x80000044
#define BOOTINFO2_ADDR 0x800000F4
#define OS_BI2_DEBUGFLAG_OFFSET 0xC
#define ARENAHI_ADDR 0x80000034
#define DEBUGFLAG_ADDR 0x800030E8
#define DVD_DEVICECODE_ADDR 0x800030E6
#define DOL_ADDR_LIMIT 0x80700000

extern void InitMetroTRK();

u16 Pad3Button : PAD3_BUTTON_ADDR;

extern int main(int argc, char* argv[]);
extern void exit(int);
extern void __init_user(void);
extern void InitMetroTRK_BBA(void);
extern void OSInit(void);
extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu);

SECTION_INIT extern void __check_pad3(void);
SECTION_INIT extern void __set_debug_bba(void);
SECTION_INIT extern u8 __get_debug_bba(void);
SECTION_INIT extern void __start(void);
SECTION_INIT extern void __init_registers(void);
SECTION_INIT extern void __init_data(void);
SECTION_INIT extern void __init_hardware(void);
SECTION_INIT extern void __flush_cache(void* addr, u32 size);

SECTION_INIT extern u8 _stack_addr[];
SECTION_INIT extern char _SDA_BASE_[];
SECTION_INIT extern char _SDA2_BASE_[];

typedef struct __rom_copy_info {
char* rom;
char* addr;
uint size;
} __rom_copy_info;

SECTION_INIT extern __rom_copy_info _rom_copy_info[];

typedef struct __bss_init_info {
char* addr;
uint size;
} __bss_init_info;

SECTION_INIT extern __bss_init_info _bss_init_info[];

#ifdef __cplusplus
};
#endif // ifdef __cplusplus

#endif /* __START_H */
200 changes: 176 additions & 24 deletions src/dolphin/os/OSAlloc.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
#include "dolphin/os/OSAlloc.h"
#include "dolphin/os/OS.h"

#define ALIGNMENT 32
#define MINOBJSIZE 64

#define HEADERSIZE 32

#define InRange(addr, start, end) ((u8*)(start) <= (u8*)(addr) && (u8*)(addr) < (u8*)(end))
#define OFFSET(addr, align) (((u32)(addr) & ((align)-1)))

static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child) {
OSHeapCell* prev = NULL;
Expand Down Expand Up @@ -58,11 +67,62 @@ inline OSHeapCell* DLExtract(OSHeapCell* list, OSHeapCell* child) {

static OSHeapDescriptor* HeapArray;

static inline void* DLAddFront(OSHeapCell* neighbor, OSHeapCell* cell)
{
cell->next = neighbor;
cell->prev = NULL;
if (neighbor != NULL)
neighbor->prev = cell;
return cell;
}

void* OSAllocFromHeap(OSHeapHandle heap, u32 size)
{
OSHeapDescriptor* hd = &HeapArray[heap];
s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size);
OSHeapCell* cell;
OSHeapCell* oldTail;
u32 leftoverSpace;

// find first cell with enough capacity
for (cell = hd->free; cell != NULL; cell = cell->next) {
if (sizeAligned <= (s32)cell->size)
break;
}
if (cell == NULL)
return NULL;

leftoverSpace = cell->size - sizeAligned;
if (leftoverSpace < MINOBJSIZE) {
// remove this cell from the free list
hd->free = DLExtract(hd->free, cell);
} else {
// remove this cell from the free list and make a new cell out of the
// remaining space
OSHeapCell* newcell = (void*)((u8*)cell + sizeAligned);
cell->size = sizeAligned;
newcell->size = leftoverSpace;
newcell->prev = cell->prev;
newcell->next = cell->next;
if (newcell->next != NULL)
newcell->next->prev = newcell;
if (newcell->prev != NULL)
newcell->prev->next = newcell;
else
hd->free = newcell;
}

// add the cell to the beginning of the allocated list
hd->allocated = DLAddFront(hd->allocated, cell);

return (u8*)cell + ALIGNMENT;
}

void OSFreeToHeap(OSHeapHandle handle, void* ptr) {
OSHeapDescriptor* hd = &HeapArray[handle];
OSHeapCell* cell = (OSHeapCell*)((char*)ptr - sizeof(OSHeapCell));
hd->usedList = DLExtract(hd->usedList, cell);
hd->freeList = DLInsert(hd->freeList, cell);
hd->allocated = DLExtract(hd->allocated, cell);
hd->free = DLInsert(hd->free, cell);
}

volatile s32 __OSCurrHeap = -1;
Expand Down Expand Up @@ -90,38 +150,130 @@ void* OSInitAlloc(void* lo, void* hi, s32 maxHeaps) {
OSHeapDescriptor* hd = &HeapArray[i];
hd->size = -1;

hd->freeList = hd->usedList = NULL;
hd->free = hd->allocated = NULL;
}

__OSCurrHeap = -1;

lo = (u8*)HeapArray + totalSize;
lo = OSRoundUpPtr(lo, 0x20);
lo = OSRoundUpPtr(lo, 0x20);

ArenaStart = lo;
ArenaEnd = OSRoundDownPtr(hi, 0x20);
ArenaStart = lo;
ArenaEnd = OSRoundDownPtr(hi, 0x20);

return ArenaStart;
}

OSHeapHandle OSCreateHeap(void* start, void* end) {
int i;
OSHeapCell* cell = OSRoundUpPtr(start, 0x20);
end = OSRoundDownPtr(end, 0x20);

for (i = 0; i < NumHeaps; i++) {
OSHeapDescriptor* hd = &HeapArray[i];

if (hd->size < 0) {
hd->size = (u8*)end - (u8*)cell;
cell->prev = NULL;
cell->next = NULL;
cell->size = hd->size;
hd->freeList = cell;
hd->usedList = NULL;
return i;
}
}

return -1;
OSHeapCell* cell = OSRoundUpPtr(start, 0x20);
end = OSRoundDownPtr(end, 0x20);

for (i = 0; i < NumHeaps; i++) {
OSHeapDescriptor* hd = &HeapArray[i];

if (hd->size < 0) {
hd->size = (u8*)end - (u8*)cell;
cell->prev = NULL;
cell->next = NULL;
cell->size = hd->size;
hd->free = cell;
hd->allocated = NULL;
return i;
}
}

return -1;
}

void OSDestroyHeap(OSHeapHandle heap) {
OSHeapDescriptor* hd;
long size;

hd = &HeapArray[heap];

hd->size = -1;
}

// custom macro for OSCheckHeap
#define ASSERTREPORT(line, cond) \
if (!(cond)) { OSReport("OSCheckHeap: Failed " #cond " in %d", line); return -1; }

long OSCheckHeap(OSHeapHandle heap) {
OSHeapDescriptor* hd;
OSHeapCell* cell;
long total = 0;
long free = 0;

ASSERTREPORT(0x37D, HeapArray);
ASSERTREPORT(0x37E, 0 <= heap && heap < NumHeaps);
hd = &HeapArray[heap];
ASSERTREPORT(0x381, 0 <= hd->size);

ASSERTREPORT(0x383, hd->allocated == NULL || hd->allocated->prev == NULL);

for(cell = hd->allocated; cell; cell = cell->next) {
ASSERTREPORT(0x386, InRange(cell, ArenaStart, ArenaEnd));
ASSERTREPORT(0x387, OFFSET(cell, ALIGNMENT) == 0);
ASSERTREPORT(0x388, cell->next == NULL || cell->next->prev == cell);
ASSERTREPORT(0x389, MINOBJSIZE <= cell->size);
ASSERTREPORT(0x38A, OFFSET(cell->size, ALIGNMENT) == 0);
total += cell->size;
ASSERTREPORT(0x38D, 0 < total && total <= hd->size);
#ifdef ENABLE_HEAPDESC
ASSERTREPORT(0x390, cell->hd == hd);
ASSERTREPORT(0x391, HEADERSIZE + cell->requested <= cell->size);
#endif
}


ASSERTREPORT(0x395, hd->free == NULL || hd->free->prev == NULL);

for(cell = hd->free; cell; cell = cell->next) {
ASSERTREPORT(0x398, InRange(cell, ArenaStart, ArenaEnd));
ASSERTREPORT(0x399, OFFSET(cell, ALIGNMENT) == 0);
ASSERTREPORT(0x39A, cell->next == NULL || cell->next->prev == cell);
ASSERTREPORT(0x39B, MINOBJSIZE <= cell->size);
ASSERTREPORT(0x39C, OFFSET(cell->size, ALIGNMENT) == 0);
ASSERTREPORT(0x39D, cell->next == NULL || (char*) cell + cell->size < (char*) cell->next);
total += cell->size;
free = (cell->size + free);
free -= HEADERSIZE;
ASSERTREPORT(0x3A1, 0 < total && total <= hd->size);
#ifdef ENABLE_HEAPDESC
ASSERTREPORT(0x3A4, cell->hd == NULL);
#endif
}
ASSERTREPORT(0x3A8, total == hd->size);
return free;
}

s32 OSReferentSize(void* ptr) {
OSHeapCell* cell;

cell = (void*)((u32)ptr - HEADERSIZE);
return (long)((u32)cell->size - HEADERSIZE);
}

void OSDumpHeap(OSHeapHandle heap) {
OSHeapDescriptor* hd;
OSHeapCell* cell;

OSReport("\nOSDumpHeap(%d):\n", heap);
hd = &HeapArray[heap];
if (hd->size < 0) {
OSReport("--------Inactive\n");
return;
}

OSReport("addr size end prev next\n");
OSReport("--------Allocated\n");

for(cell = hd->allocated; cell; cell = cell->next) {
OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next);
}
OSReport("--------Free\n");
for(cell = hd->free; cell; cell = cell->next) {
OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next);
}
}
Loading

0 comments on commit 42d942d

Please sign in to comment.