- PKE simulation almost finished. Needed enhancements:

* trace file generation
  * FIFO pruning

- PKE functions still missing due to external dependencies:
  * interrupt to 5900 (igen?)
  * VU busy checking (sky-vu / coprocessor registers)
  * PATH3 masking (sky-gpuif / covert control interface)
This commit is contained in:
Frank Ch. Eigler 1998-02-13 23:29:38 +00:00
parent 62e89e48a4
commit db6dac32c7
2 changed files with 217 additions and 164 deletions

View file

@ -6,6 +6,7 @@
#include <stdlib.h>
#include "sky-pke.h"
#include "sky-dma.h"
#include "sim-bits.h"
#include "sim-assert.h"
#include "sky-vu0.h"
#include "sky-vu1.h"
@ -26,6 +27,8 @@ static int pke_io_write_buffer(device*, const void*, int, address_word,
static void pke_issue(struct pke_device*);
static void pke_pc_advance(struct pke_device*, int num_words);
static unsigned_4* pke_pc_operand(struct pke_device*, int operand_num);
static unsigned_4 pke_pc_operand_bits(struct pke_device*, int bit_offset,
int bit_width, unsigned_4* sourceaddr);
static struct fifo_quadword* pke_pc_fifo(struct pke_device*, int operand_num,
unsigned_4** operand);
static int pke_track_write(struct pke_device*, const void* src, int len,
@ -67,6 +70,7 @@ struct pke_device pke0_device =
{ "pke0", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
0, 0, /* ID, flags */
{}, /* regs */
{}, 0, /* FIFO write buffer */
NULL, 0, 0, NULL, /* FIFO */
0, 0 /* pc */
};
@ -77,6 +81,7 @@ struct pke_device pke1_device =
{ "pke1", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
1, 0, /* ID, flags */
{}, /* regs */
{}, 0, /* FIFO write buffer */
NULL, 0, 0, NULL, /* FIFO */
0, 0 /* pc */
};
@ -334,12 +339,12 @@ pke_io_write_buffer(device *me_,
PKE_REG_MASK_SET(me, STAT, INT, 0);
PKE_REG_MASK_SET(me, STAT, ER0, 0);
PKE_REG_MASK_SET(me, STAT, ER1, 0);
me->flags &= ~PKE_FLAG_PENDING_PSS;
/* will allow resumption of possible stalled instruction */
}
if(BIT_MASK_GET(input[0], 2, 2)) /* STP bit */
{
/* XXX: how to safely abort "currently executing" (=> stalled) instruction? */
PKE_REG_MASK_SET(me, STAT, PSS, 1);
me->flags |= PKE_FLAG_PENDING_PSS;
}
if(BIT_MASK_GET(input[0], 1, 1)) /* FBK bit */
{
@ -351,8 +356,9 @@ pke_io_write_buffer(device *me_,
prevents re-execution attempt of possible stalled
instruction */
me->fifo_num_elements = me->fifo_pc;
/* clear registers */
/* clear registers, flag, other state */
memset(me->regs, 0, sizeof(me->regs));
me->fifo_qw_done = 0;
me->flags = 0;
me->qw_pc = 0;
}
@ -424,10 +430,22 @@ pke_io_write_buffer(device *me_,
{
/* FIFO */
struct fifo_quadword* fqw;
int fifo_byte = ADDR_OFFSET_QW(addr); /* find byte-offset inside fifo quadword */
int i;
/* assert transfer size == 128 bits */
if(nr_bytes != sizeof(quadword))
return 0;
/* collect potentially-partial quadword in write buffer */
memcpy(((unsigned_1*)& me->fifo_qw_in_progress) + fifo_byte, src, nr_bytes);
/* mark bytes written */
for(i = fifo_byte; i < fifo_byte + nr_bytes; i++)
BIT_MASK_SET(me->fifo_qw_done, i, i, 1);
/* return if quadword not quite written yet */
if(BIT_MASK_GET(me->fifo_qw_done, 0, sizeof(quadword)-1) !=
BIT_MASK_BTW(0, sizeof(quadword)))
return nr_bytes;
/* all done - process quadword after clearing flag */
BIT_MASK_SET(me->fifo_qw_done, 0, sizeof(quadword)-1, 0);
/* ensure FIFO has enough elements */
if(me->fifo_num_elements == me->fifo_buffer_size)
@ -448,7 +466,7 @@ pke_io_write_buffer(device *me_,
/* add new quadword at end of FIFO */
fqw = & me->fifo[me->fifo_num_elements];
memcpy((void*) fqw->data, src, nr_bytes);
memcpy((void*) fqw->data, me->fifo_qw_in_progress, sizeof(quadword));
sim_read(CPU_STATE(cpu),
(SIM_ADDR) (me->pke_number == 0 ? DMA_D0_SRCADDR : DMA_D1_SRCADDR),
(void*) & fqw->source_address,
@ -485,9 +503,17 @@ pke_issue(struct pke_device* me)
/* 1 -- test go / no-go for PKE execution */
/* switch on STAT:PSS if PSS-pending and in idle state */
if((PKE_REG_MASK_GET(me, STAT, PPS) == PKE_REG_STAT_PPS_IDLE) &&
(me->flags & PKE_FLAG_PENDING_PSS) != 0)
{
me->flags &= ~PKE_FLAG_PENDING_PSS;
PKE_REG_MASK_SET(me, STAT, PSS, 1);
}
/* check for stall/halt control bits */
if(PKE_REG_MASK_GET(me, STAT, PSS) || /* XXX: PSS may be a special case */
PKE_REG_MASK_GET(me, STAT, PFS) ||
if(PKE_REG_MASK_GET(me, STAT, PFS) ||
PKE_REG_MASK_GET(me, STAT, PSS) || /* note special treatment below */
/* PEW bit not a reason to keep stalling - it's re-checked below */
/* PGW bit not a reason to keep stalling - it's re-checked below */
/* maskable stall controls: ER0, ER1, PIS */
@ -498,7 +524,6 @@ pke_issue(struct pke_device* me)
/* try again next cycle; no state change */
return;
}
/* XXX: handle PSS by *skipping* instruction? */
/* confirm availability of new quadword of PKE instructions */
if(me->fifo_num_elements <= me->fifo_pc)
@ -531,7 +556,7 @@ pke_issue(struct pke_device* me)
{
/* set INT flag in STAT register */
PKE_REG_MASK_SET(me, STAT, INT, 1);
/* XXX: send interrupt to R5900? */
/* XXX: how to send interrupt to R5900? */
}
/* decoding */
@ -580,7 +605,7 @@ pke_issue(struct pke_device* me)
pke_code_directhl(me, fw);
else if(IS_PKE_CMD(cmd, UNPACK))
pke_code_unpack(me, fw);
/* ... other commands ... */
/* ... no other commands ... */
else
pke_code_error(me, fw);
}
@ -705,6 +730,31 @@ pke_pc_operand(struct pke_device* me, int operand_num)
}
/* Return a bit-field extract of given operand# in FIFO, and its
source-addr. `bit_offset' starts at 0, referring to LSB after PKE
instruction word. Width must be >0, <=32. Assume FIFO is full
enough. Skip over DMA tags, but mark them as an error (ER0). */
unsigned_4
pke_pc_operand_bits(struct pke_device* me, int bit_offset, int bit_width, unsigned_4* source_addr)
{
unsigned_4* word = NULL;
unsigned_4 value;
struct fifo_quadword* fifo_operand;
/* find operand word with bitfield */
fifo_operand = pke_pc_fifo(me, (bit_offset / 32) + 1, &word);
ASSERT(word != 0);
/* extract bitfield from word */
value = BIT_MASK_GET(*word, bit_offset % 32, bit_width);
/* extract source addr from fifo word */
*source_addr = fifo_operand->source_address;
return value;
}
@ -747,30 +797,38 @@ pke_check_stall(struct pke_device* me, enum pke_check_target what)
{
int any_stall = 0;
/* read VU status word - commonly used */
unsigned_4 vu_stat;
/* read GPUIF status word - commonly used */
unsigned_4 gpuif_stat;
sim_read(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VPE0_STAT : VPE1_STAT),
(void*) & vu_stat,
(SIM_ADDR) (GIF_REG_STAT),
(void*) & gpuif_stat,
sizeof(unsigned_4));
/* perform checks */
if(what == chk_vu)
{
/* check if VBS bit is set, i.e., VU is busy */
if(BIT_MASK_GET(vu_stat, VU_REG_STAT_VBS_B, VU_REG_STAT_VBS_E) == 1)
ASSERT(0);
/* XXX: have to check COP2 control register VBS0 / VBS1 bits */
}
else if(what == chk_path1) /* VU -> GPUIF */
{
if(BIT_MASK_GET(gpuif_stat, GPUIF_REG_STAT_APATH_B, GPUIF_REG_STAT_APATH_E) == 1)
any_stall = 1;
}
else if(what == chk_path1)
else if(what == chk_path2) /* PKE -> GPUIF */
{
/* only valid on PKE1 */
/* check if VGW bit is set, i.e., PATH1 is busy */
if(BIT_MASK_GET(vu_stat, VU_REG_STAT_VGW_B, VU_REG_STAT_VGW_E) == 1)
if(BIT_MASK_GET(gpuif_stat, GPUIF_REG_STAT_APATH_B, GPUIF_REG_STAT_APATH_E) == 2)
any_stall = 1;
}
else if(what == chk_path3) /* DMA -> GPUIF */
{
if(BIT_MASK_GET(gpuif_stat, GPUIF_REG_STAT_APATH_B, GPUIF_REG_STAT_APATH_E) == 3)
any_stall = 1;
}
else
{
ASSERT(0); /* XXX: not done yet */
/* invalid what */
ASSERT(0);
}
/* any stall reasons? */
@ -889,7 +947,7 @@ void
pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
{
ASSERT(0);
/* XXX: cannot handle this one yet */
/* XXX: no easy interface toward GPUIF for this purpose */
}
@ -1030,7 +1088,7 @@ pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
pke_flip_dbf(me);
/* compute new PC for VU */
vu_pc = BIT_MASK_GET(imm, 0, 15); /* XXX: all bits significant? */
vu_pc = BIT_MASK_GET(imm, 0, 15);
/* write new PC; callback function gets VU running */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_PC_START : VU1_PC_START),
@ -1127,7 +1185,7 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
pke_flip_dbf(me);
/* compute new PC for VU */
vu_pc = BIT_MASK_GET(imm, 0, 15); /* XXX: all bits significant? */
vu_pc = BIT_MASK_GET(imm, 0, 15);
/* write new PC; callback function gets VU running */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_PC_START : VU1_PC_START),
@ -1152,8 +1210,16 @@ pke_code_stmask(struct pke_device* me, unsigned_4 pkecode)
{
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 1);
/* fill the register */
PKE_REG_MASK_SET(me, MASK, MASK, *mask);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 0);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 1);
@ -1179,12 +1245,18 @@ pke_code_strow(struct pke_device* me, unsigned_4 pkecode)
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 1);
/* copy ROW registers: must all exist if 4th operand exists */
me->regs[PKE_REG_R0][0] = * pke_pc_operand(me, 1);
me->regs[PKE_REG_R1][0] = * pke_pc_operand(me, 2);
me->regs[PKE_REG_R2][0] = * pke_pc_operand(me, 3);
me->regs[PKE_REG_R3][0] = * pke_pc_operand(me, 4);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 0);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 5);
@ -1210,12 +1282,18 @@ pke_code_stcol(struct pke_device* me, unsigned_4 pkecode)
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 1);
/* copy COL registers: must all exist if 4th operand exists */
me->regs[PKE_REG_C0][0] = * pke_pc_operand(me, 1);
me->regs[PKE_REG_C1][0] = * pke_pc_operand(me, 2);
me->regs[PKE_REG_C2][0] = * pke_pc_operand(me, 3);
me->regs[PKE_REG_C3][0] = * pke_pc_operand(me, 4);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, 0);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 5);
@ -1244,15 +1322,7 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
if(last_mpg_word != NULL)
{
/* perform implied FLUSHE */
/* read VU status word */
unsigned_4 vu_stat;
sim_read(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VPE0_STAT : VPE1_STAT),
(void*) & vu_stat,
sizeof(unsigned_4));
/* check if VBS bit is clear, i.e., VU is idle */
if(BIT_MASK_GET(vu_stat, VU_REG_STAT_VBS_B, VU_REG_STAT_VBS_E) == 0)
if(pke_check_stall(me, chk_vu))
{
/* VU idle */
int i;
@ -1268,10 +1338,10 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
unsigned_4* operand;
struct fifo_quadword* fq = pke_pc_fifo(me, num, & operand);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, (num*2 - i) / 2);
/* imm: in 64-bit units for MPG instruction */
/* XXX: set NUM */
/* VU*_MEM0 : instruction memory */
vu_addr_base = (me->pke_number == 0) ?
VU0_MEM0_WINDOW_START : VU0_MEM0_WINDOW_START;
@ -1292,6 +1362,9 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
(void*) & fq->source_address,
sizeof(unsigned_4));
} /* VU xfer loop */
/* check NUM */
ASSERT(PKE_REG_MASK_GET(me, NUM, NUM) == 0);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -1346,7 +1419,7 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
/* write to GPUIF FIFO only with full word */
if(i%4 == 3)
{
address_word gpuif_fifo = GPUIF_PATH2_FIFO_ADDR+(i/4);
address_word gpuif_fifo = GIF_PATH2_FIFO_ADDR+(i/4);
pke_track_write(me, fifo_data, sizeof(quadword),
(SIM_ADDR) gpuif_fifo, fq->source_address);
} /* write collected quadword */
@ -1380,13 +1453,14 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
int cmd = BIT_MASK_GET(pkecode, PKE_OPCODE_CMD_B, PKE_OPCODE_CMD_E);
int num = BIT_MASK_GET(pkecode, PKE_OPCODE_NUM_B, PKE_OPCODE_NUM_E);
short vn = BIT_MASK_GET(cmd, 2, 3);
short vn = BIT_MASK_GET(cmd, 2, 3); /* unpack shape controls */
short vl = BIT_MASK_GET(cmd, 0, 1);
short vnvl = BIT_MASK_GET(cmd, 0, 3);
int m = BIT_MASK_GET(cmd, 4, 4);
short cl = PKE_REG_MASK_GET(me, CYCLE, CL);
short cl = PKE_REG_MASK_GET(me, CYCLE, CL); /* cycle controls */
short wl = PKE_REG_MASK_GET(me, CYCLE, WL);
int r = BIT_MASK_GET(imm, 15, 15); /* indicator bits in imm value */
int sx = BIT_MASK_GET(imm, 14, 14);
int n, num_operands;
unsigned_4* last_operand_word;
@ -1405,38 +1479,40 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
if(last_operand_word != NULL)
{
address_word vu_addr_base;
int operand_num, vector_num;
int vector_num;
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* don't check whether VU is idle */
/* compute VU address base */
if(me->pke_number == 0)
vu_addr_base = VU0_MEM1_WINDOW_START + BIT_MASK_GET(imm, 0, 9);
else
{
vu_addr_base = VU1_MEM1_WINDOW_START + BIT_MASK_GET(imm, 0, 9);
if(BIT_MASK_GET(imm, 15, 15)) /* fetch R flag from imm word */
vu_addr_base += PKE_REG_MASK_GET(me, TOPS, TOPS);
if(r) vu_addr_base += PKE_REG_MASK_GET(me, TOPS, TOPS);
}
/* XXX: vu_addr overflow check */
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, num);
/* transfer given number of vectors */
operand_num = 1; /* word index into instruction stream: 1..num_operands */
vector_num = 0; /* vector number being processed: 0..num-1 */
while(operand_num <= num_operands)
vector_num = 0; /* output vector number being processed */
do
{
quadword vu_old_data;
quadword vu_new_data;
quadword unpacked_data;
address_word vu_addr;
struct fifo_quadword* fq;
unsigned_4 source_addr = 0;
int i;
/* XXX: set NUM */
/* decrement NUM */
PKE_REG_MASK_SET(me, NUM, NUM,
PKE_REG_MASK_GET(me, NUM, NUM) - 1);
/* compute VU destination address, as bytes in R5900 memory */
if(cl >= wl)
{
@ -1446,13 +1522,12 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
}
else
vu_addr = vu_addr_base + 16*vector_num;
/* XXX: can vu_addr overflow? */
/* read old VU data word at address */
sim_read(NULL, (SIM_ADDR) vu_addr, (void*) & vu_old_data, sizeof(vu_old_data));
/* Let sourceaddr track the first operand */
fq = pke_pc_fifo(me, operand_num, NULL);
/* For cyclic unpack, next operand quadword may come from instruction stream
or be zero. */
if((cl < wl) && ((vector_num % wl) >= cl)) /* wl != 0, set above */
@ -1463,78 +1538,51 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
}
else
{
/* compute unpacked words from instruction stream */
switch(vnvl)
/* compute packed vector dimensions */
int vectorbits, unitbits;
if(vl < 3) /* PKE_UNPACK_*_{32,16,8} */
{
case PKE_UNPACK_S_32:
case PKE_UNPACK_V2_32:
case PKE_UNPACK_V3_32:
case PKE_UNPACK_V4_32:
/* copy (vn+1) 32-bit values */
for(i = 0; i < vn+1; i++)
{
unsigned_4* operand = pke_pc_operand(me, operand_num);
unpacked_data[i] = *operand;
operand_num ++;
}
break;
case PKE_UNPACK_S_16:
case PKE_UNPACK_V2_16:
case PKE_UNPACK_V3_16:
case PKE_UNPACK_V4_16:
/* copy (vn+1) 16-bit values, packed two-per-word */
for(i=0; i<vn+1; i+=2)
{
unsigned_4* operand = pke_pc_operand(me, operand_num);
unpacked_data[i] = BIT_MASK_GET_SX(*operand, 0, 15, 31);
unpacked_data[i+1] = BIT_MASK_GET_SX(*operand, 16, 31, 31);
operand_num ++;
}
break;
case PKE_UNPACK_S_8:
case PKE_UNPACK_V2_8:
case PKE_UNPACK_V3_8:
case PKE_UNPACK_V4_8:
/* copy (vn+1) 8-bit values, packed four-per-word */
for(i=0; i<vn+1; i+=4)
{
unsigned_4* operand = pke_pc_operand(me, operand_num);
unpacked_data[i] = BIT_MASK_GET_SX(*operand, 0, 7, 31);
unpacked_data[i+1] = BIT_MASK_GET_SX(*operand, 8, 15, 31);
unpacked_data[i+2] = BIT_MASK_GET_SX(*operand, 16, 23, 31);
unpacked_data[i+3] = BIT_MASK_GET_SX(*operand, 24, 31, 31);
operand_num ++;
}
break;
case PKE_UNPACK_V4_5:
/* copy four 1/5/5/5-bit values, packed into a sixteen-bit */
for(i=0; i<vn+1; i+=4)
{
unsigned_4* operand = pke_pc_operand(me, operand_num);
unpacked_data[i] = BIT_MASK_GET_SX(*operand, 0, 4, 31);
unpacked_data[i+1] = BIT_MASK_GET_SX(*operand, 5, 9, 31);
unpacked_data[i+2] = BIT_MASK_GET_SX(*operand, 10, 14, 31);
unpacked_data[i+3] = BIT_MASK_GET_SX(*operand, 15, 15, 31);
operand_num ++;
}
break;
/* XXX: handle multiple rows of data in same word */
/* clue: increment operand_num less frequently */
default: /* bad UNPACK code */
{
/* treat as illegal instruction */
pke_code_error(me, pkecode);
return;
}
unitbits = (32 >> vl);
vectorbits = unitbits * (vn+1);
}
}
else if(vl == 3 && vn == 3) /* PKE_UNPACK_V4_5 */
{
unitbits = 5;
vectorbits = 16;
}
else /* illegal unpack variant */
{
/* treat as illegal instruction */
pke_code_error(me, pkecode);
return;
}
/* loop over columns */
for(i=0; i<=vn; i++)
{
unsigned_4 operand;
/* offset in bits in current operand word */
int bitoffset =
(vector_num * vectorbits) + (i * unitbits); /* # of bits from PKEcode */
/* last unit of V4_5 is only one bit wide */
if(vl == 3 && vn == 3 && i == 3) /* PKE_UNPACK_V4_5 */
unitbits = 1;
/* fetch bitfield operand */
operand = pke_pc_operand_bits(me, bitoffset, unitbits, & source_addr);
/* selectively sign-extend; not for V4_5 1-bit value */
if(sx && unitbits > 0)
unpacked_data[i] = SEXT32(operand, unitbits-1);
else
unpacked_data[i] = operand;
}
} /* unpack word from instruction operand */
/* compute replacement word - function of vn, vl, mask */
/* compute replacement word */
if(m) /* use mask register? */
{
/* compute index into mask register for this word */
@ -1577,9 +1625,9 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
}
/* copy masked value for column */
memcpy(& vu_new_data[i], masked_value, sizeof(unsigned_4));
vu_new_data[i] = *masked_value;
} /* loop over columns */
}
} /* mask */
else
{
/* no mask - just copy over entire unpacked quadword */
@ -1611,11 +1659,12 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* write replacement word */
pke_track_write(me, vu_new_data, sizeof(vu_new_data),
(SIM_ADDR) vu_addr, fq->source_address);
(SIM_ADDR) vu_addr, source_addr);
/* next vector please */
vector_num ++;
} /* vector transfer loop */
while(PKE_REG_MASK_GET(me, NUM, NUM) > 0);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);

