OpenCores
URL https://opencores.org/ocsvn/s6soc/s6soc/trunk

Subversion Repositories s6soc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 48 to Rev 49
    Reverse comparison

Rev 48 → Rev 49

/s6soc/trunk/bench/cpp/Makefile
6,8 → 6,9
#
# Purpose: This makefile builds the final verilator simulation of the
# zipsystem. Specifically, it builds the final C++ portion
# of the simulator, and thus the final simulator executable.
# of the simulator, and thus the final simulator executable.
#
# This simulator depends upon the libelf library.
#
# Creator: Dan Gisselquist, Ph.D.
# Gisselquist Technology, LLC
14,7 → 15,7
#
################################################################################
#
# Copyright (C) 2015, Gisselquist Technology, LLC
# Copyright (C) 2015,2017, Gisselquist Technology, LLC
#
# This program is free software (firmware): you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
35,37 → 36,59
all: zip_sim
 
CXX := g++
FLAGS := -Wall -Og -g
CFLAGS := -Wall -Og -g
OBJDIR := obj-pc
SWHOST := ../../sw/host
RTLD := ../../rtl
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I/usr/share/verilator/include \
-I$(SWHOST)
SOURCES := zip_sim.cpp twoc.cpp qspiflashsim.cpp uartsim.cpp
VLIB := /usr/share/verilator/include/verilated.cpp
RAWLIB := $(VLIB) $(RTLD)/obj_dir/Vbusmaster__ALL.a
RTLOBJD := $(RTLD)/obj_dir
VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"')
VROOT := $(VERILATOR_ROOT)
VINCS := -I$(VROOT)/include -I$(VROOT)/include/vltstd
INCS := -I$(RTLOBJD) -I$(RTLD) -I$(VROOT)/include -I$(SWHOST) $(VINCS)
SOURCES := zip_sim.cpp twoc.cpp qspiflashsim.cpp uartsim.cpp zipelf.cpp byteswap.cpp
VLSRCS := verilated.cpp verilated_vcd_c.cpp
VLOBJS := $(OBJDIR)/verilated.o $(OBJDIR)/verilated_vcd_c.o
VLIB := $(addprefix $(VROOT)/include/,$(VLSRCS))
RAWLIB := $(RTLOBJD)/Vbusmaster__ALL.a
OBJECTS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(SOURCES) $(VLSRCS)))
LIBS := $(RAWLIB) -lelf
TESTF := $(ZASM)/z.out
DHRYSTONEF := ../asm/zipdhry.z
 
zip_sim: $(SOURCES) $(RAWLIB) testb.h
$(CXX) $(FLAGS) $(INCS) $(SOURCES) $(LIBS) -o $@
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CFLAGS) $(INCS) -c $< -o $@
 
# .PHONY: stest
# stest: zippy_tb
# ./zippy_tb -s $(TESTF)
$(OBJDIR)/%.o: $(VROOT)/include/%.cpp
$(CXX) $(CFLAGS) $(INCS) -c $< -o $@
 
# .PHONY: itest
# itest: zippy_tb
# ./zippy_tb $(TESTF)
zip_sim: $(OBJECTS)
$(CXX) $(CFLAGS) $(INCS) $(OBJECTS) $(LIBS) -o $@
 
# .PHONY: test
# test: zippy_tb stest
# ./zippy_tb -a $(TESTF)
 
# .PHONY: dhrystone
# dhrystone: zippy_tb
# ./zippy_tb -a $(DHRYSTONEF)
 
 
define build-depends
@echo "Building dependencies"
@$(CXX) $(CFLAGS) $(INCS) -MM $(VLIB) $(SOURCES) > $(OBJDIR)/xdepends.txt
@sed -e 's/^.*.o: /$(OBJDIR)\/&/' < $(OBJDIR)/xdepends.txt > $(OBJDIR)/depends.txt
@rm $(OBJDIR)/xdepends.txt
endef
 
tags: $(VLIB) $(SOURCES)
@ctags $(SOURCES) $(VLIB)
 
.PHONY: depends
depends: tags $(OBJDIR)/
$(build-depends)
 
$(OBJDIR)/:
@bash -c "if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR)/; fi"
 
$(OBJDIR)/depends.txt: $(OBJDIR)/ depends
 
.PHONY: clean
clean:
rm ./zip_sim
rm -rf $(OBJDIR)/
rm -f ./zip_sim
 
-include $(OBJDIR)/depends.txt
/s6soc/trunk/bench/cpp/byteswap.cpp
0,0 → 1,86
////////////////////////////////////////////////////////////////////////////////
//
// Filename: byteswap.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdint.h>
#include "byteswap.h"
 
uint32_t
byteswap(uint32_t v) {
uint32_t r = 0;
 
r = (v & 0x0ff);
r <<= 8; v >>= 8;
r |= (v & 0x0ff);
r <<= 8; v >>= 8;
r |= (v & 0x0ff);
r <<= 8; v >>= 8;
r |= (v & 0x0ff);
 
return r;
}
 
uint32_t
buildword(const unsigned char *p) {
uint32_t r = 0;
 
r = (*p++); r <<= 8;
r |= (*p++); r <<= 8;
r |= (*p++); r <<= 8;
r |= (*p );
 
return r;
}
 
uint32_t
buildswap(const unsigned char *p) {
uint32_t r = 0;
 
r = p[3]; r <<= 8;
r |= p[2]; r <<= 8;
r |= p[1]; r <<= 8;
r |= p[0];
 
return r;
}
 
void
byteswapbuf(int ln, uint32_t *buf) {
for(int i=0; i<ln; i++)
buf[i] = byteswap(buf[i]);
}
 
 
/s6soc/trunk/bench/cpp/byteswap.h
0,0 → 1,54
////////////////////////////////////////////////////////////////////////////////
//
// Filename: byteswap.h
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef BYTESWAP_H
#define BYTESWAP_H
 
#include <stdint.h>
 
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
extern uint32_t byteswap(uint32_t v);
extern void byteswapbuf(int ln, uint32_t *buf);
#else
#define byteswap(A) (A)
#define byteswapbuf(A, B)
#endif
 
extern uint32_t buildword(const unsigned char *p);
extern uint32_t buildswap(const unsigned char *p);
 
#endif
/s6soc/trunk/bench/cpp/qspiflashsim.cpp
1,4 → 1,4
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename: spiflashsim.cpp
14,12 → 14,12
// environment, where this simulator can be used in place of
// the actual hardware.
//
// Creator: Dan Gisselquist
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
32,7 → 32,7
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory, run make with no
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
40,7 → 40,9
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdio.h>
#include <string.h>
#include <assert.h>
49,7 → 51,8
#include "regdefs.h"
#include "qspiflashsim.h"
 
#define MEMBYTES (FLASHWORDS<<2)
#define MEMBYTES (1<<24)
#define MEMMASK ((MEMBYTES)-1)
 
static const unsigned DEVID = 0x0115,
DEVESD = 0x014,
75,7 → 78,7
m_write_count = 0;
m_ireg = m_oreg = 0;
m_sreg = 0x01c;
m_creg = 0x001; // Iinitial creg on delivery
m_creg = 0x003; // Initial creg on delivery--assumes quad mode enabled
m_quad_mode = false;
m_mode_byte = 0;
 
84,6 → 87,7
 
