* Very, very early support for vu1 based on sce code.

* Modified Files:
*    ChangeLog Makefile.in hardware.c vu1.c vu1.h
* Added Files:
*    libvpe.c libvpe.h vpe.h vu.h
This commit is contained in:
Ian Carmichael 1998-01-28 02:04:32 +00:00
parent 4b95e9a13d
commit 8ae6b5cd79
9 changed files with 6349 additions and 28 deletions

View File

@ -1,15 +1,19 @@
Tue Jan 27 18:24:01 1998 Ian Carmichael <iancarm@cygnus.com>
* Very, very early support for vu1 based on sce code.
Thu Jan 22 15:44:46 1998 Ian Carmichael <iancarm@cygnus.com>
* Incorporate GPR_SET from mips/sim-main.h
* Incorporate GPR_SET from mips/sim-main.h.
Fri Jan 16 14:25:54 1998 Ian Carmichael <iancarm@cygnus.com>
* Devices now get decode() call
* Devices now get decode() call.
Fri Jan 16 14:25:54 1998 Ian Carmichael <iancarm@cygnus.com>
* Initial Device Support
* Initial Device Support.
Thu Jan 15 10:25:54 1998 Ian Carmichael <iancarm@cygnus.com>
* ChangeLog created
* ChangeLog created.

View File

@ -37,6 +37,7 @@ SIM_OBJS = \
dma.o \
vu0.o \
vu1.o \
libvpe.o \
pke.o \
sim-hload.o \
sim-engine.o \
@ -59,6 +60,8 @@ SIM_EXTRA_CFLAGS = \
-I$(srcdir)/../../newlib/libc/sys/idt \
$(SIM_@sim_gen@_CFLAGS)
SIM_EXTRA_CCFLAGS = $(SIM_EXTRA_CFLAGS)
SIM_EXTRA_CLEAN = clean-igen clean-m16 clean-extra
SIM_EXTRA_ALL = $(SIM_@sim_gen@_ALL)

View File

@ -18,6 +18,6 @@ register_devices(SIM_DESC sd)
dma_attach(sd);
pke0_attach(sd);
vu0_attach(sd);
vu1_attach(sd);
vu1_init(sd);
pke1_attach(sd);
}

5877
sim/txvu/libvpe.c Normal file

File diff suppressed because it is too large Load Diff

35
sim/txvu/libvpe.h Normal file
View File

@ -0,0 +1,35 @@
/****************************************************************************/
/* */
/* Sony Computer Entertainment CONFIDENTIAL */
/* (C) 1997 Sony Computer Entertainment Inc. All Rights Reserved */
/* */
/* VPE1 simulator (part of VU1) global variables */
/* */
/****************************************************************************/
#ifndef LIBVPE_H_
#define LIBVPE_H_
extern unsigned long _ITOP;
extern unsigned long _TOP;
extern unsigned long _vpepc;
extern int _is_dbg;
extern int _is_verb;
extern int _is_dump;
extern int _pgpuif;
extern FILE *_fp_gpu;
extern int _GIF_SIM_OFF;
extern int _GIF_BUSY;
extern int _GIF_VUCALL;
extern int _GIF_VUADDR;
#include "vu.h"
void initvpe(VectorUnitState *state);
void vpecallms_init(VectorUnitState *state);
void vpecallms_cycle(VectorUnitState* state);
#endif

114
sim/txvu/vpe.h Normal file
View File

