1 /* Copyright (C) 1998, Cygnus Solutions */
9 #include "sim-assert.h"
13 #include "sky-gpuif.h"
15 #include "sky-device.h"
27 /* Internal function declarations */
29 static int pke_io_read_buffer(device
*, void*, int, address_word
,
30 unsigned, sim_cpu
*, sim_cia
);
31 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
32 unsigned, sim_cpu
*, sim_cia
);
33 static void pke_reset(struct pke_device
*);
34 static void pke_issue(SIM_DESC
, struct pke_device
*);
35 static void pke_pc_advance(struct pke_device
*, int num_words
);
36 static struct fifo_quadword
* pke_pcrel_fifo(struct pke_device
*, int operand_num
,
37 unsigned_4
** operand
);
38 static unsigned_4
* pke_pcrel_operand(struct pke_device
*, int operand_num
);
39 static unsigned_4
pke_pcrel_operand_bits(struct pke_device
*, int bit_offset
,
40 int bit_width
, unsigned_4
* sourceaddr
);
41 static void pke_attach(SIM_DESC sd
, struct pke_device
* me
);
42 enum pke_check_target
{ chk_vu
, chk_path1
, chk_path2
, chk_path3
};
43 static int pke_check_stall(struct pke_device
* me
, enum pke_check_target what
);
44 static void pke_flip_dbf(struct pke_device
* me
);
45 static void pke_begin_interrupt_stall(struct pke_device
* me
);
46 /* PKEcode handlers */
47 static void pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
);
48 static void pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
);
49 static void pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
);
50 static void pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
);
51 static void pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
);
52 static void pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
);
53 static void pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
);
54 static void pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
);
55 static void pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
);
56 static void pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
);
57 static void pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
);
58 static void pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
);
59 static void pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
);
60 static void pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
);
61 static void pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
);
62 static void pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
);
63 static void pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
);
64 static void pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
);
65 static void pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
);
66 static void pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
);
67 static void pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
);
68 static void pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
);
69 unsigned_4
pke_fifo_flush(struct pke_fifo
*);
70 void pke_fifo_reset(struct pke_fifo
*);
71 struct fifo_quadword
* pke_fifo_fit(struct pke_fifo
*);
72 struct fifo_quadword
* pke_fifo_access(struct pke_fifo
*, unsigned_4 qwnum
);
73 void pke_fifo_old(struct pke_fifo
*, unsigned_4 qwnum
);
75 /* Default --log-file names */
76 const char *pke0_default_trace
= "vif0.s";
77 const char *pke1_default_trace
= "vif1.s";
82 struct pke_device pke0_device
=
84 { "vif0", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
87 {}, 0, /* FIFO write buffer */
88 { NULL
, 0, 0, 0 }, /* FIFO */
89 NULL
, NULL
, /* FIFO trace file descriptor and name */
90 -1, -1, 0, 0, 0, /* invalid FIFO cache */
92 NULL
, NULL
/* disassembly trace file descriptor and name */
96 struct pke_device pke1_device
=
98 { "vif1", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
101 {}, 0, /* FIFO write buffer */
102 { NULL
, 0, 0, 0 }, /* FIFO */
103 NULL
, NULL
, /* FIFO trace file descriptor and name */
104 -1, -1, 0, 0, 0, /* invalid FIFO cache */
106 NULL
, NULL
/* disassembly trace file descriptor and name */
111 /* External functions */
114 /* Attach PKE addresses to main memory */
117 pke0_attach(SIM_DESC sd
)
119 pke_attach(sd
, & pke0_device
);
120 pke_reset(& pke0_device
);
124 pke1_attach(SIM_DESC sd
)
126 pke_attach(sd
, & pke1_device
);
127 pke_reset(& pke1_device
);
132 /* Issue a PKE instruction if possible */
135 pke0_issue(SIM_DESC sd
)
137 pke_issue(sd
, & pke0_device
);
141 pke1_issue(SIM_DESC sd
)
143 pke_issue(sd
, & pke1_device
);
148 /* Internal functions */
151 /* Attach PKE memory regions to simulator */
154 pke_attach(SIM_DESC sd
, struct pke_device
* me
)
157 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
158 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
,
159 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
165 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
166 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
,
167 sizeof(quadword
) /*nr_bytes*/,
172 /* VU MEM0 tracking table */
173 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
174 ((me
->pke_number
== 0) ? VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
),
175 ((me
->pke_number
== 0) ? VU0_MEM0_SIZE
: VU1_MEM0_SIZE
) / 2,
180 /* VU MEM1 tracking table */
181 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
182 ((me
->pke_number
== 0) ? VU0_MEM1_SRCADDR_START
: VU1_MEM1_SRCADDR_START
),
183 ((me
->pke_number
== 0) ? VU0_MEM1_SIZE
: VU1_MEM1_SIZE
) / 4,
190 /* Read PKE Pseudo-PC index into buf in target order */
192 read_pke_pcx (struct pke_device
*me
, void *buf
)
194 *((int *) buf
) = H2T_4( (me
->fifo_pc
<< 2) | me
->qw_pc
);
199 /* Read PKE Pseudo-PC source address into buf in target order */
201 read_pke_pc (struct pke_device
*me
, void *buf
)
203 struct fifo_quadword
* fqw
= pke_fifo_access(& me
->fifo
, me
->fifo_pc
);
210 addr
= (fqw
->source_address
& ~15) | (me
->qw_pc
<< 2);
211 *((unsigned_4
*) buf
) = H2T_4( addr
);
218 /* Read PKE reg into buf in target order */
220 read_pke_reg (struct pke_device
*me
, int reg_num
, void *buf
)
222 /* handle reads to individual registers; clear `readable' on error */
225 /* handle common case of register reading, side-effect free */
226 /* PKE1-only registers*/
232 if (me
->pke_number
== 0)
239 /* PKE0 & PKE1 common registers*/
258 *((int *) buf
) = H2T_4(me
->regs
[reg_num
][0]);
261 /* handle common case of write-only registers */
267 ASSERT(0); /* tests above should prevent this possibility */
274 /* Handle a PKE read; return no. of bytes read */
277 pke_io_read_buffer(device
*me_
,
285 /* downcast to gather embedding pke_device struct */
286 struct pke_device
* me
= (struct pke_device
*) me_
;
288 /* find my address ranges */
289 address_word my_reg_start
=
290 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
291 address_word my_fifo_addr
=
292 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
294 /* enforce that an access does not span more than one quadword */
295 address_word low
= ADDR_TRUNC_QW(addr
);
296 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
300 /* classify address & handle */
301 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
304 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
305 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
309 result
[0] = result
[1] = result
[2] = result
[3] = 0;
311 read_pke_reg (me
, reg_num
, result
);
313 /* perform transfer & return */
314 memcpy(dest
, ((unsigned_1
*) &result
) + reg_byte
, nr_bytes
);
319 else if(addr
>= my_fifo_addr
&&
320 addr
< my_fifo_addr
+ sizeof(quadword
))
324 /* FIFO is not readable: return a word of zeroes */
325 memset(dest
, 0, nr_bytes
);
333 /* Write PKE reg from buf, which is in target order */
335 write_pke_reg (struct pke_device
*me
, int reg_num
, const void *buf
)
338 /* make words host-endian */
339 unsigned_4 input
= T2H_4( *((unsigned_4
*) buf
) );
341 /* handle writes to individual registers; clear `writeable' on error */
345 /* Order these tests from least to most overriding, in case
346 multiple bits are set. */
347 if(BIT_MASK_GET(input
, PKE_REG_FBRST_STC_B
, PKE_REG_FBRST_STC_E
))
349 /* clear a bunch of status bits */
350 PKE_REG_MASK_SET(me
, STAT
, PSS
, 0);
351 PKE_REG_MASK_SET(me
, STAT
, PFS
, 0);
352 PKE_REG_MASK_SET(me
, STAT
, PIS
, 0);
353 PKE_REG_MASK_SET(me
, STAT
, INT
, 0);
354 PKE_REG_MASK_SET(me
, STAT
, ER0
, 0);
355 PKE_REG_MASK_SET(me
, STAT
, ER1
, 0);
356 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
357 /* will allow resumption of possible stalled instruction */
359 if(BIT_MASK_GET(input
, PKE_REG_FBRST_STP_B
, PKE_REG_FBRST_STP_E
))
361 me
->flags
|= PKE_FLAG_PENDING_PSS
;
363 if(BIT_MASK_GET(input
, PKE_REG_FBRST_FBK_B
, PKE_REG_FBRST_FBK_E
))
365 PKE_REG_MASK_SET(me
, STAT
, PFS
, 1);
367 if(BIT_MASK_GET(input
, PKE_REG_FBRST_RST_B
, PKE_REG_FBRST_RST_E
))
374 /* copy bottom three bits */
375 BIT_MASK_SET(me
->regs
[PKE_REG_ERR
][0], 0, 2, BIT_MASK_GET(input
, 0, 2));
379 /* copy bottom sixteen bits */
380 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(input
, 0, 15));
381 /* reset MRK bit in STAT */
382 PKE_REG_MASK_SET(me
, STAT
, MRK
, 0);
385 /* handle common case of read-only registers */
386 /* PKE1-only registers - not really necessary to handle separately */
392 if(me
->pke_number
== 0)
395 /* PKE0 & PKE1 common registers*/
397 /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */
417 ASSERT(0); /* test above should prevent this possibility */
423 return 0; /* error */
430 /* Handle a PKE write; return no. of bytes written */
433 pke_io_write_buffer(device
*me_
,
441 /* downcast to gather embedding pke_device struct */
442 struct pke_device
* me
= (struct pke_device
*) me_
;
444 /* find my address ranges */
445 address_word my_reg_start
=
446 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
447 address_word my_fifo_addr
=
448 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
450 /* enforce that an access does not span more than one quadword */
451 address_word low
= ADDR_TRUNC_QW(addr
);
452 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
456 /* classify address & handle */
457 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
460 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
461 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
465 input
[0] = input
[1] = input
[2] = input
[3] = 0;
467 /* write user-given bytes into input */
468 memcpy(((unsigned_1
*) &input
) + reg_byte
, src
, nr_bytes
);
470 write_pke_reg (me
, reg_num
, input
);
475 else if(addr
>= my_fifo_addr
&&
476 addr
< my_fifo_addr
+ sizeof(quadword
))
479 struct fifo_quadword
* fqw
;
480 int fifo_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside fifo quadword */
481 unsigned_4 dma_tag_present
= 0;
484 /* collect potentially-partial quadword in write buffer; LE byte order */
485 memcpy(((unsigned_1
*)& me
->fifo_qw_in_progress
) + fifo_byte
, src
, nr_bytes
);
486 /* mark bytes written */
487 for(i
= fifo_byte
; i
< fifo_byte
+ nr_bytes
; i
++)
488 BIT_MASK_SET(me
->fifo_qw_done
, i
, i
, 1);
490 /* return if quadword not quite written yet */
491 if(BIT_MASK_GET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1) !=
492 BIT_MASK_BTW(0, sizeof(quadword
)-1))
495 /* all done - process quadword after clearing flag */
496 BIT_MASK_SET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1, 0);
498 /* allocate required address in FIFO */
499 fqw
= pke_fifo_fit(& me
->fifo
);
502 /* fill in unclassified FIFO quadword data in host byte order */
503 fqw
->word_class
[0] = fqw
->word_class
[1] =
504 fqw
->word_class
[2] = fqw
->word_class
[3] = wc_unknown
;
505 fqw
->data
[0] = T2H_4(me
->fifo_qw_in_progress
[0]);
506 fqw
->data
[1] = T2H_4(me
->fifo_qw_in_progress
[1]);
507 fqw
->data
[2] = T2H_4(me
->fifo_qw_in_progress
[2]);
508 fqw
->data
[3] = T2H_4(me
->fifo_qw_in_progress
[3]);
510 /* read DMAC-supplied indicators */
511 ASSERT(sizeof(unsigned_4
) == 4);
512 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? DMA_D0_MADR
: DMA_D1_MADR
),
513 & fqw
->source_address
, /* converted to host-endian */
515 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? DMA_D0_PKTFLAG
: DMA_D1_PKTFLAG
),
521 /* lower two words are DMA tags */
522 fqw
->word_class
[0] = fqw
->word_class
[1] = wc_dma
;
525 /* set FQC to "1" as FIFO is now not empty */
526 PKE_REG_MASK_SET(me
, STAT
, FQC
, 1);
538 /* Reset the simulated PKE hardware state. Preserve other internal
541 pke_reset(struct pke_device
* me
)
543 /* advance PC over last quadword in FIFO; keep previous FIFO history */
544 me
->fifo_pc
= pke_fifo_flush(& me
->fifo
);
546 /* clear registers, flag, other state */
547 memset(me
->regs
, 0, sizeof(me
->regs
));
548 me
->fifo_qw_done
= 0;
549 /* Command options will remain alive over the reset. */
550 me
->flags
&= PKE_FLAG_TRACE_ON
;
552 /* NOTE: Since disassembly / trace logs remain open across ordinary
553 simulated hardware resets, there may be a problem of producing a
554 trace file that has only partial results from the prior
555 operation. For the current PKE model, however, this cannot
556 happen as stalls & interrupts only occur *between* simulated
557 PKEcode executions. This means that our trace files ought remain
558 syntactically valid, despite resets. */
560 if(me
->trace_file
!= NULL
)
562 fprintf(me
->trace_file
,
570 /* Issue & swallow next PKE opcode if possible/available */
573 pke_issue(SIM_DESC sd
, struct pke_device
* me
)
575 struct fifo_quadword
* fqw
;
577 unsigned_4 cmd
, intr
;
579 /* 1 -- fetch PKE instruction */
581 /* confirm availability of new quadword of PKE instructions */
582 fqw
= pke_fifo_access(& me
->fifo
, me
->fifo_pc
);
586 /* skip over DMA tag, if present */
587 pke_pc_advance(me
, 0);
588 /* note: this can only change qw_pc from 0 to 2 and will not
591 /* "fetch" instruction quadword and word */
592 fw
= fqw
->data
[me
->qw_pc
];
594 /* store word in PKECODE register */
595 me
->regs
[PKE_REG_CODE
][0] = fw
;
598 /* 2 -- test go / no-go for PKE execution */
600 /* switch on STAT:PSS if PSS-pending and in idle state */
601 if((PKE_REG_MASK_GET(me
, STAT
, PPS
) == PKE_REG_STAT_PPS_IDLE
) &&
602 (me
->flags
& PKE_FLAG_PENDING_PSS
) != 0)
604 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
605 PKE_REG_MASK_SET(me
, STAT
, PSS
, 1);
608 /* check for stall/halt control bits */
609 if(PKE_REG_MASK_GET(me
, STAT
, PFS
) ||
610 PKE_REG_MASK_GET(me
, STAT
, PSS
) || /* note special treatment below */
611 /* PEW bit not a reason to keep stalling - it's just an indication, re-computed below */
612 /* PGW bit not a reason to keep stalling - it's just an indication, re-computed below */
613 /* ER0/ER1 not a reason to keep stalling - it's just an indication */
614 PKE_REG_MASK_GET(me
, STAT
, PIS
))
616 /* (still) stalled */
617 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
618 /* try again next cycle */
623 /* 3 -- decode PKE instruction */
626 if(PKE_REG_MASK_GET(me
, STAT
, PPS
) == PKE_REG_STAT_PPS_IDLE
)
627 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_DECODE
);
629 /* Extract relevant bits from PKEcode */
630 intr
= BIT_MASK_GET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
);
631 cmd
= BIT_MASK_GET(fw
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
633 /* handle interrupts */
636 /* are we resuming an interrupt-stalled instruction? */
637 if(me
->flags
& PKE_FLAG_INT_NOLOOP
)
639 /* clear loop-prevention flag */
640 me
->flags
&= ~PKE_FLAG_INT_NOLOOP
;
642 /* fall through to decode & execute */
643 /* The pke_code_* functions should not check the MSB in the
646 else /* new interrupt-flagged instruction */
648 /* set INT flag in STAT register */
649 PKE_REG_MASK_SET(me
, STAT
, INT
, 1);
650 /* set loop-prevention flag */
651 me
->flags
|= PKE_FLAG_INT_NOLOOP
;
653 /* set PIS if stall not masked */
654 if(!PKE_REG_MASK_GET(me
, ERR
, MII
))
655 pke_begin_interrupt_stall(me
);
657 /* suspend this instruction unless it's PKEMARK */
658 if(!IS_PKE_CMD(cmd
, PKEMARK
))
660 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
665 ; /* fall through to decode & execute */
670 /* open trace file if necessary */
671 if((me
->flags
& PKE_FLAG_TRACE_ON
) &&
672 (me
->trace_file
== NULL
))
674 /* use default names */
675 if(me
->trace_file_name
== NULL
)
677 if(me
->pke_number
== 0)
678 me
->trace_file_name
= (char *) pke0_default_trace
;
680 me
->trace_file_name
= (char *) pke1_default_trace
;
683 sky_open_file(& (me
->trace_file
),
685 (char *) NULL
, _IOFBF
);
687 /* print disassembly header */
688 fprintf(me
->trace_file
,
689 "\t.global %s_disassembly_tag\n"
690 "%s_disassembly_tag:\n",
691 me
->dev
.name
, me
->dev
.name
);
694 /* decode & execute */
695 /* order tests in decreasing order of frequency */
696 if(IS_PKE_CMD(cmd
, PKENOP
))
697 pke_code_nop(me
, fw
);
698 else if(IS_PKE_CMD(cmd
, PKEMSCAL
))
699 pke_code_pkemscal(me
, fw
);
700 else if(IS_PKE_CMD(cmd
, PKEMSCNT
))
701 pke_code_pkemscnt(me
, fw
);
702 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, PKEMSCALF
))
703 pke_code_pkemscalf(me
, fw
);
704 else if(IS_PKE_CMD(cmd
, UNPACK
))
705 pke_code_unpack(me
, fw
);
706 else if(IS_PKE_CMD(cmd
, STCYCL
))
707 pke_code_stcycl(me
, fw
);
708 else if(IS_PKE_CMD(cmd
, FLUSHE
))
709 pke_code_flushe(me
, fw
);
710 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSH
))
711 pke_code_flush(me
, fw
);
712 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSHA
))
713 pke_code_flusha(me
, fw
);
714 else if(IS_PKE_CMD(cmd
, DIRECT
))
715 pke_code_direct(me
, fw
);
716 else if(IS_PKE_CMD(cmd
, DIRECTHL
))
717 pke_code_directhl(me
, fw
);
718 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, OFFSET
))
719 pke_code_offset(me
, fw
);
720 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, BASE
))
721 pke_code_base(me
, fw
);
722 else if(IS_PKE_CMD(cmd
, ITOP
))
723 pke_code_itop(me
, fw
);
724 else if(IS_PKE_CMD(cmd
, STMOD
))
725 pke_code_stmod(me
, fw
);
726 else if(IS_PKE_CMD(cmd
, PKEMARK
))
727 pke_code_pkemark(me
, fw
);
728 else if(IS_PKE_CMD(cmd
, STMASK
))
729 pke_code_stmask(me
, fw
);
730 else if(IS_PKE_CMD(cmd
, STROW
))
731 pke_code_strow(me
, fw
);
732 else if(IS_PKE_CMD(cmd
, STCOL
))
733 pke_code_stcol(me
, fw
);
734 else if(IS_PKE_CMD(cmd
, MPG
))
735 pke_code_mpg(me
, fw
);
736 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, MSKPATH3
))
737 pke_code_mskpath3(me
, fw
);
738 else if(cmd
== TXVU_VIF_BRK_MASK
)
740 sim_cpu
*cpu
= STATE_CPU (sd
, 0);
741 unsigned_4 pc_addr
= (fqw
->source_address
& ~15) | (me
->qw_pc
<< 2);
743 sim_engine_halt (sd
, cpu
, NULL
, pc_addr
, sim_stopped
, SIM_SIGTRAP
);
745 /* ... no other commands ... */
747 pke_code_error(me
, fw
);
752 /* Clear out contents of FIFO; act as if it was empty. Return PC
753 pointing to one-past-last word. */
756 pke_fifo_flush(struct pke_fifo
* fifo
)
758 /* don't modify any state! */
759 return fifo
->origin
+ fifo
->next
;
764 /* Clear out contents of FIFO; make it really empty. */
767 pke_fifo_reset(struct pke_fifo
* fifo
)
771 /* clear fifo quadwords */
772 for(i
=0; i
<fifo
->next
; i
++)
774 zfree(fifo
->quadwords
[i
]);
775 fifo
->quadwords
[i
] = NULL
;
785 /* Make space for the next quadword in the FIFO. Allocate/enlarge
786 FIFO pointer block if necessary. Return a pointer to it. */
788 struct fifo_quadword
*
789 pke_fifo_fit(struct pke_fifo
* fifo
)
791 struct fifo_quadword
* fqw
;
793 /* out of space on quadword pointer array? */
794 if(fifo
->next
== fifo
->length
) /* also triggered before fifo->quadwords allocated */
796 struct fifo_quadword
** new_qw
;
797 unsigned_4 new_length
= fifo
->length
+ PKE_FIFO_GROW_SIZE
;
799 /* allocate new pointer block */
800 new_qw
= zalloc(new_length
* sizeof(struct fifo_quadword
*));
801 ASSERT(new_qw
!= NULL
);
803 /* copy over old contents, if any */
804 if(fifo
->quadwords
!= NULL
)
806 /* copy over old pointers to beginning of new block */
807 memcpy(new_qw
, fifo
->quadwords
,
808 fifo
->length
* sizeof(struct fifo_quadword
*));
811 zfree(fifo
->quadwords
);
814 /* replace pointers & counts */
815 fifo
->quadwords
= new_qw
;
816 fifo
->length
= new_length
;
820 ASSERT(fifo
->quadwords
!= NULL
);
822 /* allocate new quadword from heap */
823 fqw
= zalloc(sizeof(struct fifo_quadword
));
826 /* push quadword onto fifo */
827 fifo
->quadwords
[fifo
->next
] = fqw
;
834 /* Return a pointer to the FIFO quadword with given absolute index, or
835 NULL if it is out of range */
837 struct fifo_quadword
*
838 pke_fifo_access(struct pke_fifo
* fifo
, unsigned_4 qwnum
)
840 struct fifo_quadword
* fqw
;
842 if((qwnum
< fifo
->origin
) || /* before history */
843 (qwnum
>= fifo
->origin
+ fifo
->next
)) /* after last available quadword */
847 ASSERT(fifo
->quadwords
!= NULL
); /* must be allocated already */
848 fqw
= fifo
->quadwords
[qwnum
- fifo
->origin
]; /* pull out pointer from array */
849 ASSERT(fqw
!= NULL
); /* must be allocated already */
856 /* Authorize release of any FIFO entries older than given absolute quadword. */
858 pke_fifo_old(struct pke_fifo
* fifo
, unsigned_4 qwnum
)
860 /* do we have any too-old FIFO elements? */
861 if(fifo
->origin
+ PKE_FIFO_ARCHEOLOGY
< qwnum
)
863 /* count quadwords to forget */
864 int horizon
= qwnum
- (fifo
->origin
+ PKE_FIFO_ARCHEOLOGY
);
867 /* free quadwords at indices below horizon */
868 for(i
=0; i
< horizon
; i
++)
869 zfree(fifo
->quadwords
[i
]);
871 /* move surviving quadword pointers down to beginning of array */
872 for(i
=horizon
; i
< fifo
->next
; i
++)
873 fifo
->quadwords
[i
-horizon
] = fifo
->quadwords
[i
];
875 /* clear duplicate pointers */
876 for(i
=fifo
->next
- horizon
; i
< fifo
->next
; i
++)
877 fifo
->quadwords
[i
] = NULL
;
879 /* adjust FIFO pointers */
880 fifo
->origin
= fifo
->origin
+ horizon
;
881 fifo
->next
= fifo
->next
- horizon
;
888 /* advance the PC by given number of data words; update STAT/FQC
889 field; assume FIFO is filled enough; classify passed-over words;
890 write FIFO trace line */
893 pke_pc_advance(struct pke_device
* me
, int num_words
)
896 struct fifo_quadword
* fq
= NULL
;
897 unsigned_4 old_fifo_pc
= me
->fifo_pc
;
899 ASSERT(num_words
>= 0);
901 /* printf("pke %d pc_advance num_words %d\n", me->pke_number, num_words); */
905 /* find next quadword, if any */
906 fq
= pke_fifo_access(& me
->fifo
, me
->fifo_pc
);
908 /* skip over DMA tag words if present in word 0 or 1 */
909 if(fq
!= NULL
&& fq
->word_class
[me
->qw_pc
] == wc_dma
)
911 /* skip by going around loop an extra time */
915 /* nothing left to skip / no DMA tag here */
919 /* we are supposed to skip existing words */
922 /* one word skipped */
925 /* point to next word */
932 /* trace the consumption of the FIFO quadword we just skipped over */
933 /* fq still points to it */
934 if ( indebug (me
->dev
.name
))
936 if (( me
->fifo_trace_file
== NULL
) &&
937 ( me
->fifo_trace_file_name
!= NULL
))
938 sky_open_file (&me
->fifo_trace_file
, me
->fifo_trace_file_name
,
939 (char *) NULL
, _IOLBF
);
941 /* assert complete classification */
942 ASSERT(fq
->word_class
[3] != wc_unknown
);
943 ASSERT(fq
->word_class
[2] != wc_unknown
);
944 ASSERT(fq
->word_class
[1] != wc_unknown
);
945 ASSERT(fq
->word_class
[0] != wc_unknown
);
947 /* print trace record */
948 fprintf((me
->fifo_trace_file
!= NULL
) ? me
->fifo_trace_file
: stdout
,
949 "%d 0x%08x_%08x_%08x_%08x 0x%08x %c%c%c%c\n",
950 (me
->pke_number
== 0 ? 0 : 1),
951 (unsigned) fq
->data
[3], (unsigned) fq
->data
[2],
952 (unsigned) fq
->data
[1], (unsigned) fq
->data
[0],
953 (unsigned) fq
->source_address
,
954 fq
->word_class
[3], fq
->word_class
[2],
955 fq
->word_class
[1], fq
->word_class
[0]);
957 } /* next quadword */
960 /* age old entries before PC */
961 if(me
->fifo_pc
!= old_fifo_pc
)
963 /* we advanced the fifo-pc; authorize disposal of anything
964 before previous PKEcode */
965 pke_fifo_old(& me
->fifo
, old_fifo_pc
);
968 /* clear FQC if FIFO is now empty */
969 fq
= pke_fifo_access(& me
->fifo
, me
->fifo_pc
);
972 PKE_REG_MASK_SET(me
, STAT
, FQC
, 0);
974 else /* annote the word where the PC lands as an PKEcode */
976 ASSERT(fq
->word_class
[me
->qw_pc
] == wc_pkecode
|| fq
->word_class
[me
->qw_pc
] == wc_unknown
);
977 fq
->word_class
[me
->qw_pc
] = wc_pkecode
;
985 /* Return pointer to FIFO quadword containing given operand# in FIFO.
986 `operand_num' starts at 1. Return pointer to operand word in last
987 argument, if non-NULL. If FIFO is not full enough, return 0.
988 Signal an ER0 indication upon skipping a DMA tag. */
990 struct fifo_quadword
*
991 pke_pcrel_fifo(struct pke_device
* me
, int operand_num
, unsigned_4
** operand
)
994 int new_qw_pc
, new_fifo_pc
;
995 struct fifo_quadword
* fq
= NULL
;
997 /* check for validity of last search results in cache */
998 if(me
->last_fifo_pc
== me
->fifo_pc
&&
999 me
->last_qw_pc
== me
->qw_pc
&&
1000 operand_num
> me
->last_num
)
1002 /* continue search from last stop */
1003 new_fifo_pc
= me
->last_new_fifo_pc
;
1004 new_qw_pc
= me
->last_new_qw_pc
;
1005 num
= operand_num
- me
->last_num
;
1009 /* start search from scratch */
1010 new_fifo_pc
= me
->fifo_pc
;
1011 new_qw_pc
= me
->qw_pc
;
1017 /* printf("pke %d pcrel_fifo operand_num %d\n", me->pke_number, operand_num); */
1021 /* one word skipped */
1024 /* point to next word */
1032 fq
= pke_fifo_access(& me
->fifo
, new_fifo_pc
);
1034 /* check for FIFO underflow */
1038 /* skip over DMA tag words if present in word 0 or 1 */
1039 if(fq
->word_class
[new_qw_pc
] == wc_dma
)
1042 PKE_REG_MASK_SET(me
, STAT
, ER0
, 1);
1044 /* mismatch error! */
1045 if(! PKE_REG_MASK_GET(me
, ERR
, ME0
))
1047 pke_begin_interrupt_stall(me
);
1048 /* don't stall just yet -- finish this instruction */
1049 /* the PPS_STALL state will be entered by pke_issue() next time */
1051 /* skip by going around loop an extra time */
1057 /* return pointer to operand word itself */
1060 *operand
= & fq
->data
[new_qw_pc
];
1062 /* annote the word where the pseudo-PC lands as an PKE operand */
1063 ASSERT(fq
->word_class
[new_qw_pc
] == wc_pkedata
|| fq
->word_class
[new_qw_pc
] == wc_unknown
);
1064 fq
->word_class
[new_qw_pc
] = wc_pkedata
;
1066 /* store search results in cache */
1068 me
->last_fifo_pc
= me
->fifo_pc
;
1069 me
->last_qw_pc
= me
->qw_pc
;
1071 me
->last_num
= operand_num
;
1072 me
->last_new_fifo_pc
= new_fifo_pc
;
1073 me
->last_new_qw_pc
= new_qw_pc
;
1080 /* Return pointer to given operand# in FIFO. `operand_num' starts at 1.
1081 If FIFO is not full enough, return 0. Skip over DMA tags, but mark
1082 them as an error (ER0). */
1085 pke_pcrel_operand(struct pke_device
* me
, int operand_num
)
1087 unsigned_4
* operand
= NULL
;
1088 struct fifo_quadword
* fifo_operand
;
1090 fifo_operand
= pke_pcrel_fifo(me
, operand_num
, & operand
);
1092 if(fifo_operand
== NULL
)
1093 ASSERT(operand
== NULL
); /* pke_pcrel_fifo() ought leave it untouched */
1099 /* Return a bit-field extract of given operand# in FIFO, and its
1100 word-accurate source-addr. `bit_offset' starts at 0, referring to
1101 LSB after PKE instruction word. Width must be >0, <=32. Assume
1102 FIFO is full enough. Skip over DMA tags, but mark them as an error
1106 pke_pcrel_operand_bits(struct pke_device
* me
, int bit_offset
, int bit_width
, unsigned_4
* source_addr
)
1108 unsigned_4
* word
= NULL
;
1110 struct fifo_quadword
* fifo_operand
;
1111 int wordnumber
, bitnumber
;
1114 wordnumber
= bit_offset
/32;
1115 bitnumber
= bit_offset
%32;
1117 /* find operand word with bitfield */
1118 fifo_operand
= pke_pcrel_fifo(me
, wordnumber
+ 1, &word
);
1119 ASSERT(word
!= NULL
);
1121 /* extract bitfield from word */
1122 value
= BIT_MASK_GET(*word
, bitnumber
, bitnumber
+ bit_width
- 1);
1124 /* extract source addr from fifo word */
1125 *source_addr
= fifo_operand
->source_address
;
1127 /* add word offset */
1129 if(word
== & fifo_operand
->data
[i
])
1130 *source_addr
+= sizeof(unsigned_4
) * i
;
1137 /* check for stall conditions on indicated devices (path* only on
1138 PKE1), do not change status; return 0 iff no stall */
1140 pke_check_stall(struct pke_device
* me
, enum pke_check_target what
)
1143 unsigned_4 cop2_stat
, gpuif_stat
;
1145 /* read status words */
1146 ASSERT(sizeof(unsigned_4
) == 4);
1147 PKE_MEM_READ(me
, (GIF_REG_STAT
),
1150 PKE_MEM_READ(me
, (COP2_REG_STAT_ADDR
),
1154 /* perform checks */
1157 if(me
->pke_number
== 0)
1158 any_stall
= BIT_MASK_GET(cop2_stat
, COP2_REG_STAT_VBS0_B
, COP2_REG_STAT_VBS0_E
);
1159 else /* if(me->pke_number == 1) */
1160 any_stall
= BIT_MASK_GET(cop2_stat
, COP2_REG_STAT_VBS1_B
, COP2_REG_STAT_VBS1_E
);
1162 else if(what
== chk_path1
) /* VU -> GPUIF */
1164 ASSERT(me
->pke_number
== 1);
1165 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 1)
1168 else if(what
== chk_path2
) /* PKE -> GPUIF */
1170 ASSERT(me
->pke_number
== 1);
1171 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 2)
1174 else if(what
== chk_path3
) /* DMA -> GPUIF */
1176 ASSERT(me
->pke_number
== 1);
1177 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 3)
1186 /* any stall reasons? */
1191 /* PKE1 only: flip the DBF bit; recompute TOPS, TOP */
1193 pke_flip_dbf(struct pke_device
* me
)
1196 /* compute new TOP */
1197 PKE_REG_MASK_SET(me
, TOP
, TOP
,
1198 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
1200 newdf
= PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1;
1201 PKE_REG_MASK_SET(me
, DBF
, DF
, newdf
);
1202 PKE_REG_MASK_SET(me
, STAT
, DBF
, newdf
);
1203 /* compute new TOPS */
1204 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
1205 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
1206 newdf
* PKE_REG_MASK_GET(me
, OFST
, OFFSET
)));
1208 /* this is equivalent to last word from okadaa (98-02-25):
1210 2) TOPS=BASE + !DBF*OFFSET
1215 /* set the STAT:PIS bit and send an interrupt to the 5900 */
1217 pke_begin_interrupt_stall(struct pke_device
* me
)
1220 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1221 sky_signal_interrupt();
1227 /* PKEcode handler functions -- responsible for checking and
1228 confirming old stall conditions, executing pkecode, updating PC and
1229 status registers -- may assume being run on correct PKE unit */
1232 pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
)
1235 if(me
->trace_file
!= NULL
)
1237 fprintf(me
->trace_file
,
1242 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1243 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""));
1245 pke_pc_advance(me
, 1);
1246 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1251 pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
)
1253 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1255 /* copy immediate value into CYCLE reg */
1256 PKE_REG_MASK_SET(me
, CYCLE
, WL
, BIT_MASK_GET(imm
, 8, 15));
1257 PKE_REG_MASK_SET(me
, CYCLE
, CL
, BIT_MASK_GET(imm
, 0, 7));
1259 if(me
->trace_file
!= NULL
)
1261 fprintf(me
->trace_file
,
1264 "\tSTCYCL%s %d,%d\n"
1266 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1267 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1268 BIT_MASK_GET(imm
, 8, 15), BIT_MASK_GET(imm
, 0, 7));
1270 pke_pc_advance(me
, 1);
1271 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1276 pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
)
1278 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1280 /* copy 10 bits to OFFSET field */
1281 PKE_REG_MASK_SET(me
, OFST
, OFFSET
, BIT_MASK_GET(imm
, 0, 9));
1283 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
1284 /* clear other DBF bit */
1285 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
1286 /* set TOPS = BASE */
1287 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
1289 if(me
->trace_file
!= NULL
)
1291 fprintf(me
->trace_file
,
1296 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1297 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1300 pke_pc_advance(me
, 1);
1301 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1306 pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
)
1308 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1310 /* copy 10 bits to BASE field */
1311 PKE_REG_MASK_SET(me
, BASE
, BASE
, BIT_MASK_GET(imm
, 0, 9));
1313 if(me
->trace_file
!= NULL
)
1315 fprintf(me
->trace_file
,
1320 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1321 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1324 pke_pc_advance(me
, 1);
1325 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1330 pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
)
1332 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1334 /* copy 10 bits to ITOPS field */
1335 PKE_REG_MASK_SET(me
, ITOPS
, ITOPS
, BIT_MASK_GET(imm
, 0, 9));
1337 if(me
->trace_file
!= NULL
)
1339 fprintf(me
->trace_file
,
1344 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1345 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1348 pke_pc_advance(me
, 1);
1349 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1354 pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
)
1356 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1358 /* copy 2 bits to MODE register */
1359 PKE_REG_MASK_SET(me
, MODE
, MDE
, BIT_MASK_GET(imm
, 0, 1));
1361 if(me
->trace_file
!= NULL
)
1364 if(BIT_MASK_GET(imm
, 0, 1) == 0) mode
= "direct";
1365 else if(BIT_MASK_GET(imm
, 0, 1) == 1) mode
= "add";
1366 else if(BIT_MASK_GET(imm
, 0, 1) == 2) mode
= "addrow";
1367 else mode
= "3"; /* invalid mode */
1369 fprintf(me
->trace_file
,
1374 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1375 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1378 pke_pc_advance(me
, 1);
1379 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1384 pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
)
1386 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1387 unsigned_4 gif_mode
;
1389 /* set appropriate bit */
1390 if(BIT_MASK_GET(imm
, PKE_REG_MSKPATH3_B
, PKE_REG_MSKPATH3_E
) != 0)
1391 gif_mode
= GIF_REG_STAT_M3P
;
1395 /* write register to "read-only" register; gpuif code will look at M3P bit only */
1396 PKE_MEM_WRITE(me
, GIF_REG_VIF_M3P
, & gif_mode
, 4);
1399 if(me
->trace_file
!= NULL
)
1401 fprintf(me
->trace_file
,
1406 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1407 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1408 (gif_mode
? "disable" : "enable"));
1410 pke_pc_advance(me
, 1);
1411 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1416 pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
)
1418 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1419 /* copy 16 bits to MARK register */
1420 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(imm
, 0, 15));
1421 /* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
1422 PKE_REG_MASK_SET(me
, STAT
, MRK
, 1);
1424 if(me
->trace_file
!= NULL
)
1426 fprintf(me
->trace_file
,
1431 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1432 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1435 pke_pc_advance(me
, 1);
1436 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1441 pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
)
1443 /* compute next PEW bit */
1444 if(pke_check_stall(me
, chk_vu
))
1447 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1448 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1449 /* try again next cycle */
1454 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1455 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1456 if(me
->trace_file
!= NULL
)
1458 fprintf(me
->trace_file
,
1463 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1464 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""));
1466 pke_pc_advance(me
, 1);
1472 pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
)
1474 int something_busy
= 0;
1476 /* compute next PEW, PGW bits */
1477 if(pke_check_stall(me
, chk_vu
))
1480 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1483 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1486 if(pke_check_stall(me
, chk_path1
) ||
1487 pke_check_stall(me
, chk_path2
))
1490 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1493 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1498 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1499 /* try again next cycle */
1504 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1505 if(me
->trace_file
!= NULL
)
1507 fprintf(me
->trace_file
,
1512 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1513 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""));
1515 pke_pc_advance(me
, 1);
1521 pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
)
1523 int something_busy
= 0;
1525 /* compute next PEW, PGW bits */
1526 if(pke_check_stall(me
, chk_vu
))
1529 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1532 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1535 if(pke_check_stall(me
, chk_path1
) ||
1536 pke_check_stall(me
, chk_path2
) ||
1537 pke_check_stall(me
, chk_path3
))
1540 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1543 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1547 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1548 /* try again next cycle */
1553 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1554 if(me
->trace_file
!= NULL
)
1556 fprintf(me
->trace_file
,
1561 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1562 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""));
1564 pke_pc_advance(me
, 1);
1570 pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
)
1572 /* compute next PEW bit */
1573 if(pke_check_stall(me
, chk_vu
))
1576 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1577 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1578 /* try again next cycle */
1583 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1586 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1588 /* flip DBF on PKE1 */
1589 if(me
->pke_number
== 1)
1592 /* compute new PC for VU (host byte-order) */
1593 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1594 vu_pc
= T2H_4(vu_pc
);
1596 /* write new PC; callback function gets VU running */
1597 ASSERT(sizeof(unsigned_4
) == 4);
1598 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1602 /* copy ITOPS field to ITOP */
1603 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1606 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1607 if(me
->trace_file
!= NULL
)
1609 fprintf(me
->trace_file
,
1614 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1615 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "[i]" : ""),
1618 pke_pc_advance(me
, 1);
1625 pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
)
1627 /* compute next PEW bit */
1628 if(pke_check_stall(me
, chk_vu
))
1631 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1632 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1633 /* try again next cycle */
1640 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1642 /* flip DBF on PKE1 */
1643 if(me
->pke_number
== 1)
1647 ASSERT(sizeof(unsigned_4
) == 4);
1648 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1652 /* rewrite new PC; callback function gets VU running */
1653 ASSERT(sizeof(unsigned_4
) == 4);
1654 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1658 /* copy ITOPS field to ITOP */
1659 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1662 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1663 if(me
->trace_file
!= NULL
)
1665 fprintf(me
->trace_file
,
1670 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
);
1672 pke_pc_advance(me
, 1);
1678 pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
)
1680 int something_busy
= 0;
1682 /* compute next PEW, PGW bits */
1683 if(pke_check_stall(me
, chk_vu
))
1686 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1689 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1692 if(pke_check_stall(me
, chk_path1
) ||
1693 pke_check_stall(me
, chk_path2
) ||
1694 pke_check_stall(me
, chk_path3
))
1697 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1700 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1705 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1706 /* try again next cycle */
1711 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1713 /* flip DBF on PKE1 */
1714 if(me
->pke_number
== 1)
1717 /* compute new PC for VU (host byte-order) */
1718 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1719 vu_pc
= T2H_4(vu_pc
);
1721 /* rewrite new PC; callback function gets VU running */
1722 ASSERT(sizeof(unsigned_4
) == 4);
1723 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1727 /* copy ITOPS field to ITOP */
1728 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1731 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1732 if(me
->trace_file
!= NULL
)
1734 fprintf(me
->trace_file
,
1739 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1742 pke_pc_advance(me
, 1);
1748 pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
)
1752 /* check that FIFO has one more word for STMASK operand */
1753 mask
= pke_pcrel_operand(me
, 1);
1756 /* "transferring" operand */
1757 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1760 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1762 /* fill the register */
1763 PKE_REG_MASK_SET(me
, MASK
, MASK
, *mask
);
1766 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1769 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1770 if(me
->trace_file
!= NULL
)
1772 fprintf(me
->trace_file
,
1777 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1780 pke_pc_advance(me
, 2);
1784 /* need to wait for another word */
1785 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1786 /* try again next cycle */
1792 pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
)
1794 /* check that FIFO has four more words for STROW operand */
1795 unsigned_4
* last_op
;
1797 last_op
= pke_pcrel_operand(me
, 4);
1800 /* "transferring" operand */
1801 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1804 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1806 /* copy ROW registers: must all exist if 4th operand exists */
1807 me
->regs
[PKE_REG_R0
][0] = * pke_pcrel_operand(me
, 1);
1808 me
->regs
[PKE_REG_R1
][0] = * pke_pcrel_operand(me
, 2);
1809 me
->regs
[PKE_REG_R2
][0] = * pke_pcrel_operand(me
, 3);
1810 me
->regs
[PKE_REG_R3
][0] = * pke_pcrel_operand(me
, 4);
1813 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1816 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1817 if(me
->trace_file
!= NULL
)
1819 fprintf(me
->trace_file
,
1822 "\tSTROW 0x%x,0x%x,0x%x,0x%x\n"
1824 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1825 * pke_pcrel_operand(me
, 1),
1826 * pke_pcrel_operand(me
, 2),
1827 * pke_pcrel_operand(me
, 3),
1828 * pke_pcrel_operand(me
, 4));
1830 pke_pc_advance(me
, 5);
1834 /* need to wait for another word */
1835 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1836 /* try again next cycle */
1842 pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
)
1844 /* check that FIFO has four more words for STCOL operand */
1845 unsigned_4
* last_op
;
1847 last_op
= pke_pcrel_operand(me
, 4);
1850 /* "transferring" operand */
1851 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1854 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1856 /* copy COL registers: must all exist if 4th operand exists */
1857 me
->regs
[PKE_REG_C0
][0] = * pke_pcrel_operand(me
, 1);
1858 me
->regs
[PKE_REG_C1
][0] = * pke_pcrel_operand(me
, 2);
1859 me
->regs
[PKE_REG_C2
][0] = * pke_pcrel_operand(me
, 3);
1860 me
->regs
[PKE_REG_C3
][0] = * pke_pcrel_operand(me
, 4);
1863 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1866 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1867 if(me
->trace_file
!= NULL
)
1869 fprintf(me
->trace_file
,
1872 "\tSTCOL 0x%x,0x%x,0x%x,0x%x\n"
1874 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1875 * pke_pcrel_operand(me
, 1),
1876 * pke_pcrel_operand(me
, 2),
1877 * pke_pcrel_operand(me
, 3),
1878 * pke_pcrel_operand(me
, 4));
1880 pke_pc_advance(me
, 5);
1884 /* need to wait for another word */
1885 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1886 /* try again next cycle */
1892 pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
)
1894 unsigned_4
* last_mpg_word
;
1895 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1896 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1898 /* assert 64-bit alignment of MPG operand */
1899 if(me
->qw_pc
!= 3 && me
->qw_pc
!= 1)
1900 return pke_code_error(me
, pkecode
);
1902 /* map zero to max+1 */
1903 if(num
==0) num
=0x100;
1905 /* check that FIFO has a few more words for MPG operand */
1906 last_mpg_word
= pke_pcrel_operand(me
, num
*2); /* num: number of 64-bit words */
1907 if(last_mpg_word
!= NULL
)
1909 /* perform implied FLUSHE */
1910 if(pke_check_stall(me
, chk_vu
))
1913 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1914 /* retry this instruction next clock */
1921 /* "transferring" operand */
1922 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1925 PKE_REG_MASK_SET(me
, NUM
, NUM
, num
);
1928 if(me
->trace_file
!= NULL
)
1930 fprintf(me
->trace_file
,
1933 "\tMPG 0x%x,0x%x\n",
1934 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
1938 /* transfer VU instructions, one word-pair per iteration */
1939 for(i
=0; i
<num
; i
++)
1941 address_word vu_addr_base
, vu_addr
;
1942 address_word vutrack_addr_base
, vutrack_addr
;
1943 address_word vu_addr_max_size
;
1944 unsigned_4 vu_lower_opcode
, vu_upper_opcode
;
1945 unsigned_4
* operand
;
1946 unsigned_4 source_addr
;
1947 struct fifo_quadword
* fq
;
1952 next_num
= PKE_REG_MASK_GET(me
, NUM
, NUM
) - 1;
1953 PKE_REG_MASK_SET(me
, NUM
, NUM
, next_num
);
1955 /* imm: in 64-bit units for MPG instruction */
1956 /* VU*_MEM0 : instruction memory */
1957 vu_addr_base
= (me
->pke_number
== 0) ?
1958 VU0_MEM0_WINDOW_START
: VU1_MEM0_WINDOW_START
;
1959 vu_addr_max_size
= (me
->pke_number
== 0) ?
1960 VU0_MEM0_SIZE
: VU1_MEM0_SIZE
;
1961 vutrack_addr_base
= (me
->pke_number
== 0) ?
1962 VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
;
1964 /* compute VU address for this word-pair */
1965 vu_addr
= vu_addr_base
+ (imm
+ i
) * 8;
1966 /* check for vu_addr overflow */
1967 while(vu_addr
>= vu_addr_base
+ vu_addr_max_size
)
1968 vu_addr
-= vu_addr_max_size
;
1970 /* compute VU tracking address */
1971 vutrack_addr
= vutrack_addr_base
+ ((signed_8
)vu_addr
- (signed_8
)vu_addr_base
) / 2;
1973 /* Fetch operand words; assume they are already little-endian for VU imem */
1974 fq
= pke_pcrel_fifo(me
, i
*2 + 1, & operand
);
1975 vu_lower_opcode
= *operand
;
1977 source_addr
= fq
->source_address
;
1978 /* add word offset */
1980 if(operand
== & fq
->data
[j
])
1981 source_addr
+= sizeof(unsigned_4
) * j
;
1983 fq
= pke_pcrel_fifo(me
, i
*2 + 2, & operand
);
1984 vu_upper_opcode
= *operand
;
1986 /* write data into VU memory */
1987 /* lower (scalar) opcode comes in first word ; macro performs H2T! */
1988 PKE_MEM_WRITE(me
, vu_addr
,
1991 /* upper (vector) opcode comes in second word ; H2T */
1992 ASSERT(sizeof(unsigned_4
) == 4);
1993 PKE_MEM_WRITE(me
, vu_addr
+ 4,
1997 /* write tracking address in target byte-order */
1998 ASSERT(sizeof(unsigned_4
) == 4);
1999 PKE_MEM_WRITE(me
, vutrack_addr
,
2004 if(me
->trace_file
!= NULL
)
2006 unsigned long opcodes
[2] = { vu_upper_opcode
, vu_lower_opcode
};
2007 fprintf(me
->trace_file
, "\t");
2008 opcode_analyze(me
->trace_file
, opcodes
);
2009 fprintf(me
->trace_file
, "\n");
2011 } /* VU xfer loop */
2014 ASSERT(PKE_REG_MASK_GET(me
, NUM
, NUM
) == 0);
2017 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
2018 if(me
->trace_file
!= NULL
)
2020 fprintf(me
->trace_file
,
2024 pke_pc_advance(me
, 1 + num
*2);
2026 } /* if FIFO full enough */
2029 /* need to wait for another word */
2030 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
2031 /* retry this instruction next clock */
2037 pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
)
2039 /* check that FIFO has a few more words for DIRECT operand */
2040 unsigned_4
* last_direct_word
;
2041 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
2043 /* assert 128-bit alignment of DIRECT operand */
2045 return pke_code_error(me
, pkecode
);
2047 /* map zero to max+1 */
2048 if(imm
==0) imm
=0x10000;
2050 last_direct_word
= pke_pcrel_operand(me
, imm
*4); /* imm: number of 128-bit words */
2051 if(last_direct_word
!= NULL
)
2055 unsigned_16 fifo_data
;
2057 /* "transferring" operand */
2058 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
2061 if(me
->trace_file
!= NULL
)
2063 fprintf(me
->trace_file
,
2067 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
2068 (IS_PKE_CMD(pkecode
, DIRECT
) ? "DIRECT" : "DIRECTHL"),
2072 /* transfer GPUIF quadwords, one word per iteration */
2073 for(i
=0; i
<imm
*4; i
++)
2075 unsigned_4
* operand
= pke_pcrel_operand(me
, 1+i
);
2077 /* collect word into quadword */
2078 *A4_16(&fifo_data
, 3 - (i
% 4)) = *operand
;
2080 /* write to GPUIF FIFO only with full quadword */
2083 ASSERT(sizeof(fifo_data
) == 16);
2084 PKE_MEM_WRITE(me
, GIF_PATH2_FIFO_ADDR
,
2089 if(me
->trace_file
!= NULL
)
2091 char buffer
[200]; /* one line of disassembly */
2092 gif_disassemble_pke_data(buffer
, (quadword
*) &fifo_data
);
2093 fprintf(me
->trace_file
, "\t%s\n", buffer
);
2095 } /* write collected quadword */
2096 } /* GPUIF xfer loop */
2099 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
2100 if(me
->trace_file
!= NULL
)
2102 fprintf(me
->trace_file
,
2106 pke_pc_advance(me
, 1 + imm
*4);
2107 } /* if FIFO full enough */
2110 /* need to wait for another word */
2111 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
2112 /* retry this instruction next clock */
2118 pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
)
2120 /* treat the same as DIRECT */
2121 pke_code_direct(me
, pkecode
);
2122 /* dissassembly code handles DIRECT/DIRECTHL overloading */
2127 pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
)
2129 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
2130 int cmd
= BIT_MASK_GET(pkecode
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
2131 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
2132 int nummx
= (num
== 0) ? 0x0100 : num
;
2133 short vn
= BIT_MASK_GET(cmd
, 2, 3); /* unpack shape controls */
2134 short vl
= BIT_MASK_GET(cmd
, 0, 1);
2135 int m
= BIT_MASK_GET(cmd
, 4, 4);
2136 short cl
= PKE_REG_MASK_GET(me
, CYCLE
, CL
); /* cycle controls */
2137 short wl
= PKE_REG_MASK_GET(me
, CYCLE
, WL
);
2138 short addrwl
= (wl
== 0) ? 0x0100 : wl
;
2139 int r
= BIT_MASK_GET(imm
, 15, 15); /* indicator bits in imm value */
2140 int usn
= BIT_MASK_GET(imm
, 14, 14);
2142 int n
, num_operands
;
2143 unsigned_4
* last_operand_word
= NULL
;
2145 /* catch all illegal UNPACK variants */
2146 if(vl
== 3 && vn
< 3)
2148 pke_code_error(me
, pkecode
);
2152 /* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
2156 n
= cl
* (nummx
/ addrwl
) + PKE_LIMIT(nummx
% addrwl
, cl
);
2157 num_operands
= (31 + (32 >> vl
) * (vn
+1) * n
)/32; /* round up to next word */
2159 /* confirm that FIFO has enough words in it */
2160 if(num_operands
> 0)
2161 last_operand_word
= pke_pcrel_operand(me
, num_operands
);
2162 if(last_operand_word
!= NULL
|| num_operands
== 0)
2164 address_word vu_addr_base
, vutrack_addr_base
;
2165 address_word vu_addr_max_size
;
2166 int vector_num_out
, vector_num_in
;
2168 /* "transferring" operand */
2169 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
2172 if(me
->trace_file
!= NULL
)
2174 char unpack_type
[8];
2176 sprintf(flags
,"[%s%s%s%s]",
2180 (BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
) ? "i" : ""));
2182 sprintf(unpack_type
, "V%d_%d",
2184 (vl
== 3 ? 5 : (32 >> vl
)));
2186 sprintf(unpack_type
, "S_%d",
2187 (vl
== 3 ? 5 : (32 >> vl
)));
2189 fprintf(me
->trace_file
,
2192 "\tUNPACK%s %s,0x%x,0x%x\n",
2193 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
2194 flags
, unpack_type
, imm
, num
);
2197 /* don't check whether VU is idle */
2199 /* compute VU address base */
2200 if(me
->pke_number
== 0)
2202 vu_addr_base
= VU0_MEM1_WINDOW_START
;
2203 vu_addr_max_size
= VU0_MEM1_SIZE
;
2204 vutrack_addr_base
= VU0_MEM1_SRCADDR_START
;
2209 vu_addr_base
= VU1_MEM1_WINDOW_START
;
2210 vu_addr_max_size
= VU1_MEM1_SIZE
;
2211 vutrack_addr_base
= VU1_MEM1_SRCADDR_START
;
2215 PKE_REG_MASK_SET(me
, NUM
, NUM
, nummx
);
2217 /* transfer given number of vectors */
2218 vector_num_out
= 0; /* output vector number being processed */
2219 vector_num_in
= 0; /* argument vector number being processed */
2222 quadword vu_old_data
;
2223 quadword vu_new_data
;
2224 quadword unpacked_data
;
2225 address_word vu_addr
;
2226 address_word vutrack_addr
;
2227 unsigned_4 source_addr
= 0;
2232 next_num
= PKE_REG_MASK_GET(me
, NUM
, NUM
) - 1;
2233 PKE_REG_MASK_SET(me
, NUM
, NUM
, next_num
);
2235 /* compute VU destination address, as bytes in R5900 memory */
2238 /* map zero to max+1 */
2239 vu_addr
= vu_addr_base
+ 16 * (BIT_MASK_GET(imm
, 0, 9) +
2240 (vector_num_out
/ addrwl
) * cl
+
2241 (vector_num_out
% addrwl
));
2244 vu_addr
= vu_addr_base
+ 16 * (BIT_MASK_GET(imm
, 0, 9) +
2247 /* handle "R" double-buffering bit */
2249 vu_addr
+= 16 * PKE_REG_MASK_GET(me
, TOPS
, TOPS
);
2251 /* check for vu_addr overflow */
2252 while(vu_addr
>= vu_addr_base
+ vu_addr_max_size
)
2253 vu_addr
-= vu_addr_max_size
;
2255 /* compute address of tracking table entry */
2256 vutrack_addr
= vutrack_addr_base
+ ((signed_8
)vu_addr
- (signed_8
)vu_addr_base
) / 4;
2258 /* read old VU data word at address; reverse words if needed */
2260 unsigned_16 vu_old_badwords
;
2261 ASSERT(sizeof(vu_old_badwords
) == 16);
2262 PKE_MEM_READ(me
, vu_addr
,
2263 &vu_old_badwords
, 16);
2264 vu_old_data
[0] = * A4_16(& vu_old_badwords
, 3);
2265 vu_old_data
[1] = * A4_16(& vu_old_badwords
, 2);
2266 vu_old_data
[2] = * A4_16(& vu_old_badwords
, 1);
2267 vu_old_data
[3] = * A4_16(& vu_old_badwords
, 0);
2270 /* For cyclic unpack, next operand quadword may come from instruction stream
2273 (vector_num_out
% addrwl
) >= cl
)
2275 /* clear operand - used only in a "indeterminate" state */
2276 for(i
= 0; i
< 4; i
++)
2277 unpacked_data
[i
] = 0;
2281 /* compute packed vector dimensions */
2282 int vectorbits
= 0, unitbits
= 0;
2285 if(me
->trace_file
!= NULL
)
2287 fprintf(me
->trace_file
, "\t; unpack input row %d\n", vector_num_in
);
2290 if(vl
< 3) /* PKE_UNPACK_*_{32,16,8} */
2292 unitbits
= (32 >> vl
);
2293 vectorbits
= unitbits
* (vn
+1);
2295 else if(vl
== 3 && vn
== 3) /* PKE_UNPACK_V4_5 */
2300 else /* illegal unpack variant */
2302 /* should have been caught at top of function */
2306 /* loop over columns */
2307 for(i
=0; i
<=vn
; i
++)
2311 /* offset in bits in current operand word */
2313 (vector_num_in
* vectorbits
) + (i
* unitbits
); /* # of bits from PKEcode */
2315 /* last unit of V4_5 is only one bit wide */
2316 if(vl
== 3 && vn
== 3 && i
== 3) /* PKE_UNPACK_V4_5 */
2319 /* confirm we're not reading more than we said we needed */
2320 if(vector_num_in
* vectorbits
>= num_operands
* 32)
2322 /* this condition may be triggered by illegal
2323 PKEcode / CYCLE combinations. */
2324 pke_code_error(me
, pkecode
);
2325 /* XXX: this case needs to be better understood,
2326 and detected at a better time. */
2330 /* fetch bitfield operand */
2331 operand
= pke_pcrel_operand_bits(me
, bitoffset
, unitbits
, & source_addr
);
2334 if(me
->trace_file
!= NULL
&& vl
< 3) /* not for V4_5 */
2337 if(vl
== 0) data_size
=".word";
2338 else if(vl
== 1) data_size
=".short";
2339 else if(vl
== 2) data_size
=".byte";
2340 else data_size
= "<invalid>";
2342 fprintf(me
->trace_file
, "\t%s 0x%x\n", data_size
, operand
);
2345 /* selectively sign-extend; not for V4_5 1-bit value */
2346 if(usn
|| unitbits
== 1)
2347 unpacked_data
[i
] = operand
;
2349 unpacked_data
[i
] = SEXT32(operand
, unitbits
-1);
2353 if(me
->trace_file
!= NULL
&& vl
== 3) /* only for V4_5 */
2355 unsigned short operand
=
2356 ((unpacked_data
[0] & 0x1f) << 0) |
2357 ((unpacked_data
[1] & 0x1f) << 5) |
2358 ((unpacked_data
[2] & 0x1f) << 10) |
2359 ((unpacked_data
[3] & 0x1) << 15);
2361 fprintf(me
->trace_file
, "\t.short 0x%x\n", operand
);
2364 /* set remaining top words in vector */
2365 for(i
=vn
+1; i
<4; i
++)
2367 if(vn
== 0) /* S_{32,16,8}: copy lowest element */
2368 unpacked_data
[i
] = unpacked_data
[0];
2370 unpacked_data
[i
] = 0;
2373 /* consumed a vector from the PKE instruction stream */
2375 } /* unpack word from instruction operand */
2377 /* process STMOD register for accumulation operations */
2378 switch(PKE_REG_MASK_GET(me
, MODE
, MDE
))
2380 case PKE_MODE_ADDROW
: /* add row registers to output data */
2381 case PKE_MODE_ACCROW
: /* same .. later conditionally accumulate */
2383 /* exploit R0..R3 contiguity */
2384 unpacked_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
2387 case PKE_MODE_INPUT
: /* pass data through */
2388 default: /* specified as undefined */
2392 /* compute replacement word */
2393 if(m
) /* use mask register? */
2395 /* compute index into mask register for this word */
2396 int mask_index
= PKE_LIMIT(vector_num_out
% addrwl
, 3);
2398 for(i
=0; i
<4; i
++) /* loop over columns */
2400 int mask_op
= PKE_MASKREG_GET(me
, mask_index
, i
);
2401 unsigned_4
* masked_value
= NULL
;
2405 case PKE_MASKREG_INPUT
:
2406 masked_value
= & unpacked_data
[i
];
2408 /* conditionally accumulate */
2409 if(PKE_REG_MASK_GET(me
, MODE
, MDE
) == PKE_MODE_ACCROW
)
2410 me
->regs
[PKE_REG_R0
+ i
][0] = unpacked_data
[i
];
2414 case PKE_MASKREG_ROW
: /* exploit R0..R3 contiguity */
2415 masked_value
= & me
->regs
[PKE_REG_R0
+ i
][0];
2418 case PKE_MASKREG_COLUMN
: /* exploit C0..C3 contiguity */
2419 masked_value
= & me
->regs
[PKE_REG_C0
+ mask_index
][0];
2422 case PKE_MASKREG_NOTHING
:
2423 /* "write inhibit" by re-copying old data */
2424 masked_value
= & vu_old_data
[i
];
2429 /* no other cases possible */
2432 /* copy masked value for column */
2433 vu_new_data
[i
] = *masked_value
;
2434 } /* loop over columns */
2438 /* no mask - just copy over entire unpacked quadword */
2439 memcpy(vu_new_data
, unpacked_data
, sizeof(unpacked_data
));
2441 /* conditionally store accumulated row results */
2442 if(PKE_REG_MASK_GET(me
, MODE
, MDE
) == PKE_MODE_ACCROW
)
2444 me
->regs
[PKE_REG_R0
+ i
][0] = unpacked_data
[i
];
2447 /* write new VU data word at address; reverse words if needed */
2449 unsigned_16 vu_new_badwords
;
2450 * A4_16(& vu_new_badwords
, 3) = vu_new_data
[0];
2451 * A4_16(& vu_new_badwords
, 2) = vu_new_data
[1];
2452 * A4_16(& vu_new_badwords
, 1) = vu_new_data
[2];
2453 * A4_16(& vu_new_badwords
, 0) = vu_new_data
[3];
2454 ASSERT(sizeof(vu_new_badwords
) == 16);
2455 PKE_MEM_WRITE(me
, vu_addr
,
2456 &vu_new_badwords
, 16);
2459 /* write tracking address */
2460 ASSERT(sizeof(unsigned_4
) == 4);
2461 PKE_MEM_WRITE(me
, vutrack_addr
,
2465 /* next vector please */
2467 } /* vector transfer loop */
2468 while(PKE_REG_MASK_GET(me
, NUM
, NUM
) > 0);
2470 /* confirm we've written as many vectors as told */
2471 ASSERT(nummx
== vector_num_out
);
2474 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
2475 if(me
->trace_file
!= NULL
)
2477 fprintf(me
->trace_file
,
2481 pke_pc_advance(me
, 1 + num_operands
);
2482 } /* PKE FIFO full enough */
2485 /* need to wait for another word */
2486 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
2487 /* retry this instruction next clock */
2493 pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
)
2495 /* set ER1 flag in STAT register */
2496 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
2498 if(! PKE_REG_MASK_GET(me
, ERR
, ME1
))
2500 pke_begin_interrupt_stall(me
);
2501 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
2505 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
2508 if(me
->trace_file
!= NULL
)
2510 fprintf(me
->trace_file
,
2515 me
->dev
.name
, me
->fifo_pc
, me
->qw_pc
,
2519 /* advance over faulty word */
2520 pke_pc_advance(me
, 1);
2524 pke_options(struct pke_device
*me
, unsigned_4 option
, char *option_string
)
2528 case SKY_OPT_DEBUG_NAME
:
2529 if ( me
->fifo_trace_file
!= NULL
)
2531 fclose (me
->fifo_trace_file
);
2532 me
->fifo_trace_file
= NULL
;
2534 sky_store_file_name (&me
->fifo_trace_file_name
, option_string
);
2537 case SKY_OPT_TRACE_ON
:
2538 me
->flags
|= PKE_FLAG_TRACE_ON
;
2541 case SKY_OPT_TRACE_OFF
:
2542 case SKY_OPT_TRACE_NAME
:
2543 if ( me
->trace_file
!= NULL
)
2545 fprintf(me
->trace_file
,
2548 fclose (me
->trace_file
);
2549 me
->trace_file
= NULL
;
2552 if ( option
== SKY_OPT_TRACE_OFF
)
2553 me
->flags
&= ~PKE_FLAG_TRACE_ON
;
2555 sky_store_file_name (&me
->trace_file_name
, option_string
);
2560 if (me
->trace_file
!= NULL
)
2562 fprintf(me
->trace_file
,
2565 fclose(me
->trace_file
);
2566 me
->trace_file
= NULL
;
2568 if (me
->fifo_trace_file
!= NULL
)
2569 fclose (me
->fifo_trace_file
);
2570 me
->fifo_trace_file
= NULL
;