From c567d0b94165e65bc8b18f4524bb36e8335ac584 Mon Sep 17 00:00:00 2001 From: Ron Unrau Date: Thu, 2 Apr 1998 21:02:38 +0000 Subject: [PATCH] * sim-main.h: add vif registers * interp.c: incorporate vif register load/store * sky-pke.[ch]: add register load/store routines * sku-vu.c: P register is float --- sim/mips/sky-pke.c | 306 ++++++++++++++++++++++++--------------------- sim/mips/sky-pke.h | 7 ++ 2 files changed, 167 insertions(+), 146 deletions(-) diff --git a/sim/mips/sky-pke.c b/sim/mips/sky-pke.c index 0d3473e278..ce775bd535 100644 --- a/sim/mips/sky-pke.c +++ b/sim/mips/sky-pke.c @@ -197,6 +197,68 @@ pke_attach(SIM_DESC sd, struct pke_device* me) } } +/* Read PKE Pseudo-PC into buf in target order */ +int +read_pke_pc (struct pke_device *me, void *buf) +{ + *((int *) buf) = H2T_4( me->fifo_pc ); + return 4; +} + +/* Read PKE reg into buf in target order */ +int +read_pke_reg (struct pke_device *me, int reg_num, void *buf) +{ + /* handle reads to individual registers; clear `readable' on error */ + switch (reg_num) + { + /* handle common case of register reading, side-effect free */ + /* PKE1-only registers*/ + case PKE_REG_BASE: + case PKE_REG_OFST: + case PKE_REG_TOPS: + case PKE_REG_TOP: + case PKE_REG_DBF: + if (me->pke_number == 0) + { + *((int *) buf) = 0; + break; + } + /* fall through */ + + /* PKE0 & PKE1 common registers*/ + case PKE_REG_STAT: + case PKE_REG_ERR: + case PKE_REG_MARK: + case PKE_REG_CYCLE: + case PKE_REG_MODE: + case PKE_REG_NUM: + case PKE_REG_MASK: + case PKE_REG_CODE: + case PKE_REG_ITOPS: + case PKE_REG_ITOP: + case PKE_REG_R0: + case PKE_REG_R1: + case PKE_REG_R2: + case PKE_REG_R3: + case PKE_REG_C0: + case PKE_REG_C1: + case PKE_REG_C2: + case PKE_REG_C3: + *((int *) buf) = H2T_4(me->regs[reg_num][0]); + break; + + /* handle common case of write-only registers */ + case PKE_REG_FBRST: + *((int *) buf) = 0; + break; + + default: + ASSERT(0); /* tests above should prevent this possibility */ + } + + return 4; +} /* Handle a PKE read; return no. of bytes read */ @@ -231,68 +293,15 @@ pke_io_read_buffer(device *me_, /* register bank */ int reg_num = ADDR_TRUNC_QW(addr - my_reg_start) >> 4; int reg_byte = ADDR_OFFSET_QW(addr); /* find byte-offset inside register bank */ - int readable = 1; quadword result; /* clear result */ result[0] = result[1] = result[2] = result[3] = 0; - /* handle reads to individual registers; clear `readable' on error */ - switch(reg_num) - { - /* handle common case of register reading, side-effect free */ - /* PKE1-only registers*/ - case PKE_REG_BASE: - case PKE_REG_OFST: - case PKE_REG_TOPS: - case PKE_REG_TOP: - case PKE_REG_DBF: - if(me->pke_number == 0) - readable = 0; - /* fall through */ - /* PKE0 & PKE1 common registers*/ - case PKE_REG_STAT: - case PKE_REG_ERR: - case PKE_REG_MARK: - case PKE_REG_CYCLE: - case PKE_REG_MODE: - case PKE_REG_NUM: - case PKE_REG_MASK: - case PKE_REG_CODE: - case PKE_REG_ITOPS: - case PKE_REG_ITOP: - case PKE_REG_R0: - case PKE_REG_R1: - case PKE_REG_R2: - case PKE_REG_R3: - case PKE_REG_C0: - case PKE_REG_C1: - case PKE_REG_C2: - case PKE_REG_C3: - result[0] = H2T_4(me->regs[reg_num][0]); - break; - - /* handle common case of write-only registers */ - case PKE_REG_FBRST: - readable = 0; - break; - - default: - ASSERT(0); /* test above should prevent this possibility */ - } + read_pke_reg (me, reg_num, result); /* perform transfer & return */ - if(readable) - { - /* copy the bits */ - memcpy(dest, ((unsigned_1*) &result) + reg_byte, nr_bytes); - /* okay */ - } - else - { - /* return zero bits */ - memset(dest, 0, nr_bytes); - } + memcpy(dest, ((unsigned_1*) &result) + reg_byte, nr_bytes); return nr_bytes; /* NOTREACHED */ @@ -311,8 +320,102 @@ pke_io_read_buffer(device *me_, return 0; } +/* Write PKE reg from buf, which is in target order */ +int +write_pke_reg (struct pke_device *me, int reg_num, const void *buf) +{ + int writeable = 1; + /* make words host-endian */ + unsigned_4 input = T2H_4( *((unsigned_4 *) buf) ); -/* Handle a PKE read; return no. of bytes written */ + /* handle writes to individual registers; clear `writeable' on error */ + switch (reg_num) + { + case PKE_REG_FBRST: + /* Order these tests from least to most overriding, in case + multiple bits are set. */ + if(BIT_MASK_GET(input, PKE_REG_FBRST_STC_B, PKE_REG_FBRST_STC_E)) + { + /* clear a bunch of status bits */ + PKE_REG_MASK_SET(me, STAT, PSS, 0); + PKE_REG_MASK_SET(me, STAT, PFS, 0); + PKE_REG_MASK_SET(me, STAT, PIS, 0); + PKE_REG_MASK_SET(me, STAT, INT, 0); + PKE_REG_MASK_SET(me, STAT, ER0, 0); + PKE_REG_MASK_SET(me, STAT, ER1, 0); + me->flags &= ~PKE_FLAG_PENDING_PSS; + /* will allow resumption of possible stalled instruction */ + } + if(BIT_MASK_GET(input, PKE_REG_FBRST_STP_B, PKE_REG_FBRST_STP_E)) + { + me->flags |= PKE_FLAG_PENDING_PSS; + } + if(BIT_MASK_GET(input, PKE_REG_FBRST_FBK_B, PKE_REG_FBRST_FBK_E)) + { + PKE_REG_MASK_SET(me, STAT, PFS, 1); + } + if(BIT_MASK_GET(input, PKE_REG_FBRST_RST_B, PKE_REG_FBRST_RST_E)) + { + pke_reset(me); + } + break; + + case PKE_REG_ERR: + /* copy bottom three bits */ + BIT_MASK_SET(me->regs[PKE_REG_ERR][0], 0, 2, BIT_MASK_GET(input, 0, 2)); + break; + + case PKE_REG_MARK: + /* copy bottom sixteen bits */ + PKE_REG_MASK_SET(me, MARK, MARK, BIT_MASK_GET(input, 0, 15)); + /* reset MRK bit in STAT */ + PKE_REG_MASK_SET(me, STAT, MRK, 0); + break; + + /* handle common case of read-only registers */ + /* PKE1-only registers - not really necessary to handle separately */ + case PKE_REG_BASE: + case PKE_REG_OFST: + case PKE_REG_TOPS: + case PKE_REG_TOP: + case PKE_REG_DBF: + if(me->pke_number == 0) + writeable = 0; + /* fall through */ + /* PKE0 & PKE1 common registers*/ + case PKE_REG_STAT: + /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */ + case PKE_REG_CYCLE: + case PKE_REG_MODE: + case PKE_REG_NUM: + case PKE_REG_MASK: + case PKE_REG_CODE: + case PKE_REG_ITOPS: + case PKE_REG_ITOP: + case PKE_REG_R0: + case PKE_REG_R1: + case PKE_REG_R2: + case PKE_REG_R3: + case PKE_REG_C0: + case PKE_REG_C1: + case PKE_REG_C2: + case PKE_REG_C3: + writeable = 0; + break; + + default: + ASSERT(0); /* test above should prevent this possibility */ + } + + /* perform return */ + if(! writeable) + { + return 0; /* error */ + } + + return 4; +} +/* Handle a PKE write; return no. of bytes written */ int pke_io_write_buffer(device *me_, @@ -344,7 +447,6 @@ pke_io_write_buffer(device *me_, /* register bank */ int reg_num = ADDR_TRUNC_QW(addr - my_reg_start) >> 4; int reg_byte = ADDR_OFFSET_QW(addr); /* find byte-offset inside register bank */ - int writeable = 1; quadword input; /* clear input */ @@ -353,95 +455,7 @@ pke_io_write_buffer(device *me_, /* write user-given bytes into input */ memcpy(((unsigned_1*) &input) + reg_byte, src, nr_bytes); - /* make words host-endian */ - input[0] = T2H_4(input[0]); - /* we may ignore other words */ - - /* handle writes to individual registers; clear `writeable' on error */ - switch(reg_num) - { - case PKE_REG_FBRST: - /* Order these tests from least to most overriding, in case - multiple bits are set. */ - if(BIT_MASK_GET(input[0], PKE_REG_FBRST_STC_B, PKE_REG_FBRST_STC_E)) - { - /* clear a bunch of status bits */ - PKE_REG_MASK_SET(me, STAT, PSS, 0); - PKE_REG_MASK_SET(me, STAT, PFS, 0); - PKE_REG_MASK_SET(me, STAT, PIS, 0); - PKE_REG_MASK_SET(me, STAT, INT, 0); - PKE_REG_MASK_SET(me, STAT, ER0, 0); - PKE_REG_MASK_SET(me, STAT, ER1, 0); - me->flags &= ~PKE_FLAG_PENDING_PSS; - /* will allow resumption of possible stalled instruction */ - } - if(BIT_MASK_GET(input[0], PKE_REG_FBRST_STP_B, PKE_REG_FBRST_STP_E)) - { - me->flags |= PKE_FLAG_PENDING_PSS; - } - if(BIT_MASK_GET(input[0], PKE_REG_FBRST_FBK_B, PKE_REG_FBRST_FBK_E)) - { - PKE_REG_MASK_SET(me, STAT, PFS, 1); - } - if(BIT_MASK_GET(input[0], PKE_REG_FBRST_RST_B, PKE_REG_FBRST_RST_E)) - { - pke_reset(me); - } - break; - - case PKE_REG_ERR: - /* copy bottom three bits */ - BIT_MASK_SET(me->regs[PKE_REG_ERR][0], 0, 2, BIT_MASK_GET(input[0], 0, 2)); - break; - - case PKE_REG_MARK: - /* copy bottom sixteen bits */ - PKE_REG_MASK_SET(me, MARK, MARK, BIT_MASK_GET(input[0], 0, 15)); - /* reset MRK bit in STAT */ - PKE_REG_MASK_SET(me, STAT, MRK, 0); - break; - - /* handle common case of read-only registers */ - /* PKE1-only registers - not really necessary to handle separately */ - case PKE_REG_BASE: - case PKE_REG_OFST: - case PKE_REG_TOPS: - case PKE_REG_TOP: - case PKE_REG_DBF: - if(me->pke_number == 0) - writeable = 0; - /* fall through */ - /* PKE0 & PKE1 common registers*/ - case PKE_REG_STAT: - /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */ - case PKE_REG_CYCLE: - case PKE_REG_MODE: - case PKE_REG_NUM: - case PKE_REG_MASK: - case PKE_REG_CODE: - case PKE_REG_ITOPS: - case PKE_REG_ITOP: - case PKE_REG_R0: - case PKE_REG_R1: - case PKE_REG_R2: - case PKE_REG_R3: - case PKE_REG_C0: - case PKE_REG_C1: - case PKE_REG_C2: - case PKE_REG_C3: - writeable = 0; - break; - - default: - ASSERT(0); /* test above should prevent this possibility */ - } - - /* perform return */ - if(! writeable) - { - ; /* error */ - } - + write_pke_reg (me, reg_num, input); return nr_bytes; /* NOTREACHED */ diff --git a/sim/mips/sky-pke.h b/sim/mips/sky-pke.h index 88b4d01640..4816ce664f 100644 --- a/sim/mips/sky-pke.h +++ b/sim/mips/sky-pke.h @@ -412,6 +412,13 @@ struct pke_device int qw_pc; /* 0 .. 3: word index of next instruction */ }; +extern struct pke_device pke0_device; +extern struct pke_device pke1_device; + +int read_pke_reg (struct pke_device *device, int regno, void *buf); +int write_pke_reg (struct pke_device *device, int regno, const void *buf); +int read_pke_pc (struct pke_device *device, void *buf); + /* Flags for PKE.flags */ -- 2.34.1