void QSPIFLASHSIM::load(const unsigned addr, const char *fname) {
FILE *fp;
int nr = 0;
size_t len;
 
if (addr >= MEMBYTES)
91,7 → 95,6
len = MEMBYTES-addr*4;
 
if (NULL != (fp = fopen(fname, "r"))) {
int nr = 0;
nr = fread(&m_mem[addr], sizeof(char), len, fp);
fclose(fp);
if (nr == 0) {
104,15 → 107,10
}
}
 
void QSPIFLASHSIM::write(const unsigned addr, const unsigned len, const uint32_t *buf) {
char *ptr;
if ((addr+len < SPIFLASH)||(addr >= SPIFLASH+MEMBYTES/4))
return;
printf("FLASH: Copying into memory at S6Add4 %08x, my addr %08x, %d values\n",
addr, (addr-SPIFLASH)<<2, len<<2);
ptr = &m_mem[(addr-SPIFLASH)<<2];
memcpy(ptr, buf, len<<2);
printf("%02x %02x %02x %02x\n", ptr[0]&0x0ff, ptr[1]&0x0ff, ptr[2]&0x0ff, ptr[3]&0x0ff);
void QSPIFLASHSIM::write(const unsigned offset, const unsigned len, const char *buf) {
uint32_t moff = (offset & (MEMBYTES-1));
 
memcpy(&m_mem[moff], buf, len);
}
 
#define QOREG(A) m_oreg = ((m_oreg & (~0x0ff))|(A&0x0ff))
230,9 → 228,9
assert(m_quad_mode);
if (m_count == 24) {
if (m_debug) printf("QSPI: Entering from Quad-Read Idle to Quad-Read\n");
if (m_debug) printf("QSPI: QI/O Idle Addr = %02x\n", m_ireg&0x0ffffff);
m_addr = (m_ireg) & 0x0ffffff;
assert((m_addr & 0xfc00000)==0);
if (m_debug) printf("QSPI: QI/O Idle Addr = %02x\n", m_ireg&MEMMASK);
m_addr = (m_ireg) & MEMMASK;
assert((m_addr & (~(MEMMASK)))==0);
m_state = QSPIF_QUAD_READ;
} m_oreg = 0;
} else if (m_count == 8) {
374,7 → 372,7
break;
case QSPIF_RDID:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & MEMMASK;
if (m_debug) printf("READID, ADDR = %08x\n", m_addr);
QOREG((DEVID>>8));
if (m_debug) printf("QSPI: READING ID, %02x\n", (DEVID>>8)&0x0ff);
398,15 → 396,15
break;
case QSPIF_FAST_READ:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & MEMMASK;
if (m_debug) printf("FAST READ, ADDR = %08x\n", m_addr);
QOREG(0x0c3);
assert((m_addr & 0xfc00000)==0);
if (m_addr & (~(MEMMASK))) {
printf("QSPI: ADDR = %08x ? !!\n", m_addr);
} assert((m_addr & (~(MEMMASK)))==0);
} else if ((m_count >= 40)&&(0 == (m_sreg&0x01))) {
//if (m_count == 40)
//printf("DUMMY BYTE COMPLETE ...\n");
QOREG(m_mem[m_addr++]);
// if (m_debug) printf("SPIF[%08x] = %02x\n", m_addr-1, m_oreg);
if (m_debug) printf("SPIF[%08x] = %02x\n", m_addr-1, m_oreg);
} else m_oreg = 0;
break;
case QSPIF_QUAD_READ_CMD:
414,17 → 412,18
// that changes the timings, else we'd use quad_Read
// below
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
// printf("FAST READ, ADDR = %08x\n", m_addr);
// printf("QSPI: QUAD READ, ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
m_addr = m_ireg & MEMMASK;
if (m_debug) printf("QSPI: QUAD READ, ADDR = %06x\n", m_addr);
assert((m_addr & (~(MEMMASK)))==0);
} else if (m_count == 32+24) {
m_mode_byte = (m_ireg>>16) & 0x0ff;
// printf("QSPI: MODE BYTE = %02x\n", m_mode_byte);
if (m_debug) printf("QSPI: MODE BYTE = %02x\n", m_mode_byte);
// Send the first byte in the response ... since it's time to start sending bytes
QOREG(m_mem[m_addr++]);
} else if ((m_count > 32+24)&&(0 == (m_sreg&0x01))) {
QOREG(m_mem[m_addr++]);
// printf("QSPIF[%08x]/QR = %02x\n",
// m_addr-1, m_oreg);
if (m_debug) printf("QSPIF[%08x]/QR = %02x\n",
m_addr-1, m_oreg);
} else m_oreg = 0;
break;
case QSPIF_QUAD_READ:
433,14 → 432,14
// printf("QSPI/QR: MODE BYTE = %02x\n", m_mode_byte);
} else if ((m_count >= 32+16)&&(0 == (m_sreg&0x01))) {
QOREG(m_mem[m_addr++]);
// printf("QSPIF[%08x]/QR = %02x\n", m_addr-1, m_oreg & 0x0ff);
if (m_debug) printf("QSPIF[%08x]/QR = %02x\n", m_addr-1, m_oreg & 0x0ff);
} else m_oreg = 0;
break;
case QSPIF_PP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & MEMMASK;
if (m_debug) printf("QSPI: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(MEMMASK)))==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
451,10 → 450,10
} break;
case QSPIF_QPP:
if (m_count == 32) {
m_addr = m_ireg & 0x0ffffff;
m_addr = m_ireg & MEMMASK;
m_quad_mode = true;
if (m_debug) printf("QSPI/QR: PAGE-PROGRAM ADDR = %06x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(MEMMASK)))==0);
// m_page = m_addr >> 8;
for(int i=0; i<256; i++)
m_pmem[i] = 0x0ff;
467,7 → 466,7
if (m_count == 32) {
m_addr = m_ireg & 0x0ffc000;
if (m_debug) printf("SECTOR_ERASE ADDRESS = %08x\n", m_addr);
assert((m_addr & 0xfc00000)==0);
assert((m_addr & (~(MEMMASK)))==0);
} break;
case QSPIF_RELEASE:
if (m_count >= 32) {
/s6soc/trunk/bench/cpp/qspiflashsim.h
1,4 → 1,4
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Filename: spiflashsim.h
//
9,12 → 9,12
// board by Digilent. As such, it is defined by 32 Mbits of
// memory (4 Mbyte).
//
// Creator: Dan Gisselquist
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
27,7 → 27,7
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory, run make with no
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
35,7 → 35,9
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef QSPIFLASHSIM_H
#define QSPIFLASHSIM_H
 
76,7 → 78,7
QSPIFLASHSIM(void);
void load(const char *fname) { load(0, fname); }
void load(const unsigned addr, const char *fname);
void write(const unsigned addr, const unsigned len, const uint32_t *buf);
void write(const unsigned addr, const unsigned len, const char *buf);
void debug(const bool dbg) { m_debug = dbg; }
bool debug(void) const { return m_debug; }
int operator()(const int csn, const int sck, const int dat);
/s6soc/trunk/bench/cpp/testb.h
12,7 → 12,7
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015,2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
37,25 → 37,56
#ifndef TESTB_H
#define TESTB_H
 
#include <stdio.h>
#include <stdint.h>
#include <verilated_vcd_c.h>
 
template <class VA> class TESTB {
public:
VA *m_core;
VerilatedVcdC* m_trace;
unsigned long m_tickcount;
 
TESTB(void) { m_core = new VA; }
virtual ~TESTB(void) { delete m_core; m_core = NULL; }
TESTB(void) : m_trace(NULL), m_tickcount(0l) {
m_core = new VA;
Verilated::traceEverOn(true);
}
virtual ~TESTB(void) {
if (m_trace) m_trace->close();
delete m_core;
m_core = NULL;
}
 
virtual void opentrace(const char *vcdname) {
m_trace = new VerilatedVcdC;
m_core->trace(m_trace, 99);
m_trace->open(vcdname);
}
 
virtual void closetrace(void) {
if (m_trace) {
m_trace->close();
m_trace = NULL;
}
}
 
virtual void eval(void) {
m_core->eval();
}
 
virtual void tick(void) {
m_tickcount++;
 
//if((m_trace)&&(m_tickcount)) m_trace->dump(10*m_tickcount-4);
eval();
if ((m_trace)&&(m_tickcount)) m_trace->dump(10*m_tickcount-2);
m_core->i_clk = 1;
eval();
if (m_trace) m_trace->dump(10*m_tickcount);
m_core->i_clk = 0;
eval();
if (m_trace) m_trace->dump(10*m_tickcount+5);
 
m_tickcount++;
}
 
virtual void reset(void) {
62,7 → 93,6
m_core->i_rst = 1;
tick();
m_core->i_rst = 0;
m_tickcount = 0l;
// printf("RESET\n");
}
};
/s6soc/trunk/bench/cpp/uartsim.cpp
1,69 → 1,349
////////////////////////////////////////////////////////////////////////////////
//
// Filename: uartsim.cpp
//
// Filename: uartsim.cpp
// Project: wbuart32, a full featured UART with simulator
//
// Project: FPGA library development (S6 development board)
// Purpose: To forward a Verilator simulated UART link over a TCP/IP pipe.
//
// Purpose: To emulate the external parameters of a UART device, providing
// the UART output to, and input from, the command
// console/terminal while also providing the controller with
// appropriate busy lines as necessary.
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
// Creator: Dan Gisselquist
// Gisselquist Tecnology, LLC
////////////////////////////////////////////////////////////////////////////////
//
// Copyright: 2016
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <signal.h>
#include <ctype.h>
 
#include "uartsim.h"
 
UARTSIM::UARTSIM(int baud_counts, int fdin, int fdout) {
int fctl_flags;
void UARTSIM::setup_listener(const int port) {
struct sockaddr_in my_addr;
 
m_fdin = fdin;
m_fdout = fdout;
m_baud_counts = baud_counts;
signal(SIGPIPE, SIG_IGN);
 
m_tx_busy_count = 0;
m_rx_busy_count = -1;
printf("Listening on port %d\n", port);
 
// Set the linux O_NONBLOCK on fdin
fctl_flags = fcntl(fdin, F_GETFL, 0);
fcntl(fdin, F_SETFL, fctl_flags | O_NONBLOCK);
m_skt = socket(AF_INET, SOCK_STREAM, 0);
if (m_skt < 0) {
perror("Could not allocate socket: ");
exit(-1);
}
 
// Set the reuse address option
{
int optv = 1, er;
er = setsockopt(m_skt, SOL_SOCKET, SO_REUSEADDR, &optv, sizeof(optv));
if (er != 0) {
perror("SockOpt Err:");
exit(-1);
}
}
 
memset(&my_addr, 0, sizeof(struct sockaddr_in)); // clear structure
my_addr.sin_family = AF_INET;
// Use *all* internet ports to this computer, allowing connections from
// any/every one of them.
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons(port);
if (bind(m_skt, (struct sockaddr *)&my_addr, sizeof(my_addr))!=0) {
perror("BIND FAILED:");
exit(-1);
}
 
if (listen(m_skt, 1) != 0) {
perror("Listen failed:");
exit(-1);
}
}
 
int UARTSIM::rx(unsigned char &data) {
if (m_rx_busy_count >= 0) {
if (m_rx_busy_count-- == 0) {
data = (unsigned char)m_rx_next;
return 1;
UARTSIM::UARTSIM(const int port) {
m_conrd = m_conwr = m_skt = -1;
if (port == 0) {
m_conrd = STDIN_FILENO;
m_conwr = STDOUT_FILENO;
} else
setup_listener(port);
setup(25); // Set us up for (default) 8N1 w/ a baud rate of CLK/25
m_rx_baudcounter = 0;
m_tx_baudcounter = 0;
m_rx_state = RXIDLE;
m_tx_state = TXIDLE;
}
 
void UARTSIM::kill(void) {
fflush(stdout);
 
// Quickly double check that we aren't about to close stdin/stdout
if (m_conrd == STDIN_FILENO)
m_conwr = -1;
if (m_conwr == STDOUT_FILENO)
m_conwr = -1;
// Close any active connection
if (m_conrd >= 0) close(m_conrd);
if ((m_conwr >= 0)&&(m_conwr != m_conrd)) close(m_conwr);
if (m_skt >= 0) close(m_skt);
 
m_conrd = m_conwr = m_skt = -1;
}
 
void UARTSIM::setup(unsigned isetup) {
if (isetup != m_setup) {
m_setup = isetup;
m_baud_counts = (isetup & 0x0ffffff);
m_nbits = 8-((isetup >> 28)&0x03);
m_nstop =((isetup >> 27)&1)+1;
m_nparity = (isetup >> 26)&1;
m_fixdp = (isetup >> 25)&1;
m_evenp = (isetup >> 24)&1;
}
}
 
int UARTSIM::nettick(int i_tx) {
int o_rx = 1;
 
if ((m_conrd < 0)&&(m_conwr<0)&&(m_skt>=0)) {
// Can we accept a connection?
struct pollfd pb;
 
pb.fd = m_skt;
pb.events = POLLIN;
poll(&pb, 1, 0);
 
if (pb.revents & POLLIN) {
m_conrd = accept(m_skt, 0, 0);
m_conwr = m_conrd;
 
if (m_conrd < 0)
perror("Accept failed:");
}
}
 
if (read(m_fdin, &m_rx_next, 1) > 0)
m_rx_busy_count = m_baud_counts;
if ((!i_tx)&&(m_last_tx))
m_rx_changectr = 0;
else m_rx_changectr++;
m_last_tx = i_tx;
 
return 0;
if (m_rx_state == RXIDLE) {
if (!i_tx) {
m_rx_state = RXDATA;
m_rx_baudcounter =m_baud_counts+m_baud_counts/2-1;
m_rx_baudcounter -= m_rx_changectr;
m_rx_busy = 0;
m_rx_data = 0;
}
} else if (m_rx_baudcounter <= 0) {
if (m_rx_busy >= (1<<(m_nbits+m_nparity+m_nstop-1))) {
m_rx_state = RXIDLE;
if (m_conwr >= 0) {
char buf[1];
buf[0] = (m_rx_data >> (32-m_nbits-m_nstop-m_nparity))&0x0ff;
if (1 != send(m_conwr, buf, 1, 0)) {
close(m_conwr);
m_conrd = m_conwr = -1;
}
}
} else {
m_rx_busy = (m_rx_busy << 1)|1;
// Low order bit is transmitted first, in this
// order:
// Start bit (1'b1)
// bit 0
// bit 1
// bit 2
// ...
// bit N-1
// (possible parity bit)
// stop bit
// (possible secondary stop bit)
m_rx_data = ((i_tx&1)<<31) | (m_rx_data>>1);
} m_rx_baudcounter = m_baud_counts-1;
} else
m_rx_baudcounter--;
 
if (m_tx_state == TXIDLE) {
struct pollfd pb;
pb.fd = m_conrd;
pb.events = POLLIN;
if (poll(&pb, 1, 0) < 0)
perror("Polling error:");
if (pb.revents & POLLIN) {
char buf[1];
if (1 == recv(m_conrd, buf, 1, MSG_DONTWAIT)) {
m_tx_data = (-1<<(m_nbits+m_nparity+1))
// << nstart_bits
|((buf[0]<<1)&0x01fe);
if (m_nparity) {
int p;
 
// If m_nparity is set, we need to then
// create the parity bit.
if (m_fixdp)
p = m_evenp;
else {
p = (m_tx_data >> 1)&0x0ff;
p = p ^ (p>>4);
p = p ^ (p>>2);
p = p ^ (p>>1);
p &= 1;
p ^= m_evenp;
}
m_tx_data |= (p<<(m_nbits+m_nparity));
}
m_tx_busy = (1<<(m_nbits+m_nparity+m_nstop+1))-1;
m_tx_state = TXDATA;
o_rx = 0;
m_tx_baudcounter = m_baud_counts-1;
}
}
} else if (m_tx_baudcounter <= 0) {
m_tx_data >>= 1;
m_tx_busy >>= 1;
if (!m_tx_busy)
m_tx_state = TXIDLE;
else
m_tx_baudcounter = m_baud_counts-1;
o_rx = m_tx_data&1;
} else {
m_tx_baudcounter--;
o_rx = m_tx_data&1;
}
 
return o_rx;
}
 
int UARTSIM::tx(int stb, char data) {
if (m_tx_busy_count > 0) {
int UARTSIM::fdtick(int i_tx) {
int o_rx = 1;
 
// This write may block--if so, we don't care. Just write it.
if (--m_tx_busy_count == 0)
if (write(m_fdout, &m_tx_data, 1) != 1)
perror("O/S Write Err:");
return 1;
} else if (stb) {
m_tx_data = data;
m_tx_busy_count = m_baud_counts;
if ((!i_tx)&&(m_last_tx))
m_rx_changectr = 0;
else m_rx_changectr++;
m_last_tx = i_tx;
 
if (m_rx_state == RXIDLE) {
if (!i_tx) {
m_rx_state = RXDATA;
m_rx_baudcounter =m_baud_counts+m_baud_counts/2-1;
m_rx_baudcounter -= m_rx_changectr;
m_rx_busy = 0;
m_rx_data = 0;
}
} else if (m_rx_baudcounter <= 0) {
if (m_rx_busy >= (1<<(m_nbits+m_nparity+m_nstop-1))) {
m_rx_state = RXIDLE;
if (m_conwr >= 0) {
char buf[1];
buf[0] = (m_rx_data >> (32-m_nbits-m_nstop-m_nparity))&0x0ff;
if (1 != write(m_conwr, buf, 1)) {
fprintf(stderr, "ERR while attempting to write out--closing output port\n");
perror("UARTSIM::write() ");
m_conrd = m_conwr = -1;
}
}
} else {
m_rx_busy = (m_rx_busy << 1)|1;
// Low order bit is transmitted first, in this
// order:
// Start bit (1'b1)
// bit 0
// bit 1
// bit 2
// ...
// bit N-1
// (possible parity bit)
// stop bit
// (possible secondary stop bit)
m_rx_data = ((i_tx&1)<<31) | (m_rx_data>>1);
} m_rx_baudcounter = m_baud_counts-1;
} else
m_rx_baudcounter--;
 
if ((m_tx_state == TXIDLE)&&(m_conrd >= 0)) {
struct pollfd pb;
pb.fd = m_conrd;
pb.events = POLLIN;
if (poll(&pb, 1, 0) < 0)
perror("Polling error:");
if (pb.revents & POLLIN) {
char buf[1];
int nr;
if (1==(nr = read(m_conrd, buf, 1))) {
m_tx_data = (-1<<(m_nbits+m_nparity+1))
// << nstart_bits
|((buf[0]<<1)&0x01fe);
if (m_nparity) {
int p;
 
// If m_nparity is set, we need to then
// create the parity bit.
if (m_fixdp)
p = m_evenp;
else {
p = (m_tx_data >> 1)&0x0ff;
p = p ^ (p>>4);
p = p ^ (p>>2);
p = p ^ (p>>1);
p &= 1;
p ^= m_evenp;
}
m_tx_data |= (p<<(m_nbits+m_nparity));
}
m_tx_busy = (1<<(m_nbits+m_nparity+m_nstop+1))-1;
m_tx_state = TXDATA;
o_rx = 0;
m_tx_baudcounter = m_baud_counts-1;
} else if (nr < 0) {
fprintf(stderr, "ERR while attempting to read in--closing input port\n");
perror("UARTSIM::read() ");
m_conrd = -1;
} // and we really don't care if nr == 0 except that
// the poll above is supposed to keep it from happening
}
} else if (m_tx_baudcounter == 0) {
m_tx_data >>= 1;
m_tx_busy >>= 1;
if (!m_tx_busy)
m_tx_state = TXIDLE;
else
m_tx_baudcounter = m_baud_counts-1;
o_rx = m_tx_data&1;
} else {
m_tx_baudcounter--;
o_rx = m_tx_data&1;
}
 
return 0;
return o_rx;
}
 
 
/s6soc/trunk/bench/cpp/uartsim.h
1,33 → 1,132
////////////////////////////////////////////////////////////////////////////////
//
// Filename: uartsim.h
//
// Filename: uartsim.h
// Project: wbuart32, a full featured UART with simulator
//
// Project: FPGA library development (S6 development board)
// Purpose: To forward a Verilator simulated UART link over a TCP/IP pipe.
//
// Purpose: To emulate the external parameters of a UART device, providing
// the UART output to, and input from, the command
// console/terminal while also providing the controller with
// appropriate busy lines as necessary.
// This file provides the description of the interface between the UARTSIM
// and the rest of the world. See below for more detailed descriptions.
//
// Creator: Dan Gisselquist
// Gisselquist Tecnology, LLC
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
// Copyright: 2016
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef UARTSIM_H
#define UARTSIM_H
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <signal.h>
 
class UARTSIM {
private:
int m_tx_busy_count, m_baud_counts, m_rx_busy_count;
int m_fdin, m_fdout;
char m_rx_next, m_tx_data;
#define TXIDLE 0
#define TXDATA 1
#define RXIDLE 0
#define RXDATA 1
 
class UARTSIM {
// The file descriptors:
// m_skt is the socket/port we are listening on
// m_conrd is the file descriptor to read from
// m_conwr is the file descriptor to write to
int m_skt, m_conrd, m_conwr;
//
// The m_setup register is the 29'bit control register used within
// the core.
unsigned m_setup;
// And the pieces of the setup register broken out.
int m_nparity, m_fixdp, m_evenp, m_nbits, m_nstop, m_baud_counts;
 
// UART state
int m_rx_baudcounter, m_rx_state, m_rx_busy,
m_rx_changectr, m_last_tx;
int m_tx_baudcounter, m_tx_state, m_tx_busy;
unsigned m_rx_data, m_tx_data;
 
// setup_listener is an attempt to encapsulate all of the network
// related setup stuff.
void setup_listener(const int port);
 
// nettick() gets called if we are connected to a network, and
int nettick(const int i_tx);
// fdtick() if we are not.
int fdtick(const int i_tx);
 
// We'll use the file descriptor for the listener socket to determine
// whether we are connected to the network or not. If not connected
// to the network, then we assume m_conrd and m_conwr refer to
// your more traditional file descriptors, and use them as such.
int tick(const int i_tx) {
if (m_skt >= 0)
return nettick(i_tx);
else
return fdtick(i_tx);
}
 
public:
UARTSIM(int baud_counts, int fdin = STDIN_FILENO,
int fdout=STDOUT_FILENO);
int rx(unsigned char &data);
int tx(int stb, char data);
//
// The UARTSIM constructor takes one argument: the port on the
// localhost to listen in on. Once started, connections may be made
// to this port to get the output from the port.
UARTSIM(const int port);
 
// kill() closes any active connection and the socket. Once killed,
// no further output will be sent to the port.
void kill(void);
 
// setup() busts out the bits from isetup to the various internal
// parameters. It is ideally only called between bits at appropriate
// transition intervals.
void setup(unsigned isetup);
 
// The operator() function is called on every tick. The input is the
// the output txuart transmit wire from the device. The output is to
// be connected to the the rxuart receive wire into the device. This
// makes hookup and operation very simple.
//
// This is the most appropriate simulation entry function if the
// setup register will never change.
//
int operator()(int i_tx) {
return tick(i_tx); }
 
// If there is a possibility that the core might change the UART setup,
// then it makes sense to include that current setup when calling the
// tick operator.
int operator()(int i_tx, unsigned isetup) {
setup(isetup); return tick(i_tx); }
};
 
 
#endif
/s6soc/trunk/bench/cpp/zip_sim.cpp
52,6 → 52,8
// #include "twoc.h"
#include "qspiflashsim.h"
#include "uartsim.h"
#include "zipelf.h"
#include "byteswap.h"
 
typedef uint32_t BUSW;
 
65,14 → 67,44
unsigned operator()(const unsigned o_kpd) { return 0; }
};
 
// Add a reset line, since Vbusmaster doesn't have one
class Vbusmasterr : public Vbusmaster {
public:
int i_rst;
};
#define tx_busy v__DOT__tcvuart__DOT__r_busy
#define rx_stb v__DOT__rx_stb
#define uart_setup v__DOT__tcvuart__DOT__r_setup
#define cpu_regset v__DOT__swic__DOT__thecpu__DOT__regset
#define cpu_gie v__DOT__swic__DOT__thecpu__DOT__r_gie
#define cpu_ipc v__DOT__swic__DOT__thecpu__DOT__ipc
#define cpu_upc v__DOT__swic__DOT__thecpu__DOT__r_upc
#define cpu_op_Av v__DOT__swic__DOT__thecpu__DOT__r_op_Av
#define cpu_op_Bv v__DOT__swic__DOT__thecpu__DOT__r_op_Bv
#define cpu_iflags v__DOT__swic__DOT__thecpu__DOT__w_iflags
#define cpu_uflags v__DOT__swic__DOT__thecpu__DOT__w_uflags
#define cpu_pf_valid v__DOT__swic__DOT__thecpu__DOT__pf_valid
#define cpu_pf_pc v__DOT__swic__DOT__thecpu__DOT__pf_pc
#define cpu_pf_instruction_pc v__DOT__swic__DOT__thecpu__DOT__pf_instruction_pc
#define cpu_pf_instruction v__DOT__swic__DOT__thecpu__DOT__pf_instruction
#define cpu_op_valid v__DOT__swic__DOT__thecpu__DOT__op_valid
#define cpu_op_sim v__DOT__swic__DOT__thecpu__DOT__op_sim
#define cpu_sim_immv v__DOT__swic__DOT__thecpu__DOT__op_sim_immv
#define cpu_alu_ce v__DOT__swic__DOT__thecpu__DOT__alu_ce
//
#define pic_gie v__DOT__pic__DOT__r_gie
#define pic_int_enable v__DOT__pic__DOT__r_int_enable
#define pic_any v__DOT__pic__DOT__r_any
#define pic_int_state v__DOT__pic__DOT__r_int_state
#define wb_cyc v__DOT__wb_cyc
#define wb_stb v__DOT__wb_stb
#define wb_we v__DOT__wb_we
#define wb_data v__DOT__swic__DOT__thecpu__DOT__mem_data
#define wb_addr v__DOT__w_zip_addr
//
#define wb_ack v__DOT__wb_ack
#define wb_stall v__DOT__wb_stall
#define wb_idata v__DOT__wb_idata
//
#define watchdog_int v__DOT__watchdog_int
 
// No particular "parameters" need definition or redefinition here.
class ZIPSIM_TB : public TESTB<Vbusmasterr> {
class ZIPSIM_TB : public TESTB<Vbusmaster> {
public:
QSPIFLASHSIM m_flash;
UARTSIM m_uart;
79,12 → 111,17
GPIOSIM m_gpio;
KEYPADSIM m_keypad;
unsigned m_last_led;
unsigned m_last_gpio, m_last_pf_pc;
time_t m_start_time;
FILE *m_dbg;
 
ZIPSIM_TB(void) : m_uart(0x2b6) {
ZIPSIM_TB(int serial_port, bool debug) : m_uart(serial_port) {
m_start_time = time(NULL);
m_dbg = fopen("dbg.txt","w");
if (debug)
m_dbg = fopen("dbg.txt","w");
else m_dbg = NULL;
 
m_last_led = m_last_gpio = m_last_pf_pc = -1;
}
 
void reset(void) {
91,11 → 128,135
m_flash.debug(false);
}
 
void close(void) {
closetrace();
}
 
void dump(const uint32_t *regp) {
uint32_t uccv, iccv;
fflush(stderr);
fflush(stdout);
printf("ZIPM--DUMP: ");
if (m_core->cpu_gie)
printf("Interrupts-enabled\n");
else
printf("Supervisor mode\n");
printf("\n");
 
iccv = m_core->cpu_iflags;
uccv = m_core->cpu_uflags;
 
printf("sR0 : %08x ", regp[0]);
printf("sR1 : %08x ", regp[1]);
printf("sR2 : %08x ", regp[2]);
printf("sR3 : %08x\n",regp[3]);
printf("sR4 : %08x ", regp[4]);
printf("sR5 : %08x ", regp[5]);
printf("sR6 : %08x ", regp[6]);
printf("sR7 : %08x\n",regp[7]);
printf("sR8 : %08x ", regp[8]);
printf("sR9 : %08x ", regp[9]);
printf("sR10: %08x ", regp[10]);
printf("sR11: %08x\n",regp[11]);
printf("sR12: %08x ", regp[12]);
printf("sSP : %08x ", regp[13]);
printf("sCC : %08x ", iccv);
printf("sPC : %08x\n",m_core->cpu_ipc);
 
printf("\n");
 
printf("uR0 : %08x ", regp[16]);
printf("uR1 : %08x ", regp[17]);
printf("uR2 : %08x ", regp[18]);
printf("uR3 : %08x\n",regp[19]);
printf("uR4 : %08x ", regp[20]);
printf("uR5 : %08x ", regp[21]);
printf("uR6 : %08x ", regp[22]);
printf("uR7 : %08x\n",regp[23]);
printf("uR8 : %08x ", regp[24]);
printf("uR9 : %08x ", regp[25]);
printf("uR10: %08x ", regp[26]);
printf("uR11: %08x\n",regp[27]);
printf("uR12: %08x ", regp[28]);
printf("uSP : %08x ", regp[29]);
printf("uCC : %08x ", uccv);
printf("uPC : %08x\n",m_core->cpu_upc);
printf("\n");
fflush(stderr);
fflush(stdout);
}
 
void execsim(const uint32_t imm) {
uint32_t *regp = m_core->cpu_regset;
int rbase;
rbase = (m_core->cpu_gie)?16:0;
 
fflush(stdout);
if ((imm & 0x03fffff)==0)
return;
// fprintf(stderr, "SIM-INSN(0x%08x)\n", imm);
if ((imm & 0x0fffff)==0x00100) {
// SIM Exit(0)
close();
exit(0);
} else if ((imm & 0x0ffff0)==0x00310) {
// SIM Exit(User-Reg)
int rcode;
rcode = regp[(imm&0x0f)+16] & 0x0ff;
close();
exit(rcode);
} else if ((imm & 0x0ffff0)==0x00300) {
// SIM Exit(Reg)
int rcode;
rcode = regp[(imm&0x0f)+rbase] & 0x0ff;
close();
exit(rcode);
} else if ((imm & 0x0fff00)==0x00100) {
// SIM Exit(Imm)
int rcode;
rcode = imm & 0x0ff;
close();
exit(rcode);
} else if ((imm & 0x0fffff)==0x002ff) {
// Full/unconditional dump
printf("SIM-DUMP\n");
dump(regp);
} else if ((imm & 0x0ffff0)==0x00200) {
// Dump a register
int rid = (imm&0x0f)+rbase;
printf("%8ld @%08x R[%2d] = 0x%08x\n", m_tickcount,
m_core->cpu_ipc, rid, regp[rid]);
} else if ((imm & 0x0ffff0)==0x00210) {
// Dump a user register
int rid = (imm&0x0f);
printf("%8ld @%08x uR[%2d] = 0x%08x\n", m_tickcount,
m_core->cpu_ipc, rid, regp[rid+16]);
} else if ((imm & 0x0ffff0)==0x00230) {
// SOUT[User Reg]
int rid = (imm&0x0f)+16;
printf("%c", regp[rid]&0x0ff);
} else if ((imm & 0x0fffe0)==0x00220) {
// SOUT[User Reg]
int rid = (imm&0x0f)+rbase;
printf("%c", regp[rid]&0x0ff);
} else if ((imm & 0x0fff00)==0x00400) {
// SOUT[Imm]
printf("%c", imm&0x0ff);
} else { // if ((insn & 0x0f7c00000)==0x77800000)
uint32_t immv = imm & 0x03fffff;
// Simm instruction that we dont recognize
// if (imm)
// printf("SIM 0x%08x\n", immv);
printf("SIM 0x%08x (ipc = %08x, upc = %08x)\n", immv,
m_core->cpu_ipc, m_core->cpu_upc);
} fflush(stdout);
}
 
void tick(void) {
if ((m_tickcount & ((1<<28)-1))==0) {
double ticks_per_second = m_tickcount;
time_t nsecs = (time(NULL)-m_start_time);
if (nsecs > 0) {
if ((nsecs > 0)&&(ticks_per_second>0)) {
ticks_per_second /= (double)nsecs;
printf(" ******** %.6f TICKS PER SECOND\n",
ticks_per_second);
119,348 → 280,82
m_core->i_kp_row = m_keypad(m_core->o_kp_col);
 
// And the UART
m_core->i_rx_stb = m_uart.rx(m_core->i_rx_data);
m_core->i_tx_busy = m_uart.tx(m_core->o_tx_stb, m_core->o_tx_data);
m_core->i_uart_cts_n = 0;
m_uart.setup(m_core->uart_setup);
m_core->i_uart = m_uart(m_core->o_uart);
 
TESTB<Vbusmasterr>::tick();
TESTB<Vbusmaster>::tick();
 
if (m_core->o_led != m_last_led) {
printf("LED: %08x\n", m_core->o_led);
m_last_led = m_core->o_led;
if ((m_core->o_led != m_last_led)||(m_core->o_gpio != m_last_gpio)||(m_core->cpu_pf_pc != m_last_pf_pc)) {
printf("LED: %x\tGPIO: %04x\tPF-PC = %08x\r", m_core->o_led,
m_core->o_gpio, m_core->cpu_pf_pc);
fflush(stdout);
m_last_led = m_core->o_led;
m_last_gpio = m_core->o_gpio;
}
 
if (m_core->watchdog_int) {
printf("\nWATCHDOG-INT!!! CPU-sPC = %08x, TICKS = %08lx\n", m_core->cpu_ipc, m_tickcount);
}
if (m_dbg) fprintf(m_dbg, "PC: %08x:%08x [%08x:%08x:%08x:%08x:%08x],%08x,%08x,%d,%08x,%08x (%x,%x/0x%08x)\n",
m_core->v__DOT__thecpu__DOT__thecpu__DOT__ipc,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__upc,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[0],
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[1],
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[2],
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[3],
m_core->v__DOT__thecpu__DOT__thecpu__DOT__regset[15],
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction_decoder__DOT__r_I,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__r_opB,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction_decoder__DOT__w_dcdR_pc,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__r_opA,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__wr_reg_vl,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__w_iflags,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__w_uflags,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__pf_pc
);
if ((m_core->v__DOT__wb_cyc)&&(m_dbg))
if (m_dbg) fprintf(m_dbg, "%10ld - PC: %08x:%08x [%08x:%08x:%08x:%08x:%08x],%08x,%08x,%d,%08x,%08x (%x,%x/0x%08x)\n",
m_tickcount,
m_core->cpu_ipc,
m_core->cpu_upc,
m_core->cpu_regset[0],
m_core->cpu_regset[1],
m_core->cpu_regset[2],
m_core->cpu_regset[3],
m_core->cpu_regset[15],
m_core->v__DOT__swic__DOT__thecpu__DOT__instruction_decoder__DOT__r_I,
m_core->cpu_op_Bv,
m_core->v__DOT__swic__DOT__thecpu__DOT__instruction_decoder__DOT__w_dcdR_pc,
m_core->cpu_op_Av,
m_core->v__DOT__swic__DOT__thecpu__DOT__wr_gpreg_vl,
m_core->cpu_iflags,
m_core->cpu_uflags,
m_core->cpu_pf_pc);
if ((!m_core->o_qspi_cs_n)&&(m_dbg))
fprintf(m_dbg, "QSPI: [CS,SCK,DAT (MOD)] = %d,%d,%02x,%d -> %04x %7s, state= %x/(%d)\n",
m_core->o_qspi_cs_n,
m_core->o_qspi_sck,
m_core->o_qspi_dat,
m_core->o_qspi_mod,
m_core->i_qspi_dat,
(m_core->v__DOT__flashmem__DOT__quad_mode_enabled)?"(quad)":"",
m_core->v__DOT__flashmem__DOT__state,
m_core->v__DOT__flashmem__DOT__lldriver__DOT__state);
 
if ((m_core->wb_cyc)&&(m_dbg))
fprintf(m_dbg, "WB: %s/%s/%s[@0x%08x] %08x ->%s/%s %08x\n",
(m_core->v__DOT__wb_cyc)?"CYC":" ",
(m_core->v__DOT__wb_stb)?"STB":" ",
(m_core->v__DOT__wb_we )?"WE ":" ",
(m_core->v__DOT__w_zip_addr),
(m_core->v__DOT__wb_data),
(m_core->v__DOT__wb_ack)?"ACK":" ",
(m_core->v__DOT__wb_stall)?"STL":" ",
(m_core->v__DOT__wb_idata)
(m_core->wb_cyc)?"CYC":" ",
(m_core->wb_stb)?"STB":" ",
(m_core->wb_we )?"WE ":" ",
(m_core->wb_addr),
(m_core->wb_data),
(m_core->wb_ack)?"ACK":" ",
(m_core->wb_stall)?"STL":" ",
(m_core->wb_idata)
);
if (m_dbg)
fprintf(m_dbg, "PIC: %3s(%4x) %3s(%4x)%s\n",
(m_core->v__DOT__pic__DOT__r_gie)?"GIE":"",
(m_core->v__DOT__pic__DOT__r_int_enable),
(m_core->v__DOT__pic__DOT__r_any)?"ANY":"",
(m_core->v__DOT__pic__DOT__r_int_state),
(m_core->v__DOT__pic__DOT__r_interrupt)?" ---> INT!":"");
 
if ((m_core->v__DOT__thecpu__DOT__thecpu__DOT__pf_valid)&&(m_dbg))
if ((m_core->cpu_pf_valid)&&(m_dbg))
fprintf(m_dbg, "PC: %08x - %08x, uart=%d,%d, pic = %d,%04x,%0d,%04x\n",
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction_pc,
m_core->v__DOT__thecpu__DOT__thecpu__DOT__instruction,
m_core->i_rx_stb, m_core->i_tx_busy,
m_core->v__DOT__pic__DOT__r_gie,
m_core->v__DOT__pic__DOT__r_int_enable,
m_core->v__DOT__pic__DOT__r_any,
m_core->v__DOT__pic__DOT__r_int_state);
}
};
m_core->cpu_pf_instruction_pc,
m_core->cpu_pf_instruction,
m_core->rx_stb, m_core->tx_busy,
m_core->pic_gie,
m_core->pic_int_enable,
m_core->pic_any,
m_core->pic_int_state);
 
ZIPSIM_TB *tb;
 
bool iself(const char *fname) {
FILE *fp;
bool ret = true;
 
if ((!fname)||(!fname[0]))
return false;
 
fp = fopen(fname, "rb");
 
if (!fp) return false;
if (0x7f != fgetc(fp)) ret = false;
if ('E' != fgetc(fp)) ret = false;
if ('L' != fgetc(fp)) ret = false;
if ('F' != fgetc(fp)) ret = false;
fclose(fp);
return ret;
}
 
long fgetwords(FILE *fp) {
// Return the number of words in the current file, and return the
// file as though it had never been adjusted
long fpos, flen;
fpos = ftell(fp);
if (0 != fseek(fp, 0l, SEEK_END)) {
fprintf(stderr, "ERR: Could not determine file size\n");
perror("O/S Err:");
exit(-2);
} flen = ftell(fp);
if (0 != fseek(fp, fpos, SEEK_SET)) {
fprintf(stderr, "ERR: Could not seek on file\n");
perror("O/S Err:");
exit(-2);
} flen /= sizeof(BUSW);
return flen;
}
 
class SECTION {
public:
unsigned m_start, m_len;
BUSW m_data[1];
// SIM instruction(s)
if ((m_core->cpu_op_sim)&&(m_core->cpu_op_valid)
&&(m_core->cpu_alu_ce))
execsim(m_core->cpu_sim_immv);
}
};
 
SECTION **singlesection(int nwords) {
fprintf(stderr, "NWORDS = %d\n", nwords);
size_t sz = (2*(sizeof(SECTION)+sizeof(SECTION *))
+(nwords-1)*(sizeof(BUSW)));
char *d = (char *)malloc(sz);
SECTION **r = (SECTION **)d;
memset(r, 0, sz);
r[0] = (SECTION *)(&d[2*sizeof(SECTION *)]);
r[0]->m_len = nwords;
r[1] = (SECTION *)(&r[0]->m_data[r[0]->m_len]);
r[0]->m_start = 0;
r[1]->m_start = 0;
r[1]->m_len = 0;
 
return r;
}
 
SECTION **rawsection(const char *fname) {
SECTION **secpp, *secp;
unsigned num_words;
FILE *fp;
int nr;
 
fp = fopen(fname, "r");
if (fp == NULL) {
fprintf(stderr, "Could not open: %s\n", fname);
exit(-1);
}
 
if ((num_words=fgetwords(fp)) > FLASHWORDS) {
fprintf(stderr, "File overruns flash memory\n");
exit(-1);
}
secpp = singlesection(num_words);
secp = secpp[0];
secp->m_start = RESET_ADDRESS;
secp->m_len = num_words;
nr= fread(secp->m_data, sizeof(BUSW), num_words, fp);
if (nr != (int)num_words) {
fprintf(stderr, "Could not read entire file\n");
perror("O/S Err:");
exit(-2);
} assert(secpp[1]->m_len == 0);
 
return secpp;
}
 
unsigned byteswap(unsigned n) {
unsigned r;
 
r = (n&0x0ff); n>>= 8;
r = (r<<8) | (n&0x0ff); n>>= 8;
r = (r<<8) | (n&0x0ff); n>>= 8;
r = (r<<8) | (n&0x0ff); n>>= 8;
 
return r;
}
 
#include <libelf.h>
#include <gelf.h>
 
void elfread(const char *fname, unsigned &entry, SECTION **&sections) {
Elf *e;
int fd, i;
size_t n;
char *id;
Elf_Kind ek;
GElf_Ehdr ehdr;
GElf_Phdr phdr;
const bool dbg = false;
 
if (elf_version(EV_CURRENT) == EV_NONE) {
fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1));
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((fd = open(fname, O_RDONLY, 0)) < 0) {
fprintf(stderr, "Could not open %s\n", fname);
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) {
fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
ek = elf_kind(e);
if (ek == ELF_K_ELF) {
; // This is the kind of file we should expect
} else if (ek == ELF_K_AR) {
fprintf(stderr, "Cannot run an archive!\n");
exit(EXIT_FAILURE);
} else if (ek == ELF_K_NONE) {
;
} else {
fprintf(stderr, "Unexpected ELF file kind!\n");
exit(EXIT_FAILURE);
}
 
if (gelf_getehdr(e, &ehdr) == NULL) {
fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((i=gelf_getclass(e)) == ELFCLASSNONE) {
fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((id = elf_getident(e, NULL)) == NULL) {
fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if (i != ELFCLASS32) {
fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n");
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type);
printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine);
printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version);
printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry);
printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff);
printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff);
printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags);
printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize);
printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize);
printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize);
printf("\n");
}
 
 
// Check whether or not this is an ELF file for the ZipCPU ...
if (ehdr.e_machine != 0x0dadd) {
fprintf(stderr, "This is not a ZipCPU ELF file\n");
exit(EXIT_FAILURE);
}
 
// Get our entry address
entry = ehdr.e_entry;
 
 
// Now, let's go look at the program header
if (elf_getphdrnum(e, &n) != 0) {
fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
unsigned total_octets = 0, current_offset=0, current_section=0;
for(i=0; i<(int)n; i++) {
total_octets += sizeof(SECTION *)+sizeof(SECTION);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%x\n", "p_type", phdr.p_type);
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
total_octets += phdr.p_memsz;
}
 
char *d = (char *)malloc(total_octets + sizeof(SECTION)+sizeof(SECTION *));
memset(d, 0, total_octets);
 
SECTION **r = sections = (SECTION **)d;
current_offset = (n+1)*sizeof(SECTION *);
current_section = 0;
 
for(i=0; i<(int)n; i++) {
r[i] = (SECTION *)(&d[current_offset]);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
 
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
current_section++;
 
r[i]->m_start = phdr.p_vaddr;
r[i]->m_len = phdr.p_filesz/ sizeof(BUSW);
 
current_offset += phdr.p_memsz + sizeof(SECTION);
 
// Now, let's read in our section ...
if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) {
fprintf(stderr, "Could not seek to file position %08lx\n", phdr.p_offset);
perror("O/S Err:");
exit(EXIT_FAILURE);
} if (phdr.p_filesz > phdr.p_memsz)
phdr.p_filesz = 0;
if (read(fd, r[i]->m_data, phdr.p_filesz) != (int)phdr.p_filesz) {
fprintf(stderr, "Didnt read entire section\n");
perror("O/S Err:");
exit(EXIT_FAILURE);
}
 
// Next, we need to byte swap it from big to little endian
for(unsigned j=0; j<r[i]->m_len; j++)
r[i]->m_data[j] = byteswap(r[i]->m_data[j]);
 
if (dbg) for(unsigned j=0; j<r[i]->m_len; j++)
fprintf(stderr, "ADR[%04x] = %08x\n", r[i]->m_start+j,
r[i]->m_data[j]);
}
 
r[i] = (SECTION *)(&d[current_offset]);
r[current_section]->m_start = 0;
r[current_section]->m_len = 0;
 
elf_end(e);
close(fd);
}
 
 
void usage(void) {
fprintf(stderr, "Usage: zip_sim flash_program\n");
}
467,36 → 362,70
 
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
tb = new ZIPSIM_TB;
const char *codef = NULL;
ZIPSIM_TB *tb;
const char *codef = NULL, *trace_file = NULL;
bool debug_flag = false;
int serial_port = -1;
 
for(int argn=1; argn<argc; argn++) {
if (argv[argn][0] == '-') {
usage();
exit(-1);
} else
if (argv[argn][0] == '-') for (int j=1;
(j<512)&&(argv[argn][j]); j++) {
switch(tolower(argv[argn][j])) {
case 'c': break; // no comms to copy to stdout break;
case 'd': debug_flag = true;
if (trace_file == NULL)
trace_file = "trace.vcd";
break;
case 'p': break; // S6 has no fpga command port
case 's': serial_port=atoi(argv[++argn]); j=1000; break;
case 't': trace_file = (argn+1<argc)?argv[++argn]:NULL;j=1000; break;
case 'h': usage(); exit(EXIT_SUCCESS); break;
default:
fprintf(stderr, "ERR: Unexpected flag, -%c\n\n",
argv[argn][j]);
usage(); exit(EXIT_FAILURE);
}
} else if (iself(argv[argn])) {
codef = argv[argn];
} else {
fprintf(stderr, "ERR: Unknown/unexpected argument: %s\n",
argv[argn]);
exit(EXIT_FAILURE);
}
}
 
if ((!codef)||(!codef[0]))
fprintf(stderr, "No executable code filename found!\n");
 
if (serial_port < 0) {
printf("Using the terminal as a SERIAL port\n");
serial_port = 0;
}
tb = new ZIPSIM_TB(serial_port, debug_flag);
 
if (access(codef, R_OK)!=0)
fprintf(stderr, "Cannot read code filename, %s\n", codef);
 
if (iself(codef)) {
SECTION **secpp, *secp;
BUSW entry;
ELFSECTION **secpp, *secp;
BUSW entry;
elfread(codef, entry, secpp);
 
assert(entry == RESET_ADDRESS);
 
for(int i=0; secpp[i]->m_len; i++) {
secp = secpp[i];
tb->m_flash.write(secp->m_start, secp->m_len, secp->m_data);
tb->m_flash.write(secp->m_start, secp->m_len, (char *)&secp->m_data);
}
} else {
tb->m_flash.load(RESET_ADDRESS, codef);
fprintf(stderr, "%s is not a ZipCPU ELF executable\n", codef);
exit(EXIT_FAILURE);
}
 
// if (debug_flag) { }
if (trace_file)
tb->opentrace(trace_file);
 
tb->reset();
 
while(1)
/s6soc/trunk/bench/cpp/zipelf.cpp
0,0 → 1,251
////////////////////////////////////////////////////////////////////////////////
//
// Filename: zipelf.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose:
//
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
 
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libelf.h>
#include <assert.h>
#include <gelf.h>
#include <string.h>
 
#include "zipelf.h"
 
bool
iself(const char *fname)
{
FILE *fp;
bool ret = true;
fp = fopen(fname, "rb");
 
if (!fp) return false;
if (0x7f != fgetc(fp)) ret = false;
if ('E' != fgetc(fp)) ret = false;
if ('L' != fgetc(fp)) ret = false;
if ('F' != fgetc(fp)) ret = false;
fclose(fp);
return ret;
}
 
void elfread(const char *fname, unsigned &entry, ELFSECTION **&sections)
{
Elf *e;
int fd, i;
size_t n;
char *id;
Elf_Kind ek;
GElf_Ehdr ehdr;
GElf_Phdr phdr;
const bool dbg = false;
 
if (elf_version(EV_CURRENT) == EV_NONE) {
fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1));
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((fd = open(fname, O_RDONLY, 0)) < 0) {
fprintf(stderr, "Could not open %s\n", fname);
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) {
fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
ek = elf_kind(e);
if (ek == ELF_K_ELF) {
; // This is the kind of file we should expect
} else if (ek == ELF_K_AR) {
fprintf(stderr, "Cannot run an archive!\n");
exit(EXIT_FAILURE);
} else if (ek == ELF_K_NONE) {
;
} else {
fprintf(stderr, "Unexpected ELF file kind!\n");
exit(EXIT_FAILURE);
}
 
if (gelf_getehdr(e, &ehdr) == NULL) {
fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((i=gelf_getclass(e)) == ELFCLASSNONE) {
fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((id = elf_getident(e, NULL)) == NULL) {
fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if (i != ELFCLASS32) {
fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n");
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type);
printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine);
printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version);
printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry);
printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff);
printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff);
printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags);
printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize);
printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize);
printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize);
printf("\n");
}
 
 
// Check whether or not this is an ELF file for the ZipCPU ...
if (ehdr.e_machine != 0x0dad1) {
fprintf(stderr, "This is not a ZipCPU/8 ELF file\n");
exit(EXIT_FAILURE);
}
 
