Started work on reverse engineering EE kernel

This commit is contained in:
google0101-ryan 2024-03-02 18:28:47 -05:00
parent a6d5e65bb5
commit 1e006ca9f1
17 changed files with 940 additions and 7 deletions

72
BIOS/ee/kernel/hw.h Normal file
View file

@ -0,0 +1,72 @@
#pragma once
#include <stdint.h>
typedef volatile uint32_t vu32;
typedef volatile uint64_t vu64;
#define GIF_CTRL (*(vu32*)0x10003000)
#define GIF_STAT (*(vu32*)0x10003020)
#define GIF_FIFO0 (*(vu32*)0x10006000)
#define GIF_FIFO1 (*(vu32*)0x10006004)
#define GIF_FIFO2 (*(vu32*)0x10006008)
#define GIF_FIFO3 (*(vu32*)0x1000600C)
#define DMAC_CTRL (*(vu32*)0x1000e000)
#define DMAC_STAT (*(vu32*)0x1000e010)
#define DMAC_PCR (*(vu32*)0x1000e020)
#define DMAC_SQWC (*(vu32*)0x1000e030)
#define DMAC_RBSR (*(vu32*)0x1000e040)
#define DMAC_RBOR (*(vu32*)0x1000e050)
#define GS_SMODE1 (*(vu64*)0x12000010)
#define GS_SYNCH1 (*(vu64*)0x12000040)
#define GS_SYNCH2 (*(vu64*)0x12000050)
#define GS_SYNCV (*(vu64*)0x12000060)
#define GS_SMODE2 (*(vu64*)0x12000020)
#define GS_SRFSH (*(vu64*)0x12000030)
#define INTC_STAT (*(vu32*)0xB000F000)
#define INTC_MASK (*(vu32*)0xB000F010)
#define TIMER0_COUNT (*(vu32*)0x10000000)
#define TIMER0_MODE (*(vu32*)0x10000010)
#define TIMER0_COMP (*(vu32*)0x10000020)
#define TIMER0_HOLD (*(vu32*)0x10000030)
#define TIMER1_COUNT (*(vu32*)0x10000800)
#define TIMER1_MODE (*(vu32*)0x10000810)
#define TIMER1_COMP (*(vu32*)0x10000820)
#define TIMER1_HOLD (*(vu32*)0x10000830)
#define TIMER2_COUNT (*(vu32*)0x10001000)
#define TIMER2_MODE (*(vu32*)0x10001010)
#define TIMER2_COMP (*(vu32*)0x10001020)
#define TIMER2_HOLD (*(vu32*)0x10001030)
#define TIMER3_COUNT (*(vu32*)0x10018000)
#define TIMER3_MODE (*(vu32*)0x10018010)
#define TIMER3_COMP (*(vu32*)0x10018020)
#define TIMER3_HOLD (*(vu32*)0x10018030)
#define VU1_CODE ((vu32*)0x11008000)
#define VU1_DATA ((vu32*)0x1100c000)
#define VIF1_STAT (*(vu32*)0x10003c00)
#define VIF1_FBRST (*(vu32*)0x10003c10)
#define VIF1_FIFO0 (*(vu32*)0x10005000)
#define VIF1_FIFO1 (*(vu32*)0x10005004)
#define VIF1_FIFO2 (*(vu32*)0x10005008)
#define VIF1_FIFO3 (*(vu32*)0x1000500C)
#define VIF0_FBRST (*(vu32*)0x10003810)
#define VIF0_ERR (*(vu32*)0x10003820)
#define VIF0_MARK (*(vu32*)0x10003830)
#define VIF0_FIFO0 (*(vu32*)0x10004000)
#define VIF0_FIFO1 (*(vu32*)0x10004004)
#define VIF0_FIFO2 (*(vu32*)0x10004008)
#define VIF0_FIFO3 (*(vu32*)0x1000400C)
#define GS_CSR (*(vu32*)0x12001000)
#define GS_MODE_NTSC 0x02

View file

