1 /* Copyright (C) 1998, Cygnus Solutions */
6 #include "sim-assert.h"
11 /* Imported functions */
13 void device_error (device
*me
, char* message
); /* device.c */
16 /* Internal function declarations */
18 static int pke_io_read_buffer(device
*, void*, int, address_word
,
19 unsigned, sim_cpu
*, sim_cia
);
20 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
21 unsigned, sim_cpu
*, sim_cia
);
22 static void pke_issue(struct pke_device
*);
23 static void pke_pc_advance(struct pke_device
*, int num_words
);
24 static unsigned_4
* pke_pc_operand(struct pke_device
*, int word_num
);
25 static struct fifo_quadword
* pke_pc_fifo(struct pke_device
*, int word_num
);
26 static int pke_track_write(struct pke_device
*, const void* src
, int len
,
27 address_word dest
, unsigned_4 sourceaddr
);
28 static void pke_attach(SIM_DESC sd
, struct pke_device
* me
);
34 struct pke_device pke0_device
=
36 { "pke0", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
39 NULL
, 0, 0, NULL
, /* FIFO */
44 struct pke_device pke1_device
=
46 { "pke1", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
49 NULL
, 0, 0, NULL
, /* FIFO */
55 /* External functions */
58 /* Attach PKE addresses to main memory */
61 pke0_attach(SIM_DESC sd
)
63 pke_attach(sd
, & pke0_device
);
67 pke1_attach(SIM_DESC sd
)
69 pke_attach(sd
, & pke1_device
);
74 /* Issue a PKE instruction if possible */
79 pke_issue(& pke0_device
);
85 pke_issue(& pke0_device
);
90 /* Internal functions */
93 /* Attach PKE memory regions to simulator */
96 pke_attach(SIM_DESC sd
, struct pke_device
* me
)
104 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
,
105 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
107 (device
*) &pke0_device
,
116 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
,
117 sizeof(quadword
) /*nr_bytes*/,
119 (device
*) &pke1_device
,
122 /* source-addr tracking word */
128 (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
129 sizeof(unsigned_4
) /*nr_bytes*/,
132 zalloc(sizeof(unsigned_4
)) /*buffer*/);
137 /* Handle a PKE read; return no. of bytes read */
140 pke_io_read_buffer(device
*me_
,
148 /* downcast to gather embedding pke_device struct */
149 struct pke_device
* me
= (struct pke_device
*) me_
;
151 /* find my address ranges */
152 address_word my_reg_start
=
153 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
154 address_word my_fifo_addr
=
155 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
157 /* enforce that an access does not span more than one quadword */
158 address_word low
= ADDR_TRUNC_QW(addr
);
159 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
163 /* classify address & handle */
164 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
167 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
168 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
173 result
[0] = result
[1] = result
[2] = result
[3] = 0;
175 /* handle reads to individual registers; clear `readable' on error */
178 /* handle common case of register reading, side-effect free */
179 /* PKE1-only registers*/
185 if(me
->pke_number
== 0)
188 /* PKE0 & PKE1 common registers*/
207 result
[0] = me
->regs
[reg_num
][0];
210 /* handle common case of write-only registers */
216 ASSERT(0); /* test above should prevent this possibility */
219 /* perform transfer & return */
223 memcpy(dest
, ((unsigned_1
*) &result
) + reg_byte
, nr_bytes
);
235 else if(addr
>= my_fifo_addr
&&
236 addr
< my_fifo_addr
+ sizeof(quadword
))
240 /* FIFO is not readable: return a word of zeroes */
241 memset(dest
, 0, nr_bytes
);
250 /* Handle a PKE read; return no. of bytes written */
253 pke_io_write_buffer(device
*me_
,
261 /* downcast to gather embedding pke_device struct */
262 struct pke_device
* me
= (struct pke_device
*) me_
;
264 /* find my address ranges */
265 address_word my_reg_start
=
266 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
267 address_word my_fifo_addr
=
268 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
270 /* enforce that an access does not span more than one quadword */
271 address_word low
= ADDR_TRUNC_QW(addr
);
272 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
276 /* classify address & handle */
277 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
280 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
281 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
286 input
[0] = input
[1] = input
[2] = input
[3] = 0;
288 /* write user-given bytes into input */
289 memcpy(((unsigned_1
*) &input
) + reg_byte
, src
, nr_bytes
);
291 /* handle writes to individual registers; clear `writeable' on error */
295 /* XXX: order of evaluation? STP && STC ?? */
296 if(BIT_MASK_GET(input
[0], 0, 0)) /* RST bit */
298 /* clear FIFO: also prevents re-execution attempt of
299 possible stalled instruction */
300 me
->fifo_num_elements
= me
->fifo_pc
;
301 /* clear registers */
302 memset(me
->regs
, 0, sizeof(me
->regs
));
306 if(BIT_MASK_GET(input
[0], 1, 1)) /* FBK bit */
308 PKE_REG_MASK_SET(me
, STAT
, PFS
, 1);
310 if(BIT_MASK_GET(input
[0], 2, 2)) /* STP bit */
312 /* XXX: how to safely abort "currently executing" (=> stalled) instruction? */
313 PKE_REG_MASK_SET(me
, STAT
, PSS
, 1);
315 if(BIT_MASK_GET(input
[0], 2, 2)) /* STC bit */
317 /* clear a bunch of status bits */
318 PKE_REG_MASK_SET(me
, STAT
, PSS
, 0);
319 PKE_REG_MASK_SET(me
, STAT
, PFS
, 0);
320 PKE_REG_MASK_SET(me
, STAT
, PIS
, 0);
321 PKE_REG_MASK_SET(me
, STAT
, INT
, 0);
322 PKE_REG_MASK_SET(me
, STAT
, ER0
, 0);
323 PKE_REG_MASK_SET(me
, STAT
, ER1
, 0);
324 /* will allow resumption of possible stalled instruction */
329 /* copy bottom three bits */
330 BIT_MASK_SET(me
->regs
[PKE_REG_ERR
][0], 0, 2, BIT_MASK_GET(input
[0], 0, 2));
334 /* copy bottom sixteen bits */
335 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(input
[0], 0, 15));
336 /* reset MRK bit in STAT */
337 PKE_REG_MASK_SET(me
, STAT
, MRK
, 0);
340 /* handle common case of read-only registers */
341 /* PKE1-only registers - not really necessary to handle separately */
347 if(me
->pke_number
== 0)
350 /* PKE0 & PKE1 common registers*/
352 /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */
372 ASSERT(0); /* test above should prevent this possibility */
389 else if(addr
>= my_fifo_addr
&&
390 addr
< my_fifo_addr
+ sizeof(quadword
))
393 struct fifo_quadword
* fqw
;
395 /* assert transfer size == 128 bits */
396 if(nr_bytes
!= sizeof(quadword
))
399 /* ensure FIFO has enough elements */
400 if(me
->fifo_num_elements
== me
->fifo_buffer_size
)
403 int new_fifo_buffer_size
= me
->fifo_buffer_size
+ 20;
404 void* ptr
= realloc((void*) me
->fifo
, new_fifo_buffer_size
*sizeof(quadword
));
408 /* oops, cannot enlarge FIFO any more */
409 device_error(me_
, "Cannot enlarge FIFO buffer\n");
413 me
->fifo_buffer_size
= new_fifo_buffer_size
;
416 /* add new quadword at end of FIFO */
417 fqw
= & me
->fifo
[me
->fifo_num_elements
];
418 memcpy((void*) fqw
->data
, src
, nr_bytes
);
419 sim_read(CPU_STATE(cpu
),
420 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_CHANNEL0_SRCADDR
: DMA_CHANNEL1_SRCADDR
),
421 (void*) & fqw
->source_address
,
422 sizeof(address_word
));
423 sim_read(CPU_STATE(cpu
),
424 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_CHANNEL0_PKTFLAG
: DMA_CHANNEL1_PKTFLAG
),
425 (void*) & fqw
->dma_tag_present
,
429 me
->fifo_num_elements
++;
431 /* set FQC to "1" as FIFO is now not empty */
432 PKE_REG_MASK_SET(me
, STAT
, FQC
, 1);
444 /* Issue & swallow next PKE opcode if possible/available */
447 pke_issue(struct pke_device
* me
)
449 struct fifo_quadword
* fqw
;
451 unsigned_4 cmd
, intr
, num
;
453 int next_pps_state
; /* PPS after this instruction issue attempt */
455 /* 1 -- test go / no-go for PKE execution */
457 /* check for stall/halt control bits */
458 /* XXX: What is the PEW bit for? */
459 if(PKE_REG_MASK_GET(me
, STAT
, PSS
) ||
460 PKE_REG_MASK_GET(me
, STAT
, PFS
) ||
461 /* maskable stall controls: ER0, ER1, PIS */
462 (PKE_REG_MASK_GET(me
, STAT
, ER0
) && !PKE_REG_MASK_GET(me
, ERR
, ME0
)) ||
463 (PKE_REG_MASK_GET(me
, STAT
, ER1
) && !PKE_REG_MASK_GET(me
, ERR
, ME1
)) ||
464 (PKE_REG_MASK_GET(me
, STAT
, PIS
) && !PKE_REG_MASK_GET(me
, ERR
, MII
)))
468 /* XXX: handle PSS by *skipping* instruction? */
470 /* confirm availability of new quadword of PKE instructions */
471 if(me
->fifo_num_elements
<= me
->fifo_pc
)
475 /* 2 -- fetch PKE instruction */
477 /* "fetch" instruction quadword */
478 fqw
= & me
->fifo
[me
->fifo_pc
];
480 /* skip over DMA tags, if present */
481 if((fqw
->dma_tag_present
!= 0) && (me
->qw_pc
< 2))
483 ASSERT(me
->qw_pc
== 0);
484 /* XXX: check validity of DMA tag; if bad, set ER0 flag */
488 /* "fetch" instruction word */
489 fw
= fqw
->data
[me
->qw_pc
];
491 /* store it in PKECODE register */
492 me
->regs
[PKE_REG_CODE
][0] = fw
;
495 /* 3 -- decode PKE instruction */
497 /* PKE instruction format: [intr 0:0][pke-command 6:0][num 7:0][immediate 15:0],
498 so op-code is in top byte. */
499 intr
= BIT_MASK_GET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
);
500 cmd
= BIT_MASK_GET(fw
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
501 num
= BIT_MASK_GET(fw
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
502 imm
= BIT_MASK_GET(fw
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
506 /* set INT flag in STAT register */
507 PKE_REG_MASK_SET(me
, STAT
, INT
, 1);
508 /* XXX: send interrupt to R5900? */
512 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_DECODE
);
513 next_pps_state
= PKE_REG_STAT_PPS_IDLE
; /* assume instruction completes */
516 if(IS_PKE_CMD(cmd
, PKENOP
))
518 /* no work required, yey */
519 pke_pc_advance(me
, 1);
521 else if(IS_PKE_CMD(cmd
, STCYCL
))
523 /* copy immediate value into CYCLE reg */
524 me
->regs
[PKE_REG_CYCLE
][0] = imm
;
525 pke_pc_advance(me
, 1);
527 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, OFFSET
))
529 /* copy 10 bits to OFFSET field */
530 PKE_REG_MASK_SET(me
, OFST
, OFFSET
, BIT_MASK_GET(imm
, 0, 9));
532 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
533 /* clear other DBF bit */
534 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
535 /* set TOPS = BASE */
536 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
537 PKE_REG_MASK_GET(me
, BASE
, BASE
));
538 pke_pc_advance(me
, 1);
540 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, BASE
))
542 /* copy 10 bits to BASE field */
543 PKE_REG_MASK_SET(me
, BASE
, BASE
, BIT_MASK_GET(imm
, 0, 9));
545 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
546 /* clear other DBF bit */
547 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
548 /* set TOPS = BASE */
549 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
550 PKE_REG_MASK_GET(me
, BASE
, BASE
));
551 pke_pc_advance(me
, 1);
553 else if(IS_PKE_CMD(cmd
, ITOP
))
555 /* copy 10 bits to ITOPS field */
556 PKE_REG_MASK_SET(me
, ITOPS
, ITOPS
, BIT_MASK_GET(imm
, 0, 9));
557 pke_pc_advance(me
, 1);
559 else if(IS_PKE_CMD(cmd
, STMOD
))
561 /* copy 2 bits to MODE register */
562 PKE_REG_MASK_SET(me
, MODE
, MDE
, BIT_MASK_GET(imm
, 0, 2));
563 pke_pc_advance(me
, 1);
565 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, MSKPATH3
)) /* MSKPATH3 */
567 /* XXX: what to do with this? DMA control register? */
568 pke_pc_advance(me
, 1);
570 else if(IS_PKE_CMD(cmd
, PKEMARK
))
572 /* copy 16 bits to MARK register */
573 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(imm
, 0, 15));
574 /* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
575 PKE_REG_MASK_SET(me
, STAT
, MRK
, 1);
576 pke_pc_advance(me
, 1);
578 else if(IS_PKE_CMD(cmd
, FLUSHE
))
580 /* read VU status word */
583 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
588 /* check if VBS bit is clear, i.e., VU is idle */
589 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0)
593 pke_pc_advance(me
, 1);
598 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
599 /* retry this instruction next clock */
602 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSH
))
604 /* read VU status word */
607 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
612 /* check if VGW bit is clear, i.e., PATH1 is idle */
613 /* simulator design implies PATH2 is always "idle" */
614 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0 &&
615 BIT_MASK_GET(vu_stat
, VU_REG_STAT_VGW_B
, VU_REG_STAT_VGW_E
) == 0 &&
616 1 /* PATH2 always idle */)
622 pke_pc_advance(me
, 1);
627 /* retry this instruction next clock */
630 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSHA
))
632 /* read VU status word */
635 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
640 /* check if VGW bit is clear, i.e., PATH1 is idle */
641 /* simulator design implies PATH2 is always "idle" */
642 /* XXX: simulator design implies PATH3 is always "idle" */
643 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0 &&
644 BIT_MASK_GET(vu_stat
, VU_REG_STAT_VGW_B
, VU_REG_STAT_VGW_E
) == 0 &&
645 1 /* PATH2 always idle */ &&
646 1 /* PATH3 always idle */)
653 pke_pc_advance(me
, 1);
658 /* retry this instruction next clock */
661 else if(IS_PKE_CMD(cmd
, PKEMSCAL
))
663 /* read VU status word */
666 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
671 /* check if VBS bit is clear, i.e., VU is idle */
672 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0)
677 /* perform PKE1-unique processing for microprogram calls */
678 if(me
->pke_number
== 1)
681 PKE_REG_MASK_SET(me
, DBF
, DF
,
682 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
683 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
684 /* compute new TOPS */
685 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
686 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
687 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
688 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
689 /* compute new ITOP and TOP */
690 PKE_REG_MASK_SET(me
, ITOP
, ITOP
,
691 PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
692 PKE_REG_MASK_SET(me
, TOP
, TOP
,
693 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
697 vu_pc
= BIT_MASK_GET(imm
, 0, 15); /* XXX: all bits significant? */
698 /* write new PC; callback function gets VU running */
700 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
704 pke_pc_advance(me
, 1);
709 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
710 /* retry this instruction next clock */
713 else if(IS_PKE_CMD(cmd
, PKEMSCNT
))
715 /* read VU status word */
718 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
723 /* check if VBS bit is clear, i.e., VU is idle */
724 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0)
729 /* flip DBF etc. for PKE1 */
730 if(me
->pke_number
== 1)
732 PKE_REG_MASK_SET(me
, DBF
, DF
,
733 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
734 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
735 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
736 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
737 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
738 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
739 PKE_REG_MASK_SET(me
, ITOP
, ITOP
,
740 PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
741 PKE_REG_MASK_SET(me
, TOP
, TOP
,
742 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
747 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
750 /* rewrite its PC; callback function gets VU running */
752 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
756 pke_pc_advance(me
, 1);
761 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
762 /* retry this instruction next clock */
765 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, PKEMSCALF
))
767 /* read VU status word */
770 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
775 /* check if VGW bit is clear, i.e., PATH1 is idle */
776 /* simulator design implies PATH2 is always "idle" */
777 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0 &&
778 BIT_MASK_GET(vu_stat
, VU_REG_STAT_VGW_B
, VU_REG_STAT_VGW_E
) == 0 &&
779 1 /* PATH2 always idle */)
786 /* flip DBF etc. for PKE1 */
787 if(me
->pke_number
== 1)
789 PKE_REG_MASK_SET(me
, DBF
, DF
,
790 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
791 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
792 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
793 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
794 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
795 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
796 PKE_REG_MASK_SET(me
, ITOP
, ITOP
,
797 PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
798 PKE_REG_MASK_SET(me
, TOP
, TOP
,
799 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
803 vu_pc
= BIT_MASK_GET(imm
, 0, 15); /* XXX: all bits significant? */
804 /* write new PC; callback function gets VU running */
806 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
810 pke_pc_advance(me
, 1);
815 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
816 /* retry this instruction next clock */
819 else if(IS_PKE_CMD(cmd
, STMASK
))
821 /* check that FIFO has one more word for STMASK operand */
824 mask
= pke_pc_operand(me
, 1);
827 /* "transferring" operand */
828 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
829 /* fill the register */
830 PKE_REG_MASK_SET(me
, MASK
, MASK
, *mask
);
832 pke_pc_advance(me
, 2);
836 /* need to wait for another word */
837 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
838 /* retry this instruction next clock */
841 else if(IS_PKE_CMD(cmd
, STROW
))
843 /* check that FIFO has four more words for STROW operand */
846 last_op
= pke_pc_operand(me
, 4);
849 /* "transferring" operand */
850 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
852 /* copy ROW registers: must all exist if 4th operand exists */
853 me
->regs
[PKE_REG_R0
][0] = * pke_pc_operand(me
, 1);
854 me
->regs
[PKE_REG_R1
][0] = * pke_pc_operand(me
, 2);
855 me
->regs
[PKE_REG_R2
][0] = * pke_pc_operand(me
, 3);
856 me
->regs
[PKE_REG_R3
][0] = * pke_pc_operand(me
, 4);
859 pke_pc_advance(me
, 5);
863 /* need to wait for another word */
864 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
865 /* retry this instruction next clock */
868 else if(IS_PKE_CMD(cmd
, STCOL
))
870 /* check that FIFO has four more words for STCOL operand */
873 last_op
= pke_pc_operand(me
, 4);
876 /* "transferring" operand */
877 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
879 /* copy COL registers: must all exist if 4th operand exists */
880 me
->regs
[PKE_REG_C0
][0] = * pke_pc_operand(me
, 1);
881 me
->regs
[PKE_REG_C1
][0] = * pke_pc_operand(me
, 2);
882 me
->regs
[PKE_REG_C2
][0] = * pke_pc_operand(me
, 3);
883 me
->regs
[PKE_REG_C3
][0] = * pke_pc_operand(me
, 4);
886 pke_pc_advance(me
, 5);
890 /* need to wait for another word */
891 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
892 /* retry this instruction next clock */
895 else if(IS_PKE_CMD(cmd
, MPG
))
897 unsigned_4
* last_mpg_word
;
899 /* map zero to max+1 */
900 if(num
==0) num
=0x100;
902 /* check that FIFO has a few more words for MPG operand */
903 last_mpg_word
= pke_pc_operand(me
, num
*2); /* num: number of 64-bit words */
904 if(last_mpg_word
!= NULL
)
906 /* perform implied FLUSHE */
907 /* read VU status word */
910 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
915 /* check if VBS bit is clear, i.e., VU is idle */
916 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0)
921 /* "transferring" operand */
922 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
924 /* transfer VU instructions, one word per iteration */
925 for(i
=0; i
<num
*2; i
++)
927 address_word vu_addr_base
, vu_addr
;
928 address_word vutrack_addr_base
, vutrack_addr
;
929 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
);
930 unsigned_4
* operand
= pke_pc_operand(me
, num
);
932 /* imm: in 64-bit units for MPG instruction */
936 /* VU*_MEM0 : instruction memory */
937 vu_addr_base
= (me
->pke_number
== 0) ?
938 VU0_MEM0_WINDOW_START
: VU0_MEM0_WINDOW_START
;
939 vu_addr
= vu_addr_base
+ (imm
*2) + i
;
941 /* VU*_MEM0_TRACK : source-addr tracking table */
942 vutrack_addr_base
= (me
->pke_number
== 0) ?
943 VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
;
944 vutrack_addr
= vu_addr_base
+ (imm
*2) + i
;
946 /* write data into VU memory */
947 pke_track_write(me
, operand
, sizeof(unsigned_4
),
948 vu_addr
, fq
->source_address
);
950 /* write srcaddr into VU srcaddr tracking table */
952 (SIM_ADDR
) vutrack_addr
,
953 (void*) & fq
->source_address
,
959 pke_pc_advance(me
, 1 + num
*2);
964 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
965 /* retry this instruction next clock */
967 } /* if FIFO full enough */
970 /* need to wait for another word */
971 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
972 /* retry this instruction next clock */
975 else if(IS_PKE_CMD(cmd
, DIRECT
) || IS_PKE_CMD(cmd
, DIRECTHL
)) /* treat identically */
977 /* check that FIFO has a few more words for DIRECT operand */
978 unsigned_4
* last_direct_word
;
980 /* map zero to max+1 */
981 if(imm
==0) imm
=0x10000;
983 last_direct_word
= pke_pc_operand(me
, imm
*4); /* num: number of 128-bit words */
984 if(last_direct_word
!= NULL
)
990 /* "transferring" operand */
991 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
993 /* transfer GPUIF quadwords, one word per iteration */
994 for(i
=0; i
<imm
*4; i
++)
996 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
);
997 unsigned_4
* operand
= pke_pc_operand(me
, num
);
999 /* collect word into quadword */
1000 fifo_data
[i
%4] = *operand
;
1002 /* write to GPUIF FIFO only with full word */
1005 address_word gpuif_fifo
= GPUIF_PATH2_FIFO_ADDR
+(i
/4);
1006 pke_track_write(me
, fifo_data
, sizeof(quadword
),
1007 (SIM_ADDR
) gpuif_fifo
, fq
->source_address
);
1009 } /* write collected quadword */
1011 } /* GPUIF xfer loop */
1014 pke_pc_advance(me
, 1 + imm
*4);
1015 } /* if FIFO full enough */
1018 /* need to wait for another word */
1019 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
1020 /* retry this instruction next clock */
1023 else if(IS_PKE_CMD(cmd
, UNPACK
)) /* warning: monster complexity */
1025 short vn
= BIT_MASK_GET(cmd
, 2, 3);
1026 short vl
= BIT_MASK_GET(cmd
, 0, 1);
1027 short vnvl
= BIT_MASK_GET(cmd
, 0, 3);
1028 int m
= BIT_MASK_GET(cmd
, 4, 4);
1029 short cl
= PKE_REG_MASK_GET(me
, CYCLE
, CL
);
1030 short wl
= PKE_REG_MASK_GET(me
, CYCLE
, WL
);
1031 int n
, num_operands
;
1032 unsigned_4
* last_operand_word
;
1034 /* map zero to max+1 */
1035 if(num
==0) num
=0x100;
1037 /* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
1041 n
= cl
* (num
/wl
) + PKE_LIMIT(num
% wl
, cl
);
1042 num_operands
= (((sizeof(unsigned_4
) >> vl
) * (vn
+1) * n
)/sizeof(unsigned_4
));
1044 /* confirm that FIFO has enough words in it */
1045 last_operand_word
= pke_pc_operand(me
, num_operands
);
1046 if(last_operand_word
!= NULL
)
1048 address_word vu_addr_base
;
1049 int operand_num
, vector_num
;
1051 /* "transferring" operand */
1052 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1054 /* XXX: don't check whether VU is idle?? */
1056 if(me
->pke_number
== 0)
1057 vu_addr_base
= VU0_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1060 vu_addr_base
= VU1_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1061 if(BIT_MASK_GET(imm
, 15, 15)) /* fetch R flag from imm word */
1062 vu_addr_base
+= PKE_REG_MASK_GET(me
, TOPS
, TOPS
);
1065 /* XXX: vu_addr overflow check */
1067 /* transfer given number of vectors */
1068 operand_num
= 1; /* word index into instruction stream: 1..num_operands */
1069 vector_num
= 0; /* vector number being processed: 0..num-1 */
1070 while(operand_num
<= num_operands
)
1072 quadword vu_old_data
;
1073 quadword vu_new_data
;
1074 quadword unpacked_data
;
1075 address_word vu_addr
;
1076 struct fifo_quadword
* fq
;
1081 /* compute VU destination address, as bytes in R5900 memory */
1084 /* map zero to max+1 */
1085 if(wl
== 0) wl
= 0x0100;
1086 vu_addr
= vu_addr_base
+ 16*(cl
*(vector_num
/wl
) + (vector_num
%wl
));
1089 vu_addr
= vu_addr_base
+ 16*vector_num
;
1091 /* read old VU data word at address */
1092 sim_read(NULL
, (SIM_ADDR
) vu_addr
, (void*) & vu_old_data
, sizeof(vu_old_data
));
1094 /* Let sourceaddr track the first operand */
1095 fq
= pke_pc_fifo(me
, operand_num
);
1097 /* For cyclic unpack, next operand quadword may come from instruction stream
1099 if((cl
< wl
) && ((vector_num
% wl
) >= cl
)) /* wl != 0, set above */
1101 /* clear operand - used only in a "indeterminate" state */
1102 for(i
= 0; i
< 4; i
++)
1103 unpacked_data
[i
] = 0;
1107 /* compute unpacked words from instruction stream */
1110 case PKE_UNPACK_S_32
:
1111 case PKE_UNPACK_V2_32
:
1112 case PKE_UNPACK_V3_32
:
1113 case PKE_UNPACK_V4_32
:
1114 /* copy (vn+1) 32-bit values */
1115 for(i
= 0; i
< vn
+1; i
++)
1117 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1118 unpacked_data
[i
] = *operand
;
1123 case PKE_UNPACK_S_16
:
1124 case PKE_UNPACK_V2_16
:
1125 case PKE_UNPACK_V3_16
:
1126 case PKE_UNPACK_V4_16
:
1127 /* copy (vn+1) 16-bit values, packed two-per-word */
1128 for(i
=0; i
<vn
+1; i
+=2)
1130 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1131 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 15, 31);
1132 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 16, 31, 31);
1137 case PKE_UNPACK_S_8
:
1138 case PKE_UNPACK_V2_8
:
1139 case PKE_UNPACK_V3_8
:
1140 case PKE_UNPACK_V4_8
:
1141 /* copy (vn+1) 8-bit values, packed four-per-word */
1142 for(i
=0; i
<vn
+1; i
+=4)
1144 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1145 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 7, 31);
1146 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 8, 15, 31);
1147 unpacked_data
[i
+2] = BIT_MASK_GET_SX(*operand
, 16, 23, 31);
1148 unpacked_data
[i
+3] = BIT_MASK_GET_SX(*operand
, 24, 31, 31);
1153 case PKE_UNPACK_V4_5
:
1154 /* copy four 1/5/5/5-bit values, packed into a sixteen-bit */
1155 for(i
=0; i
<vn
+1; i
+=4)
1157 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1158 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 4, 31);
1159 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 5, 9, 31);
1160 unpacked_data
[i
+2] = BIT_MASK_GET_SX(*operand
, 10, 14, 31);
1161 unpacked_data
[i
+3] = BIT_MASK_GET_SX(*operand
, 15, 15, 31);
1162 /* ignore other 16 bits in operand */
1167 default: /* bad UNPACK code */
1169 /* XXX: how to handle? */
1170 /* set ER1 flag in STAT register */
1171 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
1176 /* compute replacement word - function of vn, vl, mask */
1177 if(m
) /* use mask register? */
1179 /* compute index into mask register for this word */
1180 int mask_index
= PKE_LIMIT(vector_num
% wl
, 3); /* wl != 0, set above */
1182 for(i
=0; i
<3; i
++) /* loop over columns */
1184 int mask_op
= PKE_MASKREG_GET(me
, mask_index
, i
);
1185 unsigned_4
* masked_value
= NULL
;
1186 unsigned_4 zero
= 0;
1190 case PKE_MASKREG_INPUT
:
1191 /* for vn == 0, all columns are copied from column 0 */
1193 masked_value
= & unpacked_data
[0];
1195 masked_value
= & zero
; /* XXX: what to put here? */
1197 masked_value
= & unpacked_data
[i
];
1200 case PKE_MASKREG_ROW
: /* exploit R0..R3 contiguity */
1201 masked_value
= & me
->regs
[PKE_REG_R0
+ i
][0];
1204 case PKE_MASKREG_COLUMN
: /* exploit C0..C3 contiguity */
1205 masked_value
= & me
->regs
[PKE_REG_C0
+ PKE_LIMIT(vector_num
,3)][0];
1208 case PKE_MASKREG_NOTHING
:
1209 /* "write inhibit" by re-copying old data */
1210 masked_value
= & vu_old_data
[i
];
1215 /* no other cases possible */
1218 /* copy masked value for column */
1219 memcpy(& vu_new_data
[i
], masked_value
, sizeof(unsigned_4
));
1220 } /* loop over columns */
1224 /* no mask - just copy over entire unpacked quadword */
1225 memcpy(vu_new_data
, unpacked_data
, sizeof(unpacked_data
));
1228 /* process STMOD register for accumulation operations */
1229 switch(PKE_REG_MASK_GET(me
, MODE
, MDE
))
1231 case PKE_MODE_ADDROW
: /* add row registers to output data */
1233 /* exploit R0..R3 contiguity */
1234 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1237 case PKE_MODE_ACCROW
: /* add row registers to output data; accumulate */
1240 /* exploit R0..R3 contiguity */
1241 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1242 me
->regs
[PKE_REG_R0
+ i
][0] = vu_new_data
[i
];
1246 case PKE_MODE_INPUT
: /* pass data through */
1251 /* write replacement word */
1252 pke_track_write(me
, vu_new_data
, sizeof(vu_new_data
),
1253 (SIM_ADDR
) vu_addr
, fq
->source_address
);
1255 /* next vector please */
1257 } /* vector transfer loop */
1258 } /* PKE FIFO full enough */
1261 /* need to wait for another word */
1262 next_pps_state
= PKE_REG_STAT_PPS_WAIT
;
1263 /* retry this instruction next clock */
1269 /* set ER1 flag in STAT register */
1270 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
1271 /* advance over faulty word */
1272 pke_pc_advance(me
, 1);
1275 /* PKE is now idle or waiting */
1276 PKE_REG_MASK_SET(me
, STAT
, PPS
, next_pps_state
);
1284 /* advance the PC by given number of words; update STAT/FQC field */
1287 pke_pc_advance(struct pke_device
* me
, int num_words
)
1289 ASSERT(num_words
> 0);
1291 me
->qw_pc
+= num_words
;
1292 /* handle overflow */
1293 while(me
->qw_pc
>= 4)
1299 /* clear FQC if FIFO is now empty */
1300 if(me
->fifo_num_elements
== me
->fifo_pc
)
1302 PKE_REG_MASK_SET(me
, STAT
, FQC
, 0);
1309 /* Return pointer to given operand# in FIFO. `word_num' starts at 1.
1310 If FIFO is not full enough, return 0. */
1313 pke_pc_operand(struct pke_device
* me
, int word_num
)
1317 unsigned_4
* operand
;
1319 ASSERT(word_num
> 0);
1321 new_fifo_pc
= me
->fifo_pc
;
1322 new_qw_pc
+= me
->qw_pc
+ word_num
;
1324 /* handle overflow */
1325 while(new_qw_pc
>= 4)
1331 /* not enough elements */
1332 if(me
->fifo_num_elements
== me
->fifo_pc
)
1335 operand
= & me
->fifo
[new_fifo_pc
].data
[new_qw_pc
];
1342 /* Return pointer to FIFO quadword containing given operand# in FIFO.
1343 `word_num' starts at 1. If FIFO is not full enough, return 0. */
1345 struct fifo_quadword
*
1346 pke_pc_fifo(struct pke_device
* me
, int word_num
)
1350 struct fifo_quadword
* operand
;
1352 ASSERT(word_num
> 0);
1354 new_fifo_pc
= me
->fifo_pc
;
1355 new_qw_pc
+= me
->qw_pc
+ word_num
;
1357 /* handle overflow */
1358 while(new_qw_pc
>= 4)
1364 /* not enough elements */
1365 if(me
->fifo_num_elements
== me
->fifo_pc
)
1368 operand
= & me
->fifo
[new_fifo_pc
];
1375 /* Write a bunch of bytes into simulator memory. Store the given source address into the
1376 PKE sourceaddr tracking word. */
1378 pke_track_write(struct pke_device
* me
, const void* src
, int len
,
1379 address_word dest
, unsigned_4 sourceaddr
)
1382 unsigned_4 no_sourceaddr
= 0;
1384 /* write srcaddr into PKE srcaddr tracking */
1386 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
1387 (void*) & sourceaddr
,
1388 sizeof(unsigned_4
));
1390 /* write bytes into simulator */
1391 rc
= sim_write(NULL
,
1396 /* clear srcaddr from PKE srcaddr tracking */
1398 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
1399 (void*) & no_sourceaddr
,
1400 sizeof(unsigned_4
));