aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>1998-02-06 02:29:22 +0000
committerDoug Evans <dje@google.com>1998-02-06 02:29:22 +0000
commitaea481da17221b63c14e4567a1260dfb842b0899 (patch)
tree422e5c5eecbd282fe58e1e9672673e13322d3517 /sim
parent587c41ae20915753b2ada8741489101d3f0dfebf (diff)
downloadgdb-aea481da17221b63c14e4567a1260dfb842b0899.zip
gdb-aea481da17221b63c14e4567a1260dfb842b0899.tar.gz
gdb-aea481da17221b63c14e4567a1260dfb842b0899.tar.bz2
First pass at moving sky stuff from ../txvu to mips dir.
Diffstat (limited to 'sim')
-rw-r--r--sim/mips/.Sanitize11
-rw-r--r--sim/mips/sky-pke.c306
-rw-r--r--sim/mips/sky-pke.h117
-rw-r--r--sim/mips/sky-vu0.c86
-rw-r--r--sim/mips/sky-vu0.h37
-rw-r--r--sim/mips/sky-vu1.c323
-rw-r--r--sim/mips/sky-vu1.h43
7 files changed, 923 insertions, 0 deletions
diff --git a/sim/mips/.Sanitize b/sim/mips/.Sanitize
index 090d4f7..c2e1470 100644
--- a/sim/mips/.Sanitize
+++ b/sim/mips/.Sanitize
@@ -24,6 +24,17 @@ else
lose_these_too="${r5900_files} ${lose_these_too}"
fi
+sky_files="ChangeLog.sky sky-device.c sky-device.h sky-dma.c sky-dma.h"
+sky_files="$sky_files sky-engine.c sky-gpuif.c sky-gpuif.h"
+sky_files="$sky_files sky-hardware.c sky-hardware.h"
+sky_files="$sky_files sky-libvpe.c sky-libvpe.h sky-pke.c sky-pke.h"
+sky_files="$sky_files sky-vpe.h sky-vu.h sky-vu0.c sky-vu0.h sky-vu1.c sky-vu1.h"
+if ( echo $* | grep keep\-sky > /dev/null ) ; then
+ keep_these_too="${sky_files} ${keep_these_too}"
+else
+ lose_these_too="${sky_files} ${lose_these_too}"
+fi
+
vr5400_files="vr5400.igen mdmx.igen"
if ( echo $* | grep keep\-vr5400 > /dev/null ) ; then
keep_these_too="${vr5400_files} ${keep_these_too}"
diff --git a/sim/mips/sky-pke.c b/sim/mips/sky-pke.c
new file mode 100644
index 0000000..669455c
--- /dev/null
+++ b/sim/mips/sky-pke.c
@@ -0,0 +1,306 @@
+/* Copyright (C) 1998, Cygnus Solutions */
+
+#include "pke.h"
+#include <stdlib.h>
+
+
+/* Imported functions */
+
+void device_error (device *me, char* message); /* device.c */
+
+
+/* Internal function declarations */
+
+static int pke_io_read_buffer(device*, void*, int, address_word,
+ unsigned, sim_cpu*, sim_cia);
+static int pke_io_write_buffer(device*, const void*, int, address_word,
+ unsigned, sim_cpu*, sim_cia);
+static void pke_issue(struct pke_device*);
+
+
+/* Static data */
+
+struct pke_device pke0_device =
+{
+ { "pke0", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
+ 0, 0, /* ID, flags */
+ PKE0_REGISTER_WINDOW_START, PKE0_FIFO_START, /* memory-mapping addresses */
+ {}, /* regs */
+ NULL, 0, 0, NULL, /* FIFO */
+ 0 /* pc */
+};
+
+
+struct pke_device pke1_device =
+{
+ { "pke1", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
+ 1, 0, /* ID, flags */
+ PKE1_REGISTER_WINDOW_START, PKE1_FIFO_START, /* memory-mapping addresses */
+ {}, /* regs */
+ NULL, 0, 0, NULL, /* FIFO */
+ 0 /* pc */
+};
+
+
+
+/* External functions */
+
+
+/* Attach PKE0 addresses to main memory */
+
+void
+pke0_attach(SIM_DESC sd)
+{
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ pke0_device.register_memory_addr,
+ PKE_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ (device*) &pke0_device,
+ NULL /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ pke0_device.fifo_memory_addr,
+ sizeof(quadword) /*nr_bytes*/,
+ 0 /*modulo*/,
+ (device*) &pke1_device,
+ NULL /*buffer*/);
+}
+
+
+/* Attach PKE1 addresses to main memory */
+
+void
+pke1_attach(SIM_DESC sd)
+{
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ pke1_device.register_memory_addr,
+ PKE_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ (device*) &pke1_device,
+ NULL /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ pke1_device.fifo_memory_addr,
+ sizeof(quadword) /*nr_bytes*/,
+ 0 /*modulo*/,
+ (device*) &pke1_device,
+ NULL /*buffer*/);
+}
+
+
+/* Issue a PKE0 instruction if possible */
+
+void
+pke0_issue()
+{
+ pke_issue(& pke0_device);
+}
+
+
+/* Issue a PKE1 instruction if possible */
+
+void
+pke1_issue()
+{
+ pke_issue(& pke0_device);
+}
+
+
+
+/* Internal functions */
+
+
+/* Handle a PKE read; return no. of bytes read */
+
+int
+pke_io_read_buffer(device *me_,
+ void *dest,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ /* downcast to gather embedding pke_device struct */
+ struct pke_device* me = (struct pke_device*) me_;
+
+ /* enforce that an access does not span more than one quadword */
+ address_word low = ADDR_TRUNC_QW(addr);
+ address_word high = ADDR_TRUNC_QW(addr + nr_bytes - 1);
+ if(low != high)
+ return 0;
+
+ /* classify address & handle */
+ if(addr >= me->register_memory_addr &&
+ addr < me->register_memory_addr + PKE_REGISTER_WINDOW_SIZE)
+ {
+ /* register bank */
+ int reg_num = ADDR_TRUNC_QW(addr - me->register_memory_addr) >> 4;
+ int readable = 1;
+
+ /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
+ switch(reg_num)
+ {
+ 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) /* PKE0 cannot access these registers */
+ readable = 0;
+ }
+
+ /* perform read & return */
+ if(readable)
+ {
+ /* find byte-offset inside register bank */
+ int reg_byte = ADDR_OFFSET_QW(addr);
+ void* src = ((unsigned_1*) (& me->regs[reg_num])) + reg_byte;
+ /* copy the bits */
+ memcpy(dest, src, nr_bytes);
+ /* okay */
+ return nr_bytes;
+ }
+ else
+ {
+ /* error */
+ return 0;
+ }
+
+ /* NOTREACHED */
+ }
+ else if(addr >= me->fifo_memory_addr &&
+ addr < me->fifo_memory_addr + sizeof(quadword))
+ {
+ /* FIFO */
+
+ /* XXX: FIFO is not readable. */
+ return 0;
+ }
+
+ /* NOTREACHED */
+}
+
+
+/* Handle a PKE read; return no. of bytes written */
+
+int
+pke_io_write_buffer(device *me_,
+ const void *src,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ /* downcast to gather embedding pke_device struct */
+ struct pke_device* me = (struct pke_device*) me_;
+
+ /* enforce that an access does not span more than one quadword */
+ address_word low = ADDR_TRUNC_QW(addr);
+ address_word high = ADDR_TRUNC_QW(addr + nr_bytes - 1);
+ if(low != high)
+ return 0;
+
+ /* classify address & handle */
+ if(addr >= me->register_memory_addr &&
+ addr < me->register_memory_addr + PKE_REGISTER_WINDOW_SIZE)
+ {
+ /* register bank */
+ int reg_num = ADDR_TRUNC_QW(addr - me->register_memory_addr) >> 4;
+ int writeable = 1;
+
+ /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
+ switch(reg_num)
+ {
+ 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) /* PKE0 cannot access these registers */
+ writeable = 0;
+ }
+
+ /* perform write & return */
+ if(writeable)
+ {
+ /* find byte-offset inside register bank */
+ int reg_byte = ADDR_OFFSET_QW(addr);
+ void* dest = ((unsigned_1*) (& me->regs[reg_num])) + reg_byte;
+ /* copy the bits */
+ memcpy(dest, src, nr_bytes);
+ return nr_bytes;
+ }
+ else
+ {
+ /* error */
+ return 0;
+ }
+
+ /* NOTREACHED */
+ }
+ else if(addr >= me->fifo_memory_addr &&
+ addr < me->fifo_memory_addr + sizeof(quadword))
+ {
+ /* FIFO */
+
+ /* assert transfer size == 128 bits */
+ if(nr_bytes != sizeof(quadword))
+ return 0;
+
+ /* ensure FIFO has enough elements */
+ if(me->fifo_num_elements == me->fifo_buffer_size)
+ {
+ /* time to grow */
+ int new_fifo_buffer_size = me->fifo_buffer_size + 20;
+ void* ptr = realloc((void*) me->fifo, new_fifo_buffer_size*sizeof(quadword));
+
+ if(ptr == NULL)
+ {
+ /* oops, cannot enlarge FIFO any more */
+ device_error(me_, "Cannot enlarge FIFO buffer\n");
+ return 0;
+ }
+
+ me->fifo_buffer_size = new_fifo_buffer_size;
+ }
+
+ /* add new quadword at end of FIFO */
+ memcpy(& me->fifo[++me->fifo_num_elements], src, nr_bytes);
+
+ /* okay */
+ return nr_bytes;
+ }
+
+ /* NOTREACHED */
+}
+
+
+
+/* Issue & swallow one PKE opcode if possible */
+
+void
+pke_issue(struct pke_device* me)
+{
+
+
+}
+
+
diff --git a/sim/mips/sky-pke.h b/sim/mips/sky-pke.h
new file mode 100644
index 0000000..293e2e8
--- /dev/null
+++ b/sim/mips/sky-pke.h
@@ -0,0 +1,117 @@
+/* Copyright (C) 1998, Cygnus Solutions */
+
+#ifndef H_PKE_H
+#define H_PKE_H
+
+#include "sim-main.h"
+#include "device.h"
+
+
+/* External functions */
+
+void pke0_attach(SIM_DESC sd);
+void pke0_issue();
+void pke1_attach(SIM_DESC sd);
+void pke1_issue();
+
+
+/* Quadword data type */
+
+typedef unsigned int quadword[4];
+
+/* truncate address to quadword */
+#define ADDR_TRUNC_QW(addr) ((addr) & ~0x0f)
+/* extract offset in quadword */
+#define ADDR_OFFSET_QW(addr) ((addr) & 0x0f)
+
+
+/* SCEI memory mapping information */
+
+#define PKE0_REGISTER_WINDOW_START 0x10000800
+#define PKE1_REGISTER_WINDOW_START 0x10000A00
+#define PKE0_FIFO_START 0x10008000
+#define PKE1_FIFO_START 0x10008010
+
+
+/* Quadword indices of PKE registers. Actual registers sit at bottom
+ 32 bits of each quadword. */
+#define PKE_REG_STAT 0x00
+#define PKE_REG_FBRST 0x01
+#define PKE_REG_ERR 0x02
+#define PKE_REG_MARK 0x03
+#define PKE_REG_CYCLE 0x04
+#define PKE_REG_MODE 0x05
+#define PKE_REG_NUM 0x06
+#define PKE_REG_MASK 0x07
+#define PKE_REG_CODE 0x08
+#define PKE_REG_ITOPS 0x09
+#define PKE_REG_BASE 0x0a /* pke1 only */
+#define PKE_REG_OFST 0x0b /* pke1 only */
+#define PKE_REG_TOPS 0x0c /* pke1 only */
+#define PKE_REG_ITOP 0x0d
+#define PKE_REG_TOP 0x0e /* pke1 only */
+#define PKE_REG_DBF 0x0f /* pke1 only */
+#define PKE_REG_R0 0x10
+#define PKE_REG_R1 0x11
+#define PKE_REG_R2 0x12
+#define PKE_REG_R3 0x13
+#define PKE_REG_C0 0x14
+#define PKE_REG_C1 0x15
+#define PKE_REG_C2 0x16
+#define PKE_REG_C3 0x17
+/* one plus last index */
+#define PKE_NUM_REGS 0x18
+
+#define PKE_REGISTER_WINDOW_SIZE (sizeof(quadword) * PKE_NUM_REGS)
+
+/* virtual addresses for source-addr tracking */
+#define PKE0_SRCADDR 0x20000020
+#define PKE1_SRCADDR 0x20000024
+
+
+/* One row in the FIFO */
+struct fifo_quadword
+{
+ /* 128 bits of data */
+ quadword data;
+ /* source main memory address (or 0: unknown) */
+ address_word source_address;
+};
+
+
+/* PKE internal state: FIFOs, registers, handle to VU friend */
+struct pke_device
+{
+ /* common device info */
+ device dev;
+
+ /* identity: 0=PKE0, 1=PKE1 */
+ int pke_number;
+ int flags;
+
+ address_word register_memory_addr;
+ address_word fifo_memory_addr;
+
+ /* quadword registers */
+ quadword regs[PKE_NUM_REGS];
+
+ /* FIFO */
+ struct fifo_quadword* fifo;
+ int fifo_num_elements; /* no. of quadwords occupied in FIFO */
+ int fifo_buffer_size; /* no. of quadwords of space in FIFO */
+ FILE* fifo_trace_file; /* or 0 for no trace */
+
+ /* index into FIFO of current instruction */
+ int program_counter;
+
+};
+
+
+/* Flags for PKE.flags */
+
+#define PKE_FLAG_NONE 0
+/* none at present */
+
+
+
+#endif /* H_PKE_H */
diff --git a/sim/mips/sky-vu0.c b/sim/mips/sky-vu0.c
new file mode 100644
index 0000000..ce60db4
--- /dev/null
+++ b/sim/mips/sky-vu0.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 1998, Cygnus Solutions
+
+ */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "vu0.h"
+
+static char vu0_mem0_buffer[VU0_MEM0_SIZE];
+static char vu0_mem1_buffer[VU0_MEM1_SIZE];
+
+void
+vu0_issue()
+{
+}
+
+int
+vu0_io_read_buffer(device *me,
+ void *dest,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ printf("%s: Read!\n", me->name);
+ return nr_bytes;
+}
+
+int
+vu0_io_write_buffer(device *me,
+ const void *source,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ printf("%s: Write!\n", me->name);
+ return nr_bytes;
+}
+
+device vu0_device =
+ {
+ "vu0",
+ &vu0_io_read_buffer,
+ &vu0_io_write_buffer
+ };
+
+void
+vu0_attach(SIM_DESC sd)
+{
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU0_REGISTER_WINDOW_START,
+ VU0_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ &vu0_device,
+ NULL /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU0_MEM0_WINDOW_START,
+ VU0_MEM0_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ 0 /*device*/,
+ &vu0_mem0_buffer /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU0_MEM1_WINDOW_START,
+ VU0_MEM1_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ 0 /*device*/,
+ &vu0_mem1_buffer /*buffer*/);
+}
diff --git a/sim/mips/sky-vu0.h b/sim/mips/sky-vu0.h
new file mode 100644
index 0000000..22d1272
--- /dev/null
+++ b/sim/mips/sky-vu0.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 1998, Cygnus Solutions
+
+ */
+
+#ifndef VU0_H_
+#define VU0_H_
+
+#include "sim-main.h"
+
+void vu0_attach(SIM_DESC sd);
+void vu0_issue();
+
+#define VU0_MEM0_WINDOW_START 0x11000000
+#define VU0_MEM0_SIZE 0x1000 /* 4K = 4096 */
+
+#define VU0_MEM1_WINDOW_START 0x11004000
+#define VU0_MEM1_SIZE 0x1000 /* 4K = 4096 */
+
+#define VU0_REGISTER_WINDOW_START 0x10000c00
+
+#define VU0_VF00 0x10000c00
+/* ... */
+#define VU0_VF31 0x10000df0
+
+#define VU0_VI00 0x10000e00
+/* ... */
+#define VU0_VI15 0x10000ef0
+
+/* ... */
+
+#define VPE0_STAT 0x10000fd0
+
+#define VU0_REGISTER_WINDOW_END 0x10000fe0
+
+#define VU0_REGISTER_WINDOW_SIZE (VU0_REGISTER_WINDOW_END - VU0_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/mips/sky-vu1.c b/sim/mips/sky-vu1.c
new file mode 100644
index 0000000..08231ab
--- /dev/null
+++ b/sim/mips/sky-vu1.c
@@ -0,0 +1,323 @@
+/* Copyright (C) 1998, Cygnus Solutions
+
+ */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "vu1.h"
+#include "libvpe.h"
+#include "vu.h"
+
+VectorUnitState vu1_state;
+
+static char vu1_umem_buffer[VU1_MEM0_SIZE];
+static char vu1_mem_buffer[VU1_MEM1_SIZE];
+
+void init_vu1();
+void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer);
+
+void
+vu1_issue()
+{
+ if (vu1_state.runState == VU_RUN)
+ vpecallms_cycle(&vu1_state);
+}
+
+int
+vu1_io_read_register_window(device *me,
+ void *dest,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ /* Slow and crappy hack ... */
+
+ int i;
+
+ char source_buffer[VU1_REGISTER_WINDOW_SIZE];
+ char* src;
+
+ memcpy(source_buffer, &vu1_state.regs.VF[0][0], 0x200); /* copy VF registers */
+ for (i = 0; i<16; i++ ) {
+ *(short*)&source_buffer[0x200 + i*16] = vu1_state.regs.VI[i];
+ }
+ *(u_long*)&source_buffer[VU1_MST - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MST;
+ *(u_long*)&source_buffer[VU1_MMC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MMC;
+ *(u_long*)&source_buffer[VU1_MCP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MCP;
+ *(u_long*)&source_buffer[VU1_MR - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MR;
+ *(u_long*)&source_buffer[VU1_MI - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MI;
+ *(u_long*)&source_buffer[VU1_MQ - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MQ;
+ *(u_long*)&source_buffer[VU1_MP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MP;
+ *(u_long*)&source_buffer[VU1_MTPC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MTPC;
+ *(VpeStat*)&source_buffer[VPE1_STAT - VU1_REGISTER_WINDOW_START] = vu1_state.regs.VPE_STAT;
+
+ printf("%s: Read: %x, %d, dest: %x, space: %d, %x!\n", me->name, addr, nr_bytes, dest, space, vu1_state.regs.VPE_STAT);
+ printf(" vu1_state.regs.VPE_STAT = %x\n", vu1_state.regs.VPE_STAT);
+
+ if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) {
+ fprintf(stderr, "Error: Read past end of vu1 register window!!!\n");
+ exit(1);
+ }
+
+ src = &source_buffer[0] + (addr - VU1_REGISTER_WINDOW_START);
+ memcpy(dest, src, nr_bytes);
+ return nr_bytes;
+}
+
+int
+vu1_io_write_register_window(device *me,
+ const void *source,
+ int space,
+ address_word addr,
+ unsigned nr_bytes,
+ sim_cpu *processor,
+ sim_cia cia)
+{
+ char *dest;
+
+ if (addr == VPE1_STAT && nr_bytes == 4) {
+ /* Magic to switch VU to run state, until other methods are available. */
+ vu1_state.runState = VU_RUN;
+ vu1_state.regs.VPE_STAT.vbs = 1;
+printf("Magic start run...\n");
+printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.VPE_STAT,
+ ((char*)&vu1_state.regs.VPE_STAT) - ((char*)&vu1_state.regs.VF[0][0]),
+ ((char*)&vu1_state.regs.VPE_STAT) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
+ );
+
+printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.VI[0],
+ ((char*)&vu1_state.regs.VI[0]) - ((char*)&vu1_state.regs.VF[0][0]),
+ ((char*)&vu1_state.regs.VI[0]) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
+ );
+printf("%x,%x,%x,%x\n", &vu1_state.regs.VF[0][0], &vu1_state.regs.MST,
+ ((char*)&vu1_state.regs.MST) - ((char*)&vu1_state.regs.VF[0][0]),
+ ((char*)&vu1_state.regs.MST) - ((char*)&vu1_state.regs.VF[0][0]) + VU1_REGISTER_WINDOW_START
+ );
+ return nr_bytes;
+ }
+
+ printf("%s: Write: %x, %d, source: %x, space: %d!\n", me->name, addr, nr_bytes, source, space);
+
+ if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) {
+ fprintf(stderr, "Error: Read past end of vu1 register window!!!\n");
+ exit(1);
+ }
+
+ dest = ((char*) (&vu1_state.regs)) + (addr - VU1_REGISTER_WINDOW_START);
+
+ memcpy(dest, source, nr_bytes);
+
+ return nr_bytes;
+}
+
+device vu1_device =
+ {
+ "vu1",
+ &vu1_io_read_register_window,
+ &vu1_io_write_register_window
+ };
+
+void
+vu1_init(SIM_DESC sd)
+{
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU1_REGISTER_WINDOW_START,
+ VU1_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ &vu1_device,
+ NULL /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU1_MEM0_WINDOW_START,
+ VU1_MEM0_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ 0 /*device*/,
+ &vu1_umem_buffer /*buffer*/);
+
+ sim_core_attach (sd,
+ NULL,
+ 0 /*level*/,
+ access_read_write,
+ 0 /*space ???*/,
+ VU1_MEM1_WINDOW_START,
+ VU1_MEM1_SIZE /*nr_bytes*/,
+ 0 /*modulo*/,
+ 0 /*device*/,
+ &vu1_mem_buffer /*buffer*/);
+
+ init_vu1();
+ /*initvpe();*/
+ vpecallms_init(&vu1_state);
+}
+
+/****************************************************************************/
+/* */
+/* Sony Computer Entertainment CONFIDENTIAL */
+/* (C) 1997 Sony Computer Entertainment Inc. All Rights Reserved */
+/* */
+/* VPE1 simulator */
+/* */
+/****************************************************************************/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "libvpe.h"
+
+char ifilename[64] = "vu.bin";
+char ofilename[64] = "";
+char pfilename[64] = "";
+
+void abend2(char *fmt, char* p) {
+ fprintf(stderr, fmt, p);
+ exit(1);
+}
+
+void getoption();
+
+void init_vu1() {
+ init_vu(&vu1_state, &vu1_umem_buffer[0], &vu1_mem_buffer[0]);
+}
+
+void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer)
+{
+ FILE *fp;
+ int i, j;
+ u_long data[4];
+
+ /* set up memory buffers */
+ state->uMEM = (uMEM_Entry_Type *) umem_buffer;
+ state->MEM = (MEM_Entry_Type*) mem_buffer;
+
+ /* set up run state */
+ state->runState = VU_READY;
+
+ /* read option */
+ getoption();
+
+ /* read instruction file (mandatory) */
+ if (*ifilename) {
+ if((fp = fopen(ifilename, "r")) == NULL)
+ abend2("%s: can not open\n", ifilename);
+
+ for (i = 0; fread(&data[0], 4, 1, fp) != 0; i++) {
+ fread(&data[1], 4, 1, fp);
+ LoadMMem(state, i, data, 1);
+ }
+ fclose(fp);
+ }
+
+ /* PKE dirven simvpe */
+ if (*pfilename) {
+ /* initpke(pfilename); */
+ initvpe(&vu1_state);
+ /* while (simpke() != -1)
+ simvpe(); */
+ }
+
+ /* conventional simvpe */
+ else {
+ initvpe(&vu1_state);
+ /*simvpe();*/
+ }
+
+ /* write result memory image (optional) */
+ if (*ofilename) {
+ if((fp = fopen(ofilename, "w")) == NULL)
+ abend2("%s: can not open\n", ofilename);
+
+ for(i = 0; i < 2048; i++){
+ StoreVUMem(i, data, 1);
+ for(j = 0; j < 4; j++)
+ fwrite(&data[j], 4, 1, fp);
+ }
+ fclose(fp);
+ }
+}
+
+static void Usage(void)
+{
+ fprintf(stderr, "Usage: simvpe [options]\n");
+ fprintf(stderr, "\t\t-i instruction-file\n");
+ fprintf(stderr, "\t\t-o output-memory-file\n");
+ fprintf(stderr, "\t\t-t PKE-file (text type)\n");
+ fprintf(stderr, "\t\t-s start-address [default = 0]\n");
+ fprintf(stderr, "\t\t-d [interactive mode enable: default desable]\n");
+ fprintf(stderr, "\t\t-v [statistics mode enable: default desable]\n");
+ fprintf(stderr, "\t\t-p [debug print mode enable: default desable]\n");
+}
+
+void getoption()
+{
+ int startline = 0;
+ int count = 1;
+
+ _is_dbg = 1;
+ _vpepc = 0;
+ _is_verb = 0;
+ _is_dump = 0;
+ _pgpuif = 2;
+ _ITOP = 20;
+ _TOP = 10;
+
+#if 0
+ while(argc - count){
+ if(argv[count][0] == '-'){
+ switch(argv[count][1]){
+ case 'i':
+ strcpy(ifilename, argv[count+1]);
+ count += 2;
+ break;
+ case 'o':
+ strcpy(ofilename, argv[count+1]);
+ count += 2;
+ break;
+ case 't':
+ strcpy(pfilename, argv[count+1]);
+ count += 2;
+ break;
+ case 's':
+ sscanf(argv[count+1], "%d", &startline);
+ _vpepc = startline;
+ count += 2;
+ break;
+ case 'd':
+ _is_dbg = 1;
+ count += 1;
+ break;
+ case 'v':
+ _is_verb = 1;
+ count += 1;
+ break;
+ case 'p':
+ _is_dump = 1;
+ count += 1;
+ break;
+ case 'h':
+ case '?':
+ Usage();
+ exit(1);
+ break;
+ default:
+ Usage();
+ exit(1);
+ }
+ }else{
+ Usage();
+ exit(1);
+ }
+ }
+#endif
+}
diff --git a/sim/mips/sky-vu1.h b/sim/mips/sky-vu1.h
new file mode 100644
index 0000000..6150b09
--- /dev/null
+++ b/sim/mips/sky-vu1.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 1998, Cygnus Solutions
+
+ */
+
+#ifndef VU1_H_
+#define VU1_H_
+
+#include "sim-main.h"
+
+void vu1_attach(SIM_DESC sd);
+void vu1_issue();
+
+#define VU1_MEM0_WINDOW_START 0x11008000
+#define VU1_MEM0_SIZE 0x4000 /* 16K = 16384 */
+
+#define VU1_MEM1_WINDOW_START 0x1100c000
+#define VU1_MEM1_SIZE 0x4000 /* 16K = 16384 */
+
+#define VU1_REGISTER_WINDOW_START 0x11007000
+
+#define VU1_VF00 0x11007000
+/* ... */
+#define VU1_VF31 0x110071f0
+
+#define VU1_VI00 0x11007200
+/* ... */
+#define VU1_VI15 0x110072f0
+
+#define VU1_MST 0x11007300
+#define VU1_MMC 0x11007310
+#define VU1_MCP 0x11007320
+#define VU1_MR 0x11007330
+#define VU1_MI 0x11007340
+#define VU1_MQ 0x11007350
+#define VU1_MP 0x11007360
+#define VU1_MTPC 0x110073a0
+#define VPE1_STAT 0x110073d0
+
+#define VU1_REGISTER_WINDOW_END 0x110073e0
+
+#define VU1_REGISTER_WINDOW_SIZE (VU1_REGISTER_WINDOW_END - VU1_REGISTER_WINDOW_START)
+
+#endif