@ -0,0 +1,516 @@
#include <stdint.h>
#include <stdio.h>
#include "hw.h"
#include "reset.h"
#include "vif1.h"
// TODO: Split this into multiple files to clean up a bit
// TODO: This sets up a bunch of virtual -> physical mappings
long InitTLB()
{
int kernelBitPos = 0xD + 0x12;
printf("# TLB spad=0 kernel=1:%d default=%d:%d extended=%d:%d\n", kernelBitPos-1, kernelBitPos, kernelBitPos+0x7);
}
void ClearInterrupt(int index)
{
// Clear all pending interrupts + index, except SBUS and Timer 3 interrupts
INTC_MASK = INTC_MASK & index & 0xdffd;
INTC_STAT = INTC_STAT & index & 0xdffd;
}
uint32_t GsInitRegList[] =
{
0x1A,
0x1B,
0x0A,
0x01,
0x02,
0x03,
0x18,
0x19,
0x22,
0x06,
0x07,
0x14,
0x15,
0x16,
0x17,
0x1C,
0x34,
0x35,
0x36,
0x37,
0x3B,
0x08,
0x09,
0x3D,
0x40,
0x41,
0x47,
0x48,
0x42,
0x43,
0x49,
0x44
};
void InitGS()
{
// Reset GIF bit
GIF_CTRL = 1;
// Reset GS bit
GS_CSR = 0x200;
// GIF Tag settings:
// NLOOP: 0x2c
// EOP: 1
// PRIM enable: 0
// PRIM data: 0
// Data format: PACKED
// NREGS: 1
// Reg list: A+D
GIF_FIFO0 = 0x802c;
GIF_FIFO1 = 0x10000000;
GIF_FIFO2 = 0xe;
GIF_FIFO3 = 0;
int listIndex = 0;
int j = 0;
for (int i = 0; i < 11; i++)
{
uint32_t* curRegListSlice = &GsInitRegList[i];
j = 3;
for (; j >= 0; j--)
{
// Register field
// First 64 bits are the register data
// Last 64 bits are the register
// This is technically a 128-bit store
GIF_FIFO0 = 0;
GIF_FIFO1 = 0;
GIF_FIFO2 = *curRegListSlice;
GIF_FIFO3 = 0;
curRegListSlice++;
}
// Wait for the GIF to finish processing this data
// Read the GIF FIFO count and wait for it to be 0
while ((GIF_STAT & 0x1f000000) != 0)
;
j = i * 0x10;
}
// Ack any GS interrupts
ClearInterrupt(1);
}
uint64_t GS_Settings = 0x90B27D0000000000ULL;
void SetGsCrt(int interlaced, int display_mode, int frame)
{
if (display_mode == 0)
{
display_mode = 2;
if ((((GS_Settings << 0x1d) >> 32) & 7) == 2)
display_mode = 3;
}
int delay = 9999;
do
{
delay--;
} while (delay >= 0);
if (display_mode == 2)
{
if (interlaced == 0)
{
unsigned int VHP = (((GS_Settings << 0x1f) >> 0x20 & 1) << 0x24);
unsigned int GCONT = (GS_Settings & 1) << 0x19;
GS_SMODE1 = GCONT | VHP | 0x740834504;
// Horizontal front porch: 64
// Horizontal back porch: 222
// HSEQ: 124
// HSVS: 1462
// HS: 254
GS_SYNCH1 = 0x7f5b61f06f040;
// HB: 1652
// HF: 1240
GS_SYNCH2 = 0x33a4d8;
// Vertical front porch: two halflines
// Vertical front porch, no color burst: 6 halflines
// Vertical back porch, color burst: 13 halflines
// Vertical back porch, no color burst: 3 halflines
// Half lines with video data: 240
// Half lines with VSYNC: 3
GS_SYNCV = 0xc7800601a01802;
// Non-interlaced, field mode, power mode = 0 = ON
GS_SMODE2 = 0;
// Undocumented and unknown
GS_SRFSH = 8;
GS_SMODE1 = GCONT | 0x740814504;
return;
}
}
}
int CheckAndSetINTMask(int index)
{
int bit = 1 << (index & 0x1f);
int ret = (INTC_MASK & bit) == 0;
if (!ret)
bit = INTC_MASK;
INTC_MASK = bit;
return ret;
}
void InitTimers()
{
// Bus clock, gate disabled, do not clear counter, timer disabled, interrupts disabled, clear interrupts
TIMER0_MODE = 0xc00;
// Reset counter
TIMER0_COUNT = 0;
// Trigger interrupt just before overflow
TIMER0_COMP = 0xffff;
TIMER0_HOLD = 0;
TIMER1_MODE = 0xc00;
TIMER1_COUNT = 0;
TIMER1_COMP = 0xffff;
TIMER1_HOLD = 0;
TIMER2_MODE = 0xc00;
TIMER2_COUNT = 0;
TIMER2_COMP = 0xffff;
TIMER2_HOLD = 0;
TIMER3_MODE = 0xc00;
TIMER3_COUNT = 0;
TIMER3_COMP = 0xffff;
TIMER3_HOLD = 0;
// Clear pending timer interrupts
ClearInterrupt(0x1e00);
// Unmask timer interrupts
CheckAndSetINTMask(0xc);
}
uint32_t ChannelAddrList[] =
{
0xB0008000, 0xB0009000, 0xB000A000, 0xB000B000,
0xB000B400, 0xB000C000, 0xB000C400, 0xB000C800,
0xB000D000, 0xB000D400
};
void ResetDMAC(int channel_mask)
{
for (int i = 0; i < 11; i++)
{
int channelBit = i & 0x1f;
if ((channel_mask >> channelBit) & 1)
{
uint32_t* addr = ChannelAddrList[i];
addr[0x20] = 0;
addr[0x00] = 0;
addr[0x0C] = 0;
addr[0x04] = 0;
addr[0x14] = 0;
addr[0x10] = 0;
}
}
// Clear all newly initialized channel's interrupts
// Also clear DMA stall, MFIFO empty, and BUSERR interrupts
DMAC_STAT = channel_mask & 0xffff | 0xe000;
int stat = DMAC_STAT;
// If interrupts are enabled, disable them
//
DMAC_STAT = stat & 0xffff0000 & (channel_mask | 0x6000);
// If all channels are being reset and bits 5 & 6 are set, then also reset CTRL and PCR
if ((channel_mask & 0x7f) == 0x7f)
{
DMAC_CTRL = 0;
DMAC_PCR = 0;
}
else
{
// Enable DMA, and set all newly enabled channels to priority 0
DMAC_CTRL = 1;
int pcr = DMAC_PCR;
DMAC_PCR = pcr & (~channel_mask << 16 | ~channel_mask);
}
DMAC_SQWC = 0;
DMAC_RBSR = 0;
DMAC_RBOR = 0;
}
void ClearVU0MemWord(int offs)
{
// Write offs to VI1
// Store VI0 to VI1
// Restore VI1
}
void ClearVU0Mem128(int offs)
{
// Save VI1
// Save VF1
// Zero out VF1
// Set VI1 to offs
// Zero 128-bits of memory at VI1
// Restore VI1
// Restore VF1
}
void ResetVU1()
{
// Here, control VI12 has bit 0x200 set in VU0
for (int i = 1; i < 0x10; i++)
{
ClearVU0MemWord(0x420 + i);
}
ClearVU0MemWord(0x434);
ClearVU0MemWord(0x435);
ClearVU0MemWord(0x436);
ClearVU0MemWord(0x437);
for (int i = 1; i < 0x20; i++)
{
ClearVU0Mem128(0x400 + i);
}
// Clear VU1 data memory
for (int i = 0x3ff; i >= 0; i--)
{
VU1_DATA[i+0] = 0;
VU1_DATA[i+1] = 0;
VU1_DATA[i+2] = 0;
VU1_DATA[i+3] = 0;
}
// Clear VU1 instruction memory
uint64_t* memPtr = VU1_CODE;
for (int i = 0x7ff; i >= 0; i--)
{
// Upper instruction: nop, lower instruction: ilw vi0, vi0(0x2FF)
*memPtr = 0x8000033c080002ff;
memPtr++;
}
// Clear VU1 interrupts
ClearInterrupt(0x80);
}
void ResetVIF1()
{
// Reset VIF1
VIF1_FBRST = 1;
VIF1_STAT = 0;
// Initialize VIF1 registers
VIF1_FIFO0 = VIF_STCYCL(4, 4);
VIF1_FIFO1 = VIF_STMOD(0);
VIF1_FIFO2 = VIF_MSKPATH3(0);
VIF1_FIFO3 = VIF_MARK(0);
VIF1_FIFO0 = VIF_BASE(0);
VIF1_FIFO1 = VIF_OFFSET(0);
VIF1_FIFO2 = VIF_ITOP(0);
VIF1_FIFO3 = VIF_NOP;
VIF1_FIFO0 = VIF_OFFSET(0);
VIF1_FIFO1 = VIF_NOP;
VIF1_FIFO2 = VIF_BASE(0);
VIF1_FIFO3 = VIF_NOP;
VIF1_FIFO0 = VIF_NOP;
VIF1_FIFO1 = VIF_NOP;
VIF1_FIFO2 = VIF_NOP;
VIF1_FIFO3 = VIF_STCOL;
VIF1_FIFO0 = VIF_NOP;
VIF1_FIFO1 = VIF_NOP;
VIF1_FIFO2 = VIF_NOP;
VIF1_FIFO3 = VIF_NOP;
// Acknowledge VIF1 interrupts
ClearInterrupt(0x20);
}
void ResetGIF()
{
// Reset GIF
GIF_CTRL = 1;
// Clear GIF FIFO
GIF_FIFO0 = 0;
GIF_FIFO1 = 0;
GIF_FIFO2 = 0;
GIF_FIFO3 = 0;
}
void ResetVU0Watchdog()
{
*(vu32*)0x1000F510 = 0;
ClearInterrupt(0x4000);
}
void ClearVU0Mem()
{
vu32* data = (vu32*)0x11000000;
vu32* code = (vu32*)0x11004000;
for (int i = 0xff; i >= 0; i--)
{
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
code[0] = 0;
code[1] = 0;
code[2] = 0;
code[3] = 0;
}
}
void ResetVU0Registers()
{
// vsub vf0..31, vf0, vf0
// viadd vi0..31, vi0, vi0
// ctc2 zero,vc0
// ctc2 zero,vc2
// ctc2 zero,vc4
// ctc2 zero,vc5
// ctc2 zero,vc6
// ctc2 zero,vc11
}
void ResetVU0()
{
ResetVU0Watchdog();
ClearVU0Mem();
ResetVU0Registers();
ClearInterrupt(0x40);
}
void ResetVIF0()
{
VIF0_MARK = 0;
VIF0_ERR = 0;
VIF0_FBRST = 1;
VIF0_FIFO0 = VIF_STCYCL(4, 4);
VIF0_FIFO1 = VIF_OFFSET(0);
VIF0_FIFO2 = VIF_NOP;
VIF0_FIFO3 = VIF_STMOD(0);
VIF0_FIFO0 = VIF_ITOP(0);
VIF0_FIFO1 = VIF_NOP;
VIF0_FIFO2 = VIF_NOP;
VIF0_FIFO3 = VIF_NOP;
ClearInterrupt(0x10);
}
void ResetEE(int mask)
{
if (mask & RESET_DMAC)
{
printf("# Initialize DMAC ...\n");
// Reset all channels
ResetDMAC(0x31F);
}
if (mask & RESET_VU1)
{
printf("# Initialize VU1 ...\n");
ResetVU1();
}
if (mask & RESET_VIF)
{
printf("# Initialize VIF1 ...\n");
ResetVIF1();
}
if (mask & RESET_GIF)
{
printf("# Initialize GIF ...\n");
ResetGIF();
}
if (mask & RESET_VU0)
{
printf("# Initialize VU0 ...\n");
ResetVU0();
}
if (mask & RESET_VIF)
{
printf("# Initialize VIF0 ...\n");
ResetVIF0();
}
// TODO: IPU Reset
ClearInterrupt(0xc);
}
void ResetFPU()
{
// Clear f0...f31
// clear fcsr
}
uint32_t* GetUserMemEnd()
{
}
void ResetUserMem(uint32_t* begin)
{
uint32_t* end = GetUserMemEnd();
if (begin < end)
{
while (begin < end)
{
*begin = 0;
begin[1] = 0;
begin[2] = 0;
begin[3] = 0;
begin += 4;
}
}
}
void ClearScratchpad()
{
uint32_t* sp = (uint32_t*)0x70000000;
while (sp < (uint32_t*)0x70004000)
{
sp[0] = sp[1] = sp[2] = sp[3] = 0;
sp += 4;
}
}
void InitHardware()
{
printf("Initialize Start.\n");
printf("Initiailize GS ...");
InitGS();
SetGsCrt(1, GS_MODE_NTSC, 1);
printf("\n");
printf("# Initialize INTC ...\n");
ClearInterrupt(0xffff);
printf("# Initialize TIMER ...\n");
InitTimers();
ResetEE(RESET_ALL);
printf("# Initialize FPU ...\n");
ResetFPU();
printf("# Initialize User Memory ...\n");
ResetUserMem(0x80000);
printf("# Initialize Scratch Pad ...\n");
ClearScratchpad();
printf("# Initialize Done.\n");
}
void main()
{
InitTLB();
}

