mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
First pass at moving sky stuff from ../txvu to mips dir.
This commit is contained in:
@ -24,6 +24,17 @@ else
|
|||||||
lose_these_too="${r5900_files} ${lose_these_too}"
|
lose_these_too="${r5900_files} ${lose_these_too}"
|
||||||
fi
|
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"
|
vr5400_files="vr5400.igen mdmx.igen"
|
||||||
if ( echo $* | grep keep\-vr5400 > /dev/null ) ; then
|
if ( echo $* | grep keep\-vr5400 > /dev/null ) ; then
|
||||||
keep_these_too="${vr5400_files} ${keep_these_too}"
|
keep_these_too="${vr5400_files} ${keep_these_too}"
|
||||||
|
306
sim/mips/sky-pke.c
Normal file
306
sim/mips/sky-pke.c
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
117
sim/mips/sky-pke.h
Normal file
117
sim/mips/sky-pke.h
Normal file
@ -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 */
|
86
sim/mips/sky-vu0.c
Normal file
86
sim/mips/sky-vu0.c
Normal file
@ -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*/);
|
||||||
|
}
|
37
sim/mips/sky-vu0.h
Normal file
37
sim/mips/sky-vu0.h
Normal file
@ -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
|
323
sim/mips/sky-vu1.c
Normal file
323
sim/mips/sky-vu1.c
Normal file
@ -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
|
||||||
|
}
|
43
sim/mips/sky-vu1.h
Normal file
43
sim/mips/sky-vu1.h
Normal file
@ -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
|
Reference in New Issue
Block a user