// Get our entry address
entry = ehdr.e_entry;
 
 
// Now, let's go look at the program header
if (elf_getphdrnum(e, &n) != 0) {
fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
assert(n != 0);
 
unsigned total_octets = 0, current_offset=0, current_section=0;
for(i=0; i<(int)n; i++) {
total_octets += sizeof(ELFSECTION *)+sizeof(ELFSECTION);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%x\n", "p_type", phdr.p_type);
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
total_octets += phdr.p_memsz;
}
 
char *d = (char *)malloc(total_octets + sizeof(ELFSECTION)+sizeof(ELFSECTION *));
memset(d, 0, total_octets);
 
ELFSECTION **r = sections = (ELFSECTION **)d;
current_offset = (n+1)*sizeof(ELFSECTION *);
current_section = 0;
 
for(i=0; i<(int)n; i++) {
r[i] = (ELFSECTION *)(&d[current_offset]);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
 
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
current_section++;
 
r[i]->m_start = phdr.p_paddr;
r[i]->m_len = phdr.p_filesz;
 
current_offset += phdr.p_memsz + sizeof(ELFSECTION);
 
// Now, let's read in our section ...
if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) {
fprintf(stderr, "Could not seek to file position %08lx\n", phdr.p_offset);
perror("O/S Err:");
exit(EXIT_FAILURE);
} if (phdr.p_filesz > phdr.p_memsz)
phdr.p_filesz = 0;
if (read(fd, r[i]->m_data, phdr.p_filesz) != (int)phdr.p_filesz) {
fprintf(stderr, "Didnt read entire section\n");
perror("O/S Err:");
exit(EXIT_FAILURE);
}
 
/*
// Next, we need to byte swap it from big to little endian
for(unsigned j=0; j<r[i]->m_len; j++)
r[i]->m_data[j] = byteswap(r[i]->m_data[j]);
*/
 
if (dbg) for(unsigned j=0; j<r[i]->m_len; j++)
fprintf(stderr, "ADR[%04x] = %02x\n", r[i]->m_start+j,
r[i]->m_data[j] & 0x0ff);
}
 
r[i] = (ELFSECTION *)(&d[current_offset]);
r[current_section]->m_start = 0;
r[current_section]->m_len = 0;
 
elf_end(e);
close(fd);
}
 
/s6soc/trunk/bench/cpp/zipelf.h
0,0 → 1,53
////////////////////////////////////////////////////////////////////////////////
//
// Filename: zipelf.h
//
// Project: CMod S6 System on a Chip, ZipCPU demonstration project
//
// Purpose:
//
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef ZIPELF_H
#define ZIPELF_H
 
#include <stdint.h>
 
class ELFSECTION {
public:
uint32_t m_start, m_len;
char m_data[4];
};
 
bool iself(const char *fname);
void elfread(const char *fname, uint32_t &entry, ELFSECTION **&sections);
 
#endif
s6soc/trunk/bench/cpp Property changes : Added: svn:ignore ## -0,0 +1 ## +zip_sim

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.