10
BIOS/ee/kernel/reset.h Normal file
View file

@ -0,0 +1,10 @@
#pragma once
#define RESET_DMAC 1
#define RESET_VU1 2
#define RESET_VIF 4
#define RESET_GIF 8
#define RESET_VU0 16
#define RESET_IPU 64
#define RESET_ALL (RESET_DMAC | RESET_VU1 | RESET_VIF | RESET_GIF | RESET_VU0 | RESET_IPU)

View file

@ -0,0 +1,37 @@
#include "threading.h"
#include <stdint.h>
typedef struct LinkedList
{
LinkedList* next;
LinkedList* last;
} LinkedList;
struct unknown0
{
uint32_t unk32;
char unk[72];
} unknown0[256];
LinkedList lists[128];
int DAT_800125ec, DAT_800125f0, DAT_80016fe0;
void InitEENULL()
{
for (int i = 0x80; i >= 0; i--)
{
lists[i].next = &lists[i];
lists[i].last = &lists[i];
}
DAT_80016fe0 = 0;
DAT_800125ec = 0;
DAT_800125f0 = 0;
for (int i = 0; i < 256; i++)
{
unknown0[i].unk32 = 0;
}
}

View file

@ -0,0 +1,3 @@
#pragma once
void InitEENULL();

11
BIOS/ee/kernel/vif1.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#define VIF_NOP 0
#define VIF_STCYCL(wl, cl) ((1 << 24) | ((wl & 0xff) << 8) | ((cl & 0xff)))
#define VIF_OFFSET(offs) ((2 << 24) | (offs&0x3FF))
#define VIF_BASE(base) ((3 << 24) | (base&0x3FF))
#define VIF_ITOP(itop) ((4 << 24) | (itop&0x3FF))
#define VIF_STMOD(mode) ((5 << 24) | (mode & 3))
#define VIF_MSKPATH3(mask) ((6 << 24) | ((mask & 1) << 15))
#define VIF_MARK(mark) ((7 << 24) | (mark&0xffff))
#define VIF_STCOL (0x31 << 24)

