URL
https://opencores.org/ocsvn/openarty/openarty/trunk
Subversion Repositories openarty
Compare Revisions
- This comparison shows the changes necessary to convert path
/openarty/trunk/sw/host
- from Rev 49 to Rev 51
- ↔ Reverse comparison
Rev 49 → Rev 51
/Makefile
1,6 → 1,6
################################################################################ |
## |
## Filename: Makefile |
## Filename: Makefile |
## |
## Project: OpenArty, an entirely open SoC based upon the Arty platform |
## |
37,63 → 37,71
## |
## |
.PHONY: all |
PROGRAMS := wbregs netuart wbsettime dumpflash wbprogram netsetup manping zipload zipstate zipdbg |
PROGRAMS := wbregs netuart wbsettime wbprogram netsetup manping \ |
zipload zipstate zipdbg divutb |
SCOPES := eqspiscope etxscope erxscope cpuscope |
all: $(PROGRAMS) $(SCOPES) gps |
CXX := g++ |
OBJDIR := obj-pc |
BUSOBJS := $(OBJDIR)/ttybus.o $(OBJDIR)/llcomms.o $(OBJDIR)/regdefs.o |
BUSSRCS := ttybus.cpp llcomms.cpp regdefs.cpp byteswap.cpp |
SOURCES := wbregs.cpp wbprogram.cpp netuart.cpp wbsettime.cpp \ |
ttybus.cpp llcomms.cpp dumpflash.cpp eqspiscope.cpp flashdrvr.cpp \ |
regdefs.cpp scopecls.cpp sdramscope.cpp ttybus.cpp \ |
cfgscope.cpp zipload.cpp zipstate.cpp zipdbg.cpp \ |
dumpflash.cpp eqspiscope.cpp flashdrvr.cpp \ |
scopecls.cpp sdramscope.cpp \ |
zipload.cpp zipstate.cpp zipdbg.cpp \ |
erxscope.cpp etxscope.cpp netsetup.cpp cpuscope.cpp \ |
mdioscope.cpp manping.cpp |
# ziprun.cpp |
mdioscope.cpp manping.cpp $(BUSSRCS) |
# ziprun.cpp cfgscope.cpp |
HEADERS := llcomms.h ttybus.h devbus.h |
OBJECTS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(SOURCES))) |
ZIPD := ../../../../../zipcpu/trunk/sw/zasm |
BUSOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(BUSSRCS))) |
CFLAGS := -g -Wall -I. |
LIBS := |
SUBMAKE := $(MAKE) --no-print-directory |
|
%.o: $(OBJDIR)/%.o |
$(OBJDIR)/%.o: %.cpp |
$(CXX) -g -c $< -o $@ |
$(CXX) $(CFLAGS) -c $< -o $@ |
$(OBJDIR)/%.o: %.c |
$(CXX) $(CFLAGS) -c $< -o $@ |
|
.PHONY: gps |
gps: $(BUSOBJS) $(OBJDIR)/scopecls.o |
@bash -c "if [[ -e gps/Makefile ]]; then cd gps; make --no-print-directory; fi" |
@bash -c "if [[ -e gps/Makefile ]]; then $(SUBMAKE) --directory=gps; fi" |
|
$(OBJDIR)/hsnetuart.o: netuart.cpp |
$(CXX) -g -c -DHIGH_SPEED $< -o $@ |
$(CXX) $(CFLAGS) -c -DHIGH_SPEED $< -o $@ |
|
.PHONY: clean |
clean: |
rm -rf $(OBJDIR)/*.o $(PROGRAMS) |
rm -rf $(OBJDIR)/ $(PROGRAMS) a.out |
|
$(OBJDIR)/scopecls.o: scopecls.cpp scopecls.h |
$(OBJDIR)/eqspiscope.o: eqspiscope.cpp scopecls.h |
$(OBJDIR)/dumpflash.o: dumpflash.cpp regdefs.h |
$(OBJDIR)/scopecls.o: scopecls.cpp scopecls.h $(OBJDIR)/ |
$(OBJDIR)/eqspiscope.o: eqspiscope.cpp scopecls.h $(OBJDIR)/ |
$(OBJDIR)/dumpflash.o: dumpflash.cpp regdefs.h $(OBJDIR)/ |
|
netuart: $(OBJDIR)/netuart.o |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ -o $@ |
hsnetuart: $(OBJDIR)/hsnetuart.o |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ -o $@ |
# |
# Some simple programs that just depend upon the ability to talk to the FPGA, |
# and little more. |
wbsettime: $(OBJDIR)/wbsettime.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ -o $@ |
mtest: $(OBJDIR)/mtest.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ -o $@ |
manping: $(OBJDIR)/manping.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
wbregs: $(OBJDIR)/wbregs.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ -o $@ |
zipstate: $(OBJDIR)/zipstate.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@ |
netsetup: $(OBJDIR)/netsetup.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@ |
wbregs: $(OBJDIR)/wbregs.o $(BUSOBJS) |
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@ |
dumpflash: $(OBJDIR)/dumpflash.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@ |
divutb: $(OBJDIR)/divutb.o |
$(CXX) $(CFLAGS) $^ -o $@ |
|
# |
# Programs that depend upon not just the bus objects, but the flash driver |
100,7 → 108,7
# as well. |
wbprogram: $(OBJDIR)/wbprogram.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
zipload: $(OBJDIR)/zipload.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
zipload: $(OBJDIR)/zipload.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) $(OBJDIR)/zipelf.o |
$(CXX) -g $^ -lelf -o $@ |
|
|
125,27 → 133,15
$(CXX) -g $^ -o $@ |
|
# |
# The ZipDebugger is a bit more difficult to build, as it wants to be able |
# to disassemble opcodes given to it. Hence, it depends upon the zparser.cpp, |
# zopcodes.cpp, and twoc.cpp files from the ZipCPU build directory. |
# |
DBGRAW := zparser.cpp zopcodes.cpp twoc.cpp |
DBGSRCS := $(addprefix $(ZIPD)/,$(DBGRAW)) |
DBGOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(DBGRAW))) |
$(OBJDIR)/zipdbg.o: zipdbg.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/zparser.o: $(ZIPD)/zparser.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/zopcodes.o: $(ZIPD)/zopcodes.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/twoc.o: $(ZIPD)/twoc.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
DBGSRCS := zopcodes.cpp twoc.cpp |
DBGOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(DBGSRCS))) |
zipdbg: $(OBJDIR)/zipdbg.o $(BUSOBJS) $(DBGOBJS) |
$(CXX) -g -I$(ZIPD) $^ -lcurses -o $@ |
$(CXX) -g $^ -lcurses -o $@ |
|
define build-depends |
@echo "Building dependency file(s)" |
$(CXX) $(CPPFLAGS) -I$(ZIPD) -MM $(SOURCES) > $(OBJDIR)/xdepends.txt |
@bash -c "if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR)/; fi" |
$(CXX) $(CPPFLAGS) -MM $(SOURCES) > $(OBJDIR)/xdepends.txt |
@sed -e 's/^.*.o: /$(OBJDIR)\/&/' < $(OBJDIR)/xdepends.txt > $(OBJDIR)/depends.txt |
@rm $(OBJDIR)/xdepends.txt |
endef |
158,7 → 154,7
depends: tags |
$(build-depends) |
|
$(OBJDIR)/depends.txt: $(OBJDIR)/ $(SOURCES) $(HEADERS) |
$(OBJDIR)/depends.txt: $(SOURCES) $(HEADERS) |
$(build-depends) |
|
$(OBJDIR)/: |
/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]); |
} |
|
|
/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 |
/cpuscope.cpp
2,7 → 2,7
// |
// Filename: cpuscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To read out, and decompose, the results of the wishbone scope |
// as applied to the ZipCPU internal operation. |
25,7 → 25,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. |
// |
53,6 → 53,8
#define WBSCOPE R_CPUSCOPE |
#define WBSCOPEDATA R_CPUSCOPED |
|
#include "zopcodes.h" |
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
76,28 → 78,32
printf(" "); |
if (true) { |
if ((val & 0x40000000)==0) { |
printf("%s <- 0x.%08x", regstr[(val>>32-6)&0xf], val&0x03ffffff); |
printf("%s <- 0x.%07x", regstr[(val>>(32-6))&0xf], val&0x03ffffff); |
} else if ((val & 0x60000000)==0x60000000) { |
uint32_t addr = val & 0x7ffffff; |
if (val&0x08000000) |
printf("MEM-W[0x........] <- 0x.%07x %s", |
(val&0x07ffffff), |
addr, |
(val&0x10000000)?"(GBL)":""); |
else |
printf("MEM-R[0x.%07x] -> (Not Givn) %s", |
(val&0x07ffffff), |
(addr<<2)&0x0ffffffc, |
(val&0x10000000)?"(GBL)":""); |
} else if ((val & 0x70000000)==0x40000000) |
} else if ((val & 0x70000000)==0x40000000) { |
val &= 0x0fffffff; |
val <<= 2; |
printf("JMP 0x%08x", (val&0x0fffffff)); |
else { |
int master, halt, brk, sleep, gie, buserr, trap, |
} else { |
int master, halt, brk, sleep, buserr, trap, |
ill, clri, pfv, pfi, dcdce, dcdv, dcdstall, |
opce, opvalid, oppipe, aluce, alubsy, aluwr, |
aluill, aluwrf, memce, memwe, membsy; |
memce, memwe, membsy; |
// int gie, aluill, aluwrf; |
master = (val>>27)&1; |
halt = (val>>26)&1; |
brk = (val>>25)&1; |
sleep = (val>>24)&1; |
gie = (val>>23)&1; |
// gie = (val>>23)&1; |
buserr = (val>>22)&1; |
trap = (val>>21)&1; |
ill = (val>>20)&1; |
113,8 → 119,8
aluce = (val>>10)&1; |
alubsy = (val>> 9)&1; |
aluwr = (val>> 8)&1; |
aluill = (val>> 7)&1; |
aluwrf = (val>> 6)&1; |
// aluill = (val>> 7)&1; |
// aluwrf = (val>> 6)&1; |
memce = (val>> 5)&1; |
memwe = (val>> 4)&1; |
membsy = (val>> 3)&1; |
214,14 → 220,16
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
CPUSCOPE *scope = new CPUSCOPE(m_fpga, WBSCOPE, false); |
CPUSCOPE *scope = new CPUSCOPE(m_fpga, WBSCOPE, true); |
if (!scope->ready()) { |
printf("Scope is not yet ready:\n"); |
scope->decode_control(); |
scope->decode(WBSCOPEDATA); |
printf("\n"); |
} else |
} else { |
printf("Scope is ready\n"); |
scope->read(); |
} |
delete m_fpga; |
} |
|
/devbus.h
1,15 → 1,22
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: devbus.h |
// Filename: devbus.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: The purpose of this file is to document an interface which |
// any devic with a bus, whether it be implemented over a UART, |
// an ethernet, or a PCI express bus, must implement. This describes only |
// an interface, and not how that interface is to be accomplished. |
// any device with a bus, whether it be implemented over a UART, |
// an ethernet, or a PCI express bus, must implement. This describes |
// only an interface, and not how that interface is to be accomplished. |
// |
// The neat part of this interface is that, if programs are designed to |
// work with it, than the implementation details may be changed later |
// and any program that once worked with the interface should be able |
// to continue to do so. (i.e., switch from a UART controlled bus to a |
// PCI express controlled bus, with minimal change to the software of |
// interest.) |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
28,7 → 35,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. |
// |
61,18 → 68,56
virtual void close(void) = 0; |
|
// Write a single value to a single address |
// a is the address of the value to be read as it exists on the |
// wishbone bus within the FPGA. |
// v is the singular value to write to this address |
virtual void writeio(const BUSW a, const BUSW v) = 0; |
|
// Read a single value to a single address |
// a is the address of the value to be read as it exists on the |
// wishbone bus within the FPGA. |
// This function returns the value read from the device wishbone |
// at address a. |
virtual BUSW readio(const BUSW a) = 0; |
|
// Read a series of values from values from a block of memory |
// a is the address of the value to be read as it exists on the |
// wishbone bus within the FPGA. |
// len is the number of words to read |
// buf is a pointer to a place to store the words once read. |
// This is equivalent to: |
// for(int i=0; i<len; i++) |
// buf[i] = readio(a+i); |
// only it's faster in our implementation. |
virtual void readi(const BUSW a, const int len, BUSW *buf) = 0; |
|
// Read a series of values from the same address in memory |
// Read a series of values from the same address in memory. This |
// call is identical to readi, save that the address is not incremented |
// from one read to the next. It is equivalent to: |
// for(int i=0; i<len; i++) |
// buf[i] = readio(a); |
// only it's faster in our implementation. |
// |
virtual void readz(const BUSW a, const int len, BUSW *buf) = 0; |
|
// Write a series of values into a block of memory on the FPGA |
// a is the address of the value to be written as it exists on the |
// wishbone bus within the FPGA. |
// len is the number of words to write |
// buf is a pointer to a place to from whence to grab the data |
// to be written. |
// This is equivalent to: |
// for(int i=0; i<len; i++) |
// writeio(a+i, buf[i]); |
// only it's faster in our implementation. |
virtual void writei(const BUSW a, const int len, const BUSW *buf) = 0; |
// Write a series of values into the same address on the FPGA bus. This |
// call is identical to writei, save that the address is not incremented |
// from one write to the next. It is equivalent to: |
// for(int i=0; i<len; i++) |
// writeio(a, buf[i]); |
// only it's faster in our implementation. |
// |
virtual void writez(const BUSW a, const int len, const BUSW *buf) = 0; |
|
// Query whether or not an interrupt has taken place |
/dumpflash.cpp
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: dumpflash.cpp |
// Filename: dumpflash.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
12,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 25,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. |
// |
54,55 → 54,13
exit(0); |
} |
|
// #define DUMPMEM RAMBASE |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: dumpflash.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: The purpose of this program is to read the entire flash memory, |
// and dump it to a file. |
// |
// |
// 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 |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// #define DUMPWORDS MEMWORDS |
|
#define DUMPMEM EQSPIFLASH |
#define DUMPWORDS FLASHWORDS // 1MB Flash |
#define DUMPWORDS (FLASHLEN>>2) |
|
int main(int argc, char **argv) { |
FILE *fp; |
const int BUFLN = FLASHWORDS; |
FPGA::BUSW *buf = new FPGA::BUSW[BUFLN]; |
const int BUFLN = FLASHLEN; |
char *buf = new char[FLASHLEN]; |
|
FPGAOPEN(m_fpga); |
fprintf(stderr, "Before starting, nread = %ld\n", |
117,12 → 75,18
unsigned sz; |
|
if (vector_read) { |
m_fpga->readi(DUMPMEM, BUFLN, buf); |
m_fpga->readi(DUMPMEM, BUFLN>>2, (DEVBUS::BUSW *)&buf[0]); |
byteswapbuf(BUFLN>>2, buf); |
} else { |
for(int i=0; i<BUFLN; i++) { |
buf[i] = m_fpga->readio(DUMPMEM+i); |
// if (0 == (i&0x0ff)) |
printf("i = %02x / %04x, addr = i + %04x = %08x\n", i, BUFLN, DUMPMEM, i+DUMPMEM); |
for(int i=0; i<BUFLN; i+=4) { |
DEVBUS::BUSW word; |
|
word = m_fpga->readio(DUMPMEM+i); |
|
buf[i ] = (word>>24) & 0x0ff; |
buf[i+1] = (word>>16) & 0x0ff; |
buf[i+2] = (word>> 8) & 0x0ff; |
buf[i+3] = (word ) & 0x0ff; |
} |
} |
printf("\nREAD-COMPLETE\n"); |
129,10 → 93,9
|
// Now, let's find the end |
sz = BUFLN-1; |
while((sz>0)&&(buf[sz] == 0xffffffff)) |
while((sz>0)&&((unsigned char)buf[sz] == 0xff)) |
sz--; |
sz+=1; |
printf("The size of the buffer is 0x%06x or %d words\n", sz, sz); |
|
#define FLASHFILE "eqspidump.bin" |
|
/dumpuart.cpp
0,0 → 1,117
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: dumpuart.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To produce any and all data from the UART port onto an output |
// pipe and/or an output file. This replaces the minicom |
// interface. This is necessary because 1) minicom can take a while to |
// set up, 2) the default interface is at 115200 Baud (not minicom's |
// default), 3) this produces an unfiltered/unbuffered terminal output, |
// and 4) it also guarantees that output goes to a file (when requested). |
// |
// This program was originally a part of the S6SoC suite of host programs. It |
// has since been modified for the OpenArty project--mostly by just changing the |
// data speed from 9.6kB to 115.2kB. |
// |
// |
// 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 <stdio.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
#include <termios.h> |
|
int main(int argc, char **argv) { |
const char *dev = argv[1]; |
const char *fname = (argc>=3)?argv[2]:NULL; |
int ttyfd = -1, dumpfd = -1; |
|
ttyfd = open(dev, O_RDONLY); |
if (fname) |
dumpfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY, 0644); |
|
// Set the baud rate ... |
{ |
struct termios tb; |
|
tcgetattr(ttyfd, &tb); |
// Set to raw mode |
cfmakeraw(&tb); |
// Non-canonical mode (no line editing ...) |
tb.c_lflag &= (~(ICANON)); |
// Set no parity |
tb.c_cflag &= (~(PARENB)); |
// Set 8 data bits |
tb.c_cflag &= (~(CSIZE)); |
tb.c_cflag |= CS8; |
// Turn on hardware flow control |
tb.c_cflag |= CRTSCTS; |
// One stop bit |
tb.c_cflag &= (~(CSTOPB)); |
// 115200 Baud |
cfsetspeed(&tb, B115200); |
// Block until at least one byte is available |
tb.c_cc[VMIN] = 1; |
tb.c_cc[VTIME] = 0; |
// Commit the changes |
tcsetattr(ttyfd, TCSANOW, &tb); |
} |
|
/* |
if (isatty(STDOUT_FILENO)) { |
struct termios tb; |
tcgetattr(STDOUT_FILENO, &tb); |
} |
*/ |
|
char buf[64]; |
int nr; |
|
while((nr=read(ttyfd, buf, sizeof(buf)))>0) { |
if (dumpfd >= 0) |
write(dumpfd, buf, nr); |
write(STDOUT_FILENO, buf, nr); |
} |
|
close(ttyfd); |
if (dumpfd >= 0) |
close(dumpfd); |
} |
/eqspiscope.cpp
2,7 → 2,7
// |
// Filename: eqspiscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This program decodes the bits in the debugging wires output |
// from the eqspiflash module, and stored in the Wishbone Scope |
15,7 → 15,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
28,7 → 28,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. |
// |
120,24 → 120,6
}; |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool use_usb = false; |
|
skp=1; |
for(int argn=0; argn<argc-skp; argn++) { |
if (argv[argn+skp][0] == '-') { |
if (argv[argn+skp][1] == 'u') |
use_usb = true; |
else if (argv[argn+skp][1] == 'p') { |
use_usb = false; |
if (isdigit(argv[argn+skp][2])) |
port = atoi(&argv[argn+skp][2]); |
} |
skp++; argn--; |
} else |
argv[argn] = argv[argn+skp]; |
} argc -= skp; |
|
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
/erxscope.cpp
2,7 → 2,7
// |
// Filename: erxscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This file decodes the debug bits produced by the enetpackets.v |
// Verilog module, and stored in a Wishbone Scope. It is useful |
13,7 → 13,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
26,7 → 26,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. |
// |
/etxscope.cpp
2,7 → 2,7
// |
// Filename: etxscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This file decodes the debug bits produced by the enetpackets.v |
// Verilog module, and stored in a Wishbone Scope. It is useful |
13,7 → 13,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
26,7 → 26,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. |
// |
/flashdrvr.cpp
12,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 25,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. |
// |
38,6 → 38,7
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdint.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
48,10 → 49,12
#include "port.h" |
#include "regdefs.h" |
#include "flashdrvr.h" |
#include "byteswap.h" |
|
const bool HIGH_SPEED = false; |
|
#define SETSCOPE m_fpga->writeio(R_QSCOPE, 8180) |
#define SETSCOPE |
// #define SETSCOPE m_fpga->writeio(R_QSCOPE, 8180) |
|
|
void FLASHDRVR::flwait(void) { |
84,13 → 87,13
bool FLASHDRVR::erase_sector(const unsigned sector, const bool verify_erase) { |
DEVBUS::BUSW page[SZPAGEW]; |
|
printf("EREG before : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
printf("Erasing sector: %08x\n", sector); |
if (m_debug) printf("EREG before : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
if (m_debug) printf("Erasing sector: %08x\n", sector); |
m_fpga->writeio(R_QSPI_EREG, DISABLEWP); |
printf("EREG with WEL : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
if (m_debug) printf("EREG with WEL : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
SETSCOPE; |
m_fpga->writeio(R_QSPI_EREG, ERASEFLAG + sector); |
printf("EREG after : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
m_fpga->writeio(R_QSPI_EREG, ERASEFLAG + (sector>>2)); |
if (m_debug) printf("EREG after : %08x\n", m_fpga->readio(R_QSPI_EREG)); |
|
// If we're in high speed mode and we want to verify the erase, then |
// we can skip waiting for the erase to complete by issueing a read |
100,12 → 103,14
if ((!HIGH_SPEED)||(!verify_erase)) { |
flwait(); |
|
printf("@%08x -> %08x\n", R_QSPI_EREG, |
if (m_debug) { |
printf("@%08x -> %08x\n", R_QSPI_EREG, |
m_fpga->readio(R_QSPI_EREG)); |
printf("@%08x -> %08x\n", R_QSPI_STAT, |
printf("@%08x -> %08x\n", R_QSPI_STAT, |
m_fpga->readio(R_QSPI_STAT)); |
printf("@%08x -> %08x\n", sector, |
printf("@%08x -> %08x\n", sector, |
m_fpga->readio(sector)); |
} |
} |
|
// Now, let's verify that we erased the sector properly |
121,42 → 126,55
return true; |
} |
|
bool FLASHDRVR::write_page(const unsigned addr, const unsigned len, |
const unsigned *data, const bool verify_write) { |
DEVBUS::BUSW buf[SZPAGEW]; |
bool FLASHDRVR::page_program(const unsigned addr, const unsigned len, |
const char *data, const bool verify_write) { |
DEVBUS::BUSW buf[SZPAGEW], bswapd[SZPAGEW]; |
|
assert(len > 0); |
assert(len <= PGLENW); |
assert(len <= PGLENB); |
assert(PAGEOF(addr)==PAGEOF(addr+len-1)); |
|
if (len <= 0) |
return true; |
|
// Write the page |
m_fpga->writeio(R_ICONTROL, ISPIF_DIS); |
m_fpga->clear(); |
m_fpga->writeio(R_ICONTROL, ISPIF_EN); |
printf("Writing page: 0x%08x - 0x%08x\n", addr, addr+len-1); |
m_fpga->writeio(R_QSPI_EREG, DISABLEWP); |
SETSCOPE; |
m_fpga->writei(addr, len, data); |
bool empty_page = true; |
for(unsigned i=0; i<len; i+=4) { |
DEVBUS::BUSW v; |
v = buildword((const unsigned char *)&data[i]); |
bswapd[(i>>2)] = v; |
if (v != 0xffffffff) |
empty_page = false; |
} |
|
// If we're in high speed mode and we want to verify the write, then |
// we can skip waiting for the write to complete by issueing a read |
// command immediately. As soon as the write completes the read will |
// begin sending commands back. This allows us to recover the lost |
// time between the interrupt and the next command being received. |
flwait(); |
if (!empty_page) { |
// Write the page |
m_fpga->writeio(R_ICONTROL, ISPIF_DIS); |
m_fpga->clear(); |
m_fpga->writeio(R_ICONTROL, ISPIF_EN); |
printf("Writing page: 0x%08x - 0x%08x\r", addr, addr+len-1); |
m_fpga->writeio(R_QSPI_EREG, DISABLEWP); |
SETSCOPE; |
m_fpga->writei(addr, (len>>2), bswapd); |
fflush(stdout); |
|
// If we're in high speed mode and we want to verify the write, |
// then we can skip waiting for the write to complete by |
// issueing a read command immediately. As soon as the write |
// completes the read will begin sending commands back. This |
// allows us to recover the lost time between the interrupt and |
// the next command being received. |
flwait(); |
} |
// if ((!HIGH_SPEED)||(!verify_write)) { } |
if (verify_write) { |
// printf("Attempting to verify page\n"); |
// NOW VERIFY THE PAGE |
m_fpga->readi(addr, len, buf); |
for(int i=0; i<len; i++) { |
if (buf[i] != data[i]) { |
printf("\nVERIFY FAILS[%d]: %08x\n", i, i+addr); |
m_fpga->readi(addr, len>>2, buf); |
for(unsigned i=0; i<(len>>2); i++) { |
if (buf[i] != bswapd[i]) { |
printf("\nVERIFY FAILS[%d]: %08x\n", i, (i<<2)+addr); |
printf("\t(Flash[%d]) %08x != %08x (Goal[%08x])\n", |
i, buf[i], data[i], i+addr); |
(i<<2), buf[i], bswapd[i], (i<<2)+addr); |
return false; |
} |
} // printf("\nVerify success\n"); |
188,8 → 206,11
} |
|
bool FLASHDRVR::write(const unsigned addr, const unsigned len, |
const unsigned *data, const bool verify) { |
const char *data, const bool verify) { |
|
assert(addr >= EQSPIFLASH); |
assert(addr+len <= EQSPIFLASH + FLASHLEN); |
|
if (!verify_config()) { |
set_config(); |
if (!verify_config()) { |
202,45 → 223,34
// If this buffer is equal to the sector value(s), go on |
// If not, erase the sector |
|
// m_fpga->writeio(R_QSPI_CREG, 2); |
// m_fpga->readio(R_VERSION); // Read something innocuous |
|
// Just to make sure the driver knows that these values are ... |
// m_fpga->readio(R_QSPI_CREG); |
// m_fpga->readio(R_QSPI_SREG); |
// Because the status register may invoke protections here, we |
// void them. |
// m_fpga->writeio(R_QSPI_SREG, 0); |
// m_fpga->readio(R_VERSION); // Read something innocuous |
|
for(unsigned s=SECTOROF(addr); s<SECTOROF(addr+len+SECTORSZW-1); s+=SECTORSZW) { |
// printf("IN LOOP, s=%08x\n", s); |
for(unsigned s=SECTOROF(addr); s<SECTOROF(addr+len+SECTORSZB-1); |
s+=SECTORSZB) { |
// Do we need to erase? |
bool need_erase = false; |
bool need_erase = false, need_program = false; |
unsigned newv = 0; // (s<addr)?addr:s; |
{ |
DEVBUS::BUSW *sbuf = new DEVBUS::BUSW[SECTORSZW]; |
const DEVBUS::BUSW *dp; |
char *sbuf = new char[SECTORSZB]; |
const char *dp; // pointer to our "desired" buffer |
unsigned base,ln; |
|
base = (addr>s)?addr:s; |
ln=((addr+len>s+SECTORSZW)?(s+SECTORSZW):(addr+len))-base; |
m_fpga->readi(base, ln, sbuf); |
ln=((addr+len>s+SECTORSZB)?(s+SECTORSZB):(addr+len))-base; |
m_fpga->readi(base, ln>>2, (uint32_t *)sbuf); |
byteswapbuf(ln>>2, (uint32_t *)sbuf); |
|
dp = &data[base-addr]; |
SETSCOPE; |
for(unsigned i=0; i<ln; i++) { |
if ((sbuf[i]&dp[i]) != dp[i]) { |
printf("\nNEED-ERASE @0x%08x ... %08x != %08x (Goal)\n", |
i+base-addr, sbuf[i], dp[i]); |
if (m_debug) { |
printf("\nNEED-ERASE @0x%08x ... %08x != %08x (Goal)\n", |
i+base-addr, sbuf[i], dp[i]); |
} |
need_erase = true; |
newv = i+base; |
newv = (i&-4)+base; |
break; |
} else if ((sbuf[i] != dp[i])&&(newv == 0)) { |
// if (newv == 0) |
// printf("MEM[%08x] = %08x (!= %08x (Goal))\n", |
// i+base, sbuf[i], dp[i]); |
newv = i+base; |
} |
} else if ((sbuf[i] != dp[i])&&(newv == 0)) |
newv = (i&-4)+base; |
} |
} |
|
247,10 → 257,10
if (newv == 0) |
continue; // This sector already matches |
|
// Just erase anyway |
if (!need_erase) |
printf("NO ERASE NEEDED\n"); |
else { |
// Erase the sector if necessary |
if (!need_erase) { |
if (m_debug) printf("NO ERASE NEEDED\n"); |
} else { |
printf("ERASING SECTOR: %08x\n", s); |
if (!erase_sector(s, verify)) { |
printf("SECTOR ERASE FAILED!\n"); |
257,18 → 267,22
return false; |
} newv = (s<addr) ? addr : s; |
} |
for(unsigned p=newv; (p<s+SECTORSZW)&&(p<addr+len); p=PAGEOF(p+PGLENW)) { |
|
// Now walk through all of our pages in this sector and write |
// to them. |
for(unsigned p=newv; (p<s+SECTORSZB)&&(p<addr+len); p=PAGEOF(p+PGLENB)) { |
unsigned start = p, len = addr+len-start; |
|
// BUT! if we cross page boundaries, we need to clip |
// our results to the page boundary |
if (PAGEOF(start+len-1)!=PAGEOF(start)) |
len = PAGEOF(start+PGLENW)-start; |
if (!write_page(start, len, &data[p-addr], verify)) { |
len = PAGEOF(start+PGLENB)-start; |
if (!page_program(start, len, &data[p-addr], verify)) { |
printf("WRITE-PAGE FAILED!\n"); |
return false; |
} |
} |
} if ((need_erase)||(need_program)) |
printf("Sector 0x%08x: DONE%15s\n", s, ""); |
} |
|
m_fpga->writeio(R_QSPI_EREG, ENABLEWP); // Re-enable write protection |
/flashdrvr.h
12,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 25,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. |
// |
37,13 → 37,6
// |
// |
// |
// |
// Creator: Dan Gisselquist |
// Gisselquist Tecnology, LLC |
// |
// Copyright: 2015 |
// |
// |
#ifndef FLASHDRVR_H |
#define FLASHDRVR_H |
|
52,17 → 45,18
class FLASHDRVR { |
private: |
DEVBUS *m_fpga; |
bool m_debug; |
|
bool verify_config(void); |
void set_config(void); |
void flwait(void); |
public: |
FLASHDRVR(DEVBUS *fpga) : m_fpga(fpga) {} |
FLASHDRVR(DEVBUS *fpga) : m_fpga(fpga), m_debug(false) {} |
bool erase_sector(const unsigned sector, const bool verify_erase=true); |
bool write_page(const unsigned addr, const unsigned len, |
const unsigned *data, const bool verify_write=true); |
bool page_program(const unsigned addr, const unsigned len, |
const char *data, const bool verify_write=true); |
bool write(const unsigned addr, const unsigned len, |
const unsigned *data, const bool verify=false); |
const char *data, const bool verify=false); |
}; |
|
#endif |
/llcomms.cpp
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: llcomms.cpp |
// Filename: llcomms.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
16,7 → 16,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
29,7 → 29,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. |
// |
70,6 → 70,9
void LLCOMMSI::write(char *buf, int len) { |
int nw; |
nw = ::write(m_fdw, buf, len); |
if (nw <= 0) { |
throw "Write-Failure"; |
} |
m_total_nwrit += nw; |
assert(nw == len); |
} |
77,6 → 80,9
int LLCOMMSI::read(char *buf, int len) { |
int nr; |
nr = ::read(m_fdr, buf, len); |
if (nr <= 0) { |
throw "Read-Failure"; |
} |
m_total_nread += nr; |
return nr; |
} |
/llcomms.h
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: llcomms.cpp |
// Filename: llcomms.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
15,7 → 15,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
28,7 → 28,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. |
// |
/manping.cpp
12,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 25,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. |
// |
217,7 → 217,6
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool config_hw_mac = true, config_hw_crc = true; |
FPGA::BUSW txstat; |
int argn; |
235,6 → 234,8
if (fp != NULL) { |
int nr = fread(urand, sizeof(short), 16, fp); |
fclose(fp); |
if (nr<0) |
printf("Could not generate random numbers from /dev/urandom!\nTest may not be valid.\n"); |
} |
} |
|
/mdioscope.cpp
2,7 → 2,7
// |
// Filename: mdioscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: |
// |
11,7 → 11,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 24,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. |
// |
/netsetup.cpp
12,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 25,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. |
// |
59,8 → 59,6
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
|
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
/netuart.cpp
1,3 → 1,41
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: netuart.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 <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
130,10 → 168,20
// assert(nw == nr); |
} |
} |
} else if (nr < 0) { |
fprintf(stderr, "ERR: Could not read from TTY\n"); |
perror("O/S Err:"); |
exit(EXIT_FAILURE); |
} else if (nr == 0) { |
fprintf(stderr, "TTY device has closed\n"); |
exit(EXIT_SUCCESS); |
} for(int i=0; i<nr; i++) { |
lb.m_iline[lb.m_ilen++] = lb.m_buf[i]; |
if ((lb.m_iline[lb.m_ilen-1]=='\n')||(lb.m_iline[lb.m_ilen-1]=='\r')||(lb.m_ilen>=sizeof(lb.m_iline)-1)) { |
if (lb.m_ilen >= sizeof(lb.m_iline)-1) |
if ((lb.m_iline[lb.m_ilen-1]=='\n') |
||(lb.m_iline[lb.m_ilen-1]=='\r') |
||((unsigned)lb.m_ilen |
>= sizeof(lb.m_iline)-1)) { |
if ((unsigned)lb.m_ilen >= sizeof(lb.m_iline)-1) |
lb.m_iline[lb.m_ilen] = '\0'; |
else |
lb.m_iline[lb.m_ilen-1] = '\0'; |
143,8 → 191,12
lb.m_ilen = 0; |
} |
} |
} else if (p[0].revents) |
printf("UNKNOWN TTY EVENT: %d\n", p[0].revents); |
} else if (p[0].revents) { |
fprintf(stderr, "ERR: UNKNOWN TTY EVENT: %d\n", p[0].revents); |
perror("O/S Err?"); |
exit(EXIT_FAILURE); |
} |
|
|
if((nfds>1)&&(p[1].revents & POLLIN)) { |
int nr = read(confd, lb.m_buf, 256); |
172,6 → 224,11
perror("O/S Err: "); |
assert(nw > 0); |
break; |
} else if (nw == 0) { |
// TTY device has closed our connection |
fprintf(stderr, "TTY device has closed\n"); |
exit(EXIT_SUCCESS); |
break; |
} |
// if (nw != nr-ttlw) |
// printf("Only wrote %d\n", nw); |
180,8 → 237,11
} for(int i=0; i<nr; i++) { |
lb.m_oline[lb.m_olen++] = lb.m_buf[i]; |
assert(lb.m_buf[i] != '\0'); |
if ((lb.m_oline[lb.m_olen-1]=='\n')||(lb.m_oline[lb.m_olen-1]=='\r')||(lb.m_olen >= sizeof(lb.m_oline)-1)) { |
if (lb.m_olen >= sizeof(lb.m_oline)-1) |
if ((lb.m_oline[lb.m_olen-1]=='\n') |
||(lb.m_oline[lb.m_olen-1]=='\r') |
||((unsigned)lb.m_olen |
>= sizeof(lb.m_oline)-1)) { |
if ((unsigned)lb.m_olen >= sizeof(lb.m_oline)-1) |
lb.m_oline[lb.m_olen] = '\0'; |
else |
lb.m_oline[lb.m_olen-1] = '\0'; |
191,7 → 251,9
} |
} |
} else if ((nfds>1)&&(p[1].revents)) { |
printf("UNKNOWN SKT EVENT: %d\n", p[1].revents); |
fprintf(stderr, "UNKNOWN SKT EVENT: %d\n", p[1].revents); |
perror("O/S Err?"); |
exit(EXIT_FAILURE); |
} |
|
return (pv > 0); |
328,9 → 390,8
; |
|
// Now, process that connection until it's gone |
while(lb.m_connected) { |
while(lb.m_connected) |
check_incoming(lb, tty, con, -1); |
} |
} |
|
printf("Closing our socket\n"); |
/port.h
1,17 → 1,19
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: port.h |
// Filename: port.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: |
// Purpose: Defines the communication parameters necessary for communicating |
// with the device. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 26,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. |
// |
38,9 → 40,12
#ifndef PORT_H |
#define PORT_H |
|
// #define FPGAHOST "lazarus" |
#define FPGAHOST "jericho" |
// #define FPGAHOST "localhost" |
// There are two ways to connect: via a serial port, and via a TCP socket |
// connected to a serial port. This way, we can connect the device on one |
// computer, test it, and when/if it doesn't work we can replace the device |
// with the test-bench. Across the network, no one will know any better that |
// anything had changed. |
#define FPGAHOST "localhost" |
#define FPGATTY "/dev/ttyUSB1" |
#define FPGAPORT 6510 |
|
/program.sh
43,56 → 43,39
WBREGS=wbregs |
WBPROG=wbprogram |
|
RED=0x000f0000 |
GREEN=0x0000ff00 |
YELLOW=0x00170700 |
WHITE=0x000f0f0f |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0ff |
$WBREGS clrled0 $YELLOW |
$WBREGS clrled1 $YELLOW |
$WBREGS clrled2 $YELLOW |
$WBREGS clrled3 $YELLOW |
|
# |
# $WBREGS qspiv 0x8b # Accomplished by the flash driver |
# |
$WBREGS stopwatch 2 # Clear and stop the stopwatch |
$WBREGS stopwatch 1 # Start the stopwatch |
$WBPROG @0x0470000 $BINFILE |
$WBPROG @0x011c0000 $BINFILE |
$WBREGS stopwatch 0 # Stop the stopwatch, we are done |
$WBREGS stopwatch # Print out the time on the stopwatch |
|
$WBREGS led 0x0f0 |
$WBREGS clrled0 $DIMGREEN |
$WBREGS clrled1 $DIMGREEN |
$WBREGS clrled2 $DIMGREEN |
$WBREGS clrled3 $DIMGREEN |
|
$WBREGS wbstar 0x01c0000 |
$WBREGS fpgacmd 15 |
sleep 1 |
|
|
RED=0x00ff0000 |
GREEN=0x0000ff00 |
WHITE=0x00070707 |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0ff |
$WBREGS clrled0 $RED |
$WBREGS clrled1 $RED |
$WBREGS clrled2 $RED |
$WBREGS clrled3 $RED |
|
sleep 1 |
$WBREGS clrled0 $GREEN |
$WBREGS led 0x10 |
sleep 1 |
$WBREGS clrled1 $GREEN |
$WBREGS clrled0 $DIMGREEN |
$WBREGS led 0x20 |
sleep 1 |
$WBREGS clrled2 $GREEN |
$WBREGS clrled1 $DIMGREEN |
$WBREGS led 0x40 |
|
if [[ -x ./wbsettime ]]; then |
./wbsettime |
fi |
|
$WBREGS clrled3 $GREEN |
$WBREGS clrled2 $DIMGREEN |
$WBREGS led 0x80 |
sleep 1 |
$WBREGS clrled0 $WHITE |
$WBREGS clrled1 $WHITE |
$WBREGS clrled2 $WHITE |
$WBREGS clrled3 $WHITE |
$WBREGS led 0x00 |
|
|
/regdefs.cpp
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: regdefs.h |
// Filename: regdefs.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
11,7 → 11,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 24,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. |
// |
63,6 → 63,7
{ R_UART_SETUP, "AUXSETUP" }, |
{ R_UART_SETUP, "AUX" }, |
{ R_GPS_SETUP, "GPSSETUP" }, |
{ R_GPS_FIFO, "GPSFIFO" }, |
{ R_GPS_SETUP, "GPSUART" }, |
{ R_CLR0, "CLRLED0" }, |
{ R_CLR1, "CLRLED1" }, |
76,6 → 77,7
{ R_GPIO, "GPIO" }, |
{ R_UARTRX, "AUXRX" }, |
{ R_UARTRX, "RX" }, |
{ R_UART_FIFO, "AUXFIFO" }, |
{ R_UARTTX, "AUXTX" }, |
{ R_UARTTX, "TX" }, |
// |
/regdefs.h
11,7 → 11,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 24,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. |
// |
39,155 → 39,176
#define REGDEFS_H |
|
#define CLOCKFREQ_HZ 81250000 |
#define R_VERSION 0x00000100 |
#define R_ICONTROL 0x00000101 |
#define R_BUSERR 0x00000102 |
#define R_PWCOUNT 0x00000103 |
#define R_BTNSW 0x00000104 |
#define R_LEDS 0x00000105 |
#define R_UART_SETUP 0x00000106 |
#define R_GPS_SETUP 0x00000107 |
#define R_CLR0 0x00000108 |
#define R_CLR1 0x00000109 |
#define R_CLR2 0x0000010a |
#define R_CLR3 0x0000010b |
#define R_DATE 0x0000010c |
#define R_GPIO 0x0000010d // No GPIO device exists ... yet |
#define R_UARTRX 0x0000010e |
#define R_UARTTX 0x0000010f |
#define R_GPSRX 0x00000110 |
#define R_GPSTX 0x00000111 |
#define R_VERSION 0x00000400 |
#define R_ICONTROL 0x00000404 |
#define R_BUSERR 0x00000408 |
#define R_PWCOUNT 0x0000040c |
#define R_BTNSW 0x00000410 |
#define R_LEDS 0x00000414 |
#define R_DATE 0x00000418 |
#define R_GPIO 0x0000041c |
#define R_CLR0 0x00000420 |
#define R_CLR1 0x00000424 |
#define R_CLR2 0x00000428 |
#define R_CLR3 0x0000042c |
#define R_IOTIMES 0x00000430 |
#define R_IOSUBSEC 0x00000434 |
#define R_IOTIMSTEP 0x00000438 |
|
// WB Scope registers |
#define R_QSCOPE 0x00000120 // Scope #0: Quad SPI scope ctrl |
#define R_QSCOPED 0x00000121 // and data |
#define R_CPUSCOPE 0x00000120 // CPU scope (if so configured) |
#define R_CPUSCOPED 0x00000121 // and data |
#define R_GPSCOPE 0x00000122 // Scope #1: GPS config scope control |
#define R_GPSCOPED 0x00000123 // and data |
#define R_CFGSCOPE 0x00000122 // ICAPE2 configuration scop control |
#define R_CFGSCOPED 0x00000123 // and data |
#define R_BUSSCOPE 0x00000122 // WBUBUS scope control |
#define R_BUSSCOPED 0x00000123 // and data |
#define R_RAMSCOPE 0x00000124 // Scope #2: DDR3 SDRAM Scope |
#define R_RAMSCOPED 0x00000125 // |
#define R_NETSCOPE 0x00000126 // Scope #3: Ethernet debug scope |
#define R_NETSCOPED 0x00000127 // |
#define R_QSCOPE 0x00000480 // Scope #0: Quad SPI scope ctrl |
#define R_QSCOPED 0x00000484 // and data |
#define R_CPUSCOPE 0x00000480 // CPU scope (if so configured) |
#define R_CPUSCOPED 0x00000484 // and data |
#define R_GPSCOPE 0x00000488 // Scope #1: GPS config scope control |
#define R_GPSCOPED 0x0000048c // and data |
#define R_CFGSCOPE 0x00000488 // ICAPE2 configuration scop control |
#define R_CFGSCOPED 0x0000048c // and data |
#define R_BUSSCOPE 0x00000488 // WBUBUS scope control |
#define R_BUSSCOPED 0x0000048c // and data |
#define R_RAMSCOPE 0x00000490 // Scope #2: DDR3 SDRAM Scope |
#define R_RAMSCOPED 0x00000494 // |
#define R_NETSCOPE 0x00000498 // Scope #3: Ethernet debug scope |
#define R_NETSCOPED 0x0000049c // |
// RTC Clock Registers |
#define R_CLOCK 0x00000128 |
#define R_TIMER 0x00000129 |
#define R_STOPWATCH 0x0000012a |
#define R_CKALARM 0x0000012b |
#define R_CLOCK 0x000004a0 |
#define R_TIMER 0x000004a4 |
#define R_STOPWATCH 0x000004a8 |
#define R_CKALARM 0x000004ac |
// OLED |
#define R_OLED_CMD 0x000004b0 |
#define R_OLED_CDATA 0x000004b4 |
#define R_OLED_CDATB 0x000004b8 |
#define R_OLED_DATA 0x000004bc |
// WBUART - AUX |
#define R_UART_SETUP 0x000004c0 |
#define R_UART_FIFO 0x000004c4 |
#define R_UARTRX 0x000004c8 |
#define R_UARTTX 0x000004cc |
// WBUART - GPS |
#define R_GPS_SETUP 0x000004d0 |
#define R_GPS_FIFO 0x000004d4 |
#define R_GPSRX 0x000004d8 |
#define R_GPSTX 0x000004dc |
// SD Card Control |
#define R_SDCARD_CTRL 0x0000012c |
#define R_SDCARD_DATA 0x0000012d |
#define R_SDCARD_FIFOA 0x0000012e |
#define R_SDCARD_FIFOB 0x0000012f |
// GPS Loop control, 0x0130 |
#define R_GPS_ALPHA 0x00000130 |
#define R_GPS_BETA 0x00000131 |
#define R_GPS_GAMMA 0x00000132 |
#define R_GPS_STEP 0x00000133 |
// OLED |
#define R_OLED_CMD 0x00000134 |
#define R_OLED_CDATA 0x00000135 |
#define R_OLED_CDATB 0x00000136 |
#define R_OLED_DATA 0x00000137 |
// Network packet interface, 0x0184 |
#define R_NET_RXCMD 0x00000138 |
#define R_NET_TXCMD 0x00000139 |
#define R_NET_MACHI 0x0000013a |
#define R_NET_MACLO 0x0000013b |
#define R_NET_RXMISS 0x0000013c |
#define R_NET_RXERR 0x0000013d |
#define R_NET_RXCRC 0x0000013e |
#define R_NET_TXCOL 0x0000013f |
// Unused: 0x13c-0x13f |
// GPS Testbench: 0x140-0x147 |
#define R_GPSTB_FREQ 0x00000140 |
#define R_GPSTB_JUMP 0x00000141 |
#define R_GPSTB_ERRHI 0x00000142 |
#define R_GPSTB_ERRLO 0x00000143 |
#define R_GPSTB_COUNTHI 0x00000144 |
#define R_GPSTB_COUNTLO 0x00000145 |
#define R_GPSTB_STEPHI 0x00000146 |
#define R_GPSTB_STEPLO 0x00000147 |
// Unused: 0x148-0x19f |
#define R_SDCARD_CTRL 0x000004e0 |
#define R_SDCARD_DATA 0x000004e4 |
#define R_SDCARD_FIFOA 0x000004e8 |
#define R_SDCARD_FIFOB 0x000004ec |
// Unused, 4x positions |
// Unused 0x000004f0 |
// Unused 0x000004f4 |
// Unused 0x000004f8 |
// Unused 0x000004fc |
// GPS Loop control |
#define R_GPS_ALPHA 0x00000500 |
#define R_GPS_BETA 0x00000504 |
#define R_GPS_GAMMA 0x00000508 |
#define R_GPS_STEP 0x0000050c |
// Unused, 4x positions |
// Unused 0x00000510 |
// Unused 0x00000514 |
// Unused 0x00000518 |
// Unused 0x0000051c |
// GPS Testbench: |
#define R_GPSTB_FREQ 0x00000520 |
#define R_GPSTB_JUMP 0x00000524 |
#define R_GPSTB_ERRHI 0x00000528 |
#define R_GPSTB_ERRLO 0x0000052c |
#define R_GPSTB_COUNTHI 0x00000530 |
#define R_GPSTB_COUNTLO 0x00000534 |
#define R_GPSTB_STEPHI 0x00000538 |
#define R_GPSTB_STEPLO 0x0000053c |
// Network packet interface |
#define R_NET_RXCMD 0x00000540 |
#define R_NET_TXCMD 0x00000544 |
#define R_NET_MACHI 0x00000548 |
#define R_NET_MACLO 0x0000054c |
#define R_NET_RXMISS 0x00000550 |
#define R_NET_RXERR 0x00000554 |
#define R_NET_RXCRC 0x00000558 |
#define R_NET_TXCOL 0x0000055c |
// Unused: 0x560-0x57f |
// Ethernet configuration (MDIO) port: 0x1a0-0x1bf |
#define R_MDIO_BMCR 0x000001a0 |
#define R_MDIO_BMSR 0x000001a1 |
#define R_MDIO_PHYIDR1 0x000001a2 |
#define R_MDIO_PHYIDR2 0x000001a3 |
#define R_MDIO_ANAR 0x000001a4 |
#define R_MDIO_ANLPAR 0x000001a5 |
// #define R_MDIO_ANLPARNP 0x000001a5 |
#define R_MDIO_ANER 0x000001a6 |
#define R_MDIO_ANNPTR 0x000001a7 |
#define R_MDIO_PHYSTS 0x000001b0 |
#define R_MDIO_FCSCR 0x000001b4 |
#define R_MDIO_RECR 0x000001b5 |
#define R_MDIO_PCSR 0x000001b6 |
#define R_MDIO_RBR 0x000001b7 |
#define R_MDIO_LEDCR 0x000001b8 |
#define R_MDIO_PHYCR 0x000001b9 |
#define R_MDIO_BTSCR 0x000001ba |
#define R_MDIO_CDCTRL 0x000001bb |
#define R_MDIO_EDCR 0x000001bd |
#define R_MDIO_BMCR 0x00000580 |
#define R_MDIO_BMSR 0x00000584 |
#define R_MDIO_PHYIDR1 0x00000588 |
#define R_MDIO_PHYIDR2 0x0000058c |
#define R_MDIO_ANAR 0x00000590 |
#define R_MDIO_ANLPAR 0x00000594 |
// #define R_MDIO_ANLPARNP 0x00000594 // (duplicate reg) |
#define R_MDIO_ANER 0x00000598 |
#define R_MDIO_ANNPTR 0x0000059c |
// 8-15 |
#define R_MDIO_PHYSTS 0x000005c0 |
#define R_MDIO_FCSCR 0x000005d0 |
#define R_MDIO_RECR 0x000005d4 |
#define R_MDIO_PCSR 0x000005d8 |
#define R_MDIO_RBR 0x000005dc |
#define R_MDIO_LEDCR 0x000005d0 |
#define R_MDIO_PHYCR 0x000005d4 |
#define R_MDIO_BTSCR 0x000005d8 |
#define R_MDIO_CDCTRL 0x000005dc |
#define R_MDIO_EDCR 0x000005e4 |
// |
// Flash: 0x1c0-0x1df |
#define R_QSPI_EREG 0x000001c0 |
#define R_QSPI_STAT 0x000001c1 |
#define R_QSPI_NVCONF 0x000001c2 |
#define R_QSPI_VCONF 0x000001c3 |
#define R_QSPI_EVCONF 0x000001c4 |
#define R_QSPI_LOCK 0x000001c5 |
#define R_QSPI_FLAG 0x000001c6 |
// #define R_QSPI_ASYNC 0x000001c7 |
#define R_QSPI_ID 0x000001c8 |
#define R_QSPI_IDA 0x000001c9 |
#define R_QSPI_IDB 0x000001ca |
#define R_QSPI_IDC 0x000001cb |
#define R_QSPI_IDD 0x000001cc |
#define R_QSPI_EREG 0x00000600 |
#define R_QSPI_STAT 0x00000604 |
#define R_QSPI_NVCONF 0x00000608 |
#define R_QSPI_VCONF 0x0000060c |
#define R_QSPI_EVCONF 0x00000610 |
#define R_QSPI_LOCK 0x00000614 |
#define R_QSPI_FLAG 0x00000618 |
// #define R_QSPI_ASYNC 0x0000061c |
#define R_QSPI_ID 0x00000620 |
#define R_QSPI_IDA 0x00000624 |
#define R_QSPI_IDB 0x00000628 |
#define R_QSPI_IDC 0x0000062c |
#define R_QSPI_IDD 0x00000630 |
// |
#define R_QSPI_OTPWP 0x000001cf |
#define R_QSPI_OTP 0x000001d0 |
#define R_QSPI_OTPWP 0x0000063c |
#define R_QSPI_OTP 0x00000640 |
|
// FPGA CONFIG REGISTERS: 0x1e0-0x1ff |
#define R_CFG_CRC 0x000001e0 |
#define R_CFG_FAR 0x000001e1 |
#define R_CFG_FDRI 0x000001e2 |
#define R_CFG_FDRO 0x000001e3 |
#define R_CFG_CMD 0x000001e4 |
#define R_CFG_CTL0 0x000001e5 |
#define R_CFG_MASK 0x000001e6 |
#define R_CFG_STAT 0x000001e7 |
#define R_CFG_LOUT 0x000001e8 |
#define R_CFG_COR0 0x000001e9 |
#define R_CFG_MFWR 0x000001ea |
#define R_CFG_CBC 0x000001eb |
#define R_CFG_IDCODE 0x000001ec |
#define R_CFG_AXSS 0x000001ed |
#define R_CFG_COR1 0x000001ee |
#define R_CFG_WBSTAR 0x000001f0 |
#define R_CFG_TIMER 0x000001f1 |
#define R_CFG_BOOTSTS 0x000001f6 |
#define R_CFG_CTL1 0x000001f8 |
#define R_CFG_BSPI 0x000001ff |
// FPGA CONFIG REGISTERS: 0x4e0-0x4ff |
#define R_CFG_CRC 0x00000680 |
#define R_CFG_FAR 0x00000684 |
#define R_CFG_FDRI 0x00000688 |
#define R_CFG_FDRO 0x0000068c |
#define R_CFG_CMD 0x00000690 |
#define R_CFG_CTL0 0x00000694 |
#define R_CFG_MASK 0x00000698 |
#define R_CFG_STAT 0x0000069c |
#define R_CFG_LOUT 0x000006a0 |
#define R_CFG_COR0 0x000006a4 |
#define R_CFG_MFWR 0x000006a8 |
#define R_CFG_CBC 0x000006ac |
#define R_CFG_IDCODE 0x000006b0 |
#define R_CFG_AXSS 0x000006b4 |
#define R_CFG_COR1 0x000006b8 |
#define R_CFG_WBSTAR 0x000006c0 |
#define R_CFG_TIMER 0x000006c4 |
#define R_CFG_BOOTSTS 0x000006d8 |
#define R_CFG_CTL1 0x000006e0 |
#define R_CFG_BSPI 0x000006fc |
// Network buffer space |
#define R_NET_RXBUF 0x00000800 |
#define R_NET_TXBUF 0x00000c00 |
#define R_NET_RXBUF 0x00002000 |
#define R_NET_TXBUF 0x00003000 |
// Block RAM memory space |
#define MEMBASE 0x00008000 |
#define MEMWORDS 0x00008000 |
#define MEMBASE 0x00020000 |
#define MEMLEN 0x00020000 |
// Flash memory space |
#define EQSPIFLASH 0x00400000 |
#define RESET_ADDRESS 0x004e0000 |
#define FLASHWORDS (1<<22) |
#define EQSPIFLASH 0x01000000 |
#define RESET_ADDRESS 0x01380000 |
// #define FLASHWORDS (1<<22) |
#define FLASHLEN (1<<24) |
// DDR3 SDRAM memory space |
#define RAMBASE 0x04000000 |
#define RAMBASE 0x10000000 |
#define SDRAMBASE RAMBASE |
#define RAMWORDS (1<<26) |
// #define RAMWORDS (1<<26) |
#define RAMLEN (1<<28) |
// Zip CPU Control and Debug registers |
#define R_ZIPCTRL 0x08000000 |
#define R_ZIPDATA 0x08000001 |
#define R_ZIPCTRL 0x20000000 |
#define R_ZIPDATA 0x20000004 |
|
// Interrupt control constants |
#define GIE 0x80000000 // Enable all interrupts |
209,9 → 230,9
#define SECTORSZB (NPAGES * SZPAGEB) // In bytes, not words!! |
#define SECTORSZW (NPAGES * SZPAGEW) // In words |
#define NSECTORS 64 |
#define SECTOROF(A) ((A) & (-1<<14)) |
#define SUBSECTOROF(A) ((A) & (-1<<10)) |
#define PAGEOF(A) ((A) & (-1<<6)) |
#define SECTOROF(A) ((A) & (-1<<16)) |
#define SUBSECTOROF(A) ((A) & (-1<<12)) |
#define PAGEOF(A) ((A) & (-1<<8)) |
|
#define CPU_GO 0x0000 |
#define CPU_RESET 0x0040 |
/scopecls.cpp
2,7 → 2,7
// |
// Filename: scopecls.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: After rebuilding the same code over and over again for every |
// "scope" I tried to interact with, I thought it would be simpler |
14,7 → 14,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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. |
// |
95,10 → 95,10
buf = new DEVBUS::BUSW[m_scoplen]; |
|
if (m_vector_read) { |
m_fpga->readz(m_addr+1, m_scoplen, buf); |
m_fpga->readz(m_addr+4, m_scoplen, buf); |
} else { |
for(unsigned int i=0; i<m_scoplen; i++) |
buf[i] = m_fpga->readio(m_addr+1); |
buf[i] = m_fpga->readio(m_addr+4); |
} |
|
if(m_compressed) { |
/scopecls.h
2,7 → 2,7
// |
// Filename: scopecls.h |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: After rebuilding the same code over and over again for every |
// "scope" I tried to interact with, I thought it would be simpler |
14,7 → 14,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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. |
// |
/sdramscope.cpp
2,7 → 2,7
// |
// Filename: sdramscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: |
// |
11,7 → 11,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 24,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. |
// |
/ttybus.cpp
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: ttybus.cpp |
// Filename: ttybus.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
8,9 → 8,9
// with a UART on an FPGA, to command the WISHBONE on that same |
// FPGA to ... whatever we wish to command it to do. |
// |
// This code does not run on an FPGA, is not a test bench, neither |
// is it a simulator. It is a portion of a command program |
// for commanding an FPGA. |
// This code does not run on an FPGA, is not a test bench, neither |
// is it a simulator. It is a portion of a command program |
// for commanding an FPGA. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
17,7 → 17,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
30,7 → 30,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. |
// |
80,6 → 80,7
#endif |
|
void null(...) {} |
|
#include <stdarg.h> // replaces the (defunct) varargs.h include file |
void filedump(const char *fmt, ...) { |
static FILE *dbgfp = NULL; |
266,7 → 267,7
} |
} |
|
if (p == 1) m_lastaddr++; |
if (p == 1) m_lastaddr+=4; |
} |
// *ptr++ = charenc(0x2e); |
if (ln == len-nw) |
327,15 → 328,20
} |
|
char *TTYBUS::encode_address(const TTYBUS::BUSW a) { |
TTYBUS::BUSW addr = a; |
TTYBUS::BUSW addr = a>>2; |
char *ptr = m_buf; |
|
// Double check that we are aligned |
if ((a&3)!=0) { |
throw BUSERR(a); |
} |
|
if ((m_addr_set)&&(a == m_lastaddr)) |
return ptr; |
|
if (m_addr_set) { |
// Encode a difference address |
int diffaddr = addr - m_lastaddr; |
int diffaddr = (a - m_lastaddr)>>2; |
ptr = m_buf; |
if ((diffaddr >= -32)&&(diffaddr < 32)) { |
*ptr++ = charenc(0x09); |
463,14 → 469,14
} |
} catch(BUSERR b) { |
DBGPRINTF("READV::BUSERR trying to read %08x\n", a+((inc)?nread:0)); |
throw BUSERR(a+((inc)?nread:0)); |
throw BUSERR(a+((inc)?(nread<<2):0)); |
} |
|
if ((unsigned)m_lastaddr != (a+((inc)?(len):0))) { |
DBGPRINTF("TTYBUS::READV(a=%08x,inc=%d,len=%4x,x) ERR: (Last) %08x != %08x + %08x (Expected)\n", a, inc, len, m_lastaddr, a, (inc)?(len):0); |
printf("TTYBUS::READV(a=%08x,inc=%d,len=%4x,x) ERR: (Last) %08x != %08x + %08x (Expected)\n", a, inc, len, m_lastaddr, a, (inc)?(len):0); |
if ((unsigned)m_lastaddr != (a+((inc)?(len<<2):0))) { |
DBGPRINTF("TTYBUS::READV(a=%08x,inc=%d,len=%4x,x) ERR: (Last) %08x != %08x + %08x (Expected)\n", a, inc, len<<2, m_lastaddr, a, (inc)?(len<<2):0); |
printf("TTYBUS::READV(a=%08x,inc=%d,len=%4x,x) ERR: (Last) %08x != %08x + %08x (Expected)\n", a, inc, len<<2, m_lastaddr, a, (inc)?(len<<2):0); |
sleep(1); |
assert((int)m_lastaddr == (a+(inc)?(len):0)); |
assert((int)m_lastaddr == (a+(inc)?(len<<2):0)); |
exit(-3); |
} |
|
538,9 → 544,9
val = (val<<6) | (chardec(m_buf[5]) & 0x03f); |
|
m_addr_set = true; |
m_lastaddr = val; |
m_lastaddr = val<<2; |
|
DBGPRINTF("RCVD ADDR: 0x%08x\n", val); |
DBGPRINTF("RCVD ADDR: 0x%08x\n", val<<2); |
} else if (0x0c == (sixbits & 0x03c)) { // Set 32-bit address,compressed |
int nw = (sixbits & 0x03) + 2; |
do { |
564,8 → 570,8
} |
|
m_addr_set = true; |
m_lastaddr = val; |
DBGPRINTF("RCVD ADDR: 0x%08x (%d bytes)\n", val, nw+1); |
m_lastaddr = val<<2; |
DBGPRINTF("RCVD ADDR: 0x%08x (%d bytes)\n", val<<2, nw+1); |
} else |
found_start = true; |
} while(!found_start); |
576,7 → 582,7
if (0x06 == (sixbits & 0x03e)) { // Tbl read, last value |
rdaddr = (m_rdaddr-1)&0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-WORD() -- repeat last value, %08x, A= %08x\n", val, m_lastaddr); |
} else if (0x10 == (sixbits & 0x030)) { // Tbl read, up to 521 into past |
int idx; |
588,7 → 594,7
idx = ((idx<<6) | (chardec(m_buf[1]) & 0x03f)) + 2 + 8; |
rdaddr = (m_rdaddr-idx)&0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-WORD() -- long table value[%3d], %08x, A=%08x\n", idx, val, m_lastaddr); |
} else if (0x20 == (sixbits & 0x030)) { // Tbl read, 2-9 into past |
int idx; |
595,7 → 601,7
idx = (((sixbits>>1)&0x07)+2); |
rdaddr = (m_rdaddr - idx) & 0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-WORD() -- short table value[%3d], %08x, A=%08x\n", idx, val, m_lastaddr); |
} else if (0x38 == (sixbits & 0x038)) { // Raw read |
// DBGPRINTF("READ-WORD() -- RAW-READ, nr = %d\n", nr); |
611,7 → 617,7
val = (val<<6) | (chardec(m_buf[5]) & 0x03f); |
|
m_readtbl[m_rdaddr++] = val; m_rdaddr &= 0x03ff; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-WORD() -- RAW-READ %02x:%02x:%02x:%02x:%02x:%02x -- %08x, A=%08x\n", |
m_buf[0], m_buf[1], m_buf[2], m_buf[3], |
m_buf[4], m_buf[5], val, m_lastaddr); |
719,7 → 725,7
if (0x06 == (sixbits & 0x03e)) { // Tbl read, last value |
rdaddr = (m_rdaddr-1)&0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-IDLE() -- repeat last value, %08x\n", val); |
} else if (0x10 == (sixbits & 0x030)) { // Tbl read, up to 521 into past |
int idx; |
731,12 → 737,12
idx = ((idx<<6) | (chardec(m_buf[1]) & 0x03f)) + 2 + 8; |
rdaddr = (m_rdaddr-idx)&0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-IDLE() -- long table value[%3d], %08x\n", idx, val); |
} else if (0x20 == (sixbits & 0x030)) { // Tbl read, 2-9 into past |
rdaddr = (m_rdaddr - (((sixbits>>1)&0x07)+2)) & 0x03ff; |
val = m_readtbl[rdaddr]; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-IDLE() -- short table value[%3d], %08x\n", rdaddr, val); |
} else if (0x38 == (sixbits & 0x038)) { // Raw read |
do { |
751,7 → 757,7
val = (val<<6) | (chardec(m_buf[5]) & 0x03f); |
|
m_readtbl[m_rdaddr++] = val; m_rdaddr &= 0x03ff; |
m_lastaddr += (sixbits&1); |
m_lastaddr += (sixbits&1)?4:0; |
DBGPRINTF("READ-IDLE() -- RAW-READ %02x:%02x:%02x:%02x:%02x:%02x -- %08x\n", |
m_buf[0], m_buf[1], m_buf[2], m_buf[3], |
m_buf[4], m_buf[5], val); |
/ttybus.h
1,27 → 1,52
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: ttybus.h |
// |
// Filename: ttybus.h |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Project: UART to WISHBONE FPGA library |
// |
// Purpose: This is the C++ program on the command side that will interact |
// with a UART on an FPGA, to command the WISHBONE on that same |
// FPGA to ... whatever we wish to command it to do. |
// |
// This code does not run on an FPGA, is not a test bench, neither |
// is it a simulator. It is a portion of a command program |
// for commanding an FPGA. |
// This code does not run on an FPGA, is not a test bench, neither |
// is it a simulator. It is a portion of a command program |
// for commanding an FPGA. |
// |
// This particular implementation is a complete rewrite of the |
// last implementation, adding compression into the interface that |
// wasn't there before. |
// This particular implementation is a complete rewrite of the |
// last implementation, adding compression into the interface that |
// wasn't there before. |
// |
// Creator: Dan Gisselquist |
// Gisselquist Tecnology, LLC |
// |
// Copyright: 2015 |
// 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 TTYBUS_H |
#define TTYBUS_H |
|
90,8 → 115,8
void close(void) { m_dev->close(); } |
void writeio(const BUSW a, const BUSW v); |
BUSW readio(const BUSW a); |
void readi(const BUSW a, const int len, BUSW *buf); |
void readz(const BUSW a, const int len, BUSW *buf); |
void readi( const BUSW a, const int len, BUSW *buf); |
void readz( const BUSW a, const int len, BUSW *buf); |
void writei(const BUSW a, const int len, const BUSW *buf); |
void writez(const BUSW a, const int len, const BUSW *buf); |
bool poll(void) { return m_interrupt_flag; }; |
/twoc.cpp
0,0 → 1,106
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: twoc.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: Some various two's complement related C++ helper routines. |
// Specifically, these help extract signed numbers from |
// packed bitfields, while guaranteeing that the upper bits |
// are properly sign extended (or not) as desired. |
// |
// 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 <stdio.h> |
#include <assert.h> |
#include "twoc.h" |
|
long sbits(const long val, const int bits) { |
long r; |
|
r = val & ((1l<<bits)-1); |
if (r & (1l << (bits-1))) |
r |= (-1l << bits); |
return r; |
} |
|
bool sfits(const long val, const int bits) { |
return (sbits(val, bits) == bits); |
} |
|
unsigned long ubits(const long val, const int bits) { |
unsigned long r = val & ((1l<<bits)-1); |
return r; |
} |
|
unsigned long rndbits(const long val, const int bits_in, const int bits_out) { |
long s = sbits(val, bits_in); // Signed input value |
long t = s; // Truncated input value |
long r; // Result |
|
// printf("RNDBITS(%08lx, %d, %d)\n", val, bits_in, bits_out); |
// printf("S = %lx\n", s); |
// printf("T = %lx\n", t); |
// assert(bits_in > bits_out); |
if (bits_in == bits_out) |
r = s; |
else if (bits_in-1 == bits_out) { |
t = sbits(val>>1, bits_out); |
// printf("TEST! S = %ld, T = %ld\n", s, t); |
if (3 == (s&3)) |
t = t+1; |
r = t; |
} else { |
// A. 0XXXX.0xxxxx -> 0XXXX |
// B. 0XXX0.100000 -> 0XXX0; |
// C. 0XXX1.100000 -> 0XXX1+1; |
// D. 0XXXX.1zzzzz -> 0XXXX+1; |
// E. 1XXXX.0xxxxx -> 1XXXX |
// F. 1XXX0.100000 -> ??? XXX0; |
// G. 1XXX1.100000 -> ??? XXX1+1; |
// H. 1XXXX.1zzzzz -> 1XXXX+1; |
t = sbits(val>>(bits_in-bits_out), bits_out); // Truncated value |
if (0 == ((s >> (bits_in-bits_out-1))&1)) { |
// printf("A\n"); |
r = t; |
} else if (0 != (s & ((1<<(bits_in-bits_out-1))-1))) { |
// printf("D\n"); |
r = t+1; |
} else if (t&1) { |
// printf("C\n"); |
r = t+1; |
} else { // 3 ..?11 |
// printf("B\n"); |
r = t; |
} |
} return r; |
} |
|
|
/twoc.h
0,0 → 1,50
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: twoc.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: Some various two's complement related C++ helper routines. |
// Specifically, these help extract signed numbers from |
// packed bitfields, while guaranteeing that the upper bits |
// are properly sign extended (or not) as desired. |
// |
// 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 TWOC_H |
#define TWOC_H |
|
extern long sbits(const long val, const int bits); |
extern bool sfits(const long val, const int bits); |
extern unsigned long ubits(const long val, const int bits); |
extern unsigned long rndbits(const long val, const int bi, const int bo); |
|
#endif |
|
/wbprogram.cpp
4,7 → 4,8
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: Program the memory with a given '.bin' file. |
// Purpose: Program the memory with a given '.bin' file onto the flash |
// memory on a given board. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
11,7 → 12,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
24,7 → 25,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. |
// |
49,6 → 50,7
#include "llcomms.h" |
#include "regdefs.h" |
#include "flashdrvr.h" |
#include "byteswap.h" |
|
DEVBUS *m_fpga; |
void closeup(int v) { |
56,26 → 58,57
exit(0); |
} |
|
unsigned byteswap(unsigned x) { |
unsigned r; |
|
r = x&0x0ff; x>>=8; r<<= 8; |
r |= x&0x0ff; x>>=8; r<<= 8; |
r |= x&0x0ff; x>>=8; r<<= 8; |
r |= x&0x0ff; |
|
return r; |
} |
|
void usage(void) { |
printf("USAGE: wbprogram [@<Address>] file.bit\n"); |
printf("\tYou can also use a .bin file in place of the file.bit.\n"); |
} |
|
void skip_bitfile_header(FILE *fp) { |
const unsigned SEARCHLN = 204, MATCHLN = 52; |
const unsigned char matchstr[MATCHLN] = { |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
// |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
// |
0x00, 0x00, 0x00, 0xbb, |
0x11, 0x22, 0x00, 0x44, |
0xff, 0xff, 0xff, 0xff, |
0xff, 0xff, 0xff, 0xff, |
// |
0xaa, 0x99, 0x55, 0x66 }; |
unsigned char buf[SEARCHLN]; |
|
rewind(fp); |
fread(buf, sizeof(char), SEARCHLN, fp); |
for(int start=0; start+MATCHLN<SEARCHLN; start++) { |
int mloc; |
|
// Search backwards, since the starting bytes just aren't that |
// interesting. |
for(mloc = MATCHLN-1; mloc >= 0; mloc--) |
if (buf[start+mloc] != matchstr[mloc]) |
break; |
if (mloc < 0) { |
fseek(fp, start, SEEK_SET); |
return; |
} |
} |
|
fprintf(stderr, "Could not find bin-file header within bit file\n"); |
fclose(fp); |
exit(EXIT_FAILURE); |
} |
|
int main(int argc, char **argv) { |
FILE *fp; |
const int BUFLN = (1<<20); // 4MB Flash |
DEVBUS::BUSW *buf = new DEVBUS::BUSW[BUFLN], v, addr = EQSPIFLASH; |
DEVBUS::BUSW addr = EQSPIFLASH; |
char *buf = new char[FLASHLEN]; |
FLASHDRVR *flash; |
int argn = 1; |
|
97,11 → 130,7
exit(-1); |
} |
|
// SPI flash testing |
// Enable the faster (vector) reads |
bool vector_read = true; |
unsigned sz; |
bool esectors[NSECTORS]; |
|
argn = 1; |
if (argc <= argn) { |
135,14 → 164,10
|
fp = fopen(argv[argn], "r"); |
if (strcmp(&argv[argn][strlen(argv[argn])-4],".bit")==0) |
fseek(fp, 0x5dl, SEEK_SET); |
sz = fread(buf, sizeof(buf[0]), BUFLN, fp); |
skip_bitfile_header(fp); |
sz = fread(buf, sizeof(buf[0]), FLASHLEN, fp); |
fclose(fp); |
|
for(int i=0; i<sz; i++) { |
buf[i] = byteswap(buf[i]); |
} |
|
try { |
flash->write(addr, sz, buf, true); |
} catch(BUSERR b) { |
/wbregs.cpp
1,6 → 1,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbregs.cpp |
// Filename: wbregs.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
14,7 → 14,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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. |
// |
74,8 → 74,8
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool use_usb = true, use_decimal = false; |
int skp=0; |
bool use_decimal = false; |
|
skp=1; |
for(int argn=0; argn<argc-skp; argn++) { |
/wbsettime.cpp
1,18 → 1,22
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbsettime |
// Filename: wbsettime.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To set the on-board clock of an FPGA using the rtclight or |
// rtcclock FPGA protocols. |
// Purpose: To give a user access, via a command line program, to set the |
// real time clock within the FPGA. Note, however, that the RTC |
// clock device only sets the subseconds field when you program it at the |
// top of a minute. This program, therefore, will wait 'til the top of a |
// minute to set the clock. It can be annoying, but ... it works. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
25,7 → 29,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. |
// |
57,8 → 61,6
} |
|
int main(int argc, char **argv) { |
DEVBUS::BUSW v; |
|
bool set_time = true, read_hack = false; |
|
FPGAOPEN(m_fpga); |
/zipdbg.cpp
1,11 → 1,9
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: |
// Filename: zipdbg.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// |
// Purpose: Provide a debugger to step through the ZipCPU assembler, |
// evaluate the ZipCPU's current state, modify registers as(if) |
// needed, etc. All of this through the UART port of the Arty board. |
16,7 → 14,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
29,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. |
// |
40,6 → 38,11
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// BUGS: |
// - No ability to verify CPU functionality (3rd party simulator) |
// - No ability to set/clear breakpoints |
// |
// |
#include <stdlib.h> |
#include <signal.h> |
#include <time.h> |
50,7 → 53,6
#include <ncurses.h> |
|
#include "zopcodes.h" |
#include "zparser.h" |
#include "devbus.h" |
#include "regdefs.h" |
|
119,7 → 121,7
if (m_state.m_last_pc_valid) |
m_state.m_imem[0].m_a = m_state.m_last_pc; |
else |
m_state.m_imem[0].m_a = m_state.m_pc - 1; |
m_state.m_imem[0].m_a = m_state.m_pc - 4; |
try { |
m_state.m_imem[0].m_d = readio(m_state.m_imem[0].m_a); |
m_state.m_imem[0].m_valid = true; |
137,7 → 139,7
for(int i=1; i<4; i++) { |
if (!m_state.m_imem[i].m_valid) { |
m_state.m_imem[i+1].m_valid = false; |
m_state.m_imem[i+1].m_a = m_state.m_imem[i].m_a+1; |
m_state.m_imem[i+1].m_a = m_state.m_imem[i].m_a+4; |
continue; |
} |
m_state.m_imem[i+1].m_a = zop_early_branch( |
153,7 → 155,7
|
m_state.m_smem[0].m_a = m_state.m_sp; |
for(int i=1; i<5; i++) |
m_state.m_smem[i].m_a = m_state.m_smem[i-1].m_a+1; |
m_state.m_smem[i].m_a = m_state.m_smem[i-1].m_a+4; |
for(int i=0; i<5; i++) { |
m_state.m_smem[i].m_valid = true; |
if (m_state.m_smem[i].m_valid) |
215,9 → 217,9
mvprintw(y, x, " %s: 0x%08x ", n, v); |
} |
|
int showins(int y, const char *lbl, const unsigned int pcidx) { |
int showins(int y, const char *lbl, const unsigned int pcidx, bool ignore_a) { |
char la[80], lb[80]; |
int r = y-1; |
int r = y-1, bln = r; |
|
mvprintw(y, 0, "%s0x%08x", lbl, m_state.m_imem[pcidx].m_a); |
|
227,13 → 229,17
la[0] = '\0'; |
lb[0] = '\0'; |
if (m_state.m_imem[pcidx].m_valid) { |
zipi_to_string(m_state.m_imem[pcidx].m_d, la, lb); |
printw(" 0x%08x", m_state.m_imem[pcidx].m_d); |
printw(" %-25s", la); |
if (lb[0]) { |
mvprintw(y-1, 0, "%s", lbl); |
mvprintw(y-1, strlen(lbl)+10+3+8+2, "%-25s", lb); |
zipi_to_double_string(m_state.m_imem[pcidx].m_a, |
m_state.m_imem[pcidx].m_d, la, lb); |
if ((lb[0]=='\0')||(!ignore_a)) { |
printw(" 0x%08x", m_state.m_imem[pcidx].m_d); |
printw(" %-25s", la); |
} if (lb[0]) { |
mvprintw(bln, 0, "%11s", ""); |
mvprintw(bln, strlen(lbl)+10+3+8+2, "%-25s", lb); |
r--; |
} else { |
mvprintw(y-1, 0, "%46s", ""); |
} |
} else { |
printw(" 0x-------- %-25s", "(Bus Error)"); |
471,11 → 477,11
attroff(A_BOLD); |
ln+=3; |
|
showins(ln+4, " ", 0); |
showins(ln+4, " ", 0, true); |
{ |
int lclln = ln+3; |
for(int i=1; i<5; i++) |
lclln = showins(lclln, (i==1)?">":" ", i); |
for(int i=1; ((i<5)&&(lclln > ln)); i++) |
lclln = showins(lclln, (i==1)?">":" ", i, false); |
for(int i=0; i<5; i++) |
showstack(ln+i, (i==0)?">":" ", i); |
} |
595,88 → 601,92
// FPGAOPEN(m_fpga); |
ZIPPY *zip; // |
|
int skp=0, port = FPGAPORT; |
|
FPGAOPEN(m_fpga); |
zip = new ZIPPY(m_fpga); |
|
try { |
|
initscr(); |
raw(); |
noecho(); |
keypad(stdscr, true); |
initscr(); |
raw(); |
noecho(); |
keypad(stdscr, true); |
|
signal(SIGINT, on_sigint); |
signal(SIGINT, on_sigint); |
|
int chv; |
bool done = false; |
int chv; |
bool done = false; |
|
zip->halt(); |
for(int i=0; (i<5)&&(zip->stalled()); i++) |
; |
if (!zip->stalled()) |
zip->read_state(); |
else |
stall_screen(); |
while((!done)&&(!gbl_err)) { |
chv = getch(); |
switch(chv) { |
case 'c': case 'C': |
zip->toggle_cc(); |
break; |
case 'g': case 'G': |
m_fpga->writeio(R_ZIPCTRL, CPU_GO); |
// We just released the CPU, so we're now done. |
done = true; |
break; |
case 'l': case 'L': case CTRL('L'): |
redrawwin(stdscr); |
case 'm': case 'M': |
zip->show_user_timers(false); |
break; |
case 'q': case 'Q': case CTRL('C'): |
case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT: |
case KEY_ESCAPE: |
done = true; |
break; |
case 'r': case 'R': |
zip->reset(); |
erase(); |
break; |
case 't': case 'T': |
case 's': case 'S': |
zip->step(); |
break; |
case 'u': case 'U': |
zip->show_user_timers(true); |
break; |
case '\r': case '\n': |
case KEY_IC: case KEY_ENTER: |
get_value(zip); |
break; |
case KEY_UP: |
zip->cursor_up(); |
break; |
case KEY_DOWN: |
zip->cursor_down(); |
break; |
case KEY_LEFT: |
zip->cursor_left(); |
break; |
case KEY_RIGHT: |
zip->cursor_right(); |
break; |
case ERR: case KEY_CLEAR: |
default: |
zip->halt(); |
for(int i=0; (i<5)&&(zip->stalled()); i++) |
; |
if (!zip->stalled()) |
zip->read_state(); |
else |
stall_screen(); |
while((!done)&&(!gbl_err)) { |
chv = getch(); |
switch(chv) { |
case 'c': case 'C': |
zip->toggle_cc(); |
break; |
case 'g': case 'G': |
m_fpga->writeio(R_ZIPCTRL, CPU_GO); |
// We just released the CPU, so we're now done. |
done = true; |
break; |
case 'l': case 'L': case CTRL('L'): |
redrawwin(stdscr); |
case 'm': case 'M': |
zip->show_user_timers(false); |
break; |
case 'q': case 'Q': case CTRL('C'): |
case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT: |
case KEY_ESCAPE: |
done = true; |
break; |
case 'r': case 'R': |
zip->reset(); |
erase(); |
break; |
case 't': case 'T': |
case 's': case 'S': |
zip->step(); |
break; |
case 'u': case 'U': |
zip->show_user_timers(true); |
break; |
case '\r': case '\n': |
case KEY_IC: case KEY_ENTER: |
get_value(zip); |
break; |
case KEY_UP: |
zip->cursor_up(); |
break; |
case KEY_DOWN: |
zip->cursor_down(); |
break; |
case KEY_LEFT: |
zip->cursor_left(); |
break; |
case KEY_RIGHT: |
zip->cursor_right(); |
break; |
case ERR: case KEY_CLEAR: |
default: |
; |
} |
|
if ((done)||(gbl_err)) |
break; |
else if (zip->stalled()) |
stall_screen(); |
else |
zip->read_state(); |
} |
|
if ((done)||(gbl_err)) |
break; |
else if (zip->stalled()) |
stall_screen(); |
else |
zip->read_state(); |
} catch(const char *err) { |
fprintf(stderr, "ERR: Caught exception -- %s", err); |
} catch(...) { |
fprintf(stderr, "ERR: Caught anonymous exception!!\n"); |
} |
|
endwin(); |
/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 **§ions) |
{ |
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); |
} |
|
/zipelf.h
0,0 → 1,53
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: zipelf.h |
// |
// 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 |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#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 **§ions); |
|
#endif |
/zipload.cpp
14,7 → 14,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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. |
// |
54,297 → 54,15
#include "llcomms.h" |
#include "regdefs.h" |
#include "flashdrvr.h" |
#include "zipelf.h" |
#include "byteswap.h" |
|
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(FPGA::BUSW); |
return flen; |
} |
|
FPGA *m_fpga; |
class SECTION { |
public: |
unsigned m_start, m_len; |
FPGA::BUSW m_data[1]; |
}; |
|
SECTION **singlesection(int nwords) { |
fprintf(stderr, "NWORDS = %d\n", nwords); |
size_t sz = (2*(sizeof(SECTION)+sizeof(SECTION *)) |
+(nwords-1)*(sizeof(FPGA::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-(RESET_ADDRESS-EQSPIFLASH)) { |
fprintf(stderr, "File overruns flash memory\n"); |
exit(-1); |
} |
secpp = singlesection(num_words); |
secp = secpp[0]; |
secp->m_start = RAMBASE; |
secp->m_len = num_words; |
nr= fread(secp->m_data, sizeof(FPGA::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; |
} |
|
// #define CHEAP_AND_EASY |
#ifdef CHEAP_AND_EASY |
#else |
#include <libelf.h> |
#include <gelf.h> |
|
void elfread(const char *fname, unsigned &entry, SECTION **§ions) { |
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_paddr; |
r[i]->m_len = phdr.p_filesz/ sizeof(FPGA::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); |
} |
#endif |
|
void usage(void) { |
printf("USAGE: zipload [-hr] <zip-program-file>\n"); |
printf("\n" |
"\t-h\tDisplay this usage statement\n"); |
printf( |
"\t-h\tDisplay this usage statement\n" |
"\t-r\tStart the ZipCPU running from the address in the program file\n"); |
} |
|
353,7 → 71,7
bool start_when_finished = false, verbose = false; |
unsigned entry = 0; |
FLASHDRVR *flash = NULL; |
const char *bitfile = NULL, *altbitfile = NULL; |
const char *bitfile = NULL, *altbitfile = NULL, *execfile = NULL; |
|
if (argc < 2) { |
usage(); |
382,34 → 100,69
break; |
} skp++; argn--; |
} else { |
// Anything here must be the program to load. |
// Anything here must be either the program to load, |
// or a bit file to load |
argv[argn] = argv[argn+skp]; |
} |
} argc -= skp; |
|
|
if (argc == 0) { |
printf("No executable file given!\n\n"); |
for(int argn=0; argn<argc; argn++) { |
if (iself(argv[argn])) { |
if (execfile) { |
printf("Too many executable files given, %s and %s\n", execfile, argv[argn]); |
usage(); |
exit(EXIT_FAILURE); |
} execfile = argv[argn]; |
} else { // if (isbitfile(argv[argn])) |
if (!bitfile) |
bitfile = argv[argn]; |
else if (!altbitfile) |
altbitfile = argv[argn]; |
else { |
printf("Unknown file name or too many files, %s\n", argv[argn]); |
usage(); |
exit(EXIT_FAILURE); |
} |
} |
} |
|
if ((execfile == NULL)&&(bitfile == NULL)) { |
printf("No executable or bit file(s) given!\n\n"); |
usage(); |
exit(EXIT_FAILURE); |
} if (access(argv[0],R_OK)!=0) { |
} |
|
if ((bitfile)&&(access(bitfile,R_OK)!=0)) { |
// If there's no code file, or the code file cannot be opened |
fprintf(stderr, "Cannot open executable, %s\n", argv[0]); |
fprintf(stderr, "Cannot open bitfile, %s\n", bitfile); |
exit(EXIT_FAILURE); |
} |
|
if ((altbitfile)&&(access(altbitfile,R_OK)!=0)) { |
// If there's no code file, or the code file cannot be opened |
fprintf(stderr, "Cannot open alternate bitfile, %s\n", altbitfile); |
exit(EXIT_FAILURE); |
} |
|
if ((execfile)&&(access(execfile,R_OK)!=0)) { |
// If there's no code file, or the code file cannot be opened |
fprintf(stderr, "Cannot open executable, %s\n", execfile); |
exit(EXIT_FAILURE); |
} |
|
const char *codef = (argc>0)?argv[0]:NULL; |
DEVBUS::BUSW *fbuf = new DEVBUS::BUSW[FLASHWORDS]; |
char *fbuf = new char[FLASHLEN]; |
|
// Set the flash buffer to all ones |
memset(fbuf, -1, FLASHWORDS*sizeof(fbuf[0])); |
memset(fbuf, -1, FLASHLEN); |
|
m_fpga = FPGAOPEN(m_fpga); |
FPGAOPEN(m_fpga); |
|
// Make certain we can talk to the FPGA |
try { |
unsigned v = m_fpga->readio(R_VERSION); |
if (v < 0x20161000) { |
if (v < 0x20170000) { |
fprintf(stderr, "Could not communicate with board (invalid version)\n"); |
exit(EXIT_FAILURE); |
} |
420,7 → 173,6
|
// Halt the CPU |
try { |
unsigned v; |
printf("Halting the CPU\n"); |
m_fpga->writeio(R_ZIPCTRL, CPU_HALT|CPU_RESET); |
} catch(BUSERR b) { |
431,7 → 183,7
flash = new FLASHDRVR(m_fpga); |
|
if (codef) try { |
SECTION **secpp = NULL, *secp; |
ELFSECTION **secpp = NULL, *secp; |
|
if(iself(codef)) { |
// zip-readelf will help with both of these ... |
450,19 → 202,19
// Make sure our section is either within block RAM |
if ((secp->m_start >= MEMBASE) |
&&(secp->m_start+secp->m_len |
<= MEMBASE+MEMWORDS)) |
<= MEMBASE+MEMLEN)) |
valid = true; |
|
// Flash |
if ((secp->m_start >= RESET_ADDRESS) |
&&(secp->m_start+secp->m_len |
<= EQSPIFLASH+FLASHWORDS)) |
<= EQSPIFLASH+FLASHLEN)) |
valid = true; |
|
// Or SDRAM |
if ((secp->m_start >= RAMBASE) |
&&(secp->m_start+secp->m_len |
<= RAMBASE+RAMWORDS)) |
<= RAMBASE+RAMLEN)) |
valid = true; |
if (!valid) { |
fprintf(stderr, "No such memory on board: 0x%08x - %08x\n", |
476,18 → 228,27
secp = secpp[i]; |
if ( ((secp->m_start >= RAMBASE) |
&&(secp->m_start+secp->m_len |
<= RAMBASE+RAMWORDS)) |
<= RAMBASE+RAMLEN)) |
||((secp->m_start >= MEMBASE) |
&&(secp->m_start+secp->m_len |
<= MEMBASE+MEMWORDS)) ) { |
<= MEMBASE+MEMLEN)) ) { |
if (verbose) |
printf("Writing to MEM: %08x-%08x\n", |
secp->m_start, |
secp->m_start+secp->m_len); |
m_fpga->writei(secp->m_start, secp->m_len, |
secp->m_data); |
unsigned ln = (secp->m_len+3)&-4; |
uint32_t *bswapd = new uint32_t[ln>>2]; |
if (ln != (secp->m_len&-4)) |
memset(bswapd, 0, ln); |
memcpy(bswapd, secp->m_data, ln); |
byteswapbuf(ln>>2, bswapd); |
m_fpga->writei(secp->m_start, ln>>2, bswapd); |
} else { |
// Otherwise writing to flash |
if (secp->m_start < startaddr) { |
// Keep track of the first address in |
// flash, as well as the last address |
// that we will write |
codelen += (startaddr-secp->m_start); |
startaddr = secp->m_start; |
} if (secp->m_start+secp->m_len > startaddr+codelen) { |
496,9 → 257,11
printf("Sending to flash: %08x-%08x\n", |
secp->m_start, |
secp->m_start+secp->m_len); |
|
// Copy this data into our copy of what we want |
// the flash to look like. |
memcpy(&fbuf[secp->m_start-EQSPIFLASH], |
secp->m_data, |
secp->m_len*sizeof(FPGA::BUSW)); |
secp->m_data, secp->m_len); |
} |
} |
|
/zipstate.cpp
15,7 → 15,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, 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 |
28,7 → 28,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. |
// |
87,9 → 87,9
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool long_state = false; |
unsigned int v; |
int skp; |
|
skp=1; |
for(int argn=0; argn<argc-skp; argn++) { |
/zopcodes.cpp
0,0 → 1,666
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: zopcodes.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: A simple program to handle the disassembly and definition |
// of the various Zip Assembly opcodes. The primary function |
// of this file is the zipi_to_double_string, or Zip Instruction to a |
// pair of strings (disassemble) conversion. The pair of strings is |
// necessary since Zip instruction words may contain two separate |
// instructions. |
// |
// 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 <stdio.h> |
#include <strings.h> |
#include <string.h> |
#include <assert.h> |
#include <ctype.h> |
|
#include "twoc.h" |
#include "zopcodes.h" |
|
const char *zip_regstr[] = { |
"R0", "R1", "R2", "R3", |
"R4", "R5", "R6", "R7", |
"R8", "R9", "R10","R11", |
"R12","SP", "CC", "PC", |
"uR0", "uR1", "uR2", "uR3", |
"uR4", "uR5", "uR6", "uR7", |
"uR8", "uR9", "uR10", "uR11", |
"uR12", "uSP", "uCC", "uPC", |
"sR0", "sR1", "sR2", "sR3", |
"sR4", "sR5", "sR6", "sR7", |
"sR8", "sR9", "sR10","sR11", |
"sR12","sSP", "sCC", "sPC", "rILL" |
}; |
|
const char *zip_ccstr[8] = { |
"", ".Z", ".LT", ".C", |
".V",".NZ", ".GE", ".NC" |
}; |
|
static const ZOPCODE zip_oplist_raw[] = { |
// Special case instructions. These are general instructions, but with |
// special opcodes |
// Conditional branches |
// 0.1111.0111.ccc.0.111.10iiiii-- |
// 0111 1011 11cc c011 110i iiii iiii iiii |
{ "BUSY", 0xffc7ffff, 0x7883ffff, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "BZ", 0xfffc0000, 0x78880000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BLT", 0xfffc0000, 0x78900000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BC", 0xfffc0000, 0x78980000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BV", 0xfffc0000, 0x78a00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BNZ", 0xfffc0000, 0x78a80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BGE", 0xfffc0000, 0x78b00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BNC", 0xfffc0000, 0x78b80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED }, |
{ "BRA", 0xffc40000, 0x78800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
// Changes/updates to CC, based upon LDI |
{ "TRAP", 0xfffffff0, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "TRAP", 0xff800000, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// BREV based traps |
{ "TRAP", 0xffc7ffff, 0x72000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
// LDILO based traps |
{ "TRAP",0xffc4ffff, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "TRAP",0xffc40000, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
// CLR -- a LDI of zero |
// 0.rrrr.1100.iiiiiii-- |
// 0rrr r110 0... |
{ "CLR", 0x87ffffff, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// BREV based clears |
{ "CLR", 0x87c7ffff, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
// HALT |
// 0.1110.00011.ccc.0.0000000000010 |
// 0111.0000.11cc.c000.0000.0000.0000.0010 |
{ "HALT", 0xffc7ffff, 0x70c00010, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
// The "wait" instruction is identical, with the only difference being |
// the interrrupt context of the processor. Well, almost. To |
// facilitate waits from supervisor mode, the wait instruction |
// explicitly forces the CPU into user mode. |
{ "WAIT", 0xffc7ffff, 0x70c00030, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
// 1.0011.11000.000.0000...... 5f ? A carefully chosen illegal insn ?? |
// "INT", 0xff10007f, 0x9e00005f, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19), |
// Return to user space |
{ "RTU", 0xffc7ffff, 0x70c00020, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
// The return instruction: JMP R0 (possibly conditional) = MOV R0,PC |
{ "RTN", 0xffc7ffff, 0x7b400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
// JMP (possibly a conditional jump, if not covered by branches above) |
// 0.1111.01101.ccc.a.rrrr.biiiiiiiiiiiiiiii |
// 0111.1011.01cc.c0rr.rrbi.iiii.iiii.iiii MOV x,PC |
{ "JMP", 0xffc40000, 0x7b400000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) }, |
// 0.1111.1100.ii.iiii.iiii.iiii.iiii.iiii.iiii |
// 0111.1110.0iii.iiii.iiii.iiii.iiii.iiii LDI x,PC |
{ "JMPI", 0xff800000, 0x7e000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED }, |
// 0.1111.10010.000.1.1111.000000000000000 |
// 0111.1100.1000.0111.11ii.iiii.iiii.iiii LOD (PC),PC |
{ "LJMP", 0xffffffff, 0x7c87c000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// NOT : XOR w/ -1 |
// 0.rrrr.00100.ccc.0111.11111111111 |
// 0rrr.r001.00cc.c011.f.f.f.f |
// { "NOT", 0x87c7ffff, 0x0103ffff, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
// General instructions |
// 0rrr.rooo.oocc.cxrr.rrii.iiii.iiii.iiii |
{ "SUB", 0x87c40000, 0x00000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "SUB", 0x87c40000, 0x00040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "AND", 0x87c40000, 0x00400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "AND", 0x87c40000, 0x00440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "ADD", 0x87c40000, 0x00800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "ADD", 0x87c40000, 0x00840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "OR", 0x87c40000, 0x00c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "OR", 0x87c40000, 0x00c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "XOR", 0x87c40000, 0x01000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "XOR", 0x87c40000, 0x01040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LSR", 0x87c40000, 0x01400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LSR", 0x87c40000, 0x01440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LSL", 0x87c40000, 0x01800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LSL", 0x87c40000, 0x01840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "ASR", 0x87c40000, 0x01c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "ASR", 0x87c40000, 0x01c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "BREV",0x87c40000, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "BREV",0x87c40000, 0x02040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LDILO",0x87c40000, 0x02400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LDILO",0x87c40000, 0x02440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
// |
{ "MPYUHI", 0x87c40000, 0x02800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "MPYUHI", 0x87c40000, 0x02840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "MPYSHI", 0x87c40000, 0x02c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "MPYSHI", 0x87c40000, 0x02c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "MPY", 0x87c40000, 0x03000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "MPY", 0x87c40000, 0x03040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "MOV", 0x87c42000, 0x03400000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) }, |
{ "MOV", 0x87c42000, 0x03440000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) }, |
{ "MOV", 0x87c42000, 0x03402000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) }, |
{ "MOV", 0x87c42000, 0x03442000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) }, |
// |
{ "DIVU", 0x87c40000, 0x03800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "DIVU", 0x87c40000, 0x03840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "DIVS", 0x87c40000, 0x03c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "DIVS", 0x87c40000, 0x03c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "CMP", 0x87c40000, 0x04000000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "CMP", 0x87c40000, 0x04040000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
{ "TST", 0x87c40000, 0x04400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "TST", 0x87c40000, 0x04440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LW", 0x87c40000, 0x04800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LW", 0x87c40000, 0x04840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "SW", 0x87c40000, 0x04c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "SW", 0x87c40000, 0x04c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LH", 0x87c40000, 0x05000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LH", 0x87c40000, 0x05040000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "SH", 0x87c40000, 0x05400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "SH", 0x87c40000, 0x05440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "LB", 0x87c40000, 0x05800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "LB", 0x87c40000, 0x05840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
{ "SB", 0x87c40000, 0x05c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "SB", 0x87c40000, 0x05c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
// 0rrr.r101.1 |
{ "LDI", 0x87800000, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED }, |
// 0111.x111.00.xxxxxxxx |
{ "BRK", 0xf7ffffff, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "BRK", 0xf7c00000, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED }, |
{ "LOCK", 0xf7ffffff, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "LOCK", 0xf7c00000, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED }, |
// 0.111x.00000.xxx.xxx.xxxx.xxxx.xxxx.xxxx |
// 0111.x111.11.xxx.xxx.xxxx.xxxx.xxxx.xxxx |
// SNOOP = SIM w/ no argument(s) |
{ "SIM", 0xf7ffffff, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SEXIT",0xf7ffffff, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SEXIT",0xf7fffff0, 0x77800310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SEXIT",0xf7ffffe0, 0x77800300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SEXIT",0xf7ffff00, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED }, |
{ "SDUMP",0xf7ffffff, 0x778002ff, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SDUMP",0xf7fffff0, 0x77800200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SDUMP",0xf7fffff0, 0x77800210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SOUT", 0xf7fffff0, 0x77800230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SOUT", 0xf7ffffe0, 0x77800220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "SOUT", 0xf7ffff00, 0x77800400, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED }, |
{ "SDUMP",0xf7ffff00, 0x77800200, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED }, |
{ "SIM", 0xf7c00000, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED }, |
{ "NOOP", 0xf7ffffff, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NEXIT",0xf7ffffff, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NEXIT",0xf7ffff00, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED }, |
{ "NEXIT",0xf7fffff0, 0x77c00310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NEXIT",0xf7ffffe0, 0x77c00300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NDUMP",0xf7ffffff, 0x77c002ff, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NDUMP",0xf7fffff0, 0x77c00200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NDUMP",0xf7fffff0, 0x77c00210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
|
{ "NOUT", 0xf7fffff0, 0x77c00230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NOUT", 0xf7ffffe0, 0x77c00220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NOUT", 0xf7ffff00, 0x77c00400, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED }, |
{ "NDUMP",0xf7ffff00, 0x77c00200, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
{ "NSIM", 0xf7c00000, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED }, |
// |
// |
// 0rrr.r11f.ffcc.cxrr.rrii.iiii.iiii.iiii |
{ "FPADD",0x87c43fff, 0x06840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "FPSUB",0x87c43fff, 0x06c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "FPMPY",0x87c43fff, 0x07040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "FPDIV",0x87c43fff, 0x07440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) }, |
{ "FPI2F",0x87c40000, 0x07800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) }, |
{ "FPI2F",0x87c40000, 0x07840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
{ "FPF2I",0x87c40000, 0x07c40000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) }, |
// |
// |
// |
// |
// |
// 16-bit instructions, high side |
// |
// |
// 1.1111.00010.xcc.0iiii.xxxx.xxxxx.xxxxx |
// 1111.1000.10xc.c0ii.iixx.xxxx.xxxx.xxxx |
// Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST) |
// BRA: 1.1111.011.0.sssssss |
{ "BRA", 0xff800000, 0xf9000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
// CLR: 1.rrrr.110.00000000 |
{ "CLR", 0x87ff0000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// RTN: 1.1111.111.0.0000.000, MOV R0,Pc |
{ "RTN", 0xffff0000, 0xff800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// JMP: 1.1111.111.0.rrrrsss |
{ "JMP", 0xff800000, 0xff000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// LJSR: 1.000_0.011_.0.111_1.001 ?.1111.110.1.1111.000 |
// { "LJSR",0xffffffff, 0x83797ef8, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// |
// 1.rrrr.000.0.sssssss |
// 1rrr.r000.0sss.ssss |
{ "SUB", 0x87800000, 0x80000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
// 1.rrrr.000.1.rrrrsss |
{ "SUB", 0x87800000, 0x80800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// |
// 1.rrrr.001.0.sssssss |
// 1.rrrr.001.1.rrrrsss |
{ "AND", 0x87800000, 0x81000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
{ "AND", 0x87800000, 0x81800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// |
// 1.rrrr.010.0.sssssss |
// 1.rrrr.010.1.rrrrsss |
{ "ADD", 0x87800000, 0x82000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
{ "ADD", 0x87800000, 0x82800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// |
// 1.rrrr.011.a.rrrrsss |
{ "CMP", 0x87800000, 0x83000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
{ "CMP", 0x87800000, 0x83800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// |
// 1.rrrr.100.0.sssssss |
// 1.rrrr.100.1.rrrrsss |
{ "LW", 0x87800000, 0x84000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_SP, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
{ "LW", 0x87800000, 0x84800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// 1.rrrr.101.ssssssss |
{ "SW", 0x87000000, 0x85000000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_SP, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED }, |
// 1.rrrr.110.0.sssssss |
{ "SW", 0x87800000, 0x85800000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// 1.rrrr.110.iiiiiiii |
{ "LDI", 0x87000000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(8,16), ZIP_OPUNUSED }, |
// 1.rrrr.111.1.sssssss |
{ "MOV", 0x87800000, 0x87800000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED }, |
// 1.rrrr.111.1.rrrrsss |
// Illegal instruction !! |
{ "ILLV", 0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,16), ZIP_OPUNUSED }, |
// Global illegal instruction |
{ "ILL", 0x00000000, 0x00000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,0), ZIP_OPUNUSED } |
}; |
|
static const ZOPCODE zip_opbottomlist_raw[] = { |
// |
// |
// |
// 16-bit instructions, low side ... treat these as special |
// |
// |
// Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST) |
// BRA: 1.xxx_xxxx_xxxx_xxxx_?.111_1.011.0.sssssss |
{ "BRA", 0x80007f80, 0x80007900, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
// CLR: 1.xxx_xxxx_xxxx_xxxx_?.rrr_r.101.0000_0000 |
{ "CLR", 0x800007ff, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// RTN: 1.1111.111.0.0000.000, MOV R0,Pc |
{ "RTN", 0x80007fff, 0x80007f80, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED }, |
// JMP: 1.1111.111.0.rrrrsss |
{ "JMP", 0x80007f80, 0x80007f00, ZIP_REGFIELD(11),ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// LJMP: 1.xxx_xxxx_xxxx_xxxx_?.111_1.100._1.111_1.000 |
{ "LJMP", 0x80007fff, 0x80007cf8, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// 1.rrrr.000.0.sssssss |
{ "SUB", 0x80000780, 0x80000000, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
// 1.rrrr.000.1.rrrrsss |
{ "SUB", 0x80000780, 0x80000080, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// 1.rrrr.001.0.sssssss |
// 1.rrrr.001.1.rrrrsss |
{ "AND", 0x80000780, 0x80000100, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
{ "AND", 0x80000780, 0x80000180, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// 1.rrrr.010.0.sssssss |
// 1.rrrr.010.1.rrrrsss |
{ "ADD", 0x80000780, 0x80000200, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
{ "ADD", 0x80000780, 0x80000280, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// 1.rrrr.011.a.rrrrsss |
{ "CMP", 0x80000780, 0x80000300, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
{ "CMP", 0x80000780, 0x80000380, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// 1.rrrr.100.0.sssssss |
// 1.rrrr.100.1.rrrrsss |
{ "LW", 0x80000780, 0x80000400, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
{ "LW", 0x80000780, 0x80000480, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// 1.rrrr.101.ssssssss |
{ "SW", 0x80000780, 0x80000500, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED }, |
{ "SW", 0x80000780, 0x80000580, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// 1.rrr_r.110.ssssssss |
{ "LDI", 0x80000700, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(8,0), ZIP_OPUNUSED }, |
// 1.rrr_r.111_.x.rrr_rsss |
{ "MOV", 0x80000780, 0x80000780, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED }, |
// |
// |
// Illegal instruction !! |
{ "ILLV", 0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED }, |
{ "ILL", 0x00000000, 0x00000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED } |
}; |
|
const ZOPCODE *zip_oplist = zip_oplist_raw, |
*zip_opbottomlist = zip_opbottomlist_raw; |
|
const int nzip_oplist = (sizeof(zip_oplist_raw)/sizeof(ZOPCODE)); |
const int nzip_opbottom = (sizeof(zip_opbottomlist_raw)/sizeof(ZOPCODE)); |
|
|
static inline int |
TWOWORD_LOAD(uint32_t one, uint32_t two) { |
// BREV followed by LODILO |
if (((one&0x87c40000)==0x02000000)&&((two&0x87c40000)==0x02400000) |
// Must be to the same register too, and on the same condition |
&&(((one^two)&0xf8380000)==0)) |
return 1; |
return 0; |
} |
|
static inline int |
OFFSET_PC_MOV(uint32_t ins) { |
// 0.xxxx.01101.ccc.0.1111.0.iiiiiiiiiiiii |
// 0xxx.x011.01cc.c011.110i.iiii.iiii.iiii |
// |
return ((ins & 0x87c7e000)==0x0343c000); |
} |
|
static inline int |
TWOWORD_LJMP(uint32_t iword) { |
// LJMP a long jump instruction, for which the address of the target |
// is found in the next word |
if (iword==0x7c87c000) |
return 1; |
// Now, the CIS form ... an |
// Unconditional LJMP in the second half word |
if ((iword&0x80007fff)==0x80007cf8) |
return 1; |
return 0; |
} |
|
|
static inline int |
TWOWORD_JSR(uint32_t iword, uint32_t nxtword) { |
// First word moves the return address to R0 |
if (iword != 0x0343c001) |
return 0; |
// Second word is a BRA statement to ... anywhere |
// 0.1111.00010.ccc.0.iiiiiiiiiiiiiiiiii |
// 0111.1000.10cc.c0ii.iiii.iiii.iiii.iiii |
if ((nxtword&0xffc40000) == 0x78800000) |
return 1; |
return 0; |
} |
|
static inline int |
THREEWORD_LJSR(uint32_t iword, uint32_t nxtword) { |
// First word moves the return address to R0 |
if (iword!=0x0343c002) |
return 0; |
// Second word is an LJMP statement |
if (nxtword==0x7c87c000) |
return 1; |
return 0; |
} |
|
static inline int |
CIS_JSR(uint32_t iword __attribute__((unused)) ) { |
// MOV 1(PC) | LOD (PC),PC |
// |
// 1.0000.111.1.1111.001 |
// 1.1111.100.1.1111.000 |
if (iword == 0x87f9fcf8) |
return 1; |
// There is no code for this without CIS_OP_UNDER_TEST |
return 0; |
} |
|
static inline int |
POSSIBLE_TWOWORD_BEGINNING(uint32_t iword) { |
// Unconditional LJMP |
if (TWOWORD_LJMP(iword)) |
return 1; |
// MOV 1(PC),PC |
if (iword == 0x0343c001) |
return 1; |
// MOV 2(PC),PC |
if (iword == 0x0343c002) |
return 1; |
if (CIS_JSR(iword)) |
return 1; |
// The conditional LJMP is three words, which we don't handle ... |
// Any BREV command could be the beginning of a twoword instruction |
// |
// Of course, the point here is to determine whether we should (or need |
// to) read a second word from our read-memory function. Reading a |
// second word, given that the first is a BREV, isn't a problem since a |
// program can't end on/with a BREV instruction. |
// |
// BREV #,Rx |
if ((iword&0x87c40000)==0x02000000) |
return 1; |
return 0; |
} |
|
|
static uint32_t |
zip_bitreverse(uint32_t v) { |
uint32_t r=0, b; |
for(b=0; b<32; b++, v>>=1) |
r = (r<<1)|(v&1); |
return r; |
} |
|
static inline uint32_t |
TWOWORD_VALUE(uint32_t one, uint32_t two) { |
return ((two&0x0ffff)|(zip_bitreverse(one&0x0ffff))); |
} |
|
static long |
zip_sbits(const long val, const int bits) { |
long r; |
|
r = val & ((1l<<bits)-1); |
if (r & (1l << (bits-1))) |
r |= (-1l << bits); |
return r; |
} |
static unsigned long |
zip_ubits(const long val, const int bits) { |
unsigned long r = val & ((1l<<bits)-1); |
return r; |
} |
|
static int |
zip_getbits(const ZIPI ins, const int which) |
{ |
if (which & 0x40000000) { |
return zip_sbits(ins>>(which & 0x03f), (which>>8)&0x03f); |
} else { // if (which &0x03f) |
return zip_ubits(ins>>(which & 0x03f), (which>>8)&0x03f) |
+ ((which>>16)&0x0ff); |
} |
} |
|
static void |
zipi_to_halfstring(const uint32_t addr, const ZIPI ins, char *line, const ZOPCODE *listp) { |
|
if (OFFSET_PC_MOV(ins)) { |
int cv = zip_getbits(ins, ZIP_BITFIELD(3,19)); |
int dv = zip_getbits(ins, ZIP_REGFIELD(27)); |
int iv = zip_sbits(ins, 13); |
uint32_t ref; |
|
ref = (iv<<2) + addr + 4; |
|
sprintf(line, "%s%s", "MOV", zip_ccstr[cv]); |
sprintf(line, "%-11s", line); |
sprintf(line, "%s0x%08x", line, ref); |
sprintf(line, "%s,%s", line, zip_regstr[dv]); |
|
return; |
} |
|
int i; |
for(i=0; i<nzip_oplist; i++) { |
if (((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)!=0) { |
printf("Instruction %d, %s, fails consistency check\n", |
i, zip_oplist[i].s_opstr); |
printf("%08x & %08x = %08x != %08x\n", |
zip_oplist[i].s_mask, |
zip_oplist[i].s_val, |
(~zip_oplist[i].s_mask)&zip_oplist[i].s_val, |
0); |
assert(((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)==0); |
} |
} line[0] = '\0'; |
for(i=0; (listp[i].s_mask != 0); i++) { |
// printf("%2d: %6s %08x & %08x == %08x\n", |
// i, zip_oplist[i].s_opstr, ins, |
// zip_oplist[i].s_mask, zip_oplist[i].s_val); |
if ((ins & listp[i].s_mask) == listp[i].s_val) { |
// Write the opcode onto our line |
sprintf(line, "%s", listp[i].s_opstr); |
if (listp[i].s_cf != ZIP_OPUNUSED) { |
int bv = zip_getbits(ins, listp[i].s_cf); |
strcat(line, zip_ccstr[bv]); |
} sprintf(line, "%-11s", line); // Pad it to 11 chars |
|
int ra = -1, rb = -1, rr = -1, imv = 0; |
|
if (listp[i].s_result != ZIP_OPUNUSED) |
rr = zip_getbits(ins, listp[i].s_result); |
if (listp[i].s_ra != ZIP_OPUNUSED) |
ra = zip_getbits(ins, listp[i].s_ra); |
if (listp[i].s_rb != ZIP_OPUNUSED) |
rb = zip_getbits(ins, listp[i].s_rb); |
if (listp[i].s_i != ZIP_OPUNUSED) |
imv = zip_getbits(ins, listp[i].s_i); |
|
if ((listp[i].s_rb != ZIP_OPUNUSED)&&(rb == 15)) |
imv <<= 2; |
|
// Treat stores special |
if ((strncasecmp("SW",listp[i].s_opstr, 2)==0) |
||(strncasecmp("SH",listp[i].s_opstr, 2)==0) |
||(strncasecmp("SB",listp[i].s_opstr, 2)==0)) { |
strcat(line, zip_regstr[ra]); |
strcat(line, ","); |
|
if (listp[i].s_i != ZIP_OPUNUSED) { |
if (listp[i].s_rb == ZIP_OPUNUSED) |
sprintf(&line[strlen(line)], |
"($%d)", imv); |
else if (imv != 0) |
sprintf(&line[strlen(line)], |
"$%d", imv); |
} if (listp[i].s_rb != ZIP_OPUNUSED) { |
sprintf(&line[strlen(line)], |
"(%s)", zip_regstr[rb]); |
} |
// Treat long jumps special |
} else if (strncasecmp("LJMP",listp[i].s_opstr, 3)==0) { |
// Treat relative jumps (branches) specially as well |
} else if ((toupper(listp[i].s_opstr[0]=='B')) |
&&(strcasecmp(listp[i].s_opstr,"BUSY")!=0) |
&&(strcasecmp(listp[i].s_opstr,"BREV")!=0) |
&&(strcasecmp(listp[i].s_opstr,"BRK")!=0) |
&&(addr != 0)) { |
// Branch instruction: starts with B and isn't |
// BREV (bit reverse), BRK (break), or |
// BUSY |
uint32_t target = addr; |
|
target += zip_getbits(ins, listp[i].s_i)+4; |
sprintf(&line[strlen(line)], "@0x%08x", target); |
} else { |
int memop = 0; |
if (('L'==toupper(listp[i].s_opstr[0])) |
&&(('W'==toupper(listp[i].s_opstr[1])) |
||('H'==toupper(listp[i].s_opstr[1])) |
||('B'==toupper(listp[i].s_opstr[1]))) |
&&(!listp[i].s_opstr[2])) |
memop = 1; |
|
if (listp[i].s_i != ZIP_OPUNUSED) { |
if((memop)&&(listp[i].s_rb == ZIP_OPUNUSED)) |
sprintf(&line[strlen(line)], |
"($%d)", imv); |
else if((memop)&&(imv != 0)) |
sprintf(&line[strlen(line)], |
"%d", imv); |
else if((!memop)&&((imv != 0)||(listp[i].s_rb == ZIP_OPUNUSED))) |
sprintf(&line[strlen(line)], |
"$%d%s", imv, |
(listp[i].s_rb!=ZIP_OPUNUSED)?"+":""); |
} if (listp[i].s_rb != ZIP_OPUNUSED) { |
if (memop) |
sprintf(&line[strlen(line)], |
"(%s)", zip_regstr[rb]); |
else |
strcat(line, zip_regstr[rb]); |
} if(((listp[i].s_i != ZIP_OPUNUSED)||(listp[i].s_rb != ZIP_OPUNUSED)) |
&&((listp[i].s_ra != ZIP_OPUNUSED)||(listp[i].s_result != ZIP_OPUNUSED))) |
strcat(line, ","); |
|
if (listp[i].s_ra != ZIP_OPUNUSED) { |
strcat(line, zip_regstr[ra]); |
} else if (listp[i].s_result != ZIP_OPUNUSED) { |
strcat(line, zip_regstr[rr]); |
} |
} |
break; |
} |
} if (line[0] == '\0') { |
sprintf(line, "ILL %08x", ins); |
} |
} |
|
void |
zipi_to_double_string(const uint32_t addr, const ZIPI ins, char *la, char *lb) { |
zipi_to_halfstring(addr, ins, la, zip_oplist); |
if (lb) { |
if (ins & 0x80000000) { |
zipi_to_halfstring(addr, ins, lb, zip_opbottomlist); |
} else lb[0] = '\0'; |
} |
} |
|
unsigned int zop_early_branch(const unsigned int pc, const ZIPI insn) { |
if ((insn & 0xf8000000) != 0x78000000) |
return pc+4; |
if ((insn & 0xffc60000) == 0x78800000) // BRA high bit clear |
return (pc + 4 + ((insn & 0x3ffff)<<2)); |
if ((insn & 0xffc60000) == 0x78820000) // BRA high bit set (negative) |
return (pc + 4 + ((0x40000 - (insn & 0x3ffff))<<2)); |
return pc+4; |
} |
|
|
/zopcodes.h
0,0 → 1,89
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: zopcodes.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: A structure defined to keep track of our various opcodes and |
// some of their shortcut synonyms. |
// |
// 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 ZOPCODES_H |
#define ZOPCODES_H |
|
#include <stdint.h> |
|
// MACROS used in the instruction definition list. |
#define ZIP_OPUNUSED -1 |
#define ISUSEROP(A) ((a&(~0x0f))==0x000) |
#define ISSUPROP(A) ((a&(~0x0f))==0x010) |
#define ISLCLROP(A) ((a&(~0x0f))==0x020) |
#define ZIP_BITFIELD(LN,MN) (((LN&0x0ff)<<8)+(MN&0x0ff)) // A generic bitfield |
#define ZIP_REGFIELD(MN) (0x00000400 +(MN&0x0ff)) // Normal register field |
#define ZIP_URGFIELD(MN) (0x0100400 +(MN&0x0ff)) // User register field |
#define ZIP_IMMFIELD(LN,MN) (0x40000000 + (((LN&0x0ff)<<8)+(MN&0x0ff))) // Sgn extnd |
#define ZIP_SRGFIELD(MN) (0x0200400 +(MN&0x0ff)) |
#define ZIP_SP 0xd0000 |
|
typedef uint32_t ZIPI; // A Zip CPU instruction |
|
typedef struct { |
char s_opstr[8]; // OPCode name |
ZIPI s_mask, // Bits that must match 4 this pattern to match |
s_val; // What those masked bits must be |
// |
// The following describe not the value, but the bits where there |
// respective vaules will be found within the instruction. For example, |
// an instruction with no immediate will have an s_i value of -1 |
// (ZIP_OPUNUSED), whereas an instruction with an immediate value of -1 |
// might have an s_i value of ZIP_BITFIELD(14,0), or 0x0400. The |
// opcode itself will tell you what the value is--not this structure |
// describing the opcode. |
// |
int s_result, // Register where the result will be placed |
s_ra, // A register, often the result |
s_rb, // B register, source operand (if used) |
s_i, // Immediate value, added to B if B is used |
s_cf; // Condition flags. |
} ZOPCODE; |
|
extern const char *zip_regstr[49], *zip_ccstr[8]; |
|
extern const ZOPCODE *zip_oplist, *zip_opbottomlist; |
extern const int nzip_oplist, nzip_opbottom; |
|
// Disassemble an opcode |
extern void zipi_to_double_string(const uint32_t, const ZIPI, char *, char *); |
extern const char *zop_regstr[]; |
extern const char *zop_ccstr[]; |
extern unsigned int zop_early_branch(const unsigned int pc, const ZIPI ins); |
|
#endif |
/zprog.sh
38,62 → 38,45
## |
## |
export PATH=$PATH:. |
export BINFILE=../../xilinx/openarty.runs/impl_1/toplevel.bin |
export BINFILE=../../xilinx/openarty.runs/impl_1/toplevel.bit |
|
WBREGS=wbregs |
WBPROG=wbprogram |
|
RED=0x000f0000 |
GREEN=0x0000ff00 |
YELLOW=0x00170700 |
WHITE=0x000f0f0f |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0ff |
$WBREGS clrled0 $YELLOW |
$WBREGS clrled1 $YELLOW |
$WBREGS clrled2 $YELLOW |
$WBREGS clrled3 $YELLOW |
|
# |
# $WBREGS qspiv 0x8b # Accomplished by the flash driver |
# |
$WBREGS stopwatch 2 # Clear and stop the stopwatch |
$WBREGS stopwatch 1 # Start the stopwatch |
echo $WBPROG @0x0400000 $BINFILE |
$WBPROG @0x0400000 $BINFILE |
echo $WBPROG @0x1000000 $BINFILE |
$WBPROG @0x1000000 $BINFILE |
$WBREGS stopwatch 0 # Stop the stopwatch, we are done |
$WBREGS stopwatch # Print out the time on the stopwatch |
|
$WBREGS led 0x0f0 |
$WBREGS clrled0 $DIMGREEN |
$WBREGS clrled1 $DIMGREEN |
$WBREGS clrled2 $DIMGREEN |
$WBREGS clrled3 $DIMGREEN |
|
$WBREGS wbstar 0 |
$WBREGS fpgacmd 15 |
sleep 1 |
|
|
RED=0x00ff0000 |
GREEN=0x0000ff00 |
WHITE=0x000f0f0f |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0f |
$WBREGS clrled0 $RED |
$WBREGS clrled1 $RED |
$WBREGS clrled2 $RED |
$WBREGS clrled3 $RED |
|
sleep 1 |
$WBREGS clrled0 $GREEN |
$WBREGS led 0x10 |
sleep 1 |
$WBREGS clrled1 $GREEN |
$WBREGS clrled0 $DIMGREEN |
$WBREGS led 0x20 |
sleep 1 |
$WBREGS clrled2 $GREEN |
$WBREGS clrled1 $DIMGREEN |
$WBREGS led 0x40 |
|
if [[ -x ./wbsettime ]]; then |
./wbsettime |
fi |
|
$WBREGS clrled3 $GREEN |
$WBREGS clrled2 $DIMGREEN |
$WBREGS led 0x80 |
sleep 1 |
$WBREGS clrled0 $WHITE |
$WBREGS clrled1 $BLACK |
$WBREGS clrled2 $BLACK |
$WBREGS clrled3 $WHITE |
$WBREGS led 0x00 |
|
|
.
Property changes :
Modified: svn:ignore
## -1,3 +1,4 ##
+capgps
cfgscope
cpuscope
crctest
## -4,6 +5,7 ##
dbg.txt
dbg2.txt
debug.txt
+divutb
dumpflash
eqspiscope
eqspidump-original.bin
## -12,6 +14,9 ##
etxscope
genoimage
genoimage.cpp
+gps
+gpscoeffs
+gpsscope
manping
mdioscope
mtee.txt
## -19,11 +24,15 ##
netsetup
netuart
obj-pc
+oled_splash.c
+oled_splash.png
+oled_splash_jr.png
scopout
scopout.txt
scopout2.txt
sdramscope
tags
+tstgps
wbprogram
wbregs
wbsettime