View file

@ -27,10 +27,30 @@ typedef unsigned_4 quadword[4];
/* SCEI memory mapping information */
#define PKE0_REGISTER_WINDOW_START 0x10000800
#define PKE1_REGISTER_WINDOW_START 0x10000A00
#define PKE0_FIFO_ADDR 0x10008000
#define PKE1_FIFO_ADDR 0x10008010
#define PKE0_REGISTER_WINDOW_START 0x10003800
#define PKE1_REGISTER_WINDOW_START 0x10003C00
#define PKE0_FIFO_ADDR 0x10004000
#define PKE1_FIFO_ADDR 0x10005000
/* and now a few definitions that rightfully belong elsewhere */
#ifdef PKE_DEBUG
/* VU PC pseudo-registers */ /* omitted from 1998-01-22 e-mail plans */
#define VU0_PC_START 0x20025000
#define VU1_PC_START 0x20026000
/* VU source-addr tracking tables */ /* changed from 1998-01-22 e-mail plans */
#define VU0_MEM0_SRCADDR_START 0x21000000
#define VU0_MEM1_SRCADDR_START 0x21004000
#define VU1_MEM0_SRCADDR_START 0x21008000
#define VU1_MEM1_SRCADDR_START 0x2100C000
/* GPUIF STAT register */
#define GPUIF_REG_STAT_APATH_E 11
#define GPUIF_REG_STAT_APATH_B 10
#endif /* PKE_DEBUG */
/* Quadword indices of PKE registers. Actual registers sit at bottom
@ -189,6 +209,10 @@ typedef unsigned_4 quadword[4];
#define PKE_REG_MODE_MDE_E 1
#define PKE_REG_MODE_MDE_B 0
/* NUM register */
#define PKE_REG_NUM_NUM_E 9
#define PKE_REG_NUM_NUM_B 0
/* MARK register */
#define PKE_REG_MARK_MARK_E 15
#define PKE_REG_MARK_MARK_B 0
@ -262,34 +286,10 @@ typedef unsigned_4 quadword[4];
((((me)->regs[PKE_REG_MASK][0]) >> (8*(row) + 2*(col))) & 0x03)
/* and now a few definitions that rightfully belong elsewhere */
#ifdef PKE_DEBUG
/* GPUIF addresses */
#define GPUIF_PATH3_FIFO_ADDR 0x10008020 /* data from CORE */
#define GPUIF_PATH1_FIFO_ADDR 0x10008030 /* data from VU1 */
#define GPUIF_PATH2_FIFO_ADDR 0x10008040 /* data from PKE1 */
/* VU STAT register */
#define VU_REG_STAT_VGW_E 4
#define VU_REG_STAT_VGW_B 4
#define VU_REG_STAT_VBS_E 0
#define VU_REG_STAT_VBS_B 0
/* VU PC pseudo-registers */ /* omitted from 1998-01-22 e-mail plans */
#define VU0_PC_START 0x20025000
#define VU1_PC_START 0x20026000
/* VU source-addr tracking tables */ /* changed from 1998-01-22 e-mail plans */
#define VU0_MEM0_SRCADDR_START 0x21000000
#define VU0_MEM1_SRCADDR_START 0x21004000
#define VU1_MEM0_SRCADDR_START 0x21008000
#define VU1_MEM1_SRCADDR_START 0x2100C000
#endif /* PKE_DEBUG */
/* operations */
/* operations - replace with those in sim-bits.h when convenient */
/* unsigned 32-bit mask of given width */
#define BIT_MASK(width) (width == 31 ? 0xffffffff : (((unsigned_4)1) << (width+1)) - 1)
/* e.g.: BIT_MASK(4) = 00011111 */
@ -354,9 +354,13 @@ struct pke_device
int pke_number;
int flags;
/* quadword registers */
/* quadword registers: data in [0] word only */
quadword regs[PKE_NUM_REGS];
/* write buffer for FIFO address */
quadword fifo_qw_in_progress;
int fifo_qw_done; /* bitfield */
/* FIFO */
struct fifo_quadword* fifo;
int fifo_num_elements; /* no. of quadwords occupied in FIFO */
@ -372,8 +376,8 @@ struct pke_device
/* Flags for PKE.flags */
#define PKE_FLAG_NONE 0
/* none at present */
#define PKE_FLAG_NONE 0x00
#define PKE_FLAG_PENDING_PSS 0x01 /* PSS bit written-to; set STAT:PSS after current instruction */
#endif /* H_PKE_H */