View file

@ -15,4 +15,6 @@ void RegisterLibraryEntries(ExportTable_t* table);
static void ExportStub()
{
// Do nothing export stub for placeholder slots
}
}
int* QueryBootMode(int mode);

93
BIOS/iop/sifcmd/exports.c Normal file
View file

@ -0,0 +1,93 @@
#include <sifcmd/global.h>
#include <sifman/global.h>
#include <intrman/global.h>
#include <stdlib.h>
void sceSifCmdInit()
{
// Send SIFCMD initialized to EE
sceSetSMFLAG(0x20000);
// TODO: Some kind of event wait happens here
}
int sifRpcInited = 0;
typedef struct SifCmdHandler
{
void* func;
void* harg;
} SifCmdHandler;
SifCmdHandler handlers[32];
char dmaDest[32];
void RegisterCommandHandler(unsigned int cid, void* func, void* harg)
{
handlers[cid].func = func;
handlers[cid].harg = harg;
}
unsigned int sceSifSendCmd_Internal(unsigned int cmd, int disableIntrs, SifCmdHdr* packet, int packet_size, void *src_extra,void *dest_extra, int size_extra)
{
SifDmaTransfer transfers[2];
int disableIntrs;
int ret = 1;
if (packet_size - 0x10 < 0x61)
{
if (size_extra < 1)
{
packet->dest = NULL;
packet->size &= 0xff;
}
else
{
transfers[0].src = src_extra;
transfers[0].size = size_extra;
transfers[0].attr = 0;
transfers[0].dst = dest_extra;
}
int index = (size_extra != 0);
packet->size = packet_size;
packet->cid = cmd;
transfers[index].src = packet;
transfers[index].attr = 4;
transfers[index].size = packet_size;
transfers[index].dst = dmaDest;
ret = disableIntrs;
if (disableIntrs)
{
CpuSuspendIntr(&disableIntrs);
sceQueueTransfer(transfers, index+1);
CpuResumeIntr(disableIntrs);
}
else
sceQueueTransfer(transfers, index+1);
}
else
ret = 0;
return ret;
}
unsigned int sceSifSendCmd(unsigned int cmd, void* packet, int packet_size, void *src_extra,void *dest_extra, int size_extra)
{
sceSifSendCmd_Internal(cmd, 0, packet, packet_size, src_extra, dest_extra, size_extra);
}
void sceSifRpcInit(int mode)
{
int intr;
sceSifCmdInit();
CpuSuspendIntr(&intr);
if (!sifRpcInited)
{
sifRpcInited = 1;
sceSifSendCmd(0x80000001, (void*)0x1a40, 0x18, NULL, NULL, 0);
}
CpuResumeIntr(intr);
}

