mirror of
https://github.com/google0101-ryan/Emotional.git
synced 2024-05-11 17:15:30 -04:00
Started work on reverse engineering EE kernel
This commit is contained in:
parent
a6d5e65bb5
commit
1e006ca9f1
72
BIOS/ee/kernel/hw.h
Normal file
72
BIOS/ee/kernel/hw.h
Normal 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
|
516
BIOS/ee/kernel/kernel_start.c
Normal file
516
BIOS/ee/kernel/kernel_start.c
Normal 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
10
BIOS/ee/kernel/reset.h
Normal 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)
|
37
BIOS/ee/kernel/threading.c
Normal file
37
BIOS/ee/kernel/threading.c
Normal 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;
|
||||
|
||||
}
|
||||
}
|
3
BIOS/ee/kernel/threading.h
Normal file
3
BIOS/ee/kernel/threading.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void InitEENULL();
|
11
BIOS/ee/kernel/vif1.h
Normal file
11
BIOS/ee/kernel/vif1.h
Normal 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)
|
|
@ -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
93
BIOS/iop/sifcmd/exports.c
Normal 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
9
BIOS/iop/sifcmd/global.h
Normal 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
51
BIOS/iop/sifcmd/sifcmd.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -235,11 +235,6 @@ void ClearIp1Pending()
|
|||
EmotionEngine::GetState()->cop0_regs[13] = cause.value;
|
||||
}
|
||||
|
||||
void CheckForInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SetIp0Pending()
|
||||
{
|
||||
COP0CAUSE cause;
|
||||
|
|
Loading…
Reference in a new issue