Skip to content

Commit

Permalink
Eepmgr OK (#42)
Browse files Browse the repository at this point in the history
* Start eepmgr

* Data + func_8007CF50

* func_8007D488

* func_8007D380

* func_8007D2C4

* func_8007D1EC WIP

* func_8007D0B0

* func_8007CFB0

* func_8007CDFC

* func_8007CDCC

* func_8007CDA0

* func_8007D508

* func_8007D540

* func_8007D590

* eepmgr_HandleWrite + docs

* strings

* cache

* Global already had a 740F0 section
  • Loading branch information
hensldm authored Feb 19, 2024
1 parent ce6ec9a commit 7e3cb48
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ endif

SPLAT_FLAGS ?=
ifneq ($(FULL_DISASM), 0)
SPLAT_FLAGS += --disassemble-all
SPLAT_FLAGS += --disassemble-all
endif

#### Files ####
Expand Down
29 changes: 29 additions & 0 deletions include/eepmgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef EEPMGR_H
#define EEPMGR_H

#include "ultra64.h"


typedef struct EepRequest {
/* 0x0 */ s16 type;
/* 0x4 */ u64* buffer;
} EepRequest;

typedef struct EepMgr {
/* 0x000 */ OSMesg unk000[4];
/* 0x010 */ OSMesg unk004[1];
/* 0x014 */ OSMesgQueue unk014;
/* 0x02C */ OSMesgQueue unk02C;
/* 0x044 */ OSMesgQueue* unk044;
/* 0x048 */ EepRequest unk048;
/* 0x050 */ char unk_04C[0x68 - 0x50];
/* 0x068 */ OSThread thread;
/* 0x218 */ s32 unk218;
/* 0x21C */ u8 type;
/* 0x21E */ u16 numBlocks;
/* 0x220 */ u64* cache;
/* 0x224 */ u8 cached;
/* 0x225 */ u8 operation;
} EepMgr; // size = 0x228

#endif
3 changes: 3 additions & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "libc/stdint.h"

#include "attributes.h"
#include "eepmgr.h"
#include "macros.h"
#include "unk.h"
#include "ys64math.h"
Expand Down Expand Up @@ -44,6 +45,8 @@ typedef struct Y511F0UnkStruct {
extern Y511F0UnkStruct D_800DA840[];

// 740F0
OSMesgQueue* func_800744B0(s32 arg0);
void func_8007451C(s32 arg0, OSMesgQueue* arg1);
void func_80074C88(UNK_PTR, struct Input*, s32);

// malloc
Expand Down
4 changes: 4 additions & 0 deletions linker_scripts/us/symbol_addrs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Fault_SetFramebuffer = 0x80071250; // type:func
Fault_Init = 0x8007127C; // type:func
Fault_HungUp = 0x80071380; // type:func

eepmgr_Create = 0x8007D488; // type:func
eepmgr_SendRead = 0x8007D540; // type:func
eepmgr_SendWrite = 0x8007D590; // type:func

DmaMgr_RequestSync = 0x8007DF0C; // type:func
DmaMgr_Init = 0x8007DF74; // type:func

Expand Down
297 changes: 297 additions & 0 deletions src/main/eepmgr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
#include "eepmgr.h"

#include "global.h"
#include "sleep.h"

#define LOOP() \
while (true) \
(void)0

s32 gEepmgrLogSeverity = 1;
static u16 sMaxBlocks[] = { 0, EEPROM_MAXBLOCKS, EEP16K_MAXBLOCKS };

#define EEP_READ_MSG 8
#define EEP_WRITE_MSG 9

//! TODO: Probably a libultra macro
#define OS_CYCLES_TO_USEC_ALT(c) (((u64)(c) * (1000000LL / 15625LL)) / (osClockRate / 15625LL))

void func_8007CDA0(EepMgr* eepmgr) {
eepmgr->unk044 = func_800744B0(eepmgr->unk218);
}

void func_8007CDCC(EepMgr* eepmgr) {
func_8007451C(eepmgr->unk218, eepmgr->unk044);
eepmgr->unk044 = NULL;
}

void eepmgr_Probe(EepMgr* eepmgr) {
s32 type;
OSTime before;
OSTime after;

func_8007CDA0(eepmgr);

eepmgr->operation = 1;
before = osGetTime();
type = osEepromProbe(eepmgr->unk044);
after = osGetTime();
eepmgr->operation = 0;

func_8007CDCC(eepmgr);

if (gEepmgrLogSeverity >= 3) {
// osEepromProbe execution time=%d us
(void)"osEepromProbe 実行時間=%d us\n";
(void)OS_CYCLES_TO_USEC_ALT(after - before);
}
if (type == 0) {
if (gEepmgrLogSeverity != 0) {
// No EEPROM
(void)"EEPROM が ありません\n";
}
} else if (type == EEPROM_TYPE_4K) {
if (gEepmgrLogSeverity != 0) {
// 4K bit EEPROM detected
(void)"4KビットEEPROMを検出\n";
}
} else if (type == EEPROM_TYPE_16K) {
if (gEepmgrLogSeverity != 0) {
// 16K bit EEPROM detected
(void)"16KビットEEPROMを検出\n";
}
} else {
LOOP();
}

if (gEepmgrLogSeverity != 0) {}

if (eepmgr->type != type) {
LOOP();
}
}

void eepmgr_Setup(EepMgr* eepmgr, s32 arg1, s32 type, u64* buffer) {
bzero(eepmgr, sizeof(EepMgr));
eepmgr->unk218 = arg1;
eepmgr->cache = buffer;
eepmgr->type = type;
eepmgr->numBlocks = sMaxBlocks[eepmgr->type];
}

s32 eepmgr_Read(EepMgr* eepmgr, u8 arg1, u64* buffer) {
s32 status;
OSTime before;
OSTime after;

func_8007CDA0(eepmgr);

eepmgr->operation = 1;
before = osGetTime();
status = osEepromRead(eepmgr->unk044, arg1, (u8*)buffer);
after = osGetTime();
eepmgr->operation = 0;

func_8007CDCC(eepmgr);

if (gEepmgrLogSeverity >= 2) {
// osEepromRead execution time=%d us
(void)"osEepromRead 実行時間=%d us\n";
(void)OS_CYCLES_TO_USEC_ALT(after - before);
}

if (status != 0) {
// EEPROM interface circuit unresponsive (READ)
(void)"EEPROM インターフェース回路反応なし (READ)\n";
return -1;
}

if (gEepmgrLogSeverity != 0) {
(void)"EEPROM READ %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n";
}

return 0;
}

s32 eepmgr_Write(EepMgr* eepmgr, u8 addr, u64* buffer) {
s32 status;
OSTime before;
OSTime after;

func_8007CDA0(eepmgr);

eepmgr->operation = 2;
before = osGetTime();
status = osEepromWrite(eepmgr->unk044, addr, (u8*)buffer);
after = osGetTime();
eepmgr->operation = 0;

func_8007CDCC(eepmgr);

if (gEepmgrLogSeverity >= 2) {
// osEepromWrite execution time=%d us
(void)"osEepromWrite 実行時間=%d us\n";
(void)OS_CYCLES_TO_USEC_ALT(after - before);
}

if (status != 0) {
// EEPROM interface circuit unresponsive (WRITE)
(void)"EEPROM インターフェース回路反応なし (WRITE)\n";
return -1;
}

if (gEepmgrLogSeverity != 0) {
(void)"EEPROM WRITE %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n";
}

// Sleep 15ms
csleep((15 * osClockRate) / 1000ULL);
return 0;
}

s32 eepmgr_HandleWrite(EepMgr* eepmgr, u64* buffer) {
u64* bufferIter;
u64* cacheIter;
s32 i;

if (eepmgr->type == 0) {
// No EEPROM
(void)"EEPROM が ありません\n";
return -1;
}

if (!eepmgr->cached) {
// EEPROM not cached
(void)"EEPROM が キャッシュされていません\n";
// Please read it once and then write it.
(void)"一度読み込んでから、書くようにしてください\n";
return -1;
}

cacheIter = eepmgr->cache;
bufferIter = buffer;
for (i = 0; i < eepmgr->numBlocks; i++) {
if (*bufferIter != *cacheIter) {
if (eepmgr_Write(eepmgr, i, bufferIter) != 0) {
return -1;
}

*cacheIter = *bufferIter;
}

cacheIter++;
bufferIter++;
}

return 0;
}

s32 eepmgr_HandleRead(EepMgr* eepmgr, u64* arg1) {
u64* cacheIter;
s32 i;

if (eepmgr->type == 0) {
// No EEPROM
(void)"EEPROM が ありません\n";
return -1;
}

if (!eepmgr->cached) {
cacheIter = eepmgr->cache;
for (i = 0; i < eepmgr->numBlocks; i++) {
if (eepmgr_Read(eepmgr, i, cacheIter) != 0) {
return -1;
}
cacheIter++;
}
eepmgr->cached = true;
}

bcopy(eepmgr->cache, arg1, eepmgr->numBlocks * EEPROM_BLOCK_SIZE);
return 0;
}

void eepmgr_ThreadEntry(void* arg) {
EepRequest* req = NULL;
EepMgr* eepmgr = (EepMgr*)arg;

if (gEepmgrLogSeverity != 0) {
// EEPROM manager thread execution starts
(void)"EEPROMマネージャスレッド実行開始\n";
}
eepmgr_Probe(eepmgr);
do {
if (gEepmgrLogSeverity != 0) {
// eepmgr: Waiting for command message
(void)"eepmgr:コマンドメッセージ待ち\n";
}

osRecvMesg(&eepmgr->unk014, (OSMesg*)&req, OS_MESG_BLOCK);
switch (req->type) {
case EEP_READ_MSG:
if (gEepmgrLogSeverity != 0) {
// eepmgr: Load command received
(void)"eepmgr:ロードコマンド受信\n";
}
osSendMesg(&eepmgr->unk02C, (OSMesg)eepmgr_HandleRead(eepmgr, req->buffer), OS_MESG_BLOCK);
break;

case EEP_WRITE_MSG:
if (gEepmgrLogSeverity != 0) {
// eepmgr: Receive save command
(void)"eepmgr:セーブコマンド受信\n";
}
osSendMesg(&eepmgr->unk02C, (OSMesg)eepmgr_HandleWrite(eepmgr, req->buffer), OS_MESG_BLOCK);
break;

default:
break;
}
} while (req->type != 4);

if (gEepmgrLogSeverity != 0) {
// EEPROM manager thread execution ends
(void)"EEPROMマネージャスレッド実行終了\n";
}
}

void eepmgr_Create(EepMgr* eepmgr, s32 arg1, s32 type, u64* buffer, s32 id, s32 priority, void* stack) {
(void)"eepmgr_Create(%08x, %08x, %d, %08x, %d, %d, %08x)\n";
eepmgr_Setup(eepmgr, arg1, type, buffer);
osCreateMesgQueue(&eepmgr->unk014, eepmgr->unk000, ARRAY_COUNT(eepmgr->unk000));
osCreateMesgQueue(&eepmgr->unk02C, eepmgr->unk004, ARRAY_COUNT(eepmgr->unk004));
osCreateThread(&eepmgr->thread, id, eepmgr_ThreadEntry, eepmgr, stack, priority);
osStartThread(&eepmgr->thread);
}

s32 func_8007D508(EepMgr* eepmgr) {
s32 msg;

osRecvMesg(&eepmgr->unk02C, (OSMesg*)&msg, OS_MESG_BLOCK);
eepmgr->unk048.type = 0;
return msg;
}

void eepmgr_SendRead(EepMgr* eepmgr, void* buffer) {
EepRequest* req = &eepmgr->unk048;

if (req->type != 0) {
LOOP();
}

req->type = EEP_READ_MSG;
req->buffer = buffer;
osSendMesg(&eepmgr->unk014, &eepmgr->unk048, OS_MESG_BLOCK);
}

void eepmgr_SendWrite(EepMgr* eepmgr, void* buffer) {
EepRequest* req = &eepmgr->unk048;

if (req->type != 0) {
LOOP();
}

req->type = EEP_WRITE_MSG;
req->buffer = buffer;
osSendMesg(&eepmgr->unk014, &eepmgr->unk048, OS_MESG_BLOCK);
}
7 changes: 4 additions & 3 deletions yamls/us/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@
- [0x7CC30, asm]
- [0x7D140, asm]
- [0x7D270, asm]
- [0x7D9A0, asm]
- [0x7E140, asm]
- [0x7D9A0, c, eepmgr]
- [0x7E1E0, asm]
- [0x7E760, c, dmamgr]
- [0x7EC30, asm]
Expand Down Expand Up @@ -373,6 +372,8 @@
- [0xA8C0C, font, fault/sFaultFont]
- [0xA900C]
- [0xA9080, data]
- [0xAA620, .data, eepmgr]
- [0xAA630, data]
- [0xAA650, .data, 7EFD0]
- [0xAA660, data, O2/gfxprint]
- [0xAAF10, .data, O2/808F0]
Expand Down Expand Up @@ -495,7 +496,7 @@
- [0xB3640, rodata, 7CA70]
- [0xB3690, rodata, 7CC30]
- [0xB36A0, rodata, 7D140]
- [0xB36E0, rodata, 7D9A0]
- [0xB36E0, .rodata, eepmgr]
- [0xB39F0, .rodata, dmamgr]
- [0xB3AA0, rodata, 7EC30]
- [0xB3B10, rodata, 7EE00]
Expand Down

0 comments on commit 7e3cb48

Please sign in to comment.