1 /* Copyright (C) 1998, Cygnus Solutions */
12 #include "sim-assert.h"
15 #include "sky-gpuif.h"
18 /* Imported functions */
20 void device_error (device
*me
, char* message
); /* device.c */
23 /* Internal function declarations */
25 static int pke_io_read_buffer(device
*, void*, int, address_word
,
26 unsigned, sim_cpu
*, sim_cia
);
27 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
28 unsigned, sim_cpu
*, sim_cia
);
29 static void pke_issue(SIM_DESC
, struct pke_device
*);
30 static void pke_pc_advance(struct pke_device
*, int num_words
);
31 static unsigned_4
* pke_pc_operand(struct pke_device
*, int operand_num
);
32 static unsigned_4
pke_pc_operand_bits(struct pke_device
*, int bit_offset
,
33 int bit_width
, unsigned_4
* sourceaddr
);
34 static struct fifo_quadword
* pke_pc_fifo(struct pke_device
*, int operand_num
,
35 unsigned_4
** operand
);
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 */
113 pke0_issue(SIM_DESC sd
)
115 pke_issue(sd
, & pke0_device
);
119 pke1_issue(SIM_DESC sd
)
121 pke_issue(sd
, & pke1_device
);
126 /* Internal functions */
129 /* Attach PKE memory regions to simulator */
132 pke_attach(SIM_DESC sd
, struct pke_device
* me
)
135 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
136 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
,
137 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
143 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
144 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
,
145 sizeof(quadword
) /*nr_bytes*/,
150 /* VU MEM0 tracking table */
151 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
152 ((me
->pke_number
== 0) ? VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
),
153 ((me
->pke_number
== 0) ? VU0_MEM0_SIZE
: VU1_MEM0_SIZE
) / 2,
158 /* VU MEM1 tracking table */
159 sim_core_attach (sd
, NULL
, 0, access_read_write
, 0,
160 ((me
->pke_number
== 0) ? VU0_MEM1_SRCADDR_START
: VU1_MEM1_SRCADDR_START
),
161 ((me
->pke_number
== 0) ? VU0_MEM1_SIZE
: VU1_MEM1_SIZE
) / 4,
167 /* attach to trace file if appropriate */
169 char trace_envvar
[80];
170 char* trace_filename
= NULL
;
171 sprintf(trace_envvar
, "VIF%d_TRACE_FILE", me
->pke_number
);
172 trace_filename
= getenv(trace_envvar
);
173 if(trace_filename
!= NULL
)
175 me
->fifo_trace_file
= fopen(trace_filename
, "w");
176 if(me
->fifo_trace_file
== NULL
)
177 perror("VIF FIFO trace error on fopen");
179 setvbuf(me
->fifo_trace_file
, NULL
, _IOLBF
, 0);
186 /* Handle a PKE read; return no. of bytes read */
189 pke_io_read_buffer(device
*me_
,
197 /* downcast to gather embedding pke_device struct */
198 struct pke_device
* me
= (struct pke_device
*) me_
;
200 /* find my address ranges */
201 address_word my_reg_start
=
202 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
203 address_word my_fifo_addr
=
204 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
206 /* enforce that an access does not span more than one quadword */
207 address_word low
= ADDR_TRUNC_QW(addr
);
208 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
212 /* classify address & handle */
213 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
216 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
217 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
222 result
[0] = result
[1] = result
[2] = result
[3] = 0;
224 /* handle reads to individual registers; clear `readable' on error */
227 /* handle common case of register reading, side-effect free */
228 /* PKE1-only registers*/
234 if(me
->pke_number
== 0)
237 /* PKE0 & PKE1 common registers*/
256 result
[0] = H2T_4(me
->regs
[reg_num
][0]);
259 /* handle common case of write-only registers */
265 ASSERT(0); /* test above should prevent this possibility */
268 /* perform transfer & return */
272 memcpy(dest
, ((unsigned_1
*) &result
) + reg_byte
, nr_bytes
);
277 /* return zero bits */
278 memset(dest
, 0, nr_bytes
);
284 else if(addr
>= my_fifo_addr
&&
285 addr
< my_fifo_addr
+ sizeof(quadword
))
289 /* FIFO is not readable: return a word of zeroes */
290 memset(dest
, 0, nr_bytes
);
299 /* Handle a PKE read; return no. of bytes written */
302 pke_io_write_buffer(device
*me_
,
310 /* downcast to gather embedding pke_device struct */
311 struct pke_device
* me
= (struct pke_device
*) me_
;
313 /* find my address ranges */
314 address_word my_reg_start
=
315 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
316 address_word my_fifo_addr
=
317 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
319 /* enforce that an access does not span more than one quadword */
320 address_word low
= ADDR_TRUNC_QW(addr
);
321 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
325 /* classify address & handle */
326 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
329 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
330 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
335 input
[0] = input
[1] = input
[2] = input
[3] = 0;
337 /* write user-given bytes into input */
338 memcpy(((unsigned_1
*) &input
) + reg_byte
, src
, nr_bytes
);
340 /* make words host-endian */
341 input
[0] = T2H_4(input
[0]);
342 /* we may ignore other words */
344 /* handle writes to individual registers; clear `writeable' on error */
348 /* Order these tests from least to most overriding, in case
349 multiple bits are set. */
350 if(BIT_MASK_GET(input
[0], PKE_REG_FBRST_STC_B
, PKE_REG_FBRST_STC_E
))
352 /* clear a bunch of status bits */
353 PKE_REG_MASK_SET(me
, STAT
, PSS
, 0);
354 PKE_REG_MASK_SET(me
, STAT
, PFS
, 0);
355 PKE_REG_MASK_SET(me
, STAT
, PIS
, 0);
356 PKE_REG_MASK_SET(me
, STAT
, INT
, 0);
357 PKE_REG_MASK_SET(me
, STAT
, ER0
, 0);
358 PKE_REG_MASK_SET(me
, STAT
, ER1
, 0);
359 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
360 /* will allow resumption of possible stalled instruction */
362 if(BIT_MASK_GET(input
[0], PKE_REG_FBRST_STP_B
, PKE_REG_FBRST_STP_E
))
364 me
->flags
|= PKE_FLAG_PENDING_PSS
;
366 if(BIT_MASK_GET(input
[0], PKE_REG_FBRST_FBK_B
, PKE_REG_FBRST_FBK_E
))
368 PKE_REG_MASK_SET(me
, STAT
, PFS
, 1);
370 if(BIT_MASK_GET(input
[0], PKE_REG_FBRST_RST_B
, PKE_REG_FBRST_RST_E
))
372 /* clear FIFO by skipping to word after PC: also
373 prevents re-execution attempt of possible stalled
375 me
->fifo_num_elements
= me
->fifo_pc
;
376 /* clear registers, flag, other state */
377 memset(me
->regs
, 0, sizeof(me
->regs
));
378 me
->fifo_qw_done
= 0;
385 /* copy bottom three bits */
386 BIT_MASK_SET(me
->regs
[PKE_REG_ERR
][0], 0, 2, BIT_MASK_GET(input
[0], 0, 2));
390 /* copy bottom sixteen bits */
391 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(input
[0], 0, 15));
392 /* reset MRK bit in STAT */
393 PKE_REG_MASK_SET(me
, STAT
, MRK
, 0);
396 /* handle common case of read-only registers */
397 /* PKE1-only registers - not really necessary to handle separately */
403 if(me
->pke_number
== 0)
406 /* PKE0 & PKE1 common registers*/
408 /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */
428 ASSERT(0); /* test above should prevent this possibility */
441 else if(addr
>= my_fifo_addr
&&
442 addr
< my_fifo_addr
+ sizeof(quadword
))
445 struct fifo_quadword
* fqw
;
446 int fifo_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside fifo quadword */
447 unsigned_4 dma_tag_present
= 0;
450 /* collect potentially-partial quadword in write buffer; LE byte order */
451 memcpy(((unsigned_1
*)& me
->fifo_qw_in_progress
) + fifo_byte
, src
, nr_bytes
);
452 /* mark bytes written */
453 for(i
= fifo_byte
; i
< fifo_byte
+ nr_bytes
; i
++)
454 BIT_MASK_SET(me
->fifo_qw_done
, i
, i
, 1);
456 /* return if quadword not quite written yet */
457 if(BIT_MASK_GET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1) !=
458 BIT_MASK_BTW(0, sizeof(quadword
)-1))
461 /* all done - process quadword after clearing flag */
462 BIT_MASK_SET(me
->fifo_qw_done
, 0, sizeof(quadword
)-1, 0);
464 /* ensure FIFO has enough elements */
465 if(me
->fifo_num_elements
== me
->fifo_buffer_size
)
468 int new_fifo_buffer_size
= me
->fifo_buffer_size
+ 20;
469 void* ptr
= realloc((void*) me
->fifo
, new_fifo_buffer_size
*sizeof(struct fifo_quadword
));
473 /* oops, cannot enlarge FIFO any more */
474 device_error(me_
, "Cannot enlarge FIFO buffer\n");
479 me
->fifo_buffer_size
= new_fifo_buffer_size
;
482 /* add new quadword at end of FIFO; store data in host-endian */
483 fqw
= & me
->fifo
[me
->fifo_num_elements
];
484 fqw
->word_class
[0] = fqw
->word_class
[1] =
485 fqw
->word_class
[2] = fqw
->word_class
[3] = wc_unknown
;
486 fqw
->data
[0] = T2H_4(me
->fifo_qw_in_progress
[0]);
487 fqw
->data
[1] = T2H_4(me
->fifo_qw_in_progress
[1]);
488 fqw
->data
[2] = T2H_4(me
->fifo_qw_in_progress
[2]);
489 fqw
->data
[3] = T2H_4(me
->fifo_qw_in_progress
[3]);
490 ASSERT(sizeof(unsigned_4
) == 4);
491 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? DMA_D0_MADR
: DMA_D1_MADR
),
492 & fqw
->source_address
, /* converted to host-endian */
494 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? DMA_D0_PKTFLAG
: DMA_D1_PKTFLAG
),
500 /* lower two words are DMA tags */
501 fqw
->word_class
[0] = fqw
->word_class
[1] = wc_dma
;
504 me
->fifo_num_elements
++;
506 /* set FQC to "1" as FIFO is now not empty */
507 PKE_REG_MASK_SET(me
, STAT
, FQC
, 1);
519 /* Issue & swallow next PKE opcode if possible/available */
522 pke_issue(SIM_DESC sd
, struct pke_device
* me
)
524 struct fifo_quadword
* fqw
;
526 unsigned_4 cmd
, intr
, num
;
529 /* 1 -- test go / no-go for PKE execution */
531 /* switch on STAT:PSS if PSS-pending and in idle state */
532 if((PKE_REG_MASK_GET(me
, STAT
, PPS
) == PKE_REG_STAT_PPS_IDLE
) &&
533 (me
->flags
& PKE_FLAG_PENDING_PSS
) != 0)
535 me
->flags
&= ~PKE_FLAG_PENDING_PSS
;
536 PKE_REG_MASK_SET(me
, STAT
, PSS
, 1);
539 /* check for stall/halt control bits */
540 if(PKE_REG_MASK_GET(me
, STAT
, PFS
) ||
541 PKE_REG_MASK_GET(me
, STAT
, PSS
) || /* note special treatment below */
542 /* PEW bit not a reason to keep stalling - it's re-checked below */
543 /* PGW bit not a reason to keep stalling - it's re-checked below */
544 /* maskable stall controls: ER0, ER1, PIS */
545 (PKE_REG_MASK_GET(me
, STAT
, ER0
) && !PKE_REG_MASK_GET(me
, ERR
, ME0
)) ||
546 (PKE_REG_MASK_GET(me
, STAT
, ER1
) && !PKE_REG_MASK_GET(me
, ERR
, ME1
)) ||
547 (PKE_REG_MASK_GET(me
, STAT
, PIS
) && !PKE_REG_MASK_GET(me
, ERR
, MII
)))
549 /* try again next cycle; no state change */
553 /* confirm availability of new quadword of PKE instructions */
554 if(me
->fifo_num_elements
<= me
->fifo_pc
)
558 /* 2 -- fetch PKE instruction */
560 /* skip over DMA tag, if present */
561 pke_pc_advance(me
, 0);
563 /* "fetch" instruction quadword and word */
564 fqw
= & me
->fifo
[me
->fifo_pc
];
565 fw
= fqw
->data
[me
->qw_pc
];
567 /* store word in PKECODE register */
568 me
->regs
[PKE_REG_CODE
][0] = fw
;
571 /* 3 -- decode PKE instruction */
573 /* PKE instruction format: [intr 0:0][pke-command 6:0][num 7:0][immediate 15:0],
574 so op-code is in top byte. */
575 intr
= BIT_MASK_GET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
);
576 cmd
= BIT_MASK_GET(fw
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
577 num
= BIT_MASK_GET(fw
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
578 imm
= BIT_MASK_GET(fw
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
580 /* handle interrupts */
583 /* are we resuming an interrupt-flagged instruction? */
584 if(me
->flags
& PKE_FLAG_INT_NOLOOP
)
586 /* clear loop-prevention flag */
587 me
->flags
&= ~PKE_FLAG_INT_NOLOOP
;
588 /* mask interrupt bit from instruction word so re-decoded instructions don't stall */
589 BIT_MASK_SET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
, 0);
591 else /* new interrupt-flagged instruction */
593 /* set INT flag in STAT register */
594 PKE_REG_MASK_SET(me
, STAT
, INT
, 1);
595 /* set loop-prevention flag */
596 me
->flags
|= PKE_FLAG_INT_NOLOOP
;
598 /* XXX: send interrupt to 5900? */
603 if(PKE_REG_MASK_GET(me
, STAT
, PPS
) == PKE_REG_STAT_PPS_IDLE
)
604 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_DECODE
);
606 /* decode & execute */
607 if(IS_PKE_CMD(cmd
, PKENOP
))
608 pke_code_nop(me
, fw
);
609 else if(IS_PKE_CMD(cmd
, STCYCL
))
610 pke_code_stcycl(me
, fw
);
611 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, OFFSET
))
612 pke_code_offset(me
, fw
);
613 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, BASE
))
614 pke_code_base(me
, fw
);
615 else if(IS_PKE_CMD(cmd
, ITOP
))
616 pke_code_itop(me
, fw
);
617 else if(IS_PKE_CMD(cmd
, STMOD
))
618 pke_code_stmod(me
, fw
);
619 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, MSKPATH3
))
620 pke_code_mskpath3(me
, fw
);
621 else if(IS_PKE_CMD(cmd
, PKEMARK
))
622 pke_code_pkemark(me
, fw
);
623 else if(IS_PKE_CMD(cmd
, FLUSHE
))
624 pke_code_flushe(me
, fw
);
625 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSH
))
626 pke_code_flush(me
, fw
);
627 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSHA
))
628 pke_code_flusha(me
, fw
);
629 else if(IS_PKE_CMD(cmd
, PKEMSCAL
))
630 pke_code_pkemscal(me
, fw
);
631 else if(IS_PKE_CMD(cmd
, PKEMSCNT
))
632 pke_code_pkemscnt(me
, fw
);
633 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, PKEMSCALF
))
634 pke_code_pkemscalf(me
, fw
);
635 else if(IS_PKE_CMD(cmd
, STMASK
))
636 pke_code_stmask(me
, fw
);
637 else if(IS_PKE_CMD(cmd
, STROW
))
638 pke_code_strow(me
, fw
);
639 else if(IS_PKE_CMD(cmd
, STCOL
))
640 pke_code_stcol(me
, fw
);
641 else if(IS_PKE_CMD(cmd
, MPG
))
642 pke_code_mpg(me
, fw
);
643 else if(IS_PKE_CMD(cmd
, DIRECT
))
644 pke_code_direct(me
, fw
);
645 else if(IS_PKE_CMD(cmd
, DIRECTHL
))
646 pke_code_directhl(me
, fw
);
647 else if(IS_PKE_CMD(cmd
, UNPACK
))
648 pke_code_unpack(me
, fw
);
649 /* ... no other commands ... */
651 pke_code_error(me
, fw
);
656 /* advance the PC by given number of data words; update STAT/FQC
657 field; assume FIFO is filled enough; classify passed-over words;
658 write FIFO trace line */
661 pke_pc_advance(struct pke_device
* me
, int num_words
)
664 struct fifo_quadword
* fq
= NULL
;
665 ASSERT(num_words
>= 0);
667 /* printf("pke %d pc_advance num_words %d\n", me->pke_number, num_words); */
671 fq
= & me
->fifo
[me
->fifo_pc
];
673 /* skip over DMA tag words if present in word 0 or 1 */
674 if(fq
->word_class
[me
->qw_pc
] == wc_dma
)
676 /* skip by going around loop an extra time */
680 /* nothing left to skip / no DMA tag here */
684 /* one word skipped */
687 /* point to next word */
694 /* trace the consumption of the FIFO quadword we just skipped over */
695 /* fq still points to it */
696 if(me
->fifo_trace_file
!= NULL
)
698 /* assert complete classification */
699 ASSERT(fq
->word_class
[3] != wc_unknown
);
700 ASSERT(fq
->word_class
[2] != wc_unknown
);
701 ASSERT(fq
->word_class
[1] != wc_unknown
);
702 ASSERT(fq
->word_class
[0] != wc_unknown
);
704 /* print trace record */
705 fprintf(me
->fifo_trace_file
,
706 "%d 0x%08x_%08x_%08x_%08x 0x%08x %c%c%c%c\n",
707 (me
->pke_number
== 0 ? 0 : 1),
708 (unsigned) fq
->data
[3], (unsigned) fq
->data
[2],
709 (unsigned) fq
->data
[1], (unsigned) fq
->data
[0],
710 (unsigned) fq
->source_address
,
711 fq
->word_class
[3], fq
->word_class
[2],
712 fq
->word_class
[1], fq
->word_class
[0]);
715 /* XXX: zap old entries in FIFO */
716 } /* next quadword */
719 /* clear FQC if FIFO is now empty */
720 if(me
->fifo_num_elements
== me
->fifo_pc
)
722 PKE_REG_MASK_SET(me
, STAT
, FQC
, 0);
724 else /* annote the word where the PC lands as an PKEcode */
726 fq
= & me
->fifo
[me
->fifo_pc
];
727 ASSERT(fq
->word_class
[me
->qw_pc
] == wc_pkecode
||
728 fq
->word_class
[me
->qw_pc
] == wc_unknown
);
729 fq
->word_class
[me
->qw_pc
] = wc_pkecode
;
735 /* Return pointer to FIFO quadword containing given operand# in FIFO.
736 `operand_num' starts at 1. Return pointer to operand word in last
737 argument, if non-NULL. If FIFO is not full enough, return 0.
738 Signal an ER0 indication upon skipping a DMA tag. */
740 struct fifo_quadword
*
741 pke_pc_fifo(struct pke_device
* me
, int operand_num
, unsigned_4
** operand
)
743 int num
= operand_num
;
744 int new_qw_pc
, new_fifo_pc
;
745 struct fifo_quadword
* fq
= NULL
;
749 /* snapshot current pointers */
750 new_fifo_pc
= me
->fifo_pc
;
751 new_qw_pc
= me
->qw_pc
;
753 /* printf("pke %d pc_fifo operand_num %d\n", me->pke_number, operand_num); */
757 /* one word skipped */
760 /* point to next word */
768 /* check for FIFO underflow */
769 if(me
->fifo_num_elements
== new_fifo_pc
)
775 /* skip over DMA tag words if present in word 0 or 1 */
776 fq
= & me
->fifo
[new_fifo_pc
];
777 if(fq
->word_class
[new_qw_pc
] == wc_dma
)
779 /* mismatch error! */
780 PKE_REG_MASK_SET(me
, STAT
, ER0
, 1);
781 /* skip by going around loop an extra time */
787 /* return pointer to operand word itself */
790 *operand
= & fq
->data
[new_qw_pc
];
792 /* annote the word where the pseudo lands as an PKE operand */
793 ASSERT(fq
->word_class
[new_qw_pc
] == wc_pkedata
||
794 fq
->word_class
[new_qw_pc
] == wc_unknown
);
795 fq
->word_class
[new_qw_pc
] = wc_pkedata
;
802 /* Return pointer to given operand# in FIFO. `operand_num' starts at 1.
803 If FIFO is not full enough, return 0. Skip over DMA tags, but mark
804 them as an error (ER0). */
807 pke_pc_operand(struct pke_device
* me
, int operand_num
)
809 unsigned_4
* operand
= NULL
;
810 struct fifo_quadword
* fifo_operand
;
812 fifo_operand
= pke_pc_fifo(me
, operand_num
, & operand
);
814 if(fifo_operand
== NULL
)
815 ASSERT(operand
== NULL
); /* pke_pc_fifo() ought leave it untouched */
821 /* Return a bit-field extract of given operand# in FIFO, and its
822 source-addr. `bit_offset' starts at 0, referring to LSB after PKE
823 instruction word. Width must be >0, <=32. Assume FIFO is full
824 enough. Skip over DMA tags, but mark them as an error (ER0). */
827 pke_pc_operand_bits(struct pke_device
* me
, int bit_offset
, int bit_width
, unsigned_4
* source_addr
)
829 unsigned_4
* word
= NULL
;
831 struct fifo_quadword
* fifo_operand
;
832 int wordnumber
, bitnumber
;
834 wordnumber
= bit_offset
/32;
835 bitnumber
= bit_offset
%32;
837 /* find operand word with bitfield */
838 fifo_operand
= pke_pc_fifo(me
, wordnumber
+ 1, &word
);
839 ASSERT(word
!= NULL
);
841 /* extract bitfield from word */
842 value
= BIT_MASK_GET(*word
, bitnumber
, bitnumber
+ bit_width
- 1);
844 /* extract source addr from fifo word */
845 *source_addr
= fifo_operand
->source_address
;
852 /* check for stall conditions on indicated devices (path* only on
853 PKE1), do not change status; return 0 iff no stall */
855 pke_check_stall(struct pke_device
* me
, enum pke_check_target what
)
858 unsigned_4 cop2_stat
, gpuif_stat
;
860 /* read status words */
861 ASSERT(sizeof(unsigned_4
) == 4);
862 PKE_MEM_READ(me
, (GIF_REG_STAT
),
865 PKE_MEM_READ(me
, (COP2_REG_STAT_ADDR
),
872 if(me
->pke_number
== 0)
873 any_stall
= BIT_MASK_GET(cop2_stat
, COP2_REG_STAT_VBS0_B
, COP2_REG_STAT_VBS0_E
);
874 else /* if(me->pke_number == 1) */
875 any_stall
= BIT_MASK_GET(cop2_stat
, COP2_REG_STAT_VBS1_B
, COP2_REG_STAT_VBS1_E
);
877 else if(what
== chk_path1
) /* VU -> GPUIF */
879 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 1)
882 else if(what
== chk_path2
) /* PKE -> GPUIF */
884 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 2)
887 else if(what
== chk_path3
) /* DMA -> GPUIF */
889 if(BIT_MASK_GET(gpuif_stat
, GPUIF_REG_STAT_APATH_B
, GPUIF_REG_STAT_APATH_E
) == 3)
898 /* any stall reasons? */
903 /* PKE1 only: flip the DBF bit; recompute TOPS, TOP */
905 pke_flip_dbf(struct pke_device
* me
)
907 /* compute new TOP */
908 PKE_REG_MASK_SET(me
, TOP
, TOP
,
909 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
911 PKE_REG_MASK_SET(me
, DBF
, DF
,
912 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
913 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
914 /* compute new TOPS */
915 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
916 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
917 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
918 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
919 /* this is equivalent to last word from okadaa (98-02-25):
921 2) TOPS=BASE + !DBF*OFFSET
927 /* PKEcode handler functions -- responsible for checking and
928 confirming old stall conditions, executing pkecode, updating PC and
929 status registers -- may assume being run on correct PKE unit */
932 pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
)
934 /* handle interrupts */
935 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
937 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
938 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
943 pke_pc_advance(me
, 1);
944 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
949 pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
)
951 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
953 /* handle interrupts */
954 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
956 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
957 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
961 /* copy immediate value into CYCLE reg */
962 PKE_REG_MASK_SET(me
, CYCLE
, WL
, BIT_MASK_GET(imm
, 8, 15));
963 PKE_REG_MASK_SET(me
, CYCLE
, CL
, BIT_MASK_GET(imm
, 0, 7));
965 pke_pc_advance(me
, 1);
966 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
971 pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
)
973 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
975 /* handle interrupts */
976 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
978 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
979 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
983 /* copy 10 bits to OFFSET field */
984 PKE_REG_MASK_SET(me
, OFST
, OFFSET
, BIT_MASK_GET(imm
, 0, 9));
986 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
987 /* clear other DBF bit */
988 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
989 /* set TOPS = BASE */
990 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
992 pke_pc_advance(me
, 1);
993 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
998 pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
)
1000 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1002 /* handle interrupts */
1003 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1005 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1006 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1010 /* copy 10 bits to BASE field */
1011 PKE_REG_MASK_SET(me
, BASE
, BASE
, BIT_MASK_GET(imm
, 0, 9));
1013 pke_pc_advance(me
, 1);
1014 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1019 pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
)
1021 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1023 /* handle interrupts */
1024 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1026 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1027 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1031 /* copy 10 bits to ITOPS field */
1032 PKE_REG_MASK_SET(me
, ITOPS
, ITOPS
, BIT_MASK_GET(imm
, 0, 9));
1034 pke_pc_advance(me
, 1);
1035 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1040 pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
)
1042 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1044 /* handle interrupts */
1045 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1047 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1048 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1052 /* copy 2 bits to MODE register */
1053 PKE_REG_MASK_SET(me
, MODE
, MDE
, BIT_MASK_GET(imm
, 0, 2));
1055 pke_pc_advance(me
, 1);
1056 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1061 pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
)
1063 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1064 unsigned_4 gif_mode
;
1066 /* handle interrupts */
1067 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1069 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1070 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1074 /* set appropriate bit */
1075 if(BIT_MASK_GET(imm
, PKE_REG_MSKPATH3_B
, PKE_REG_MSKPATH3_E
) != 0)
1076 gif_mode
= GIF_REG_MODE_M3R_MASK
;
1080 /* write register; patrickm code will look at M3R bit only */
1081 PKE_MEM_WRITE(me
, GIF_REG_MODE
, & gif_mode
, 4);
1084 pke_pc_advance(me
, 1);
1085 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1090 pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
)
1092 /* ignore possible interrupt stall */
1094 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1095 /* copy 16 bits to MARK register */
1096 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(imm
, 0, 15));
1097 /* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
1098 PKE_REG_MASK_SET(me
, STAT
, MRK
, 1);
1100 pke_pc_advance(me
, 1);
1101 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1106 pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
)
1108 /* handle interrupts */
1109 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1111 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1112 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1116 /* compute next PEW bit */
1117 if(pke_check_stall(me
, chk_vu
))
1120 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1121 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1122 /* try again next cycle */
1127 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1128 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1129 pke_pc_advance(me
, 1);
1135 pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
)
1137 int something_busy
= 0;
1139 /* handle interrupts */
1140 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1142 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1143 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1147 /* compute next PEW, PGW bits */
1148 if(pke_check_stall(me
, chk_vu
))
1151 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1154 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1157 if(pke_check_stall(me
, chk_path1
) ||
1158 pke_check_stall(me
, chk_path2
))
1161 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1164 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1169 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1170 /* try again next cycle */
1175 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1176 pke_pc_advance(me
, 1);
1182 pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
)
1184 int something_busy
= 0;
1186 /* handle interrupts */
1187 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1189 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1190 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1194 /* compute next PEW, PGW bits */
1195 if(pke_check_stall(me
, chk_vu
))
1198 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1201 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1204 if(pke_check_stall(me
, chk_path1
) ||
1205 pke_check_stall(me
, chk_path2
) ||
1206 pke_check_stall(me
, chk_path3
))
1209 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1212 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1216 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1217 /* try again next cycle */
1222 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1223 pke_pc_advance(me
, 1);
1229 pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
)
1231 /* handle interrupts */
1232 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1234 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1235 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1239 /* compute next PEW bit */
1240 if(pke_check_stall(me
, chk_vu
))
1243 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1244 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1245 /* try again next cycle */
1250 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1253 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1255 /* flip DBF on PKE1 */
1256 if(me
->pke_number
== 1)
1259 /* compute new PC for VU (host byte-order) */
1260 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1261 vu_pc
= T2H_4(vu_pc
);
1263 /* write new PC; callback function gets VU running */
1264 ASSERT(sizeof(unsigned_4
) == 4);
1265 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1269 /* copy ITOPS field to ITOP */
1270 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1273 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1274 pke_pc_advance(me
, 1);
1281 pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
)
1283 /* handle interrupts */
1284 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1286 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1287 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1291 /* compute next PEW bit */
1292 if(pke_check_stall(me
, chk_vu
))
1295 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1296 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1297 /* try again next cycle */
1304 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1306 /* flip DBF on PKE1 */
1307 if(me
->pke_number
== 1)
1311 ASSERT(sizeof(unsigned_4
) == 4);
1312 PKE_MEM_READ(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1316 /* rewrite new PC; callback function gets VU running */
1317 ASSERT(sizeof(unsigned_4
) == 4);
1318 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1322 /* copy ITOPS field to ITOP */
1323 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1326 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1327 pke_pc_advance(me
, 1);
1333 pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
)
1335 int something_busy
= 0;
1337 /* handle interrupts */
1338 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1340 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1341 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1345 /* compute next PEW, PGW bits */
1346 if(pke_check_stall(me
, chk_vu
))
1349 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1352 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1355 if(pke_check_stall(me
, chk_path1
) ||
1356 pke_check_stall(me
, chk_path2
) ||
1357 pke_check_stall(me
, chk_path3
))
1360 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1363 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1368 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1369 /* try again next cycle */
1374 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1376 /* flip DBF on PKE1 */
1377 if(me
->pke_number
== 1)
1380 /* compute new PC for VU (host byte-order) */
1381 vu_pc
= BIT_MASK_GET(imm
, 0, 15);
1382 vu_pc
= T2H_4(vu_pc
);
1384 /* rewrite new PC; callback function gets VU running */
1385 ASSERT(sizeof(unsigned_4
) == 4);
1386 PKE_MEM_WRITE(me
, (me
->pke_number
== 0 ? VU0_CIA
: VU1_CIA
),
1390 /* copy ITOPS field to ITOP */
1391 PKE_REG_MASK_SET(me
, ITOP
, ITOP
, PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
1394 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1395 pke_pc_advance(me
, 1);
1401 pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
)
1405 /* handle interrupts */
1406 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1408 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1409 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1413 /* check that FIFO has one more word for STMASK operand */
1414 mask
= pke_pc_operand(me
, 1);
1417 /* "transferring" operand */
1418 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1421 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1423 /* fill the register */
1424 PKE_REG_MASK_SET(me
, MASK
, MASK
, *mask
);
1427 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1430 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1431 pke_pc_advance(me
, 2);
1435 /* need to wait for another word */
1436 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1437 /* try again next cycle */
1443 pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
)
1445 /* check that FIFO has four more words for STROW operand */
1446 unsigned_4
* last_op
;
1448 /* handle interrupts */
1449 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1451 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1452 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1456 last_op
= pke_pc_operand(me
, 4);
1459 /* "transferring" operand */
1460 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1463 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1465 /* copy ROW registers: must all exist if 4th operand exists */
1466 me
->regs
[PKE_REG_R0
][0] = * pke_pc_operand(me
, 1);
1467 me
->regs
[PKE_REG_R1
][0] = * pke_pc_operand(me
, 2);
1468 me
->regs
[PKE_REG_R2
][0] = * pke_pc_operand(me
, 3);
1469 me
->regs
[PKE_REG_R3
][0] = * pke_pc_operand(me
, 4);
1472 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1475 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1476 pke_pc_advance(me
, 5);
1480 /* need to wait for another word */
1481 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1482 /* try again next cycle */
1488 pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
)
1490 /* check that FIFO has four more words for STCOL operand */
1491 unsigned_4
* last_op
;
1493 /* handle interrupts */
1494 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1496 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1497 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1501 last_op
= pke_pc_operand(me
, 4);
1504 /* "transferring" operand */
1505 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1508 PKE_REG_MASK_SET(me
, NUM
, NUM
, 1);
1510 /* copy COL registers: must all exist if 4th operand exists */
1511 me
->regs
[PKE_REG_C0
][0] = * pke_pc_operand(me
, 1);
1512 me
->regs
[PKE_REG_C1
][0] = * pke_pc_operand(me
, 2);
1513 me
->regs
[PKE_REG_C2
][0] = * pke_pc_operand(me
, 3);
1514 me
->regs
[PKE_REG_C3
][0] = * pke_pc_operand(me
, 4);
1517 PKE_REG_MASK_SET(me
, NUM
, NUM
, 0);
1520 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1521 pke_pc_advance(me
, 5);
1525 /* need to wait for another word */
1526 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1527 /* try again next cycle */
1533 pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
)
1535 unsigned_4
* last_mpg_word
;
1536 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1537 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1539 /* assert 64-bit alignment of MPG operand */
1540 if(me
->qw_pc
!= 3 && me
->qw_pc
!= 1)
1541 return pke_code_error(me
, pkecode
);
1543 /* handle interrupts */
1544 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1546 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1547 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1551 /* map zero to max+1 */
1552 if(num
==0) num
=0x100;
1554 /* check that FIFO has a few more words for MPG operand */
1555 last_mpg_word
= pke_pc_operand(me
, num
*2); /* num: number of 64-bit words */
1556 if(last_mpg_word
!= NULL
)
1558 /* perform implied FLUSHE */
1559 if(pke_check_stall(me
, chk_vu
))
1562 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1563 /* retry this instruction next clock */
1570 /* "transferring" operand */
1571 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1574 PKE_REG_MASK_SET(me
, NUM
, NUM
, num
);
1576 /* transfer VU instructions, one word-pair per iteration */
1577 for(i
=0; i
<num
; i
++)
1579 address_word vu_addr_base
, vu_addr
;
1580 address_word vutrack_addr_base
, vutrack_addr
;
1581 address_word vu_addr_max_size
;
1582 unsigned_4 vu_lower_opcode
, vu_upper_opcode
;
1583 unsigned_4
* operand
;
1584 struct fifo_quadword
* fq
;
1588 next_num
= PKE_REG_MASK_GET(me
, NUM
, NUM
) - 1;
1589 PKE_REG_MASK_SET(me
, NUM
, NUM
, next_num
);
1591 /* imm: in 64-bit units for MPG instruction */
1592 /* VU*_MEM0 : instruction memory */
1593 vu_addr_base
= (me
->pke_number
== 0) ?
1594 VU0_MEM0_WINDOW_START
: VU1_MEM0_WINDOW_START
;
1595 vu_addr_max_size
= (me
->pke_number
== 0) ?
1596 VU0_MEM0_SIZE
: VU1_MEM0_SIZE
;
1597 vutrack_addr_base
= (me
->pke_number
== 0) ?
1598 VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
;
1600 /* compute VU address for this word-pair */
1601 vu_addr
= vu_addr_base
+ (imm
+ i
) * 8;
1602 /* check for vu_addr overflow */
1603 while(vu_addr
>= vu_addr_base
+ vu_addr_max_size
)
1604 vu_addr
-= vu_addr_max_size
;
1606 /* compute VU tracking address */
1607 vutrack_addr
= vutrack_addr_base
+ ((signed_8
)vu_addr
- (signed_8
)vu_addr_base
) / 2;
1609 /* Fetch operand words; assume they are already little-endian for VU imem */
1610 fq
= pke_pc_fifo(me
, i
*2 + 1, & operand
);
1611 vu_lower_opcode
= *operand
;
1612 vu_upper_opcode
= *pke_pc_operand(me
, i
*2 + 2);
1614 /* write data into VU memory */
1615 /* lower (scalar) opcode comes in first word ; macro performs H2T! */
1616 PKE_MEM_WRITE(me
, vu_addr
,
1619 /* upper (vector) opcode comes in second word ; H2T */
1620 ASSERT(sizeof(unsigned_4
) == 4);
1621 PKE_MEM_WRITE(me
, vu_addr
+ 4,
1625 /* write tracking address in target byte-order */
1626 ASSERT(sizeof(unsigned_4
) == 4);
1627 PKE_MEM_WRITE(me
, vutrack_addr
,
1628 & fq
->source_address
,
1630 } /* VU xfer loop */
1633 ASSERT(PKE_REG_MASK_GET(me
, NUM
, NUM
) == 0);
1636 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1637 pke_pc_advance(me
, 1 + num
*2);
1639 } /* if FIFO full enough */
1642 /* need to wait for another word */
1643 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1644 /* retry this instruction next clock */
1650 pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
)
1652 /* check that FIFO has a few more words for DIRECT operand */
1653 unsigned_4
* last_direct_word
;
1654 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1656 /* assert 128-bit alignment of DIRECT operand */
1658 return pke_code_error(me
, pkecode
);
1660 /* handle interrupts */
1661 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1663 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1664 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1668 /* map zero to max+1 */
1669 if(imm
==0) imm
=0x10000;
1671 last_direct_word
= pke_pc_operand(me
, imm
*4); /* imm: number of 128-bit words */
1672 if(last_direct_word
!= NULL
)
1676 unsigned_16 fifo_data
;
1678 /* "transferring" operand */
1679 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1681 /* transfer GPUIF quadwords, one word per iteration */
1682 for(i
=0; i
<imm
*4; i
++)
1684 unsigned_4
* operand
= pke_pc_operand(me
, 1+i
);
1686 /* collect word into quadword */
1687 *A4_16(&fifo_data
, 3 - (i
% 4)) = *operand
;
1689 /* write to GPUIF FIFO only with full quadword */
1692 ASSERT(sizeof(fifo_data
) == 16);
1693 PKE_MEM_WRITE(me
, GIF_PATH2_FIFO_ADDR
,
1696 } /* write collected quadword */
1698 } /* GPUIF xfer loop */
1701 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1702 pke_pc_advance(me
, 1 + imm
*4);
1703 } /* if FIFO full enough */
1706 /* need to wait for another word */
1707 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1708 /* retry this instruction next clock */
1714 pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
)
1716 /* treat the same as DIRECTH */
1717 pke_code_direct(me
, pkecode
);
1722 pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
)
1724 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1725 int cmd
= BIT_MASK_GET(pkecode
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
1726 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1727 short vn
= BIT_MASK_GET(cmd
, 2, 3); /* unpack shape controls */
1728 short vl
= BIT_MASK_GET(cmd
, 0, 1);
1729 int m
= BIT_MASK_GET(cmd
, 4, 4);
1730 short cl
= PKE_REG_MASK_GET(me
, CYCLE
, CL
); /* cycle controls */
1731 short wl
= PKE_REG_MASK_GET(me
, CYCLE
, WL
);
1732 int r
= BIT_MASK_GET(imm
, 15, 15); /* indicator bits in imm value */
1733 int usn
= BIT_MASK_GET(imm
, 14, 14);
1735 int n
, num_operands
;
1736 unsigned_4
* last_operand_word
= NULL
;
1738 /* handle interrupts */
1739 if(BIT_MASK_GET(pkecode
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
))
1741 PKE_REG_MASK_SET(me
, STAT
, PIS
, 1);
1742 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1746 /* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
1750 n
= cl
* (num
/wl
) + PKE_LIMIT(num
% wl
, cl
);
1751 num_operands
= ((32 >> vl
) * (vn
+1) * n
)/32;
1753 /* confirm that FIFO has enough words in it */
1754 if(num_operands
> 0)
1755 last_operand_word
= pke_pc_operand(me
, num_operands
);
1756 if(last_operand_word
!= NULL
|| num_operands
== 0)
1758 address_word vu_addr_base
, vutrack_addr_base
;
1759 address_word vu_addr_max_size
;
1760 int vector_num_out
, vector_num_in
;
1762 /* "transferring" operand */
1763 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1765 /* don't check whether VU is idle */
1767 /* compute VU address base */
1768 if(me
->pke_number
== 0)
1770 vu_addr_base
= VU0_MEM1_WINDOW_START
;
1771 vu_addr_max_size
= VU0_MEM1_SIZE
;
1772 vutrack_addr_base
= VU0_MEM1_SRCADDR_START
;
1777 vu_addr_base
= VU1_MEM1_WINDOW_START
;
1778 vu_addr_max_size
= VU1_MEM1_SIZE
;
1779 vutrack_addr_base
= VU1_MEM1_SRCADDR_START
;
1783 PKE_REG_MASK_SET(me
, NUM
, NUM
, num
== 0 ? 0x100 : num
);
1785 /* transfer given number of vectors */
1786 vector_num_out
= 0; /* output vector number being processed */
1787 vector_num_in
= 0; /* argument vector number being processed */
1790 quadword vu_old_data
;
1791 quadword vu_new_data
;
1792 quadword unpacked_data
;
1793 address_word vu_addr
;
1794 address_word vutrack_addr
;
1795 unsigned_4 source_addr
= 0;
1800 next_num
= PKE_REG_MASK_GET(me
, NUM
, NUM
) - 1;
1801 PKE_REG_MASK_SET(me
, NUM
, NUM
, next_num
);
1803 /* compute VU destination address, as bytes in R5900 memory */
1806 /* map zero to max+1 */
1807 int addrwl
= (wl
== 0) ? 0x0100 : wl
;
1808 vu_addr
= vu_addr_base
+ 16 * (BIT_MASK_GET(imm
, 0, 9) +
1809 (r
? PKE_REG_MASK_GET(me
, TOPS
, TOPS
) : 0) +
1810 cl
*(vector_num_out
/addrwl
) +
1811 (vector_num_out
%addrwl
));
1814 vu_addr
= vu_addr_base
+ 16 * (BIT_MASK_GET(imm
, 0, 9) +
1815 (r
? PKE_REG_MASK_GET(me
, TOPS
, TOPS
) : 0) +
1818 /* check for vu_addr overflow */
1819 while(vu_addr
>= vu_addr_base
+ vu_addr_max_size
)
1820 vu_addr
-= vu_addr_max_size
;
1822 /* compute address of tracking table entry */
1823 vutrack_addr
= vutrack_addr_base
+ ((signed_8
)vu_addr
- (signed_8
)vu_addr_base
) / 4;
1825 /* read old VU data word at address; reverse words if needed */
1827 unsigned_16 vu_old_badwords
;
1828 ASSERT(sizeof(vu_old_badwords
) == 16);
1829 PKE_MEM_READ(me
, vu_addr
,
1830 &vu_old_badwords
, 16);
1831 vu_old_data
[0] = * A4_16(& vu_old_badwords
, 3);
1832 vu_old_data
[1] = * A4_16(& vu_old_badwords
, 2);
1833 vu_old_data
[2] = * A4_16(& vu_old_badwords
, 1);
1834 vu_old_data
[3] = * A4_16(& vu_old_badwords
, 0);
1837 /* For cyclic unpack, next operand quadword may come from instruction stream
1839 if((num
== 0 && cl
== 0 && wl
== 0) || /* shortcut clear */
1840 ((cl
< wl
) && ((vector_num_out
% wl
) >= cl
))) /* wl != 0, set above */
1842 /* clear operand - used only in a "indeterminate" state */
1843 for(i
= 0; i
< 4; i
++)
1844 unpacked_data
[i
] = 0;
1848 /* compute packed vector dimensions */
1849 int vectorbits
, unitbits
;
1851 if(vl
< 3) /* PKE_UNPACK_*_{32,16,8} */
1853 unitbits
= (32 >> vl
);
1854 vectorbits
= unitbits
* (vn
+1);
1856 else if(vl
== 3 && vn
== 3) /* PKE_UNPACK_V4_5 */
1861 else /* illegal unpack variant */
1863 /* treat as illegal instruction */
1864 pke_code_error(me
, pkecode
);
1868 /* loop over columns */
1869 for(i
=0; i
<=vn
; i
++)
1873 /* offset in bits in current operand word */
1875 (vector_num_in
* vectorbits
) + (i
* unitbits
); /* # of bits from PKEcode */
1877 /* last unit of V4_5 is only one bit wide */
1878 if(vl
== 3 && vn
== 3 && i
== 3) /* PKE_UNPACK_V4_5 */
1881 /* fetch bitfield operand */
1882 operand
= pke_pc_operand_bits(me
, bitoffset
, unitbits
, & source_addr
);
1884 /* selectively sign-extend; not for V4_5 1-bit value */
1885 if(usn
|| unitbits
== 1)
1886 unpacked_data
[i
] = operand
;
1888 unpacked_data
[i
] = SEXT32(operand
, unitbits
-1);
1891 /* consumed a vector from the PKE instruction stream */
1893 } /* unpack word from instruction operand */
1895 /* compute replacement word */
1896 if(m
) /* use mask register? */
1898 /* compute index into mask register for this word */
1899 int addrwl
= (wl
== 0) ? 0x0100 : wl
;
1900 int mask_index
= PKE_LIMIT(vector_num_out
% addrwl
, 3);
1902 for(i
=0; i
<4; i
++) /* loop over columns */
1904 int mask_op
= PKE_MASKREG_GET(me
, mask_index
, i
);
1905 unsigned_4
* masked_value
= NULL
;
1906 unsigned_4 zero
= 0;
1910 case PKE_MASKREG_INPUT
:
1911 /* for vn == 0, all columns are copied from column 0 */
1913 masked_value
= & unpacked_data
[0];
1915 masked_value
= & zero
; /* arbitrary data: undefined in spec */
1917 masked_value
= & unpacked_data
[i
];
1920 case PKE_MASKREG_ROW
: /* exploit R0..R3 contiguity */
1921 masked_value
= & me
->regs
[PKE_REG_R0
+ i
][0];
1924 case PKE_MASKREG_COLUMN
: /* exploit C0..C3 contiguity */
1925 masked_value
= & me
->regs
[PKE_REG_C0
+ mask_index
][0];
1928 case PKE_MASKREG_NOTHING
:
1929 /* "write inhibit" by re-copying old data */
1930 masked_value
= & vu_old_data
[i
];
1935 /* no other cases possible */
1938 /* copy masked value for column */
1939 vu_new_data
[i
] = *masked_value
;
1940 } /* loop over columns */
1944 /* no mask - just copy over entire unpacked quadword */
1945 memcpy(vu_new_data
, unpacked_data
, sizeof(unpacked_data
));
1948 /* process STMOD register for accumulation operations */
1949 switch(PKE_REG_MASK_GET(me
, MODE
, MDE
))
1951 case PKE_MODE_ADDROW
: /* add row registers to output data */
1953 /* exploit R0..R3 contiguity */
1954 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1957 case PKE_MODE_ACCROW
: /* add row registers to output data; accumulate */
1960 /* exploit R0..R3 contiguity */
1961 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1962 me
->regs
[PKE_REG_R0
+ i
][0] = vu_new_data
[i
];
1966 case PKE_MODE_INPUT
: /* pass data through */
1971 /* write new VU data word at address; reverse words if needed */
1973 unsigned_16 vu_new_badwords
;
1974 * A4_16(& vu_new_badwords
, 3) = vu_new_data
[0];
1975 * A4_16(& vu_new_badwords
, 2) = vu_new_data
[1];
1976 * A4_16(& vu_new_badwords
, 1) = vu_new_data
[2];
1977 * A4_16(& vu_new_badwords
, 0) = vu_new_data
[3];
1978 ASSERT(sizeof(vu_new_badwords
) == 16);
1979 PKE_MEM_WRITE(me
, vu_addr
,
1980 &vu_new_badwords
, 16);
1983 /* write tracking address */
1984 ASSERT(sizeof(unsigned_4
) == 4);
1985 PKE_MEM_WRITE(me
, vutrack_addr
,
1989 /* next vector please */
1991 } /* vector transfer loop */
1992 while(PKE_REG_MASK_GET(me
, NUM
, NUM
) > 0);
1995 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1996 pke_pc_advance(me
, 1 + num_operands
);
1997 } /* PKE FIFO full enough */
2000 /* need to wait for another word */
2001 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
2002 /* retry this instruction next clock */
2008 pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
)
2010 /* set ER1 flag in STAT register */
2011 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
2012 /* advance over faulty word */
2013 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
2014 pke_pc_advance(me
, 1);