@ -0,0 +1,114 @@
/****************************************************************************/
/* */
/* Sony Computer Entertainment CONFIDENTIAL */
/* (C) 1997 Sony Computer Entertainment Inc. All Rights Reserved */
/* */
/* VU simulator global definitions */
/* */
/****************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <math.h>
typedef struct {
int no; /* destination register number VF:0-31 VI:32-47*/
int mask; /* specify which units calculate */
float vf[4]; /* calculated value */
int flag; /*0: empty in this pipeline stage,
1: write value to reg,
2: store value from reg,
3: write value to I-reg ( not used ),
4: write only status to statusflag,
5: write only clip value to clipflag,
6: move value from EFU reg */
u_long status; /* calculation unit status */
u_long addr; /* store address ( store operation )*/
char code[32]; /* instruction */
} PIPELINE; /* pipeline stage specification for FMAC, Ld/St, RANDU, FDIV */
typedef struct {
int no; /* destination register number VI:0-15 */
short vi; /* calculated value */
int flag; /* 0: empty in this pipeline stage,
1: write value to reg */
char code[32]; /* instruction */
} IPIPELINE; /* pipeline stage specification for IALU */
typedef struct {
int flag; /* 0: empty in this pipeline stage,
1: write value to I-reg */
float val; /* calculated value */
} LOIPIPELINE; /* pipeline stage specification for I bit */
typedef struct {
int mask; /* specify which units calculate */
float acc[4]; /* calculated value */
int flag; /* 0: empty in this pipeline stage,
1: write value to ACC */
} APIPELINE; /* accumulator pipeline stage specification */
typedef struct {
int no; /* left stage count of pipeline */
float vn; /* calculated value */
int flag; /* 0: move to VN[4]
1: move to VN[0] (not used)*/
} SUPIPELINE;
u_long instbuf[2]; /* instruction buffer. instbuf[0]:Upper, instbuf[1]:Lower*/
u_long pc, opc; /* pc is next PC, opc is executed PC. see fetch_inst() */
u_long jaddr; /* branch address */
float VF[32][4]; /* VF registers */
/* VF[?][0] = x, VF[?][1] = y, VF[?][2] = z, VF[?][3] = w */
short VI[16]; /* VI registers */
float ACC[4]; /* accumulator registers */
float Q; /* FDIV register */
float I; /* I register */
u_long R; /* RANDU register */
float VN[32]; /* EFU registers */
u_long MACflag;
u_long statusflag;
u_long clipflag;
u_long MEM[4096][4]; /* VU (data) memory */
u_long uMEM[1024][2]; /* Micro (instruction) memory */
PIPELINE pipe[4][2]; /* FMAC, Ld/St, RANDU piepline */
PIPELINE qpipe[7]; /* FDIV(DIV,DQRT) pipeline */
PIPELINE rqpipe[13]; /*FDIV(RSQRT) pipeline */
IPIPELINE ipipe[2]; /* IALU pipeline */
APIPELINE apipe; /* ACC pipeline stage */
SUPIPELINE spipe; /* EFU pipeline stage */
LOIPIPELINE Ipipe; /* I-bit pipeline stage */
int eflag, jflag, peflag, sflag;
/* eflag: E-bit detect flag
0: not detect, 1: detect, -1: fetch stage terminate
jflag: branch detect flag
0: not detect, 1: detect
peflag: end delay slot execute flag
0: not execute, 1: execute, -1: finished ececution
sflag: data hazard stall flag
0: not stall, 1: stall */
u_long bp; /* break point address */
u_long ecount; /* end counter */
int intr_mode; /* interactive mode enable */
int verb_mode; /* verbose mode enable */
int dpr_mode; /* PRT (debug print) instruction enable */
u_long all_count; /* amount of executed cycles */
u_long hc_count; /* amount of hazard stall cycles */
extern int _GIF_SIM_OFF; /* internal GPUIF simulator disable */
extern int _GIF_BUSY; /* external GPUIF simulator is BUSY flag,
this flag uses when _GIF_SIM_OFF = 1 */
extern int _GIF_VUCALL; /* XGKICK instruction detect flag,
this flag uses when _GIF_SIM_OFF = 1 */
extern int _GIF_VUADDR; /* appointed address by XGKICK instruction,
this flag uses when _GIF_SIM_OFF = 1 */
#define DEST_X 0x8
#define DEST_Y 0x4
#define DEST_Z 0x2
#define DEST_W 0x1

