From: Frank Ch. Eigler Date: Fri, 23 Jan 1998 00:38:10 +0000 (+0000) Subject: - added first batch of PKE code X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d1a18c2f83daf6037b86812eb92912af1c3133e4;p=binutils-gdb.git - added first batch of PKE code - PKE memory region registration - basic R/W operations - combined pke[01] -> pke --- diff --git a/sim/txvu/.Sanitize b/sim/txvu/.Sanitize index 362eae05e81..0f1eaf8e491 100644 --- a/sim/txvu/.Sanitize +++ b/sim/txvu/.Sanitize @@ -48,13 +48,11 @@ gpuif.c device.h dma.c vu0.h -pke0.h +pke.h vu1.h -pke1.h vu1.c vu0.c -pke0.c -pke1.c +pke.c hardware.c hardware.h diff --git a/sim/txvu/Makefile.in b/sim/txvu/Makefile.in index 006e4406394..4871dc8a7cb 100644 --- a/sim/txvu/Makefile.in +++ b/sim/txvu/Makefile.in @@ -37,8 +37,7 @@ SIM_OBJS = \ dma.o \ vu0.o \ vu1.o \ - pke0.o \ - pke1.o \ + pke.o \ sim-hload.o \ sim-engine.o \ sim-stop.o \ diff --git a/sim/txvu/dma.h b/sim/txvu/dma.h index dc2fcb7be4d..dd1719e59aa 100644 --- a/sim/txvu/dma.h +++ b/sim/txvu/dma.h @@ -43,4 +43,12 @@ void dma_attach(SIM_DESC sd); #define DMA_REGISTER_WINDOW_END 0x10001c70 #define DMA_REGISTER_WINDOW_SIZE (DMA_REGISTER_WINDOW_END - DMA_REGISTER_WINDOW_START) +/* virtual addresses for source-addr tracking */ +#define DMA_CHANNEL0_SRCADDR 0x20000000 +#define DMA_CHANNEL1_SRCADDR 0x20000004 +#define DMA_CHANNEL2_SRCADDR 0x20000008 +#define DMA_CHANNEL0_PKTFLAG 0x20000010 +#define DMA_CHANNEL1_PKTFLAG 0x20000014 +#define DMA_CHANNEL2_PKTFLAG 0x20000018 + #endif diff --git a/sim/txvu/hardware.c b/sim/txvu/hardware.c index 2e87c1899e9..6460847dc7c 100644 --- a/sim/txvu/hardware.c +++ b/sim/txvu/hardware.c @@ -4,8 +4,7 @@ #include "gpuif.h" #include "dma.h" -#include "pke0.h" -#include "pke1.h" +#include "pke.h" #include "vu0.h" #include "vu1.h" diff --git a/sim/txvu/pke.c b/sim/txvu/pke.c new file mode 100644 index 00000000000..669455c7fdf --- /dev/null +++ b/sim/txvu/pke.c @@ -0,0 +1,306 @@ +/* Copyright (C) 1998, Cygnus Solutions */ + +#include "pke.h" +#include + + +/* 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/txvu/pke.h b/sim/txvu/pke.h new file mode 100644 index 00000000000..293e2e8be98 --- /dev/null +++ b/sim/txvu/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/txvu/pke0.c b/sim/txvu/pke0.c deleted file mode 100644 index f0f4f07390e..00000000000 --- a/sim/txvu/pke0.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 1998, Cygnus Solutions - - */ - -#include "sim-main.h" - -#include "device.h" -#include "pke0.h" - -void -pke0_issue() -{ -} - -int -pke0_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 -pke0_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 pke0_device = - { - "pke0", - &pke0_io_read_buffer, - &pke0_io_write_buffer - }; - -void -pke0_attach(SIM_DESC sd) -{ - sim_core_attach (sd, - NULL, - 0 /*level*/, - access_read_write, - 0 /*space ???*/, - PKE0_REGISTER_WINDOW_START, - PKE0_REGISTER_WINDOW_SIZE /*nr_bytes*/, - 0 /*modulo*/, - &pke0_device, - NULL /*buffer*/); -} diff --git a/sim/txvu/pke0.h b/sim/txvu/pke0.h deleted file mode 100644 index 0b10980a8c2..00000000000 --- a/sim/txvu/pke0.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (C) 1998, Cygnus Solutions - - */ - -#ifndef PKE0_H_ -#define PKE0_H_ - -#include "sim-main.h" - -void pke0_attach(SIM_DESC sd); -void pke0_issue(); - -#define PKE0_REGISTER_WINDOW_START 0x10000800 -#define PKE0_REGISTER_WINDOW_END 0x10000980 - -#define PKE0_REGISTER_WINDOW_SIZE (PKE0_REGISTER_WINDOW_END - PKE0_REGISTER_WINDOW_START) - -#endif diff --git a/sim/txvu/pke1.c b/sim/txvu/pke1.c deleted file mode 100644 index 90f704774dc..00000000000 --- a/sim/txvu/pke1.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 1998, Cygnus Solutions - - */ - -#include "sim-main.h" - -#include "device.h" -#include "pke1.h" - -void -pke1_issue() -{ -} - -int -pke1_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 -pke1_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 pke1_device = - { - "pke1", - &pke1_io_read_buffer, - &pke1_io_write_buffer - }; - -void -pke1_attach(SIM_DESC sd) -{ - sim_core_attach (sd, - NULL, - 0 /*level*/, - access_read_write, - 0 /*space ???*/, - PKE1_REGISTER_WINDOW_START, - PKE1_REGISTER_WINDOW_SIZE /*nr_bytes*/, - 0 /*modulo*/, - &pke1_device, - NULL /*buffer*/); -} diff --git a/sim/txvu/pke1.h b/sim/txvu/pke1.h deleted file mode 100644 index 120ca29703c..00000000000 --- a/sim/txvu/pke1.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (C) 1998, Cygnus Solutions - - */ - -#ifndef PKE1_H_ -#define PKE1_H_ - -#include "sim-main.h" - -void pke1_attach(SIM_DESC sd); -void pke1_issue(); - -#define PKE1_REGISTER_WINDOW_START 0x10000a00 -#define PKE1_REGISTER_WINDOW_END 0x10000b80 - -#define PKE1_REGISTER_WINDOW_SIZE (PKE1_REGISTER_WINDOW_END - PKE1_REGISTER_WINDOW_START) - -#endif