* PKE sim unit testing continuing. Starting to run milestone sample.
* sky-pke.h (PKE_MEM_READ): Removed "read" entry from FIFO trace. * sky-pke.c (pke_attach): Set trace file to line buffering iff open. (pke_io_read_buffer, pke_io_write_buffer): Handle erroneous reads/writes by zero-padding. (pke_io_write_buffer): Switch to more bit-field definition macros. (pke_issue): Remove "stalled" entry from FIFO trace. (pke_pc_advance): Correct logic for DMA-tag-skipping, PKEcode classification. (pke_code_mskpath3): Sketch of possible PATH3 masking method. (pke_code_mpg): Keep order of lower/upper VU words as supplied. (pke_code_unpack): Logic change for wl/cl/num unpacking. Weird.
This commit is contained in:
parent
3c9f13f43f
commit
b4d2f483b3
2 changed files with 103 additions and 87 deletions
|
@ -174,9 +174,8 @@ pke_attach(SIM_DESC sd, struct pke_device* me)
|
||||||
{
|
{
|
||||||
me->fifo_trace_file = fopen(trace_filename, "w");
|
me->fifo_trace_file = fopen(trace_filename, "w");
|
||||||
if(me->fifo_trace_file == NULL)
|
if(me->fifo_trace_file == NULL)
|
||||||
{
|
|
||||||
perror("VIF FIFO trace error on fopen");
|
perror("VIF FIFO trace error on fopen");
|
||||||
}
|
else
|
||||||
setvbuf(me->fifo_trace_file, NULL, _IOLBF, 0);
|
setvbuf(me->fifo_trace_file, NULL, _IOLBF, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,14 +271,14 @@ pke_io_read_buffer(device *me_,
|
||||||
/* copy the bits */
|
/* copy the bits */
|
||||||
memcpy(dest, ((unsigned_1*) &result) + reg_byte, nr_bytes);
|
memcpy(dest, ((unsigned_1*) &result) + reg_byte, nr_bytes);
|
||||||
/* okay */
|
/* okay */
|
||||||
return nr_bytes;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* error */
|
/* return zero bits */
|
||||||
return 0;
|
memset(dest, 0, nr_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nr_bytes;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
else if(addr >= my_fifo_addr &&
|
else if(addr >= my_fifo_addr &&
|
||||||
|
@ -344,7 +343,7 @@ pke_io_write_buffer(device *me_,
|
||||||
case PKE_REG_FBRST:
|
case PKE_REG_FBRST:
|
||||||
/* Order these tests from least to most overriding, in case
|
/* Order these tests from least to most overriding, in case
|
||||||
multiple bits are set. */
|
multiple bits are set. */
|
||||||
if(BIT_MASK_GET(input[0], 2, 2)) /* STC bit */
|
if(BIT_MASK_GET(input[0], PKE_REG_FBRST_STC_B, PKE_REG_FBRST_STC_E))
|
||||||
{
|
{
|
||||||
/* clear a bunch of status bits */
|
/* clear a bunch of status bits */
|
||||||
PKE_REG_MASK_SET(me, STAT, PSS, 0);
|
PKE_REG_MASK_SET(me, STAT, PSS, 0);
|
||||||
|
@ -356,15 +355,15 @@ pke_io_write_buffer(device *me_,
|
||||||
me->flags &= ~PKE_FLAG_PENDING_PSS;
|
me->flags &= ~PKE_FLAG_PENDING_PSS;
|
||||||
/* will allow resumption of possible stalled instruction */
|
/* will allow resumption of possible stalled instruction */
|
||||||
}
|
}
|
||||||
if(BIT_MASK_GET(input[0], 2, 2)) /* STP bit */
|
if(BIT_MASK_GET(input[0], PKE_REG_FBRST_STP_B, PKE_REG_FBRST_STP_E))
|
||||||
{
|
{
|
||||||
me->flags |= PKE_FLAG_PENDING_PSS;
|
me->flags |= PKE_FLAG_PENDING_PSS;
|
||||||
}
|
}
|
||||||
if(BIT_MASK_GET(input[0], 1, 1)) /* FBK bit */
|
if(BIT_MASK_GET(input[0], PKE_REG_FBRST_FBK_B, PKE_REG_FBRST_FBK_E))
|
||||||
{
|
{
|
||||||
PKE_REG_MASK_SET(me, STAT, PFS, 1);
|
PKE_REG_MASK_SET(me, STAT, PFS, 1);
|
||||||
}
|
}
|
||||||
if(BIT_MASK_GET(input[0], 0, 0)) /* RST bit */
|
if(BIT_MASK_GET(input[0], PKE_REG_FBRST_RST_B, PKE_REG_FBRST_RST_E))
|
||||||
{
|
{
|
||||||
/* clear FIFO by skipping to word after PC: also
|
/* clear FIFO by skipping to word after PC: also
|
||||||
prevents re-execution attempt of possible stalled
|
prevents re-execution attempt of possible stalled
|
||||||
|
@ -426,16 +425,12 @@ pke_io_write_buffer(device *me_,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform return */
|
/* perform return */
|
||||||
if(writeable)
|
if(! writeable)
|
||||||
{
|
{
|
||||||
/* okay */
|
; /* error */
|
||||||
|
}
|
||||||
|
|
||||||
return nr_bytes;
|
return nr_bytes;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* error */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
@ -546,14 +541,6 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
|
||||||
(PKE_REG_MASK_GET(me, STAT, PIS) && !PKE_REG_MASK_GET(me, ERR, MII)))
|
(PKE_REG_MASK_GET(me, STAT, PIS) && !PKE_REG_MASK_GET(me, ERR, MII)))
|
||||||
{
|
{
|
||||||
/* try again next cycle; no state change */
|
/* try again next cycle; no state change */
|
||||||
|
|
||||||
/* trace command */
|
|
||||||
if(me->fifo_trace_file != NULL)
|
|
||||||
{
|
|
||||||
fprintf(me->fifo_trace_file, "# stalled STAT: %08lx\n",
|
|
||||||
(unsigned long) me->regs[PKE_REG_STAT][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,10 +641,11 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
||||||
{
|
{
|
||||||
int num = num_words;
|
int num = num_words;
|
||||||
struct fifo_quadword* fq = NULL;
|
struct fifo_quadword* fq = NULL;
|
||||||
int skipped = 0;
|
|
||||||
ASSERT(num_words >= 0);
|
ASSERT(num_words >= 0);
|
||||||
|
|
||||||
do
|
/* printf("pke %d pc_advance num_words %d\n", me->pke_number, num_words); */
|
||||||
|
|
||||||
|
while(1)
|
||||||
{
|
{
|
||||||
fq = & me->fifo[me->fifo_pc];
|
fq = & me->fifo[me->fifo_pc];
|
||||||
|
|
||||||
|
@ -666,13 +654,12 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
||||||
{
|
{
|
||||||
/* skip by going around loop an extra time */
|
/* skip by going around loop an extra time */
|
||||||
num ++;
|
num ++;
|
||||||
skipped = 1;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
skipped = 0;
|
|
||||||
|
|
||||||
if(num > 0) /* increment PC */
|
/* nothing left to skip / no DMA tag here */
|
||||||
{
|
if(num == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
/* one word skipped */
|
/* one word skipped */
|
||||||
num --;
|
num --;
|
||||||
|
|
||||||
|
@ -683,7 +670,8 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
||||||
me->qw_pc = 0;
|
me->qw_pc = 0;
|
||||||
me->fifo_pc ++;
|
me->fifo_pc ++;
|
||||||
|
|
||||||
/* trace the consumption of this FIFO quadword */
|
/* trace the consumption of the FIFO quadword we just skipped over */
|
||||||
|
/* fq still points to it */
|
||||||
if(me->fifo_trace_file != NULL)
|
if(me->fifo_trace_file != NULL)
|
||||||
{
|
{
|
||||||
/* assert complete classification */
|
/* assert complete classification */
|
||||||
|
@ -704,11 +692,8 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: zap old entries in FIFO */
|
/* XXX: zap old entries in FIFO */
|
||||||
|
|
||||||
} /* next quadword */
|
} /* next quadword */
|
||||||
} /* increment PC */
|
}
|
||||||
} /* eat num words */
|
|
||||||
while(num > 0 || skipped);
|
|
||||||
|
|
||||||
/* clear FQC if FIFO is now empty */
|
/* clear FQC if FIFO is now empty */
|
||||||
if(me->fifo_num_elements == me->fifo_pc)
|
if(me->fifo_num_elements == me->fifo_pc)
|
||||||
|
@ -717,6 +702,7 @@ pke_pc_advance(struct pke_device* me, int num_words)
|
||||||
}
|
}
|
||||||
else /* annote the word where the PC lands as an PKEcode */
|
else /* annote the word where the PC lands as an PKEcode */
|
||||||
{
|
{
|
||||||
|
fq = & me->fifo[me->fifo_pc];
|
||||||
ASSERT(fq->word_class[me->qw_pc] == wc_pkecode ||
|
ASSERT(fq->word_class[me->qw_pc] == wc_pkecode ||
|
||||||
fq->word_class[me->qw_pc] == wc_unknown);
|
fq->word_class[me->qw_pc] == wc_unknown);
|
||||||
fq->word_class[me->qw_pc] = wc_pkecode;
|
fq->word_class[me->qw_pc] = wc_pkecode;
|
||||||
|
@ -743,6 +729,8 @@ pke_pc_fifo(struct pke_device* me, int operand_num, unsigned_4** operand)
|
||||||
new_fifo_pc = me->fifo_pc;
|
new_fifo_pc = me->fifo_pc;
|
||||||
new_qw_pc = me->qw_pc;
|
new_qw_pc = me->qw_pc;
|
||||||
|
|
||||||
|
/* printf("pke %d pc_fifo operand_num %d\n", me->pke_number, operand_num); */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* one word skipped */
|
/* one word skipped */
|
||||||
|
@ -1002,8 +990,29 @@ pke_code_stmod(struct pke_device* me, unsigned_4 pkecode)
|
||||||
void
|
void
|
||||||
pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
|
pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
|
||||||
{
|
{
|
||||||
ASSERT(0);
|
#if 0
|
||||||
/* XXX: no easy interface toward GPUIF for this purpose */
|
/* XXX: pending on patrickm support code */
|
||||||
|
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
|
||||||
|
unsigned_4 gif_mode;
|
||||||
|
|
||||||
|
/* read old GIF control register */
|
||||||
|
ASSERT(sizeof(unsigned_4) == 4);
|
||||||
|
PKE_MEM_READ(me, GIF_REG_MODE, & gif_mode, 4);
|
||||||
|
|
||||||
|
/* mask appropriate bit */
|
||||||
|
if(BIT_MASK_GET(imm, PKE_REG_MSKPATH3_B, PKE_REG_MSKPATH3_E) != 0)
|
||||||
|
gif_mode |= GIF_REG_MODE_M3R_MASK;
|
||||||
|
else
|
||||||
|
gif_mode &= ~GIF_REG_MODE_M3R_MASK;
|
||||||
|
|
||||||
|
/* write back modified register */
|
||||||
|
PKE_MEM_WRITE(me, GIF_REG_MODE, & gif_mode, 4);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
pke_pc_advance(me, 1);
|
||||||
|
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1427,7 +1436,7 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
|
||||||
/* VU*_MEM0_TRACK : source-addr tracking table */
|
/* VU*_MEM0_TRACK : source-addr tracking table */
|
||||||
vutrack_addr_base = (me->pke_number == 0) ?
|
vutrack_addr_base = (me->pke_number == 0) ?
|
||||||
VU0_MEM0_SRCADDR_START : VU1_MEM0_SRCADDR_START;
|
VU0_MEM0_SRCADDR_START : VU1_MEM0_SRCADDR_START;
|
||||||
vutrack_addr = vu_addr_base + (imm + i) * 4;
|
vutrack_addr = vutrack_addr_base + (imm + i) * 4;
|
||||||
|
|
||||||
/* Fetch operand words; assume they are already little-endian for VU imem */
|
/* Fetch operand words; assume they are already little-endian for VU imem */
|
||||||
fq = pke_pc_fifo(me, i*2 + 1, & operand);
|
fq = pke_pc_fifo(me, i*2 + 1, & operand);
|
||||||
|
@ -1435,15 +1444,15 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
|
||||||
vu_upper_opcode = *pke_pc_operand(me, i*2 + 2);
|
vu_upper_opcode = *pke_pc_operand(me, i*2 + 2);
|
||||||
|
|
||||||
/* write data into VU memory */
|
/* write data into VU memory */
|
||||||
/* upper (vector) opcode comes in first word */
|
/* lower (scalar) opcode comes in first word */
|
||||||
ASSERT(sizeof(unsigned_4) == 4);
|
|
||||||
PKE_MEM_WRITE(me, vu_addr,
|
PKE_MEM_WRITE(me, vu_addr,
|
||||||
& vu_upper_opcode,
|
|
||||||
4);
|
|
||||||
/* lower (scalar) opcode comes in next word */
|
|
||||||
PKE_MEM_WRITE(me, vu_addr + 4,
|
|
||||||
& vu_lower_opcode,
|
& vu_lower_opcode,
|
||||||
4);
|
4);
|
||||||
|
/* upper (vector) opcode comes in second word */
|
||||||
|
ASSERT(sizeof(unsigned_4) == 4);
|
||||||
|
PKE_MEM_WRITE(me, vu_addr + 4,
|
||||||
|
& vu_upper_opcode,
|
||||||
|
4);
|
||||||
|
|
||||||
/* write tracking address in target byte-order */
|
/* write tracking address in target byte-order */
|
||||||
source_addr = H2T_4(fq->source_address);
|
source_addr = H2T_4(fq->source_address);
|
||||||
|
@ -1617,8 +1626,8 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
|
||||||
if(cl >= wl)
|
if(cl >= wl)
|
||||||
{
|
{
|
||||||
/* map zero to max+1 */
|
/* map zero to max+1 */
|
||||||
if(wl == 0) wl = 0x0100;
|
int addrwl = (wl == 0) ? 0x0100 : wl;
|
||||||
vu_addr = vu_addr_base + 16*(cl*(vector_num_out/wl) + (vector_num_out%wl));
|
vu_addr = vu_addr_base + 16*(cl*(vector_num_out/addrwl) + (vector_num_out%addrwl));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vu_addr = vu_addr_base + 16*vector_num_out;
|
vu_addr = vu_addr_base + 16*vector_num_out;
|
||||||
|
@ -1642,7 +1651,8 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
|
||||||
|
|
||||||
/* For cyclic unpack, next operand quadword may come from instruction stream
|
/* For cyclic unpack, next operand quadword may come from instruction stream
|
||||||
or be zero. */
|
or be zero. */
|
||||||
if((cl < wl) && ((vector_num_out % wl) >= cl)) /* wl != 0, set above */
|
if((num == 0 && cl == 0 && wl == 0) || /* shortcut clear */
|
||||||
|
((cl < wl) && ((vector_num_out % wl) >= cl))) /* wl != 0, set above */
|
||||||
{
|
{
|
||||||
/* clear operand - used only in a "indeterminate" state */
|
/* clear operand - used only in a "indeterminate" state */
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
|
@ -1701,7 +1711,8 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
|
||||||
if(m) /* use mask register? */
|
if(m) /* use mask register? */
|
||||||
{
|
{
|
||||||
/* compute index into mask register for this word */
|
/* compute index into mask register for this word */
|
||||||
int mask_index = PKE_LIMIT(vector_num_out % wl, 3); /* wl != 0, set above */
|
int addrwl = (wl == 0) ? 0x0100 : wl;
|
||||||
|
int mask_index = PKE_LIMIT(vector_num_out % addrwl, 3);
|
||||||
|
|
||||||
for(i=0; i<4; i++) /* loop over columns */
|
for(i=0; i<4; i++) /* loop over columns */
|
||||||
{
|
{
|
||||||
|
|
|
@ -244,6 +244,20 @@ typedef unsigned_4 quadword[4];
|
||||||
#define PKE_REG_ERR_MII_E 0
|
#define PKE_REG_ERR_MII_E 0
|
||||||
#define PKE_REG_ERR_MII_B 0
|
#define PKE_REG_ERR_MII_B 0
|
||||||
|
|
||||||
|
/* FBRST command bitfields */
|
||||||
|
#define PKE_REG_FBRST_STC_E 3
|
||||||
|
#define PKE_REG_FBRST_STC_B 3
|
||||||
|
#define PKE_REG_FBRST_STP_E 2
|
||||||
|
#define PKE_REG_FBRST_STP_B 2
|
||||||
|
#define PKE_REG_FBRST_FBK_E 1
|
||||||
|
#define PKE_REG_FBRST_FBK_B 1
|
||||||
|
#define PKE_REG_FBRST_RST_E 0
|
||||||
|
#define PKE_REG_FBRST_RST_B 0
|
||||||
|
|
||||||
|
/* MSKPATH3 command bitfields */
|
||||||
|
#define PKE_REG_MSKPATH3_E 15
|
||||||
|
#define PKE_REG_MSKPATH3_B 15
|
||||||
|
|
||||||
|
|
||||||
/* UNPACK opcodes */
|
/* UNPACK opcodes */
|
||||||
#define PKE_UNPACK(vn,vl) ((vn) << 2 | (vl))
|
#define PKE_UNPACK(vn,vl) ((vn) << 2 | (vl))
|
||||||
|
@ -396,15 +410,6 @@ struct pke_device
|
||||||
sim_core_read_aligned_##size(cpu, CIA_GET(cpu), sim_core_read_map, \
|
sim_core_read_aligned_##size(cpu, CIA_GET(cpu), sim_core_read_map, \
|
||||||
(SIM_ADDR)(addr)); \
|
(SIM_ADDR)(addr)); \
|
||||||
memcpy((unsigned_##size*) (data), (void*) & value, size); \
|
memcpy((unsigned_##size*) (data), (void*) & value, size); \
|
||||||
if(me->fifo_trace_file != NULL) \
|
|
||||||
{ \
|
|
||||||
int i; \
|
|
||||||
fprintf((me)->fifo_trace_file, "# Read %2d bytes from ", size); \
|
|
||||||
fprintf((me)->fifo_trace_file, "0x%08lx: ", (unsigned long)(addr)); \
|
|
||||||
for(i=0; i<size; i++) \
|
|
||||||
fprintf((me)->fifo_trace_file, " %02x", ((unsigned_1*)(& value))[i]); \
|
|
||||||
fprintf((me)->fifo_trace_file, "\n"); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define PKE_MEM_WRITE(me,addr,data,size) \
|
#define PKE_MEM_WRITE(me,addr,data,size) \
|
||||||
|
|
Loading…
Reference in a new issue