Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eepmgr OK #42

Merged
merged 18 commits into from
Feb 19, 2024
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