1 /* Copyright (C) 1998, Cygnus Solutions */
10 #include "sim-assert.h"
13 #include "sky-gpuif.h"
16 /* Imported functions */
18 void device_error (device
*me
, char* message
); /* device.c */
21 /* Internal function declarations */
23 static int pke_io_read_buffer(device
*, void*, int, address_word
,
24 unsigned, sim_cpu
*, sim_cia
);
25 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
26 unsigned, sim_cpu
*, sim_cia
);
27 static void pke_issue(struct pke_device
*);
28 static void pke_pc_advance(struct pke_device
*, int num_words
);
29 static unsigned_4
* pke_pc_operand(struct pke_device
*, int operand_num
);
30 static unsigned_4
pke_pc_operand_bits(struct pke_device
*, int bit_offset
,
31 int bit_width
, unsigned_4
* sourceaddr
);
32 static struct fifo_quadword
* pke_pc_fifo(struct pke_device
*, int operand_num
,
33 unsigned_4
** operand
);
34 static int pke_track_write(struct pke_device
*, const void* src
, int len
,
35 address_word dest
, unsigned_4 sourceaddr
);
36 static void pke_attach(SIM_DESC sd
, struct pke_device
* me
);
37 enum pke_check_target
{ chk_vu
, chk_path1
, chk_path2
, chk_path3
};
38 static int pke_check_stall(struct pke_device
* me
, enum pke_check_target what
);
39 static void pke_flip_dbf(struct pke_device
* me
);
40 /* PKEcode handlers */
41 static void pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
);
42 static void pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
);
43 static void pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
);
44 static void pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
);
45 static void pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
);
46 static void pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
);
47 static void pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
);
48 static void pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
);
49 static void pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
);
50 static void pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
);
51 static void pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
);
52 static void pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
);
53 static void pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
);
54 static void pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
);
55 static void pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
);
56 static void pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
);
57 static void pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
);
58 static void pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
);
59 static void pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
);
60 static void pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
);
61 static void pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
);
62 static void pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
);
68 struct pke_device pke0_device
=
70 { "pke0", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
73 {}, 0, /* FIFO write buffer */
74 NULL
, 0, 0, NULL
, /* FIFO */
79 struct pke_device pke1_device
=
81 { "pke1", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
84 {}, 0, /* FIFO write buffer */
85 NULL
, 0, 0, NULL
, /* FIFO */
91 /* External functions */
94 /* Attach PKE addresses to main memory */
97 pke0_attach(SIM_DESC sd
)
99 pke_attach(sd
, & pke0_device
);
103 pke1_attach(SIM_DESC sd
)
105 pke_attach(sd
, & pke1_device
);
110 /* Issue a PKE instruction if possible */
115 pke_issue(& pke0_device
);
121 pke_issue(& pke0_device
);
126 /* Internal functions */
129 /* Attach PKE memory regions to simulator */
132 pke_attach(SIM_DESC sd
, struct pke_device
* me
)
140 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
,
141 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
143 (device
*) &pke0_device
,
152 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
,
153 sizeof(quadword
) /*nr_bytes*/,
155 (device
*) &pke1_device
,
158 /* source-addr tracking word */
164 (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
165 sizeof(unsigned_4
) /*nr_bytes*/,
168 zalloc(sizeof(unsigned_4
)) /*buffer*/);
173 /* Handle a PKE read; return no. of bytes read */
176 pke_io_read_buffer(device
*me_
,
184 /* downcast to gather embedding pke_device struct */
185 struct pke_device
* me
= (struct pke_device
*) me_
;
187 /* find my address ranges */
188 address_word my_reg_start
=
189 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
190 address_word my_fifo_addr
=
191 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
193 /* enforce that an access does not span more than one quadword */
194 address_word low
= ADDR_TRUNC_QW(addr
);
195 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
199 /* classify address & handle */
200 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
203 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
204 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
209 result
[0] = result
[1] = result
[2] = result
[3] = 0;
211 /* handle reads to individual registers; clear `readable' on error */
214 /* handle common case of register reading, side-effect free */
215 /* PKE1-only registers*/
221 if(me
->pke_number
== 0)
224 /* PKE0 & PKE1 common registers*/
243 result
[0] = me
->regs
[reg_num
][0];
246 /* handle common case of write-only registers */
252 ASSERT(0); /* test above should prevent this possibility */
255 /* perform transfer & return */
259 memcpy(dest
, ((unsigned_1
*) &result
) + reg_byte
, nr_bytes
);
271 else if(addr
>= my_fifo_addr
&&
272 addr
< my_fifo_addr
+ sizeof(quadword
))
276 /* FIFO is not readable: return a word of zeroes */
277 memset(dest
, 0, nr_bytes
);
286 /* Handle a PKE read; return no. of bytes written */
289 pke_io_write_buffer(device
*me_
,
297 /* downcast to gather embedding pke_device struct */
298 struct pke_device
* me
= (struct pke_device
*) me_
;
300 /* find my address ranges */
301 address_word my_reg_start
=
302 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
303 address_word my_fifo_addr
=
304 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
306 /* enforce that an access does not span more than one quadword */
307 address_word low
= ADDR_TRUNC_QW(addr
);
308 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
312 /* classify address & handle */
313 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
316 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
317 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
322 input
[0] = input
[1] = input
[2] = input
[3] = 0;
324 /* write user-given bytes into input */
325 memcpy(((unsigned_1
*) &input
) + reg_byte
, src
, nr_bytes
);
327 /* handle writes to individual registers; clear `writeable' on error */
331 /* Order these tests from least to most overriding, in case
332 multiple bits are set. */
333 if(BIT_MASK_GET(input
[0], 2, 2)) /* STC bit */
335 /* clear a bunch of status bits */
336 PKE_REG_MASK_SET(me
, STAT
, PSS
, 0);
337 PKE_REG_MASK_SET(me
, STAT
, PFS
, 0);
338 PKE_REG_MASK_SET(me
, STAT
, PIS
, 0);
339 PKE_REG_MASK_SET(me
, STAT
, INT
, 0);
340 PKE_REG_MASK_SET(me
, STAT
, ER0
, 0);
341 PKE_REG_MASK_SET(me
, STAT
, ER1
, 0);
342 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
343 /* will allow resumption of possible stalled instruction */
345 if(BIT_MASK_GET(input
[0], 2, 2)) /* STP bit */
347 me
->flags
|= PKE_FLAG_PENDING_PSS
;
349 if(BIT_MASK_GET(input
[0], 1, 1)) /* FBK bit */
351 PKE_REG_MASK_SET(me
, STAT
, PFS
, 1);
353 if(BIT_MASK_GET(input
[0], 0, 0)) /* RST bit */
355 /* clear FIFO by skipping to word after PC: also
356 prevents re-execution attempt of possible stalled
358 me
->fifo_num_elements
= me
->fifo_pc
;
359 /* clear registers, flag, other state */
360 memset(me
->regs
, 0, sizeof(me
->regs
));
361 me
->fifo_qw_done
= 0;
368 /* copy bottom three bits */
369 BIT_MASK_SET(me
->regs
[PKE_REG_ERR
][0], 0, 2, BIT_MASK_GET(input
[0], 0, 2));
373 /* copy bottom sixteen bits */
374 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(input
[0], 0, 15));
375 /* reset MRK bit in STAT */
376 PKE_REG_MASK_SET(me
, STAT
, MRK
, 0);
379 /* handle common case of read-only registers */
380 /* PKE1-only registers - not really necessary to handle separately */
386 if(me
->pke_number
== 0)
389 /* PKE0 & PKE1 common registers*/
391 /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */
411 ASSERT(0); /* test above should prevent this possibility */
428 else if(addr
>= my_fifo_addr
&&
429 addr
< my_fifo_addr
+ sizeof(quadword
))
432 struct fifo_quadword
* fqw
;
433 int fifo_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside fifo quadword */
436 /* collect potentially-partial quadword in write buffer */
437 memcpy(((unsigned_1
*)& me
->fifo_qw_in_progress
) + fifo_byte
, src
, nr_bytes
);
438 /* mark bytes written */
439 for(i
= fifo_byte
; i
< fifo_byte
+ nr_bytes
; i
++)
440 BIT_MASK_SET(me
->fifo_qw_done
, i
, i
, 1);
442 /* return if quadword not quite written yet */
443 if(BIT_MASK_GET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1) !=
444 BIT_MASK_BTW(0, sizeof(quadword
)))
447 /* all done - process quadword after clearing flag */
448 BIT_MASK_SET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1, 0);
450 /* ensure FIFO has enough elements */
451 if(me
->fifo_num_elements
== me
->fifo_buffer_size
)
454 int new_fifo_buffer_size
= me
->fifo_buffer_size
+ 20;
455 void* ptr
= realloc((void*) me
->fifo
, new_fifo_buffer_size
*sizeof(quadword
));
459 /* oops, cannot enlarge FIFO any more */
460 device_error(me_
, "Cannot enlarge FIFO buffer\n");
464 me
->fifo_buffer_size
= new_fifo_buffer_size
;
467 /* add new quadword at end of FIFO */
468 fqw
= & me
->fifo
[me
->fifo_num_elements
];
469 memcpy((void*) fqw
->data
, me
->fifo_qw_in_progress
, sizeof(quadword
));
470 sim_read(CPU_STATE(cpu
),
471 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_D0_SRCADDR
: DMA_D1_SRCADDR
),
472 (void*) & fqw
->source_address
,
473 sizeof(address_word
));
474 sim_read(CPU_STATE(cpu
),
475 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_D0_PKTFLAG
: DMA_D1_PKTFLAG
),
476 (void*) & fqw
->dma_tag_present
,
479 me
->fifo_num_elements
++;
481 /* set FQC to "1" as FIFO is now not empty */
482 PKE_REG_MASK_SET(me
, STAT
, FQC
, 1);
494 /* Issue & swallow next PKE opcode if possible/available */
497 pke_issue(struct pke_device
* me
)
499 struct fifo_quadword
* fqw
;
501 unsigned_4 cmd
, intr
, num
;
504 /* 1 -- test go / no-go for PKE execution */
506 /* switch on STAT:PSS if PSS-pending and in idle state */
507 if((PKE_REG_MASK_GET(me
, STAT
, PPS
) == PKE_REG_STAT_PPS_IDLE
) &&
508 (me
->flags
& PKE_FLAG_PENDING_PSS
) != 0)
510 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
511 PKE_REG_MASK_SET(me
, STAT
, PSS
, 1);
514 /* check for stall/halt control bits */
515 if(PKE_REG_MASK_GET(me
, STAT
, PFS
) ||
516 PKE_REG_MASK_GET(me
, STAT
, PSS
) || /* note special treatment below */
517 /* PEW bit not a reason to keep stalling - it's re-checked below */
518 /* PGW bit not a reason to keep stalling - it's re-checked below */
519 /* maskable stall controls: ER0, ER1, PIS */
520 (PKE_REG_MASK_GET(me
, STAT
, ER0
) && !PKE_REG_MASK_GET(me
, ERR
, ME0
)) ||
521 (PKE_REG_MASK_GET(me
, STAT
, ER1
) && !PKE_REG_MASK_GET(me
, ERR
, ME1
)) ||
522 (PKE_REG_MASK_GET(me
, STAT
, PIS
) && !PKE_REG_MASK_GET(me
, ERR
, MII
)))
524 /* try again next cycle; no state change */
528 /* confirm availability of new quadword of PKE instructions */
529 if(me
->fifo_num_elements
<= me
->fifo_pc
)
533 /* 2 -- fetch PKE instruction */
535 /* skip over DMA tag, if present */
536 pke_pc_advance(me
, 0);
538 /* "fetch" instruction quadword and word */
539 fqw
= & me
->fifo
[me
->fifo_pc
];
540 fw
= fqw
->data
[me
->qw_pc
];
542 /* store word in PKECODE register */
543 me
->regs
[PKE_REG_CODE
][0] = fw
;
546 /* 3 -- decode PKE instruction */
548 /* PKE instruction format: [intr 0:0][pke-command 6:0][num 7:0][immediate 15:0],
549 so op-code is in top byte. */
550 intr
= BIT_MASK_GET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
);
551 cmd
= BIT_MASK_GET(fw
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
552 num
= BIT_MASK_GET(fw
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
553 imm
= BIT_MASK_GET(fw
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
557 /* set INT flag in STAT register */
558 PKE_REG_MASK_SET(me
, STAT
, INT
, 1);
559 /* XXX: how to send interrupt to R5900? */
563 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_DECODE
);
565 /* decode & execute */
566 if(IS_PKE_CMD(cmd
, PKENOP
))
567 pke_code_nop(me
, fw
);
568 else if(IS_PKE_CMD(cmd
, STCYCL
))
569 pke_code_stcycl(me
, fw
);
570 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, OFFSET
))
571 pke_code_offset(me
, fw
);
572 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, BASE
))
573 pke_code_base(me
, fw
);
574 else if(IS_PKE_CMD(cmd
, ITOP
))
575 pke_code_itop(me
, fw
);
576 else if(IS_PKE_CMD(cmd
, STMOD
))
577 pke_code_stmod(me
, fw
);
578 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, MSKPATH3
))
579 pke_code_mskpath3(me
, fw
);
580 else if(IS_PKE_CMD(cmd
, PKEMARK
))
581 pke_code_pkemark(me
, fw
);
582 else if(IS_PKE_CMD(cmd
, FLUSHE
))
583 pke_code_flushe(me
, fw
);
584 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSH
))
585 pke_code_flush(me
, fw
);
586 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSHA
))
587 pke_code_flusha(me
, fw
);
588 else if(IS_PKE_CMD(cmd
, PKEMSCAL
))
589 pke_code_pkemscal(me
, fw
);
590 else if(IS_PKE_CMD(cmd
, PKEMSCNT
))
591 pke_code_pkemscnt(me
, fw
);
592 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, PKEMSCALF
))
593 pke_code_pkemscalf(me
, fw
);
594 else if(IS_PKE_CMD(cmd
, STMASK
))
595 pke_code_stmask(me
, fw
);
596 else if(IS_PKE_CMD(cmd
, STROW
))
597 pke_code_strow(me
, fw
);
598 else if(IS_PKE_CMD(cmd
, STCOL
))
599 pke_code_stcol(me
, fw
);
600 else if(IS_PKE_CMD(cmd
, MPG
))
601 pke_code_mpg(me
, fw
);
602 else if(IS_PKE_CMD(cmd
, DIRECT
))
603 pke_code_direct(me
, fw
);
604 else if(IS_PKE_CMD(cmd
, DIRECTHL
))
605 pke_code_directhl(me
, fw
);
606 else if(IS_PKE_CMD(cmd
, UNPACK
))
607 pke_code_unpack(me
, fw
);
608 /* ... no other commands ... */
610 pke_code_error(me
, fw
);
615 /* advance the PC by given number of data words; update STAT/FQC
616 field; assume FIFO is filled enough */
619 pke_pc_advance(struct pke_device
* me
, int num_words
)
622 ASSERT(num_words
> 0);
626 struct fifo_quadword
* fq
;
628 /* one word skipped */
631 /* point to next word */
639 /* skip over DMA tag words if present in word 0 or 1 */
640 fq
= & me
->fifo
[me
->fifo_pc
];
641 if(fq
->dma_tag_present
&& (me
->qw_pc
< 2))
643 /* skip by going around loop an extra time */
648 /* clear FQC if FIFO is now empty */
649 if(me
->fifo_num_elements
== me
->fifo_pc
)
651 PKE_REG_MASK_SET(me
, STAT
, FQC
, 0);
657 /* Return pointer to FIFO quadword containing given operand# in FIFO.
658 `operand_num' starts at 1. Return pointer to operand word in last
659 argument, if non-NULL. If FIFO is not full enough, return 0.
660 Signal an ER0 indication upon skipping a DMA tag. */
662 struct fifo_quadword
*
663 pke_pc_fifo(struct pke_device
* me
, int operand_num
, unsigned_4
** operand
)
665 int num
= operand_num
;
666 int new_qw_pc
, new_fifo_pc
;
667 struct fifo_quadword
* operand_fifo
= NULL
;
671 /* snapshot current pointers */
672 new_fifo_pc
= me
->fifo_pc
;
673 new_qw_pc
= me
->qw_pc
;
677 /* one word skipped */
680 /* point to next word */
688 /* check for FIFO underflow */
689 if(me
->fifo_num_elements
== new_fifo_pc
)
695 /* skip over DMA tag words if present in word 0 or 1 */
696 operand_fifo
= & me
->fifo
[new_fifo_pc
];
697 if(operand_fifo
->dma_tag_present
&& (new_qw_pc
< 2))
699 /* mismatch error! */
700 PKE_REG_MASK_SET(me
, STAT
, ER0
, 1);
701 /* skip by going around loop an extra time */
706 /* return pointer to operand word itself */
707 if(operand_fifo
!= NULL
)
708 *operand
= & operand_fifo
->data
[new_qw_pc
];
714 /* Return pointer to given operand# in FIFO. `operand_num' starts at 1.
715 If FIFO is not full enough, return 0. Skip over DMA tags, but mark
716 them as an error (ER0). */
719 pke_pc_operand(struct pke_device
* me
, int operand_num
)
721 unsigned_4
* operand
= NULL
;
722 struct fifo_quadword
* fifo_operand
;
724 fifo_operand
= pke_pc_fifo(me
, operand_num
, & operand
);
726 if(fifo_operand
== NULL
)
727 ASSERT(operand
== NULL
); /* pke_pc_fifo() ought leave it untouched */
733 /* Return a bit-field extract of given operand# in FIFO, and its
734 source-addr. `bit_offset' starts at 0, referring to LSB after PKE
735 instruction word. Width must be >0, <=32. Assume FIFO is full
736 enough. Skip over DMA tags, but mark them as an error (ER0). */
739 pke_pc_operand_bits(struct pke_device
* me
, int bit_offset
, int bit_width
, unsigned_4
* source_addr
)
741 unsigned_4
* word
= NULL
;
743 struct fifo_quadword
* fifo_operand
;
745 /* find operand word with bitfield */
746 fifo_operand
= pke_pc_fifo(me
, (bit_offset
/ 32) + 1, &word
);
749 /* extract bitfield from word */
750 value
= BIT_MASK_GET(*word
, bit_offset
% 32, bit_width
);
752 /* extract source addr from fifo word */
753 *source_addr
= fifo_operand
->source_address
;
762 /* Write a bunch of bytes into simulator memory. Store the given source address into the
763 PKE sourceaddr tracking word. */
765 pke_track_write(struct pke_device
* me
, const void* src
, int len
,
766 address_word dest
, unsigned_4 sourceaddr
)
769 unsigned_4 no_sourceaddr
= 0;
771 /* write srcaddr into PKE srcaddr tracking */
773 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
774 (void*) & sourceaddr
,
777 /* write bytes into simulator */
783 /* clear srcaddr from PKE srcaddr tracking */
785 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
786 (void*) & no_sourceaddr
,
793 /* check for stall conditions on indicated devices (path* only on PKE1), do not change status
794 return 0 iff no stall */
796 pke_check_stall(struct pke_device
* me
, enum pke_check_target what
)
800 /* read GPUIF status word - commonly used */
801 unsigned_4 gpuif_stat
;
803 (SIM_ADDR
) (GIF_REG_STAT
),
804 (void*) & gpuif_stat
,
811 /* XXX: have to check COP2 control register VBS0 / VBS1 bits */
813 else if(what
== chk_path1
) /* VU -> GPUIF */
815 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 1)
818 else if(what
== chk_path2
) /* PKE -> GPUIF */
820 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 2)
823 else if(what
== chk_path3
) /* DMA -> GPUIF */
825 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 3)
834 /* any stall reasons? */
839 /* flip the DBF bit; recompute TOPS, ITOP & TOP */
841 pke_flip_dbf(struct pke_device
* me
)
844 PKE_REG_MASK_SET(me
, DBF
, DF
,
845 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
846 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
847 /* compute new TOPS */
848 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
849 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
850 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
851 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
852 /* compute new ITOP and TOP */
853 PKE_REG_MASK_SET(me
, ITOP
, ITOP
,
854 PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
855 PKE_REG_MASK_SET(me
, TOP
, TOP
,
856 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
861 /* PKEcode handler functions -- responsible for checking and
862 confirming old stall conditions, executing pkecode, updating PC and
863 status registers -- may assume being run on correct PKE unit */
866 pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
)
869 pke_pc_advance(me
, 1);
870 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
875 pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
)
877 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
878 /* copy immediate value into CYCLE reg */
879 me
->regs
[PKE_REG_CYCLE
][0] = imm
;
881 pke_pc_advance(me
, 1);
882 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
887 pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
)
889 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
890 /* copy 10 bits to OFFSET field */
891 PKE_REG_MASK_SET(me
, OFST
, OFFSET
, BIT_MASK_GET(imm
, 0, 9));
893 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
894 /* clear other DBF bit */
895 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
896 /* set TOPS = BASE */
897 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
899 pke_pc_advance(me
, 1);
900 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
905 pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
)
907 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
908 /* copy 10 bits to BASE field */
909 PKE_REG_MASK_SET(me
, BASE
, BASE
, BIT_MASK_GET(imm
, 0, 9));
911 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
912 /* clear other DBF bit */
913 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
914 /* set TOPS = BASE */
915 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
917 pke_pc_advance(me
, 1);
918 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
923 pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
)
925 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
926 /* copy 10 bits to ITOPS field */
927 PKE_REG_MASK_SET(me
, ITOPS
, ITOPS
, BIT_MASK_GET(imm
, 0, 9));
929 pke_pc_advance(me
, 1);
930 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
935 pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
)
937 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
938 /* copy 2 bits to MODE register */
939 PKE_REG_MASK_SET(me
, MODE
, MDE
, BIT_MASK_GET(imm
, 0, 2));
941 pke_pc_advance(me
, 1);
942 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
947 pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
)
950 /* XXX: no easy interface toward GPUIF for this purpose */
955 pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
)
957 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
958 /* copy 16 bits to MARK register */
959 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(imm
, 0, 15));
960 /* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
961 PKE_REG_MASK_SET(me
, STAT
, MRK
, 1);
963 pke_pc_advance(me
, 1);
964 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
969 pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
)
971 /* compute next PEW bit */
972 if(pke_check_stall(me
, chk_vu
))
975 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
976 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
977 /* try again next cycle */
982 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
983 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
984 pke_pc_advance(me
, 1);
990 pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
)
992 int something_busy
= 0;
994 /* compute next PEW, PGW bits */
995 if(pke_check_stall(me
, chk_vu
))
998 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1001 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1004 if(pke_check_stall(me
, chk_path1
) ||
1005 pke_check_stall(me
, chk_path2
))
1008 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1011 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1016 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1017 /* try again next cycle */
1022 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1023 pke_pc_advance(me
, 1);
1029 pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
)
1031 int something_busy
= 0;
1033 /* compute next PEW, PGW bits */
1034 if(pke_check_stall(me
, chk_vu
))
1037 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1040 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1043 if(pke_check_stall(me
, chk_path1
) ||
1044 pke_check_stall(me
, chk_path2
) ||
1045 pke_check_stall(me
, chk_path3
))
1048 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1051 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1055 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1056 /* try again next cycle */
1061 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1062 pke_pc_advance(me
, 1);
1068 pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
)
1070 /* compute next PEW bit */
1071 if(pke_check_stall(me
, chk_vu
))
1074 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1075 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1076 /* try again next cycle */
1081 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1084 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1086 /* flip DBF on PKE1 */
1087 if(me
->pke_number
== 1)
1090 /* compute new PC for VU */
1091 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1092 /* write new PC; callback function gets VU running */
1094 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1096 sizeof(unsigned_4
));
1099 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1100 pke_pc_advance(me
, 1);
1107 pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
)
1109 /* compute next PEW bit */
1110 if(pke_check_stall(me
, chk_vu
))
1113 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1114 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1115 /* try again next cycle */
1122 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1124 /* flip DBF on PKE1 */
1125 if(me
->pke_number
== 1)
1130 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1132 sizeof(unsigned_4
));
1134 /* rewrite new PC; callback function gets VU running */
1136 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1138 sizeof(unsigned_4
));
1141 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1142 pke_pc_advance(me
, 1);
1148 pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
)
1150 int something_busy
= 0;
1152 /* compute next PEW, PGW bits */
1153 if(pke_check_stall(me
, chk_vu
))
1156 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1159 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1162 if(pke_check_stall(me
, chk_path1
) ||
1163 pke_check_stall(me
, chk_path2
) ||
1164 pke_check_stall(me
, chk_path3
))
1167 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1170 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1175 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1176 /* try again next cycle */
1181 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1183 /* flip DBF on PKE1 */
1184 if(me
->pke_number
== 1)
1187 /* compute new PC for VU */
1188 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1189 /* write new PC; callback function gets VU running */
1191 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1193 sizeof(unsigned_4
));
1196 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1197 pke_pc_advance(me
, 1);
1203 pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
)
1205 /* check that FIFO has one more word for STMASK operand */
1208 mask
= pke_pc_operand(me
, 1);
1211 /* "transferring" operand */
1212 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1215 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1217 /* fill the register */
1218 PKE_REG_MASK_SET(me
, MASK
, MASK
, *mask
);
1221 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1224 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1225 pke_pc_advance(me
, 1);
1229 /* need to wait for another word */
1230 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1231 /* try again next cycle */
1237 pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
)
1239 /* check that FIFO has four more words for STROW operand */
1240 unsigned_4
* last_op
;
1242 last_op
= pke_pc_operand(me
, 4);
1245 /* "transferring" operand */
1246 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1249 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1251 /* copy ROW registers: must all exist if 4th operand exists */
1252 me
->regs
[PKE_REG_R0
][0] = * pke_pc_operand(me
, 1);
1253 me
->regs
[PKE_REG_R1
][0] = * pke_pc_operand(me
, 2);
1254 me
->regs
[PKE_REG_R2
][0] = * pke_pc_operand(me
, 3);
1255 me
->regs
[PKE_REG_R3
][0] = * pke_pc_operand(me
, 4);
1258 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1261 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1262 pke_pc_advance(me
, 5);
1266 /* need to wait for another word */
1267 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1268 /* try again next cycle */
1274 pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
)
1276 /* check that FIFO has four more words for STCOL operand */
1277 unsigned_4
* last_op
;
1279 last_op
= pke_pc_operand(me
, 4);
1282 /* "transferring" operand */
1283 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1286 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1288 /* copy COL registers: must all exist if 4th operand exists */
1289 me
->regs
[PKE_REG_C0
][0] = * pke_pc_operand(me
, 1);
1290 me
->regs
[PKE_REG_C1
][0] = * pke_pc_operand(me
, 2);
1291 me
->regs
[PKE_REG_C2
][0] = * pke_pc_operand(me
, 3);
1292 me
->regs
[PKE_REG_C3
][0] = * pke_pc_operand(me
, 4);
1295 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1298 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1299 pke_pc_advance(me
, 5);
1303 /* need to wait for another word */
1304 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1305 /* try again next cycle */
1311 pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
)
1313 unsigned_4
* last_mpg_word
;
1314 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1315 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1317 /* map zero to max+1 */
1318 if(num
==0) num
=0x100;
1320 /* check that FIFO has a few more words for MPG operand */
1321 last_mpg_word
= pke_pc_operand(me
, num
*2); /* num: number of 64-bit words */
1322 if(last_mpg_word
!= NULL
)
1324 /* perform implied FLUSHE */
1325 if(pke_check_stall(me
, chk_vu
))
1330 /* "transferring" operand */
1331 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1333 /* transfer VU instructions, one word per iteration */
1334 for(i
=0; i
<num
*2; i
++)
1336 address_word vu_addr_base
, vu_addr
;
1337 address_word vutrack_addr_base
, vutrack_addr
;
1338 unsigned_4
* operand
;
1339 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
, & operand
);
1342 PKE_REG_MASK_SET(me
, NUM
, NUM
, (num
*2 - i
) / 2);
1344 /* imm: in 64-bit units for MPG instruction */
1345 /* VU*_MEM0 : instruction memory */
1346 vu_addr_base
= (me
->pke_number
== 0) ?
1347 VU0_MEM0_WINDOW_START
: VU0_MEM0_WINDOW_START
;
1348 vu_addr
= vu_addr_base
+ (imm
*2) + i
;
1350 /* VU*_MEM0_TRACK : source-addr tracking table */
1351 vutrack_addr_base
= (me
->pke_number
== 0) ?
1352 VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
;
1353 vutrack_addr
= vu_addr_base
+ (imm
*2) + i
;
1355 /* write data into VU memory */
1356 pke_track_write(me
, operand
, sizeof(unsigned_4
),
1357 vu_addr
, fq
->source_address
);
1359 /* write srcaddr into VU srcaddr tracking table */
1361 (SIM_ADDR
) vutrack_addr
,
1362 (void*) & fq
->source_address
,
1363 sizeof(unsigned_4
));
1364 } /* VU xfer loop */
1367 ASSERT(PKE_REG_MASK_GET(me
, NUM
, NUM
) == 0);
1370 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1371 pke_pc_advance(me
, 1 + num
*2);
1376 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1377 /* retry this instruction next clock */
1379 } /* if FIFO full enough */
1382 /* need to wait for another word */
1383 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1384 /* retry this instruction next clock */
1390 pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
)
1392 /* check that FIFO has a few more words for DIRECT operand */
1393 unsigned_4
* last_direct_word
;
1394 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1395 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1397 /* map zero to max+1 */
1398 if(imm
==0) imm
=0x10000;
1400 last_direct_word
= pke_pc_operand(me
, imm
*4); /* num: number of 128-bit words */
1401 if(last_direct_word
!= NULL
)
1407 /* "transferring" operand */
1408 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1410 /* transfer GPUIF quadwords, one word per iteration */
1411 for(i
=0; i
<imm
*4; i
++)
1413 unsigned_4
* operand
;
1414 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
, &operand
);
1416 /* collect word into quadword */
1417 fifo_data
[i
%4] = *operand
;
1419 /* write to GPUIF FIFO only with full word */
1422 address_word gpuif_fifo
= GIF_PATH2_FIFO_ADDR
+(i
/4);
1423 pke_track_write(me
, fifo_data
, sizeof(quadword
),
1424 (SIM_ADDR
) gpuif_fifo
, fq
->source_address
);
1425 } /* write collected quadword */
1427 } /* GPUIF xfer loop */
1430 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1431 pke_pc_advance(me
, 1 + imm
*4);
1432 } /* if FIFO full enough */
1435 /* need to wait for another word */
1436 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1437 /* retry this instruction next clock */
1443 pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
)
1445 /* treat the same as DIRECTH */
1446 pke_code_direct(me
, pkecode
);
1451 pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
)
1453 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1454 int cmd
= BIT_MASK_GET(pkecode
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
1455 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1456 short vn
= BIT_MASK_GET(cmd
, 2, 3); /* unpack shape controls */
1457 short vl
= BIT_MASK_GET(cmd
, 0, 1);
1458 int m
= BIT_MASK_GET(cmd
, 4, 4);
1459 short cl
= PKE_REG_MASK_GET(me
, CYCLE
, CL
); /* cycle controls */
1460 short wl
= PKE_REG_MASK_GET(me
, CYCLE
, WL
);
1461 int r
= BIT_MASK_GET(imm
, 15, 15); /* indicator bits in imm value */
1462 int sx
= BIT_MASK_GET(imm
, 14, 14);
1464 int n
, num_operands
;
1465 unsigned_4
* last_operand_word
;
1467 /* map zero to max+1 */
1468 if(num
==0) num
=0x100;
1470 /* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
1474 n
= cl
* (num
/wl
) + PKE_LIMIT(num
% wl
, cl
);
1475 num_operands
= (((sizeof(unsigned_4
) >> vl
) * (vn
+1) * n
)/sizeof(unsigned_4
));
1477 /* confirm that FIFO has enough words in it */
1478 last_operand_word
= pke_pc_operand(me
, num_operands
);
1479 if(last_operand_word
!= NULL
)
1481 address_word vu_addr_base
;
1484 /* "transferring" operand */
1485 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1487 /* don't check whether VU is idle */
1489 /* compute VU address base */
1490 if(me
->pke_number
== 0)
1491 vu_addr_base
= VU0_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1494 vu_addr_base
= VU1_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1495 if(r
) vu_addr_base
+= PKE_REG_MASK_GET(me
, TOPS
, TOPS
);
1499 PKE_REG_MASK_SET(me
, NUM
, NUM
, num
);
1501 /* transfer given number of vectors */
1502 vector_num
= 0; /* output vector number being processed */
1505 quadword vu_old_data
;
1506 quadword vu_new_data
;
1507 quadword unpacked_data
;
1508 address_word vu_addr
;
1509 unsigned_4 source_addr
= 0;
1513 PKE_REG_MASK_SET(me
, NUM
, NUM
,
1514 PKE_REG_MASK_GET(me
, NUM
, NUM
) - 1);
1516 /* compute VU destination address, as bytes in R5900 memory */
1519 /* map zero to max+1 */
1520 if(wl
== 0) wl
= 0x0100;
1521 vu_addr
= vu_addr_base
+ 16*(cl
*(vector_num
/wl
) + (vector_num
%wl
));
1524 vu_addr
= vu_addr_base
+ 16*vector_num
;
1526 /* XXX: can vu_addr overflow? */
1528 /* read old VU data word at address */
1529 sim_read(NULL
, (SIM_ADDR
) vu_addr
, (void*) & vu_old_data
, sizeof(vu_old_data
));
1531 /* For cyclic unpack, next operand quadword may come from instruction stream
1533 if((cl
< wl
) && ((vector_num
% wl
) >= cl
)) /* wl != 0, set above */
1535 /* clear operand - used only in a "indeterminate" state */
1536 for(i
= 0; i
< 4; i
++)
1537 unpacked_data
[i
] = 0;
1541 /* compute packed vector dimensions */
1542 int vectorbits
, unitbits
;
1544 if(vl
< 3) /* PKE_UNPACK_*_{32,16,8} */
1546 unitbits
= (32 >> vl
);
1547 vectorbits
= unitbits
* (vn
+1);
1549 else if(vl
== 3 && vn
== 3) /* PKE_UNPACK_V4_5 */
1554 else /* illegal unpack variant */
1556 /* treat as illegal instruction */
1557 pke_code_error(me
, pkecode
);
1561 /* loop over columns */
1562 for(i
=0; i
<=vn
; i
++)
1566 /* offset in bits in current operand word */
1568 (vector_num
* vectorbits
) + (i
* unitbits
); /* # of bits from PKEcode */
1570 /* last unit of V4_5 is only one bit wide */
1571 if(vl
== 3 && vn
== 3 && i
== 3) /* PKE_UNPACK_V4_5 */
1574 /* fetch bitfield operand */
1575 operand
= pke_pc_operand_bits(me
, bitoffset
, unitbits
, & source_addr
);
1577 /* selectively sign-extend; not for V4_5 1-bit value */
1578 if(sx
&& unitbits
> 0)
1579 unpacked_data
[i
] = SEXT32(operand
, unitbits
-1);
1581 unpacked_data
[i
] = operand
;
1583 } /* unpack word from instruction operand */
1585 /* compute replacement word */
1586 if(m
) /* use mask register? */
1588 /* compute index into mask register for this word */
1589 int mask_index
= PKE_LIMIT(vector_num
% wl
, 3); /* wl != 0, set above */
1591 for(i
=0; i
<3; i
++) /* loop over columns */
1593 int mask_op
= PKE_MASKREG_GET(me
, mask_index
, i
);
1594 unsigned_4
* masked_value
= NULL
;
1595 unsigned_4 zero
= 0;
1599 case PKE_MASKREG_INPUT
:
1600 /* for vn == 0, all columns are copied from column 0 */
1602 masked_value
= & unpacked_data
[0];
1604 masked_value
= & zero
; /* arbitrary data: undefined in spec */
1606 masked_value
= & unpacked_data
[i
];
1609 case PKE_MASKREG_ROW
: /* exploit R0..R3 contiguity */
1610 masked_value
= & me
->regs
[PKE_REG_R0
+ i
][0];
1613 case PKE_MASKREG_COLUMN
: /* exploit C0..C3 contiguity */
1614 masked_value
= & me
->regs
[PKE_REG_C0
+ PKE_LIMIT(vector_num
,3)][0];
1617 case PKE_MASKREG_NOTHING
:
1618 /* "write inhibit" by re-copying old data */
1619 masked_value
= & vu_old_data
[i
];
1624 /* no other cases possible */
1627 /* copy masked value for column */
1628 vu_new_data
[i
] = *masked_value
;
1629 } /* loop over columns */
1633 /* no mask - just copy over entire unpacked quadword */
1634 memcpy(vu_new_data
, unpacked_data
, sizeof(unpacked_data
));
1637 /* process STMOD register for accumulation operations */
1638 switch(PKE_REG_MASK_GET(me
, MODE
, MDE
))
1640 case PKE_MODE_ADDROW
: /* add row registers to output data */
1642 /* exploit R0..R3 contiguity */
1643 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1646 case PKE_MODE_ACCROW
: /* add row registers to output data; accumulate */
1649 /* exploit R0..R3 contiguity */
1650 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1651 me
->regs
[PKE_REG_R0
+ i
][0] = vu_new_data
[i
];
1655 case PKE_MODE_INPUT
: /* pass data through */
1660 /* write replacement word */
1661 pke_track_write(me
, vu_new_data
, sizeof(vu_new_data
),
1662 (SIM_ADDR
) vu_addr
, source_addr
);
1664 /* next vector please */
1666 } /* vector transfer loop */
1667 while(PKE_REG_MASK_GET(me
, NUM
, NUM
) > 0);
1670 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1671 pke_pc_advance(me
, num_operands
);
1672 } /* PKE FIFO full enough */
1675 /* need to wait for another word */
1676 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1677 /* retry this instruction next clock */
1683 pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
)
1685 /* set ER1 flag in STAT register */
1686 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
1687 /* advance over faulty word */
1688 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1689 pke_pc_advance(me
, 1);