First pass at moving sky stuff from ../txvu to mips dir.
authorDoug Evans <dje@google.com>
Fri, 6 Feb 1998 02:29:22 +0000 (02:29 +0000)
committerDoug Evans <dje@google.com>
Fri, 6 Feb 1998 02:29:22 +0000 (02:29 +0000)
sim/mips/.Sanitize
sim/mips/sky-pke.c [new file with mode: 0644]
sim/mips/sky-pke.h [new file with mode: 0644]
sim/mips/sky-vu0.c [new file with mode: 0644]
sim/mips/sky-vu0.h [new file with mode: 0644]
sim/mips/sky-vu1.c [new file with mode: 0644]
sim/mips/sky-vu1.h [new file with mode: 0644]

index 090d4f72ba0dacafda2391e5ef170820eaf1690c..c2e1470a6ff33d35e626f1e92f8f83ecae07f250 100644 (file)
@@ -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 (file)
index 0000000..669455c
--- /dev/null
@@ -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 (file)
index 0000000..293e2e8
--- /dev/null
@@ -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 (file)
index 0000000..ce60db4
--- /dev/null
@@ -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 (file)
index 0000000..22d1272
--- /dev/null
@@ -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 (file)
index 0000000..08231ab
--- /dev/null
@@ -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 (file)
index 0000000..6150b09
--- /dev/null
@@ -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