9
BIOS/iop/sifcmd/global.h Normal file
View file

@ -0,0 +1,9 @@
#pragma once
typedef struct
{
unsigned int size;
void* dest;
int cid;
unsigned int opt;
} SifCmdHdr;

51
BIOS/iop/sifcmd/sifcmd.c Normal file
View file

@ -0,0 +1,51 @@
#include <loadcore/global.h>
#include <sifman/global.h>
#include <intrman/global.h>
#include <stdlib.h>
#include <stdint.h>
typedef volatile uint32_t vu32;
#define SIF_SMCOM (*(vu32*)0xbd000010)
int IrqHandler(void* arg)
{
}
ExportTable_t exportTable =
{
.magic = 0x41C00000,
.next = NULL,
.version = 0x101,
.mode = 0,
.name = "sifman",
.exports =
{
}
};
char RecvBuf[80];
int main(int argc, char** argv)
{
int* bootMode = QueryBootMode(3);
if (bootMode == NULL)
{
int sifCmdInited = sceSifCheckInit();
if (!sifCmdInited)
sifCmdInit();
RegisterLibraryEntries(&exportTable);
if (!sifCmdInited)
{
RegisterIntrHandler(0x2b, 1, &IrqHandler, NULL);
EnableIntr(0x22b);
SIF_SMCOM = &RecvBuf;
}
}
return 0;
}

