* PKE unit testing continuing. Confusion over PKE1 double-buffering

mechanism is starting to subside.

	* sky-pke.h (PKE_FLAG_INT_NOLOOP): Added device flag to indicate
 	presence of stalled & interrupted PKEcode.

	* sky-pke.c (pke_issue): Added PKEcode interrupt bit handling.
	(pke_flip_dbf): Changed double-buffering logic to match SCEI
 	clarification.
	(pke_code_*): Added interrupt bit stalling clause.
	(pke_code_pkems*): Added ITOP/ITOPS transmission code.
	(pke_code_unpack): Added more careful logic for processing
 	overflows of VU data memory addresses.
This commit is contained in:
Frank Ch. Eigler 1998-02-25 19:34:06 +00:00
parent 574edea8b2
commit d22ea5d001
2 changed files with 210 additions and 30 deletions

View File

@ -571,11 +571,26 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
num = BIT_MASK_GET(fw, PKE_OPCODE_NUM_B, PKE_OPCODE_NUM_E);
imm = BIT_MASK_GET(fw, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(intr)
{
/* set INT flag in STAT register */
PKE_REG_MASK_SET(me, STAT, INT, 1);
/* XXX: send interrupt to 5900? */
/* are we resuming an interrupt-flagged instruction? */
if(me->flags & PKE_FLAG_INT_NOLOOP)
{
/* clear loop-prevention flag */
me->flags &= ~PKE_FLAG_INT_NOLOOP;
/* mask interrupt bit from instruction word so re-decoded instructions don't stall */
BIT_MASK_SET(fw, PKE_OPCODE_I_B, PKE_OPCODE_I_E, 0);
}
else /* new interrupt-flagged instruction */
{
/* set INT flag in STAT register */
PKE_REG_MASK_SET(me, STAT, INT, 1);
/* set loop-prevention flag */
me->flags |= PKE_FLAG_INT_NOLOOP;
/* XXX: send interrupt to 5900? */
}
}
/* decoding */
@ -828,8 +843,8 @@ pke_pc_operand_bits(struct pke_device* me, int bit_offset, int bit_width, unsign
/* check for stall conditions on indicated devices (path* only on PKE1), do not change status
return 0 iff no stall */
/* check for stall conditions on indicated devices (path* only on
PKE1), do not change status; return 0 iff no stall */
int
pke_check_stall(struct pke_device* me, enum pke_check_target what)
{
@ -879,13 +894,11 @@ pke_check_stall(struct pke_device* me, enum pke_check_target what)
}
/* flip the DBF bit; recompute TOPS, ITOP & TOP */
/* PKE1 only: flip the DBF bit; recompute TOPS, TOP */
void
pke_flip_dbf(struct pke_device* me)
{
/* compute new ITOP and TOP */
PKE_REG_MASK_SET(me, ITOP, ITOP,
PKE_REG_MASK_GET(me, ITOPS, ITOPS));
/* compute new TOP */
PKE_REG_MASK_SET(me, TOP, TOP,
PKE_REG_MASK_GET(me, TOPS, TOPS));
/* flip DBF */
@ -897,6 +910,10 @@ pke_flip_dbf(struct pke_device* me)
(PKE_REG_MASK_GET(me, BASE, BASE) +
(PKE_REG_MASK_GET(me, DBF, DF) *
PKE_REG_MASK_GET(me, OFST, OFFSET))));
/* this is equivalent to last word from okadaa (98-02-25):
1) TOP=TOPS;
2) TOPS=BASE + !DBF*OFFSET
3) DBF=!DBF */
}
@ -908,6 +925,14 @@ pke_flip_dbf(struct pke_device* me)
void
pke_code_nop(struct pke_device* me, unsigned_4 pkecode)
{
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* done */
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -918,6 +943,15 @@ void
pke_code_stcycl(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* copy immediate value into CYCLE reg */
PKE_REG_MASK_SET(me, CYCLE, WL, BIT_MASK_GET(imm, 8, 15));
PKE_REG_MASK_SET(me, CYCLE, CL, BIT_MASK_GET(imm, 0, 7));
@ -931,6 +965,15 @@ void
pke_code_offset(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* copy 10 bits to OFFSET field */
PKE_REG_MASK_SET(me, OFST, OFFSET, BIT_MASK_GET(imm, 0, 9));
/* clear DBF bit */
@ -949,14 +992,17 @@ void
pke_code_base(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* copy 10 bits to BASE field */
PKE_REG_MASK_SET(me, BASE, BASE, BIT_MASK_GET(imm, 0, 9));
/* clear DBF bit */
PKE_REG_MASK_SET(me, DBF, DF, 0);
/* clear other DBF bit */
PKE_REG_MASK_SET(me, STAT, DBF, 0);
/* set TOPS = BASE */
PKE_REG_MASK_SET(me, TOPS, TOPS, PKE_REG_MASK_GET(me, BASE, BASE));
/* done */
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -967,6 +1013,15 @@ void
pke_code_itop(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* copy 10 bits to ITOPS field */
PKE_REG_MASK_SET(me, ITOPS, ITOPS, BIT_MASK_GET(imm, 0, 9));
/* done */
@ -979,6 +1034,15 @@ void
pke_code_stmod(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* copy 2 bits to MODE register */
PKE_REG_MASK_SET(me, MODE, MDE, BIT_MASK_GET(imm, 0, 2));
/* done */
@ -993,6 +1057,14 @@ pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
unsigned_4 gif_mode;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* set appropriate bit */
if(BIT_MASK_GET(imm, PKE_REG_MSKPATH3_B, PKE_REG_MSKPATH3_E) != 0)
gif_mode = GIF_REG_MODE_M3R_MASK;
@ -1011,6 +1083,8 @@ pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_pkemark(struct pke_device* me, unsigned_4 pkecode)
{
/* ignore possible interrupt stall */
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* copy 16 bits to MARK register */
PKE_REG_MASK_SET(me, MARK, MARK, BIT_MASK_GET(imm, 0, 15));
@ -1025,6 +1099,14 @@ pke_code_pkemark(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_flushe(struct pke_device* me, unsigned_4 pkecode)
{
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW bit */
if(pke_check_stall(me, chk_vu))
{
@ -1048,6 +1130,14 @@ pke_code_flush(struct pke_device* me, unsigned_4 pkecode)
{
int something_busy = 0;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW, PGW bits */
if(pke_check_stall(me, chk_vu))
{
@ -1087,6 +1177,14 @@ pke_code_flusha(struct pke_device* me, unsigned_4 pkecode)
{
int something_busy = 0;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW, PGW bits */
if(pke_check_stall(me, chk_vu))
{
@ -1124,6 +1222,14 @@ pke_code_flusha(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
{
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW bit */
if(pke_check_stall(me, chk_vu))
{
@ -1153,6 +1259,9 @@ pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
& vu_pc,
4);
/* copy ITOPS field to ITOP */
PKE_REG_MASK_SET(me, ITOP, ITOP, PKE_REG_MASK_GET(me, ITOPS, ITOPS));
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 1);
@ -1164,6 +1273,14 @@ pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_pkemscnt(struct pke_device* me, unsigned_4 pkecode)
{
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW bit */
if(pke_check_stall(me, chk_vu))
{
@ -1195,6 +1312,9 @@ pke_code_pkemscnt(struct pke_device* me, unsigned_4 pkecode)
& vu_pc,
4);
/* copy ITOPS field to ITOP */
PKE_REG_MASK_SET(me, ITOP, ITOP, PKE_REG_MASK_GET(me, ITOPS, ITOPS));
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 1);
@ -1207,6 +1327,14 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
{
int something_busy = 0;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute next PEW, PGW bits */
if(pke_check_stall(me, chk_vu))
{
@ -1251,6 +1379,9 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
& vu_pc,
4);
/* copy ITOPS field to ITOP */
PKE_REG_MASK_SET(me, ITOP, ITOP, PKE_REG_MASK_GET(me, ITOPS, ITOPS));
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
pke_pc_advance(me, 1);
@ -1261,9 +1392,17 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_stmask(struct pke_device* me, unsigned_4 pkecode)
{
/* check that FIFO has one more word for STMASK operand */
unsigned_4* mask;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* check that FIFO has one more word for STMASK operand */
mask = pke_pc_operand(me, 1);
if(mask != NULL)
{
@ -1298,6 +1437,14 @@ pke_code_strow(struct pke_device* me, unsigned_4 pkecode)
/* check that FIFO has four more words for STROW operand */
unsigned_4* last_op;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
last_op = pke_pc_operand(me, 4);
if(last_op != NULL)
{
@ -1335,6 +1482,14 @@ pke_code_stcol(struct pke_device* me, unsigned_4 pkecode)
/* check that FIFO has four more words for STCOL operand */
unsigned_4* last_op;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
last_op = pke_pc_operand(me, 4);
if(last_op != NULL)
{
@ -1377,6 +1532,14 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
if(me->qw_pc != 3 && me->qw_pc != 1)
return pke_code_error(me, pkecode);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* map zero to max+1 */
if(num==0) num=0x100;
@ -1488,6 +1651,14 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
if(me->qw_pc != 3)
return pke_code_error(me, pkecode);
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* map zero to max+1 */
if(imm==0) imm=0x10000;
@ -1558,6 +1729,14 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
int n, num_operands;
unsigned_4* last_operand_word = NULL;
/* handle interrupts */
if(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E))
{
PKE_REG_MASK_SET(me, STAT, PIS, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_STALL);
return;
}
/* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
if(wl <= cl)
n = num;
@ -1582,23 +1761,18 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* compute VU address base */
if(me->pke_number == 0)
{
vu_addr_base = VU0_MEM1_WINDOW_START + 16 * BIT_MASK_GET(imm, 0, 9);
vu_addr_base = VU0_MEM1_WINDOW_START;
vu_addr_max_size = VU0_MEM1_SIZE;
vutrack_addr_base = VU0_MEM1_SRCADDR_START + 4 * BIT_MASK_GET(imm, 0, 9);
vutrack_addr_base = VU0_MEM1_SRCADDR_START;
r = 0;
}
else
{
vu_addr_base = VU1_MEM1_WINDOW_START + 16 * BIT_MASK_GET(imm, 0, 9);
vu_addr_base = VU1_MEM1_WINDOW_START;
vu_addr_max_size = VU1_MEM1_SIZE;
vutrack_addr_base = VU1_MEM1_SRCADDR_START + 4 * BIT_MASK_GET(imm, 0, 9);
if(r) /* double-buffering */
{
vu_addr_base += 16 * PKE_REG_MASK_GET(me, TOPS, TOPS);
vutrack_addr_base += 4 * PKE_REG_MASK_GET(me, TOPS, TOPS);
}
vutrack_addr_base = VU1_MEM1_SRCADDR_START;
}
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, num == 0 ? 0x100 : num );
@ -1625,10 +1799,15 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
{
/* map zero to max+1 */
int addrwl = (wl == 0) ? 0x0100 : wl;
vu_addr = vu_addr_base + 16*(cl*(vector_num_out/addrwl) + (vector_num_out%addrwl));
vu_addr = vu_addr_base + 16 * (BIT_MASK_GET(imm, 0, 9) +
(r ? PKE_REG_MASK_GET(me, TOPS, TOPS) : 0) +
cl*(vector_num_out/addrwl) +
(vector_num_out%addrwl));
}
else
vu_addr = vu_addr_base + 16*vector_num_out;
vu_addr = vu_addr_base + 16 * (BIT_MASK_GET(imm, 0, 9) +
(r ? PKE_REG_MASK_GET(me, TOPS, TOPS) : 0) +
vector_num_out);
/* check for vu_addr overflow */
while(vu_addr >= vu_addr_base + vu_addr_max_size)

View File

@ -183,7 +183,7 @@ typedef unsigned_4 quadword[4];
#define PKE_REG_STAT_PPS_IDLE 0x00 /* ready to execute next instruction */
#define PKE_REG_STAT_PPS_WAIT 0x01 /* not enough words in FIFO */
#define PKE_REG_STAT_PPS_DECODE 0x02 /* decoding instruction */
#define PKE_REG_STAT_PPS_STALL 0x02 /* alias state for FLUSHE stall */
#define PKE_REG_STAT_PPS_STALL 0x02 /* alias state for stall (e.g., FLUSHE) */
#define PKE_REG_STAT_PPS_XFER 0x03 /* transferring instruction operands */
/* DBF register */
@ -399,6 +399,7 @@ struct pke_device
#define PKE_FLAG_NONE 0x00
#define PKE_FLAG_PENDING_PSS 0x01 /* PSS bit written-to; set STAT:PSS after current instruction */
#define PKE_FLAG_INT_NOLOOP 0x02 /* INT PKEcode received; INT/PIS set; suppress loop after resumption */
/* Kludge alert */