49
sim/txvu/vu.h Normal file
View File

@ -0,0 +1,49 @@
/* Copyright (C) 1998, Cygnus Solutions
*/
#ifndef VU_H_
#define VU_H_
#include "sim-main.h"
#include <sys/types.h>
typedef u_long MEM_Entry_Type[4];
typedef u_long uMEM_Entry_Type[2];
typedef enum { VU_READY, VU_RUN, VU_BREAK } RunState;
/* See VU Specifications (Ver. 2.10), p7-11 */
typedef struct {
u_long vbs : 1; /* busy 0: Idle, 1: Busy */
u_long vds : 1; /* D bit stop 0: No D bit stop, 1: D bit stop */
u_long vts : 1; /* T bit stop 0: No T bit stop, 1: T bit stop*/
u_long vfs : 1; /* ForceBreak stop 0: no ForceBreak stop, 1: ForceBreak stop*/
u_long vgw : 1; /* XGKICK wait 0: Do not wait, 1: Wait */
u_long div : 1; /* DIV busy 0: Idle, 1: Busy*/
u_long efu : 1; /* EF busy 0: Idle, 1: Busy */
u_long reserved_2:25;
} VpeStat;
typedef struct {
float VF[32][4];
short VI[16];
u_long MST;
u_long MMC;
u_long MCP;
u_long MR;
u_long MI;
u_long MQ;
u_long MP;
u_long MTPC;
VpeStat VPE_STAT;
} VectorUnitRegs;
typedef struct {
MEM_Entry_Type *MEM; /* VU (data) memory */
uMEM_Entry_Type *uMEM; /* Micro (instruction) memory */
VectorUnitRegs regs;
RunState runState;
} VectorUnitState;
#endif

View File