View file

@ -2,15 +2,21 @@
#include <stdint.h>
#include <stdbool.h>
#include <intrman/global.h>
#include <sifman/global.h>
typedef volatile uint32_t vu32;
#define DMA_DPCR (*(vu32*)0xbf8010f0)
#define DMA_DPCR2 (*(vu32*)0xbf801570)
#define DMA_SIF0_BCR (*(vu32*)0xbf801524)
#define DMA_SIF0_CTRL (*(vu32*)0xbf801528)
#define DMA_SIF0_TADR (*(vu32*)0xbf80152C)
#define DMA_SIF1_CTRL (*(vu32*)0xbf801538)
#define DMA_SIF1_BCR (*(vu32*)0xbf801534)
#define DMA_SIF2_CTRL (*(vu32*)0xbf8010A8)
#define SIF_SMCOM (*(vu32*)0xbd000010)
#define SIF_MSFLG (*(vu32*)0xbd000020)
#define SIF_SMFLG (*(vu32*)0xbd000030)
@ -99,4 +105,75 @@ void sifCmdInit()
sifCmdInited = true;
}
}
int sceSifCheckInit()
{
return sifCmdInited;
}
typedef struct
{
uint32_t addr_flags;
uint32_t size;
uint32_t tword1;
uint32_t tword2;
} SIF0Pkt;
void WriteTransferPacket(SifDmaTransfer* transfer)
{
SIF0Pkt* curTransferPkt = (SIF0Pkt*)(transferBufBase + transferBufOffs * 0x10);
uint32_t srcAddr = (uint32_t)transfer->src & 0xffffff;
uint32_t unAlignedSize = transfer->size + 3;
curTransferPkt->addr_flags = srcAddr;
uint32_t alignedSize = unAlignedSize >> 2;
if (transfer->attr & 2)
curTransferPkt->addr_flags |= 0x40000000;
curTransferPkt->size = alignedSize & 0xffffff;
unAlignedSize = unAlignedSize >> 4;
if (alignedSize & 3)
unAlignedSize = unAlignedSize + 1;
curTransferPkt->tword1 = unAlignedSize | 0x10000000;
if (transfer->attr & 4)
curTransferPkt->tword1 |= 0x80000000;
curTransferPkt->tword2 = (uint32_t)transfer->dst & 0x1fffffff;
transferBufOffs++;
}
int sceQueueTransfer(SifDmaTransfer* transfer, int count)
{
int offs = transferBufOffs;
if (count <= (0x20 - transferBufOffs))
{
if (count > 0)
{
for (int i = 0; i < count; i++)
{
WriteTransferPacket(&transfer[i]);
}
}
}
// No transfer running, send previously queued transfers
if ((DMA_SIF0_CTRL & 0x1000000) == 0)
{
DMA_SIF0_TADR = transferBufBase;
if ((SIF_CTRL & 0x20) == 0)
SIF_CTRL = 0x20;
DMA_SIF0_BCR = 0x20;
transferBufOffs = 0;
curTransferId = curTransferId + 1;
DMA_SIF0_CTRL = 0x1000701;
transferBufBase = 0xf8c;
}
return (offs & 0xff) << 8 | count & 0xff;
}

