* Monster bug fixes & improvements from the last two days' demo-testing work.
* sky-pke.h (pke_fifo*): Exported these formerly private functions. (pke_device): Added FIFO cache fields. * sky-pke.c (pke_fifo_reset): New function for GPUIF client - clear FIFO contents. (pke_pcrel_fifo): Added caching facility to prevent O(n^2) cost for searching for consecutive operand words. * sky-libvpe.c (MEM, uMEM): New/changed macros that perform modulo calculations to handle out-of-range VU memory addresses. (*): Replaced many previous uses of MEM[] and state->uMEM[] with calls to above macros. * sky-vu.h (struct VectorUnitState): Added qw/dw size fields for MEM/uMEM buffers, for overflow prevention. Renamed MEM/uMEM fields to catch all their prior users. * sky-vu0.c (vu0_attach): Manually align MEM0/MEM1 buffers to force 16-byte alignment. (zalloc is not enough.) * sky-vu1.c (vu1_attach): Ditto. (init_vu): Store buffer sizes from allocation into VectorUnitState. * sky-gpuif.h (GifPath): Use a pke_fifo strucf instead of temporary fixed-size array for flexible FIFO sizing. * sky-gpuif.c (SKY_GPU2_REFRESH): This is now an integer value to be used as a modulus for periodic refresh. (refresh): New function to send GPU2 refresh code periodically. (*): Use pke_fifo calls to en/dequeue GPUIF tags & operands. * sky-pke.h (struct pke_device): Added fields to allow caching of results from recent FIFO searches.
This commit is contained in:
parent
a748b374f5
commit
121d6745bc
4 changed files with 93 additions and 19 deletions
|
@ -30,10 +30,6 @@ static int pke_io_write_buffer(device*, const void*, int, address_word,
|
|||
unsigned, sim_cpu*, sim_cia);
|
||||
static void pke_reset(struct pke_device*);
|
||||
static void pke_issue(SIM_DESC, struct pke_device*);
|
||||
static unsigned_4 pke_fifo_flush(struct pke_fifo*);
|
||||
static struct fifo_quadword* pke_fifo_fit(struct pke_fifo*);
|
||||
static inline struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum);
|
||||
static void pke_fifo_old(struct pke_fifo*, unsigned_4 qwnum);
|
||||
static void pke_pc_advance(struct pke_device*, int num_words);
|
||||
static struct fifo_quadword* pke_pcrel_fifo(struct pke_device*, int operand_num,
|
||||
unsigned_4** operand);
|
||||
|
@ -81,6 +77,7 @@ struct pke_device pke0_device =
|
|||
{}, 0, /* FIFO write buffer */
|
||||
{ NULL, 0, 0, 0 }, /* FIFO */
|
||||
NULL, /* FIFO trace file */
|
||||
-1, -1, 0, 0, 0, /* invalid FIFO cache */
|
||||
0, 0 /* pc */
|
||||
};
|
||||
|
||||
|
@ -93,6 +90,7 @@ struct pke_device pke1_device =
|
|||
{}, 0, /* FIFO write buffer */
|
||||
{ NULL, 0, 0, 0 }, /* FIFO */
|
||||
NULL, /* FIFO trace file */
|
||||
-1, -1, 0, 0, 0, /* invalid FIFO cache */
|
||||
0, 0 /* pc */
|
||||
};
|
||||
|
||||
|
@ -683,6 +681,27 @@ pke_fifo_flush(struct pke_fifo* fifo)
|
|||
|
||||
|
||||
|
||||
/* Clear out contents of FIFO; make it really empty. */
|
||||
|
||||
void
|
||||
pke_fifo_reset(struct pke_fifo* fifo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* clear fifo quadwords */
|
||||
for(i=0; i<fifo->next; i++)
|
||||
{
|
||||
zfree(fifo->quadwords[i]);
|
||||
fifo->quadwords[i] = NULL;
|
||||
}
|
||||
|
||||
/* reset pointers */
|
||||
fifo->origin = 0;
|
||||
fifo->next = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Make space for the next quadword in the FIFO. Allocate/enlarge
|
||||
FIFO pointer block if necessary. Return a pointer to it. */
|
||||
|
||||
|
@ -886,15 +905,29 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
|||
struct fifo_quadword*
|
||||
pke_pcrel_fifo(struct pke_device* me, int operand_num, unsigned_4** operand)
|
||||
{
|
||||
int num = operand_num;
|
||||
int num;
|
||||
int new_qw_pc, new_fifo_pc;
|
||||
struct fifo_quadword* fq = NULL;
|
||||
|
||||
ASSERT(num > 0);
|
||||
/* check for validity of last search results in cache */
|
||||
if(me->last_fifo_pc == me->fifo_pc &&
|
||||
me->last_qw_pc == me->qw_pc &&
|
||||
operand_num > me->last_num)
|
||||
{
|
||||
/* continue search from last stop */
|
||||
new_fifo_pc = me->last_new_fifo_pc;
|
||||
new_qw_pc = me->last_new_qw_pc;
|
||||
num = operand_num - me->last_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start search from scratch */
|
||||
new_fifo_pc = me->fifo_pc;
|
||||
new_qw_pc = me->qw_pc;
|
||||
num = operand_num;
|
||||
}
|
||||
|
||||
/* snapshot current pointers */
|
||||
new_fifo_pc = me->fifo_pc;
|
||||
new_qw_pc = me->qw_pc;
|
||||
ASSERT(num > 0);
|
||||
|
||||
/* printf("pke %d pcrel_fifo operand_num %d\n", me->pke_number, operand_num); */
|
||||
|
||||
|
@ -944,6 +977,15 @@ pke_pcrel_fifo(struct pke_device* me, int operand_num, unsigned_4** operand)
|
|||
/* annote the word where the pseudo-PC lands as an PKE operand */
|
||||
ASSERT(fq->word_class[new_qw_pc] == wc_pkedata || fq->word_class[new_qw_pc] == wc_unknown);
|
||||
fq->word_class[new_qw_pc] = wc_pkedata;
|
||||
|
||||
/* store search results in cache */
|
||||
/* keys */
|
||||
me->last_fifo_pc = me->fifo_pc;
|
||||
me->last_qw_pc = me->qw_pc;
|
||||
/* values */
|
||||
me->last_num = operand_num;
|
||||
me->last_new_fifo_pc = new_fifo_pc;
|
||||
me->last_new_qw_pc = new_qw_pc;
|
||||
}
|
||||
|
||||
return fq;
|
||||
|
|
|
@ -15,6 +15,16 @@ void pke0_issue(SIM_DESC sd);
|
|||
void pke1_attach(SIM_DESC sd);
|
||||
void pke1_issue(SIM_DESC sd);
|
||||
|
||||
/* structs declared below */
|
||||
struct pke_fifo;
|
||||
struct fifo_quadword;
|
||||
|
||||
unsigned_4 pke_fifo_flush(struct pke_fifo*);
|
||||
void pke_fifo_reset(struct pke_fifo*);
|
||||
struct fifo_quadword* pke_fifo_fit(struct pke_fifo*);
|
||||
struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum);
|
||||
void pke_fifo_old(struct pke_fifo*, unsigned_4 qwnum);
|
||||
|
||||
|
||||
/* Quadword data type */
|
||||
|
||||
|
@ -344,7 +354,8 @@ enum wordclass
|
|||
wc_dma = 'D',
|
||||
wc_pkecode = 'P',
|
||||
wc_unknown = '?',
|
||||
wc_pkedata = '.'
|
||||
wc_pkedata = '.',
|
||||
wc_gpuiftag = 'g'
|
||||
};
|
||||
|
||||
|
||||
|
@ -361,13 +372,13 @@ struct fifo_quadword
|
|||
|
||||
|
||||
/* quadword FIFO structure for PKE */
|
||||
struct pke_fifo
|
||||
typedef struct pke_fifo
|
||||
{
|
||||
struct fifo_quadword** quadwords; /* pointer to fifo quadwords */
|
||||
unsigned_4 origin; /* quadword serial number of quadwords[0] */
|
||||
unsigned_4 length; /* length of quadword pointer array: 0..N */
|
||||
unsigned_4 next; /* relative index of first unfilled quadword: 0..length-1 */
|
||||
};
|
||||
} pke_fifo;
|
||||
|
||||
#define PKE_FIFO_GROW_SIZE 1000 /* number of quadword pointers to allocate */
|
||||
#define PKE_FIFO_ARCHEOLOGY 1000 /* number of old quadwords to keep as history */
|
||||
|
@ -394,6 +405,13 @@ struct pke_device
|
|||
struct pke_fifo fifo; /* array of FIFO quadword pointers */
|
||||
FILE* fifo_trace_file; /* stdio stream open in append mode, or 0 for no trace */
|
||||
|
||||
/* FIFO cache -- curry last search pke_pcrel_fifo results */
|
||||
unsigned_4 last_fifo_pc;
|
||||
unsigned_4 last_qw_pc;
|
||||
unsigned_4 last_num;
|
||||
unsigned_4 last_new_fifo_pc;
|
||||
unsigned_4 last_new_qw_pc;
|
||||
|
||||
/* PC */
|
||||
int fifo_pc; /* 0 .. (fifo_num_elements-1): quadword index of next instruction */
|
||||
int qw_pc; /* 0 .. 3: word index of next instruction */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "sky-device.h"
|
||||
#include "sky-vu0.h"
|
||||
|
||||
/* these are aligned versions of zalloc() pointers - do not zfree()! */
|
||||
static char* vu0_mem0_buffer = 0;
|
||||
static char* vu0_mem1_buffer = 0;
|
||||
|
||||
|
@ -64,6 +65,7 @@ vu0_attach(SIM_DESC sd)
|
|||
NULL /*buffer*/);
|
||||
|
||||
vu0_mem0_buffer = zalloc(VU0_MEM0_SIZE);
|
||||
vu0_mem0_buffer = (void*) ALIGN_16((unsigned)vu0_mem0_buffer);
|
||||
sim_core_attach (sd,
|
||||
NULL,
|
||||
0 /*level*/,
|
||||
|
@ -76,6 +78,7 @@ vu0_attach(SIM_DESC sd)
|
|||
vu0_mem0_buffer /*buffer*/);
|
||||
|
||||
vu0_mem1_buffer = zalloc(VU0_MEM1_SIZE);
|
||||
vu0_mem1_buffer = (void*) ALIGN_16((unsigned)vu0_mem1_buffer);
|
||||
sim_core_attach (sd,
|
||||
NULL,
|
||||
0 /*level*/,
|
||||
|
|
|
@ -17,11 +17,14 @@ VectorUnitState vu1_state;
|
|||
|
||||
#define sim_warning printf
|
||||
|
||||
/* these are aligned versions of zalloc() pointers - do not zfree()! */
|
||||
static char* vu1_umem_buffer = 0;
|
||||
static char* vu1_mem_buffer = 0;
|
||||
|
||||
void init_vu1(void);
|
||||
void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer);
|
||||
void init_vu(VectorUnitState *state,
|
||||
char* umem_buffer, unsigned umem_dw_size,
|
||||
char* mem_buffer, unsigned mem_qw_size);
|
||||
|
||||
#if 0
|
||||
static void dump_mem() {
|
||||
|
@ -171,6 +174,7 @@ vu1_init(SIM_DESC sd)
|
|||
NULL /*buffer*/);
|
||||
|
||||
vu1_umem_buffer = zalloc(VU1_MEM0_SIZE);
|
||||
vu1_umem_buffer = (void*) ALIGN_16((unsigned)vu1_umem_buffer);
|
||||
sim_core_attach (sd,
|
||||
NULL,
|
||||
0 /*level*/,
|
||||
|
@ -182,7 +186,8 @@ vu1_init(SIM_DESC sd)
|
|||
0 /*device*/,
|
||||
vu1_umem_buffer /*buffer*/);
|
||||
|
||||
vu1_mem_buffer = zalloc(VU1_MEM1_SIZE);
|
||||
vu1_mem_buffer = zalloc(VU1_MEM1_SIZE + 2*sizeof(unsigned_16));
|
||||
vu1_mem_buffer = (void*) ALIGN_16((unsigned)vu1_mem_buffer);
|
||||
sim_core_attach (sd,
|
||||
NULL,
|
||||
0 /*level*/,
|
||||
|
@ -225,19 +230,25 @@ static void abend2(char *fmt, char* p) {
|
|||
void getoption(VectorUnitState* state);
|
||||
|
||||
void init_vu1(void) {
|
||||
init_vu(&vu1_state, &vu1_umem_buffer[0], &vu1_mem_buffer[0]);
|
||||
init_vu(&vu1_state,
|
||||
&vu1_umem_buffer[0], VU1_MEM0_SIZE/8,
|
||||
&vu1_mem_buffer[0], VU1_MEM1_SIZE/16);
|
||||
}
|
||||
|
||||
void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer)
|
||||
void init_vu(VectorUnitState *state,
|
||||
char* umem_buffer, unsigned umem_dw_size,
|
||||
char* mem_buffer, unsigned mem_qw_size)
|
||||
{
|
||||
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;
|
||||
|
||||
state->uMEM_buffer = (uMEM_Entry_Type *) umem_buffer;
|
||||
state->uMEM_size = umem_dw_size;
|
||||
state->MEM_buffer = (MEM_Entry_Type*) mem_buffer;
|
||||
state->MEM_size = mem_qw_size;
|
||||
|
||||
/* set up run state */
|
||||
state->runState = VU_READY;
|
||||
|
||||
|
|
Loading…
Reference in a new issue