@ -6,34 +6,69 @@
#include "device.h"
#include "vu1.h"
#include "libvpe.h"
#include "vu.h"
static char vu1_mem0_buffer[VU1_MEM0_SIZE];
static char vu1_mem1_buffer[VU1_MEM1_SIZE];
VectorUnitState vu1_state;
static char vu1_umem_buffer[VU1_MEM0_SIZE];
static char vu1_mem_buffer[VU1_MEM1_SIZE];
void init_vu1();
void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer);
void
vu1_issue()
{
if (vu1_state.runState == VU_RUN)
vpecallms_cycle(&vu1_state);
}
int
vu1_io_read_buffer(device *me,
void *dest,
int space,
address_word addr,
unsigned nr_bytes,
sim_cpu *processor,
sim_cia cia)
vu1_io_read_register_window(device *me,
void *dest,
int space,
address_word addr,
unsigned nr_bytes,
sim_cpu *processor,
sim_cia cia)
{
printf("%s: Read!\n", me->name);
/* Slow and crappy hack ... */
printf(" vu1_mem0[0] = %d\n", *(int*)&vu1_mem0_buffer[0]);
printf(" vu1_mem1[0] = %d\n", *(int*)&vu1_mem1_buffer[0]);
int i;
char source_buffer[VU1_REGISTER_WINDOW_SIZE];
char* src;
memcpy(source_buffer, &vu1_state.regs.VF[0][0], 0x200); /* copy VF registers */
for (i = 0; i<16; i++ ) {
*(short*)&source_buffer[0x200 + i*16] = vu1_state.regs.VI[i];
}
*(u_long*)&source_buffer[VU1_MST - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MST;
*(u_long*)&source_buffer[VU1_MMC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MMC;
*(u_long*)&source_buffer[VU1_MCP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MCP;
*(u_long*)&source_buffer[VU1_MR - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MR;
*(u_long*)&source_buffer[VU1_MI - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MI;
*(u_long*)&source_buffer[VU1_MQ - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MQ;
*(u_long*)&source_buffer[VU1_MP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MP;
*(u_long*)&source_buffer[VU1_MTPC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MTPC;
*(VpeStat*)&source_buffer[VPE1_STAT - VU1_REGISTER_WINDOW_START] = vu1_state.regs.VPE_STAT;
printf("%s: Read: %x, %d, dest: %x, space: %d, %x!\n", me->name, addr, nr_bytes, dest, space, vu1_state.regs.VPE_STAT);
printf(" vu1_state.regs.VPE_STAT = %x\n", vu1_state.regs.VPE_STAT);
if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) {
fprintf(stderr, "Error: Read past end of vu1 register window!!!\n");
exit(1);
}
src = &source_buffer[0] + (addr - VU1_REGISTER_WINDOW_START);
memcpy(dest, src, nr_bytes);
return nr_bytes;
}
int
vu1_io_write_buffer(device *me,
vu1_io_write_register_window(device *me,
const void *source,
int space,
address_word addr,
@ -41,20 +76,54 @@ vu1_io_write_buffer(device *me,
sim_cpu *processor,
sim_cia cia)
{
printf("%s: Write!\n", me->name);
char *dest;
if (addr == VPE1_STAT && nr_bytes == 4) {
/* Magic to switch VU to run state, until other methods are available. */
vu1_state.runState = VU_RUN;
vu1_state.regs.VPE_STAT.vbs = 1;
printf("Magic start run...\n");
printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.VPE_STAT,
((char*)&vu1_state.regs.VPE_STAT) - ((char*)&vu1_state.regs.VF[0][0]),
((char*)&vu1_state.regs.VPE_STAT) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
);
printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.VI[0],
((char*)&vu1_state.regs.VI[0]) - ((char*)&vu1_state.regs.VF[0][0]),
((char*)&vu1_state.regs.VI[0]) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
);
printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.MST,
((char*)&vu1_state.regs.MST) - ((char*)&vu1_state.regs.VF[0][0]),
((char*)&vu1_state.regs.MST) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
);
return nr_bytes;
}
printf("%s: Write: %x, %d, source: %x, space: %d!\n", me->name, addr, nr_bytes, source, space);
if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) {
fprintf(stderr, "Error: Read past end of vu1 register window!!!\n");
exit(1);
}
dest = ((char*) (&vu1_state.regs)) + (addr - VU1_REGISTER_WINDOW_START);
memcpy(dest, source, nr_bytes);
return nr_bytes;
}
device vu1_device =
{
"vu1",
&vu1_io_read_buffer,
&vu1_io_write_buffer
&vu1_io_read_register_window,
&vu1_io_write_register_window
};
void
vu1_attach(SIM_DESC sd)
vu1_init(SIM_DESC sd)
{
sim_core_attach (sd,
NULL,
0 /*level*/,
@ -75,7 +144,7 @@ vu1_attach(SIM_DESC sd)
VU1_MEM0_SIZE /*nr_bytes*/,
0 /*modulo*/,
0 /*device*/,
&vu1_mem0_buffer /*buffer*/);
&vu1_umem_buffer /*buffer*/);
sim_core_attach (sd,
NULL,
@ -86,5 +155,169 @@ vu1_attach(SIM_DESC sd)
VU1_MEM1_SIZE /*nr_bytes*/,
0 /*modulo*/,
0 /*device*/,
&vu1_mem1_buffer /*buffer*/);
&vu1_mem_buffer /*buffer*/);
init_vu1();
/*initvpe();*/
vpecallms_init(&vu1_state);
}
/****************************************************************************/
/* */
/* Sony Computer Entertainment CONFIDENTIAL */
/* (C) 1997 Sony Computer Entertainment Inc. All Rights Reserved */
/* */
/* VPE1 simulator */
/* */
/****************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include "libvpe.h"
char ifilename[64] = "vu.bin";
char ofilename[64] = "";
char pfilename[64] = "";
void abend2(char *fmt, char* p) {
fprintf(stderr, fmt, p);
exit(1);
}
void getoption();
void init_vu1() {
init_vu(&vu1_state, &vu1_umem_buffer[0], &vu1_mem_buffer[0]);
}
void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer)
{
FILE *fp;
int i, j;
u_long data[4];
/* set up memory buffers */
state->uMEM = (uMEM_Entry_Type *) umem_buffer;
state->MEM = (MEM_Entry_Type*) mem_buffer;
/* set up run state */
state->runState = VU_READY;
/* read option */
getoption();
/* read instruction file (mandatory) */
if (*ifilename) {
if((fp = fopen(ifilename, "r")) == NULL)
abend2("%s: can not open\n", ifilename);
for (i = 0; fread(&data[0], 4, 1, fp) != 0; i++) {
fread(&data[1], 4, 1, fp);
LoadMMem(state, i, data, 1);
}
fclose(fp);
}
/* PKE dirven simvpe */
if (*pfilename) {
/* initpke(pfilename); */
initvpe(&vu1_state);
/* while (simpke() != -1)
simvpe(); */
}
/* conventional simvpe */
else {
initvpe(&vu1_state);
/*simvpe();*/
}
/* write result memory image (optional) */
if (*ofilename) {
if((fp = fopen(ofilename, "w")) == NULL)
abend2("%s: can not open\n", ofilename);
for(i = 0; i < 2048; i++){
StoreVUMem(i, data, 1);
for(j = 0; j < 4; j++)
fwrite(&data[j], 4, 1, fp);
}
fclose(fp);
}
}
static void Usage(void)
{
fprintf(stderr, "Usage: simvpe [options]\n");
fprintf(stderr, "\t\t-i instruction-file\n");
fprintf(stderr, "\t\t-o output-memory-file\n");
fprintf(stderr, "\t\t-t PKE-file (text type)\n");
fprintf(stderr, "\t\t-s start-address [default = 0]\n");
fprintf(stderr, "\t\t-d [interactive mode enable: default desable]\n");
fprintf(stderr, "\t\t-v [statistics mode enable: default desable]\n");
fprintf(stderr, "\t\t-p [debug print mode enable: default desable]\n");
}
void getoption()
{
int startline = 0;
int count = 1;
_is_dbg = 1;
_vpepc = 0;
_is_verb = 0;
_is_dump = 0;
_pgpuif = 2;
_ITOP = 20;
_TOP = 10;
#if 0
while(argc - count){
if(argv[count][0] == '-'){
switch(argv[count][1]){
case 'i':
strcpy(ifilename, argv[count+1]);
count += 2;
break;
case 'o':
strcpy(ofilename, argv[count+1]);
count += 2;
break;
case 't':
strcpy(pfilename, argv[count+1]);
count += 2;
break;
case 's':
sscanf(argv[count+1], "%d", &startline);
_vpepc = startline;
count += 2;
break;
case 'd':
_is_dbg = 1;
count += 1;
break;
case 'v':
_is_verb = 1;
count += 1;
break;
case 'p':
_is_dump = 1;
count += 1;
break;
case 'h':
case '?':
Usage();
exit(1);
break;
default:
Usage();
exit(1);
}
}else{
Usage();
exit(1);
}
}
#endif
}

View File

@ -26,11 +26,17 @@ void vu1_issue();
/* ... */
#define VU1_VI15 0x110072f0
/* ... */
#define VU1_MST 0x11007300
#define VU1_MMC 0x11007310
#define VU1_MCP 0x11007320
#define VU1_MR 0x11007330
#define VU1_MI 0x11007340
#define VU1_MQ 0x11007350
#define VU1_MP 0x11007360
#define VU1_MTPC 0x110073a0
#define VPE1_STAT 0x110073d0
#define VPE1_STAT 0x11007370
#define VU1_REGISTER_WINDOW_END 0x11007380
#define VU1_REGISTER_WINDOW_END 0x110073e0
#define VU1_REGISTER_WINDOW_SIZE (VU1_REGISTER_WINDOW_END - VU1_REGISTER_WINDOW_START)