View file

@ -1,3 +1,14 @@
#pragma once
extern void sifCmdInit();
typedef struct
{
void* src;
void* dst;
int size;
int attr;
} SifDmaTransfer;
extern void sifCmdInit();
extern int sceSifCheckInit();
extern void sceSetSMFLAG(unsigned int value);
int sceQueueTransfer(SifDmaTransfer* transfer, int count);

View file

@ -15,6 +15,31 @@ ExportTable_t table =
ExportStub,
ExportStub,
sifCmdInit,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
ExportStub,
sceSifCheckInit,
}
};

BIN
a.out Executable file

Binary file not shown.

View file

@ -235,11 +235,6 @@ void ClearIp1Pending()
EmotionEngine::GetState()->cop0_regs[13] = cause.value;
}
void CheckForInterrupt()
{
}
void SetIp0Pending()
{
COP0CAUSE cause;

BIN
tst.o Normal file

Binary file not shown.

21
tst.s Normal file
View file

@ -0,0 +1,21 @@
.intel_syntax noprefix
.data
LC0:
.asciz "0x%08lx, 0x%08lx\n"
.text
foo:
sub rsp, 8
mov rdx, rsi
mov rsi, rdi
lea rdi, [rip+LC0]
mov eax, 0
call printf
add rsp, 8
ret
.global main
main:
mov rdi, 0xABABABAB
mov rsi, 0xBEEFBEEF
call foo
ret