OpenCores
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 30 to Rev 31
    Reverse comparison

Rev 30 → Rev 31

/cpuscope.cpp
0,0 → 1,167
////////////////////////////////////////////////////////////////////////////////
//
// Filename: cpuscope.cpp
//
// Project: XuLA2-LX25 SoC based upon the ZipCPU
//
// Purpose: To read out, and decompose, the results of the wishbone scope
// as applied to the ZipCPU internal operation.
//
// 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
 
#include "port.h"
#include "llcomms.h"
#include "regdefs.h"
#include "scopecls.h"
 
#define WBSCOPE R_CPUSCOPE
#define WBSCOPEDATA R_CPUSCOPED
 
FPGA *m_fpga;
void closeup(int v) {
m_fpga->kill();
exit(0);
}
 
const char *regstr[] = {
"R0","R1","R2","R3","R4","R5","R6","R7","R8","R9","RA","RB","RC",
"SP","CC","PC"
};
 
class CPUSCOPE : public SCOPE {
public:
CPUSCOPE(FPGA *fpga, unsigned addr, bool vecread)
: SCOPE(fpga, addr, false, false) {};
~CPUSCOPE(void) {}
virtual void decode(DEVBUS::BUSW val) const {
if (val & 0x80000000)
printf("TRIG ");
else
printf(" ");
if ((val & 0x40000000)==0) {
printf("%s <- 0x.%08x", regstr[(val>>32-6)&0xf], val&0x03ffffff);
} else if ((val & 0x60000000)==0x60000000) {
if (val&0x08000000)
printf("MEM-W[0x........] <- 0x.%07x %s",
(val&0x07ffffff),
(val&0x10000000)?"(GBL)":"");
else
printf("MEM-R[0x.%07x] -> (Not Givn) %s",
(val&0x07ffffff),
(val&0x10000000)?"(GBL)":"");
} else if ((val & 0x70000000)==0x40000000)
printf("JMP 0x%08x", (val&0x0fffffff));
else {
int master, halt, brk, sleep, gie, buserr, trap,
ill, clri, pfv, pfi, dcdce, dcdv, dcdstall,
opce, opvalid, oppipe, aluce, alubsy, aluwr,
aluill, aluwrf, memce, memwe, membsy;
master = (val>>27)&1;
halt = (val>>26)&1;
brk = (val>>25)&1;
sleep = (val>>24)&1;
gie = (val>>23)&1;
buserr = (val>>22)&1;
trap = (val>>21)&1;
ill = (val>>20)&1;
clri = (val>>19)&1;
pfv = (val>>18)&1;
pfi = (val>>17)&1;
dcdce = (val>>16)&1;
dcdv = (val>>15)&1;
dcdstall=(val>>14)&1;
opce = (val>>13)&1;
opvalid= (val>>12)&1;
oppipe = (val>>11)&1;
aluce = (val>>10)&1;
alubsy = (val>> 9)&1;
aluwr = (val>> 8)&1;
aluill = (val>> 7)&1;
aluwrf = (val>> 6)&1;
memce = (val>> 5)&1;
memwe = (val>> 4)&1;
membsy = (val>> 3)&1;
printf("FLAGS %08x", val);
printf(" CE[%c%c%c%c]",
(dcdce)?'D':' ',
(opce)?'O':' ',
(aluce)?'A':' ',
(memce)?'M':' ');
printf(" V[%c%c%c%c]",
(pfv)?'P':' ',
(dcdv)?'D':' ',
(opvalid)?'O':' ',
(aluwr)?'A':' ');
if (master) printf(" MCE");
if (halt) printf(" I-HALT");
if (brk) printf(" O-BREAK");
if (sleep) printf(" SLP");
if (GIE) printf(" GIE");
if (buserr) printf(" BE");
if (trap) printf(" TRAP");
if (ill) printf(" ILL");
if (clri) printf(" CLR-I");
if (pfi) printf(" PF-ILL");
if (dcdstall)printf(" DCD-STALL");
if (oppipe) printf(" OP-PIPE");
if (alubsy) printf(" ALU-BUSY");
if (memwe) printf(" MEM-WE");
if (membsy) printf(" MEM-BUSY");
//
}
}
};
 
int main(int argc, char **argv) {
FPGAOPEN(m_fpga);
 
signal(SIGSTOP, closeup);
signal(SIGHUP, closeup);
 
CPUSCOPE *scope = new CPUSCOPE(m_fpga, WBSCOPE, false);
if (!scope->ready()) {
printf("Scope is not yet ready:\n");
scope->decode_control();
scope->decode(WBSCOPEDATA);
printf("\n");
} else
scope->read();
delete m_fpga;
}
 
/erxscope.cpp
0,0 → 1,122
////////////////////////////////////////////////////////////////////////////////
//
// Filename: erxscope.cpp
//
// Project: XuLA2-LX25 SoC based upon the ZipCPU
//
// Purpose: This file decodes the debug bits produced by the enetpackets.v
// Verilog module, and stored in a Wishbone Scope. It is useful
// for determining if the packet transmitter works at all or not.
//
// 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
 
#include "port.h"
#include "regdefs.h"
#include "scopecls.h"
 
#define WBSCOPE R_NETSCOPE
#define WBSCOPEDATA R_NETSCOPED
 
FPGA *m_fpga;
void closeup(int v) {
m_fpga->kill();
exit(0);
}
 
class ERXSCOPE : public SCOPE {
public:
ERXSCOPE(FPGA *fpga, unsigned addr, bool vecread = true)
: SCOPE(fpga, addr, false, vecread) {};
~ERXSCOPE(void) {}
virtual void decode(DEVBUS::BUSW val) const {
int trigger, nerr, wr, nprev, crcv, mace, bcast, clear,
rxerr, miss, rxvalid, rxbusy, crs, dv, rxd, macv,
pred, crcd, macd, neop;
 
trigger= (val>>31)&1;
neop = (val>>30)&1;
wr = (val>>29)&1;
nprev = (val>>28)&1;
pred = (val>>24)&15;
crcv = (val>>23)&1;
crcd = (val>>19)&15;
mace = (val>>18)&1;
bcast = (val>>17)&1;
macv = (val>>16)&1;
macd = (val>>12)&15;
clear = (val>>11)&1;
rxerr = (val>>10)&1;
miss = (val>> 9)&1;
nerr = (val>> 8)&1;
rxvalid= (val>> 7)&1;
rxbusy = (val>> 6)&1;
crs = (val>> 5)&1;
dv = (val>> 4)&1;
rxd = (val )&15;
 
printf("%s [%s%s%s%x] p[%s%x] c[%s%x] m[%s%s%s%x] ![%s-] %s%s%s%s%s%s",
(trigger)?"TR":" ",
(rxerr)?"RXER":" ",
(crs)?"CRS":" ",
(dv)?"DV":" ", rxd,
(nprev)?"P":" ", pred,
(crcv)?"C":" ", crcd,
(bcast)?"B":" ", (mace)?"E":" ", (macv)?"M":" ", macd,
(wr)?"WR":" ", (nerr)?"ER":" ", (rxbusy)?"BSY":" ",
(neop)?"EOP":" ",
(miss)?"MISS":" ", (clear)?"CLEAR":" ",
(rxvalid)?"VALID":" ");
}
};
 
int main(int argc, char **argv) {
FPGAOPEN(m_fpga);
 
signal(SIGSTOP, closeup);
signal(SIGHUP, closeup);
 
ERXSCOPE *scope = new ERXSCOPE(m_fpga, WBSCOPE);
if (!scope->ready()) {
printf("Scope is not yet ready:\n");
scope->decode_control();
} else
scope->read();
delete m_fpga;
}
 
/zipdbg.cpp
0,0 → 1,689
////////////////////////////////////////////////////////////////////////////////
//
// Filename:
//
// 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.
//
//
// 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 <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
 
#include <ctype.h>
#include <ncurses.h>
 
#include "zopcodes.h"
#include "zparser.h"
#include "devbus.h"
#include "regdefs.h"
 
#include "port.h"
 
#define CMD_REG 0
#define CMD_DATA 1
#define CMD_HALT (1<<10)
#define CMD_STALL (1<<9)
#define CMD_STEP (1<<8)
#define CMD_INT (1<<7)
#define CMD_RESET (1<<6)
 
#define KEY_ESCAPE 27
#define KEY_RETURN 10
#define CTRL(X) ((X)&0x01f)
 
class SPARSEMEM {
public:
bool m_valid;
unsigned int m_a, m_d;
};
 
bool gbl_err = false;
class ZIPSTATE {
public:
bool m_valid, m_gie, m_last_pc_valid;
unsigned int m_sR[16], m_uR[16];
unsigned int m_p[20];
unsigned int m_last_pc, m_pc, m_sp;
SPARSEMEM m_smem[5];
SPARSEMEM m_imem[5];
ZIPSTATE(void) : m_valid(false), m_last_pc_valid(false) {}
 
void step(void) {
m_last_pc_valid = true;
m_last_pc = m_pc;
}
};
 
// No particular "parameters" need definition or redefinition here.
class ZIPPY : public DEVBUS {
static const int MAXERR;
typedef DEVBUS::BUSW BUSW;
DEVBUS *m_fpga;
int m_cursor;
ZIPSTATE m_state;
bool m_user_break, m_show_users_timers, m_show_cc;
public:
ZIPPY(DEVBUS *fpga) : m_fpga(fpga), m_cursor(0), m_user_break(false),
m_show_users_timers(false), m_show_cc(false) {}
 
void read_raw_state(void) {
m_state.m_valid = false;
for(int i=0; i<16; i++)
m_state.m_sR[i] = cmd_read(i);
for(int i=0; i<16; i++)
m_state.m_uR[i] = cmd_read(i+16);
for(int i=0; i<20; i++)
m_state.m_p[i] = cmd_read(i+32);
 
m_state.m_gie = (m_state.m_sR[14] & 0x020);
m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
 
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;
try {
m_state.m_imem[0].m_d = readio(m_state.m_imem[0].m_a);
m_state.m_imem[0].m_valid = true;
} catch(BUSERR be) {
m_state.m_imem[0].m_valid = false;
}
m_state.m_imem[1].m_a = m_state.m_pc;
try {
m_state.m_imem[1].m_d = readio(m_state.m_imem[1].m_a);
m_state.m_imem[1].m_valid = true;
} catch(BUSERR be) {
m_state.m_imem[1].m_valid = false;
}
 
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;
continue;
}
m_state.m_imem[i+1].m_a = zop_early_branch(
m_state.m_imem[i].m_a,
m_state.m_imem[i].m_d);
try {
m_state.m_imem[i+1].m_d = readio(m_state.m_imem[i+1].m_a);
m_state.m_imem[i+1].m_valid = true;
} catch(BUSERR be) {
m_state.m_imem[i+1].m_valid = false;
}
}
 
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;
for(int i=0; i<5; i++) {
m_state.m_smem[i].m_valid = true;
if (m_state.m_smem[i].m_valid)
try {
m_state.m_smem[i].m_d = readio(m_state.m_smem[i].m_a);
m_state.m_smem[i].m_valid = true;
} catch(BUSERR be) {
m_state.m_smem[i].m_valid = false;
}
}
m_state.m_valid = true;
}
 
void kill(void) { m_fpga->kill(); }
void close(void) { m_fpga->close(); }
void writeio(const BUSW a, const BUSW v) { m_fpga->writeio(a, v); }
BUSW readio(const BUSW a) { return m_fpga->readio(a); }
void readi(const BUSW a, const int len, BUSW *buf) {
return m_fpga->readi(a, len, buf); }
void readz(const BUSW a, const int len, BUSW *buf) {
return m_fpga->readz(a, len, buf); }
void writei(const BUSW a, const int len, const BUSW *buf) {
return m_fpga->writei(a, len, buf); }
void writez(const BUSW a, const int len, const BUSW *buf) {
return m_fpga->writez(a, len, buf); }
bool poll(void) { return m_fpga->poll(); }
void usleep(unsigned ms) { m_fpga->usleep(ms); }
void wait(void) { m_fpga->wait(); }
bool bus_err(void) const { return m_fpga->bus_err(); }
void reset_err(void) { m_fpga->reset_err(); }
void clear(void) { m_fpga->clear(); }
 
void reset(void) { writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT); }
void step(void) { writeio(R_ZIPCTRL, CPU_STEP); m_state.step(); }
void go(void) { writeio(R_ZIPCTRL, CPU_GO); }
void halt(void) { writeio(R_ZIPCTRL, CPU_HALT); }
bool stalled(void) { return ((readio(R_ZIPCTRL)&CPU_STALL)==0); }
 
void show_user_timers(bool v) {
m_show_users_timers = v;
}
 
void toggle_cc(void) {
m_show_cc = !m_show_cc;
}
 
void showval(int y, int x, const char *lbl, unsigned int v, bool c) {
if (c)
mvprintw(y,x, ">%s> 0x%08x<", lbl, v);
else
mvprintw(y,x, " %s: 0x%08x ", lbl, v);
}
 
void dispreg(int y, int x, const char *n, unsigned int v, bool c) {
// 4,4,8,1 = 17 of 20, +2 = 18
if (c)
mvprintw(y, x, ">%s> 0x%08x<", n, v);
else
mvprintw(y, x, " %s: 0x%08x ", n, v);
}
 
int showins(int y, const char *lbl, const unsigned int pcidx) {
char la[80], lb[80];
int r = y-1;
 
mvprintw(y, 0, "%s0x%08x", lbl, m_state.m_imem[pcidx].m_a);
 
if (m_state.m_gie) attroff(A_BOLD);
else attron(A_BOLD);
 
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);
r--;
}
} else {
printw(" 0x-------- %-25s", "(Bus Error)");
}
attroff(A_BOLD);
 
return r;
}
 
void showstack(int y, const char *lbl, const unsigned int idx) {
mvprintw(y, 27+26, "%s%08x ", lbl, m_state.m_smem[idx].m_a);
 
if (m_state.m_gie) attroff(A_BOLD);
else attron(A_BOLD);
 
if (m_state.m_smem[idx].m_valid)
printw("0x%08x", m_state.m_smem[idx].m_d);
else
printw("(Bus Err)");
attroff(A_BOLD);
}
 
unsigned int cmd_read(unsigned int a) {
int errcount = 0;
unsigned int s;
 
writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
while((((s=readio(R_ZIPCTRL))&CPU_STALL)== 0)&&(errcount<MAXERR)
&&(!m_user_break))
errcount++;
if (m_user_break) {
endwin();
exit(EXIT_SUCCESS);
} else if (errcount >= MAXERR) {
endwin();
printf("ERR: errcount(%d) >= MAXERR on cmd_read(a=%2x)\n", errcount, a);
printf("ZIPCTRL = 0x%08x", s);
if ((s & 0x0200)==0) printf(" STALL");
if (s & 0x0400) printf(" HALTED");
if ((s & 0x03000)==0x01000)
printf(" SW-HALT");
else {
if (s & 0x01000) printf(" SLEEPING");
if (s & 0x02000) printf(" GIE(UsrMode)");
} printf("\n");
exit(EXIT_FAILURE);
}
return readio(R_ZIPDATA);
}
 
void cmd_write(unsigned int a, int v) {
int errcount = 0;
unsigned int s;
 
writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
while((((s=readio(R_ZIPCTRL))&CPU_STALL)== 0)&&(errcount<MAXERR)
&&(!m_user_break))
errcount++;
if (m_user_break) {
endwin();
exit(EXIT_SUCCESS);
} else if (errcount >= MAXERR) {
endwin();
printf("ERR: errcount(%d) >= MAXERR on cmd_read(a=%2x)\n", errcount, a);
printf("ZIPCTRL = 0x%08x", s);
if ((s & 0x0200)==0) printf(" STALL");
if (s & 0x0400) printf(" HALTED");
if ((s & 0x03000)==0x01000)
printf(" SW-HALT");
else {
if (s & 0x01000) printf(" SLEEPING");
if (s & 0x02000) printf(" GIE(UsrMode)");
} printf("\n");
exit(EXIT_FAILURE);
}
 
writeio(R_ZIPDATA, (unsigned int)v);
}
 
void read_state(void) {
int ln= 0;
bool gie;
 
read_raw_state();
 
if (m_cursor < 0)
m_cursor = 0;
else if (m_cursor >= 44)
m_cursor = 43;
 
mvprintw(ln,0, "Peripherals");
mvprintw(ln,30,"%-50s", "CPU State: ");
{
unsigned int v = readio(R_ZIPCTRL);
mvprintw(ln,41, "0x%08x ", v);
// if (v & 0x010000)
// printw("INT ");
if ((v & 0x003000) == 0x03000)
printw("Sleeping ");
else if (v & 0x001000)
printw("Halted ");
else if (v & 0x002000)
printw("User Mode ");
else
printw("Supervisor mode ");
if (v& 0x0200) {
v = m_state.m_sR[15];
} else printw("Stalled ");
// if (v & 0x008000)
// printw("Break-Enabled ");
// if (v & 0x000080)
// printw("PIC Enabled ");
} ln++;
showval(ln, 0, "PIC ", m_state.m_p[0], (m_cursor==0));
showval(ln,20, "WDT ", m_state.m_p[1], (m_cursor==1));
showval(ln,40, "WBUS", m_state.m_p[2], (m_cursor==2));
showval(ln,60, "PIC2", m_state.m_p[3], (m_cursor==3));
ln++;
showval(ln, 0, "TMRA", m_state.m_p[4], (m_cursor==4));
showval(ln,20, "TMRB", m_state.m_p[5], (m_cursor==5));
showval(ln,40, "TMRC", m_state.m_p[6], (m_cursor==6));
showval(ln,60, "JIF ", m_state.m_p[7], (m_cursor==7));
 
ln++;
if (!m_show_users_timers) {
showval(ln, 0, "MTSK", m_state.m_p[ 8], (m_cursor==8));
showval(ln,20, "MOST", m_state.m_p[ 9], (m_cursor==9));
showval(ln,40, "MPST", m_state.m_p[10], (m_cursor==10));
showval(ln,60, "MICT", m_state.m_p[11], (m_cursor==11));
} else {
showval(ln, 0, "UTSK", m_state.m_p[12], (m_cursor==8));
showval(ln,20, "UMST", m_state.m_p[13], (m_cursor==9));
showval(ln,40, "UPST", m_state.m_p[14], (m_cursor==10));
showval(ln,60, "UICT", m_state.m_p[15], (m_cursor==11));
}
 
ln++;
ln++;
unsigned int cc = m_state.m_sR[14];
gie = (cc & 0x020);
if (gie)
attroff(A_BOLD);
else
attron(A_BOLD);
mvprintw(ln, 0, "Supervisor Registers");
ln++;
 
dispreg(ln, 0, "sR0 ", m_state.m_sR[0], (m_cursor==12));
dispreg(ln,20, "sR1 ", m_state.m_sR[1], (m_cursor==13));
dispreg(ln,40, "sR2 ", m_state.m_sR[2], (m_cursor==14));
dispreg(ln,60, "sR3 ", m_state.m_sR[3], (m_cursor==15)); ln++;
 
dispreg(ln, 0, "sR4 ", m_state.m_sR[4], (m_cursor==16));
dispreg(ln,20, "sR5 ", m_state.m_sR[5], (m_cursor==17));
dispreg(ln,40, "sR6 ", m_state.m_sR[6], (m_cursor==18));
dispreg(ln,60, "sR7 ", m_state.m_sR[7], (m_cursor==19)); ln++;
 
dispreg(ln, 0, "sR8 ", m_state.m_sR[ 8], (m_cursor==20));
dispreg(ln,20, "sR9 ", m_state.m_sR[ 9], (m_cursor==21));
dispreg(ln,40, "sR10", m_state.m_sR[10], (m_cursor==22));
dispreg(ln,60, "sR11", m_state.m_sR[11], (m_cursor==23)); ln++;
 
dispreg(ln, 0, "sR12", m_state.m_sR[12], (m_cursor==24));
dispreg(ln,20, "sSP ", m_state.m_sR[13], (m_cursor==25));
 
if (m_show_cc) {
mvprintw(ln,40, " sCC :%16s", "");
dispreg(ln, 40, "sCC ", m_state.m_sR[14], (m_cursor==26));
} else {
mvprintw(ln,40, " sCC :%16s", "");
mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s",
(m_cursor == 26)?">":" ",
(cc&0x1000)?"FE":"", // Floating point exception
(cc&0x0800)?"DV":"", // Division by zero
(cc&0x0400)?"BE":"", // Bus Error
(cc&0x0200)?"TP":"", // Trap
(cc&0x0100)?"IL":"", // Illegal instruction
(cc&0x0080)?"BK":"", // Break
((gie==0)&&(cc&0x0010))?"HLT":""); // Halted
mvprintw(ln,54,"%s%s%s%s",
(cc&8)?"V":" ",
(cc&4)?"N":" ",
(cc&2)?"C":" ",
(cc&1)?"Z":" ");
}
dispreg(ln,60, "sPC ", m_state.m_sR[15], (m_cursor==27));
ln++;
 
if (gie)
attron(A_BOLD);
else
attroff(A_BOLD);
mvprintw(ln, 0, "User Registers"); ln++;
dispreg(ln, 0, "uR0 ", m_state.m_uR[0], (m_cursor==28));
dispreg(ln,20, "uR1 ", m_state.m_uR[1], (m_cursor==29));
dispreg(ln,40, "uR2 ", m_state.m_uR[2], (m_cursor==30));
dispreg(ln,60, "uR3 ", m_state.m_uR[3], (m_cursor==31)); ln++;
 
dispreg(ln, 0, "uR4 ", m_state.m_uR[4], (m_cursor==32));
dispreg(ln,20, "uR5 ", m_state.m_uR[5], (m_cursor==33));
dispreg(ln,40, "uR6 ", m_state.m_uR[6], (m_cursor==34));
dispreg(ln,60, "uR7 ", m_state.m_uR[7], (m_cursor==35)); ln++;
 
dispreg(ln, 0, "uR8 ", m_state.m_uR[8], (m_cursor==36));
dispreg(ln,20, "uR9 ", m_state.m_uR[9], (m_cursor==37));
dispreg(ln,40, "uR10", m_state.m_uR[10], (m_cursor==38));
dispreg(ln,60, "uR11", m_state.m_uR[11], (m_cursor==39)); ln++;
 
dispreg(ln, 0, "uR12", m_state.m_uR[12], (m_cursor==40));
dispreg(ln,20, "uSP ", m_state.m_uR[13], (m_cursor==41));
cc = m_state.m_uR[14];
if (m_show_cc) {
mvprintw(ln,40, " uCC :%16s", "");
dispreg(ln, 40, "uCC ", m_state.m_uR[14], (m_cursor==42));
} else {
mvprintw(ln,40, " uCC :%16s", "");
mvprintw(ln,40, "%suCC :%s%s%s%s%s%s%s",
(m_cursor == 42)?">":" ",
(cc&0x1000)?"FE":"", // Floating point Exception
(cc&0x0800)?"DV":"", // Division by zero
(cc&0x0400)?"BE":"", // Bus Error
(cc&0x0200)?"TP":"", // Trap
(cc&0x0100)?"IL":"", // Illegal instruction
(cc&0x0040)?"ST":"", // Single-step
((gie)&&(cc&0x0010))?"SL":""); // Sleep
mvprintw(ln,54,"%s%s%s%s",
(cc&8)?"V":" ",
(cc&4)?"N":" ",
(cc&2)?"C":" ",
(cc&1)?"Z":" ");
}
dispreg(ln,60, "uPC ", m_state.m_uR[15], (m_cursor==43));
 
attroff(A_BOLD);
ln+=3;
 
showins(ln+4, " ", 0);
{
int lclln = ln+3;
for(int i=1; i<5; i++)
lclln = showins(lclln, (i==1)?">":" ", i);
for(int i=0; i<5; i++)
showstack(ln+i, (i==0)?">":" ", i);
}
}
 
void cursor_up(void) {
if (m_cursor > 3)
m_cursor -= 4;
} void cursor_down(void) {
if (m_cursor < 40)
m_cursor += 4;
} void cursor_left(void) {
if (m_cursor > 0)
m_cursor--;
else m_cursor = 43;
} void cursor_right(void) {
if (m_cursor < 43)
m_cursor++;
else m_cursor = 0;
}
 
int cursor(void) { return m_cursor; }
};
 
const int ZIPPY::MAXERR = 100000;
 
FPGA *m_fpga;
 
void get_value(ZIPPY *zip) {
int wy, wx, ra;
int c = zip->cursor();
 
wx = (c & 0x03) * 20 + 9 + 1;
wy = (c >> 2);
if (wy >= 3+4)
wy++;
if (wy > 3)
wy += 2;
wy++;
 
if (c >= 12)
ra = c - 12;
else
ra = c + 32;
 
bool done = false;
char str[16];
int pos = 0; str[pos] = '\0';
attron(A_NORMAL | A_UNDERLINE);
mvprintw(wy, wx, "%-8s", "");
while(!done) {
int chv = getch();
switch(chv) {
case KEY_ESCAPE:
pos = 0; str[pos] = '\0'; done = true;
break;
case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN:
done = true;
break;
case KEY_LEFT: case KEY_BACKSPACE:
if (pos > 0) pos--;
break;
case KEY_CLEAR:
pos = 0;
break;
case '0': case ' ': str[pos++] = '0'; break;
case '1': str[pos++] = '1'; break;
case '2': str[pos++] = '2'; break;
case '3': str[pos++] = '3'; break;
case '4': str[pos++] = '4'; break;
case '5': str[pos++] = '5'; break;
case '6': str[pos++] = '6'; break;
case '7': str[pos++] = '7'; break;
case '8': str[pos++] = '8'; break;
case '9': str[pos++] = '9'; break;
case 'A': case 'a': str[pos++] = 'A'; break;
case 'B': case 'b': str[pos++] = 'B'; break;
case 'C': case 'c': str[pos++] = 'C'; break;
case 'D': case 'd': str[pos++] = 'D'; break;
case 'E': case 'e': str[pos++] = 'E'; break;
case 'F': case 'f': str[pos++] = 'F'; break;
}
 
if (pos > 8)
pos = 8;
str[pos] = '\0';
 
attron(A_NORMAL | A_UNDERLINE);
mvprintw(wy, wx, "%-8s", str);
if (pos > 0) {
attron(A_NORMAL | A_UNDERLINE | A_BLINK);
mvprintw(wy, wx+pos-1, "%c", str[pos-1]);
}
attrset(A_NORMAL);
}
 
if (pos > 0) {
int v;
v = strtoul(str, NULL, 16);
zip->cmd_write(ra, v);
}
}
 
void on_sigint(int v) {
endwin();
 
fprintf(stderr, "Interrupted!\n");
exit(-2);
}
 
void stall_screen(void) {
erase();
mvprintw(0,0, "CPU is stalled. (Q to quit)\n");
}
 
int main(int argc, char **argv) {
// FPGAOPEN(m_fpga);
ZIPPY *zip; //
 
int skp=0, port = FPGAPORT;
 
FPGAOPEN(m_fpga);
zip = new ZIPPY(m_fpga);
 
 
initscr();
raw();
noecho();
keypad(stdscr, true);
 
signal(SIGINT, on_sigint);
 
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:
;
}
 
if ((done)||(gbl_err))
break;
else if (zip->stalled())
stall_screen();
else
zip->read_state();
}
 
endwin();
 
if (gbl_err) {
printf("Killed on error: could not access bus!\n");
exit(-2);
}
}
 
/zipload.cpp
0,0 → 1,535
////////////////////////////////////////////////////////////////////////////////
//
// Filename: zipload.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: To load a program for the ZipCPU into memory, whether flash
// or SDRAM. This requires a working/running configuration
// in order to successfully load.
//
//
// 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 <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 "port.h"
#include "llcomms.h"
#include "regdefs.h"
#include "flashdrvr.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 **&sections) {
Elf *e;
int fd, i;
size_t n;
char *id;
Elf_Kind ek;
GElf_Ehdr ehdr;
GElf_Phdr phdr;
const bool dbg = false;
 
if (elf_version(EV_CURRENT) == EV_NONE) {
fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1));
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((fd = open(fname, O_RDONLY, 0)) < 0) {
fprintf(stderr, "Could not open %s\n", fname);
perror("O/S Err:");
exit(EXIT_FAILURE);
} if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) {
fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
ek = elf_kind(e);
if (ek == ELF_K_ELF) {
; // This is the kind of file we should expect
} else if (ek == ELF_K_AR) {
fprintf(stderr, "Cannot run an archive!\n");
exit(EXIT_FAILURE);
} else if (ek == ELF_K_NONE) {
;
} else {
fprintf(stderr, "Unexpected ELF file kind!\n");
exit(EXIT_FAILURE);
}
 
if (gelf_getehdr(e, &ehdr) == NULL) {
fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((i=gelf_getclass(e)) == ELFCLASSNONE) {
fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if ((id = elf_getident(e, NULL)) == NULL) {
fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
} if (i != ELFCLASS32) {
fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n");
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type);
printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine);
printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version);
printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry);
printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff);
printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff);
printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags);
printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize);
printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize);
printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize);
printf("\n");
}
 
 
// Check whether or not this is an ELF file for the ZipCPU ...
if (ehdr.e_machine != 0x0dadd) {
fprintf(stderr, "This is not a ZipCPU ELF file\n");
exit(EXIT_FAILURE);
}
 
// Get our entry address
entry = ehdr.e_entry;
 
 
// Now, let's go look at the program header
if (elf_getphdrnum(e, &n) != 0) {
fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
unsigned total_octets = 0, current_offset=0, current_section=0;
for(i=0; i<(int)n; i++) {
total_octets += sizeof(SECTION *)+sizeof(SECTION);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%x\n", "p_type", phdr.p_type);
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
total_octets += phdr.p_memsz;
}
 
char *d = (char *)malloc(total_octets + sizeof(SECTION)+sizeof(SECTION *));
memset(d, 0, total_octets);
 
SECTION **r = sections = (SECTION **)d;
current_offset = (n+1)*sizeof(SECTION *);
current_section = 0;
 
for(i=0; i<(int)n; i++) {
r[i] = (SECTION *)(&d[current_offset]);
 
if (gelf_getphdr(e, i, &phdr) != &phdr) {
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
exit(EXIT_FAILURE);
}
 
if (dbg) {
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
 
if (phdr.p_flags & PF_X) printf(" Execute");
if (phdr.p_flags & PF_R) printf(" Read");
if (phdr.p_flags & PF_W) printf(" Write");
printf("]\n");
 
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
}
 
current_section++;
 
r[i]->m_start = phdr.p_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-r\tStart the ZipCPU running from the address in the program file\n");
}
 
int main(int argc, char **argv) {
int skp=0;
bool start_when_finished = false;
unsigned entry = 0;
FLASHDRVR *flash = NULL;
const char *bitfile = NULL, *altbitfile = NULL;
 
if (argc < 2) {
usage();
exit(EXIT_SUCCESS);
}
 
skp=1;
for(int argn=0; argn<argc-skp; argn++) {
if (argv[argn+skp][0] == '-') {
switch(argv[argn+skp][1]) {
case 'h':
usage();
exit(EXIT_SUCCESS);
break;
case 'r':
start_when_finished = true;
break;
default:
fprintf(stderr, "Unknown option, -%c\n\n",
argv[argn+skp][0]);
usage();
exit(EXIT_FAILURE);
break;
} skp++; argn--;
} else {
// Anything here must be the program to load.
argv[argn] = argv[argn+skp];
}
} argc -= skp;
 
 
if (argc == 0) {
printf("No executable file given!\n\n");
usage();
exit(EXIT_FAILURE);
} if (access(argv[0],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]);
exit(EXIT_FAILURE);
}
 
const char *codef = (argc>0)?argv[0]:NULL;
DEVBUS::BUSW *fbuf = new DEVBUS::BUSW[FLASHWORDS];
 
// Set the flash buffer to all ones
memset(fbuf, -1, FLASHWORDS*sizeof(fbuf[0]));
 
m_fpga = FPGAOPEN(m_fpga);
 
// Make certain we can talk to the FPGA
try {
unsigned v = m_fpga->readio(R_VERSION);
if (v < 0x20161000) {
fprintf(stderr, "Could not communicate with board (invalid version)\n");
exit(EXIT_FAILURE);
}
} catch(BUSERR b) {
fprintf(stderr, "Could not communicate with board (BUSERR when reading VERSION)\n");
exit(EXIT_FAILURE);
}
 
// Halt the CPU
try {
unsigned v;
printf("Halting the CPU\n");
m_fpga->writeio(R_ZIPCTRL, CPU_HALT|CPU_RESET);
} catch(BUSERR b) {
fprintf(stderr, "Could not halt the CPU (BUSERR)\n");
exit(EXIT_FAILURE);
}
 
flash = new FLASHDRVR(m_fpga);
 
if (codef) try {
SECTION **secpp = NULL, *secp;
 
if(iself(codef)) {
// zip-readelf will help with both of these ...
elfread(codef, entry, secpp);
} else {
fprintf(stderr, "ERR: %s is not in ELF format\n", codef);
exit(EXIT_FAILURE);
}
 
printf("Loading: %s\n", codef);
// assert(secpp[1]->m_len = 0);
for(int i=0; secpp[i]->m_len; i++) {
bool valid = false;
secp= secpp[i];
 
// Make sure our section is either within block RAM
if ((secp->m_start >= MEMBASE)
&&(secp->m_start+secp->m_len
<= MEMBASE+MEMWORDS))
valid = true;
 
// Flash
if ((secp->m_start >= RESET_ADDRESS)
&&(secp->m_start+secp->m_len
<= EQSPIFLASH+FLASHWORDS))
valid = true;
 
// Or SDRAM
if ((secp->m_start >= RAMBASE)
&&(secp->m_start+secp->m_len
<= RAMBASE+RAMWORDS))
valid = true;
if (!valid) {
fprintf(stderr, "No such memory on board: 0x%08x - %08x\n",
secp->m_start, secp->m_start+secp->m_len);
exit(EXIT_FAILURE);
}
}
 
unsigned startaddr = RESET_ADDRESS, codelen = 0;
for(int i=0; secpp[i]->m_len; i++) {
secp = secpp[i];
if ( ((secp->m_start >= RAMBASE)
&&(secp->m_start+secp->m_len
<= RAMBASE+RAMWORDS))
||((secp->m_start >= MEMBASE)
&&(secp->m_start+secp->m_len
<= MEMBASE+MEMWORDS)) ) {
for(int i=0; (unsigned)i<secp->m_len; i++) {
m_fpga->writei(secp->m_start,
secp->m_len,
secp->m_data);
}
} else {
if (secp->m_start < startaddr) {
codelen += (startaddr-secp->m_start);
startaddr = secp->m_start;
} if (secp->m_start+secp->m_len > startaddr+codelen) {
codelen = secp->m_start+secp->m_len-startaddr;
} memcpy(&fbuf[secp->m_start-EQSPIFLASH],
secp->m_data,
secp->m_len*sizeof(FPGA::BUSW));
}
}
if ((flash)&&(!flash->write(startaddr, codelen, &fbuf[startaddr-EQSPIFLASH], true))) {
fprintf(stderr, "ERR: Could not write program to flash\n");
exit(EXIT_FAILURE);
} else if (!flash)
printf("flash->write(%08x, %d, ... );\n", startaddr,
codelen);
if (m_fpga) m_fpga->readio(R_VERSION); // Check for bus errors
 
// Now ... how shall we start this CPU?
if (start_when_finished) {
printf("Clearing the CPUs registers\n");
for(int i=0; i<32; i++) {
m_fpga->writeio(R_ZIPCTRL, CPU_HALT|i);
if (i == CPU_sPC)
m_fpga->writeio(R_ZIPDATA, entry);
else
m_fpga->writeio(R_ZIPDATA, 0);
}
 
m_fpga->writeio(R_CPUSCOPE, 25);
printf("Starting the CPU\n");
m_fpga->writeio(R_ZIPCTRL, CPU_HALT|CPU_CLRCACHE|CPU_RESET);
m_fpga->writeio(R_ZIPCTRL, CPU_GO|CPU_sPC);
} else {
printf("The CPU should be fully loaded, you may now\n");
printf("start it (from reset/reboot) with:\n");
printf("> wbregs cpu 0x40\n");
printf("\n");
}
} catch(BUSERR a) {
fprintf(stderr, "ARTY-BUS error: %08x\n", a.addr);
exit(-2);
}
 
printf("CPU Status is: %08x\n", m_fpga->readio(R_ZIPCTRL));
if (m_fpga) delete m_fpga;
 
return EXIT_SUCCESS;
}
 
/zipstate.cpp
0,0 → 1,143
////////////////////////////////////////////////////////////////////////////////
//
// Filename: zipstate.cpp
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: To get a quick (understandable) peek at what the ZipCPU
// is up to without stopping the CPU. This is basically
// identical to a "wbregs cpu" command, save that the bit fields of the
// result are broken out into something more human readable.
//
//
// 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
 
#include "port.h"
#include "llcomms.h"
#include "regdefs.h"
 
FPGA *m_fpga;
void closeup(int v) {
m_fpga->kill();
exit(0);
}
 
unsigned int cmd_read(FPGA *fpga, int r) {
const unsigned int MAXERR = 1000;
unsigned int errcount = 0;
unsigned int s;
 
fpga->writeio(R_ZIPCTRL, CPU_HALT|(r&0x03f));
while((((s = fpga->readio(R_ZIPCTRL))&CPU_STALL)== 0)&&(errcount<MAXERR))
errcount++;
if (errcount >= MAXERR) {
printf("ERR: errcount(%d) >= MAXERR on cmd_read(a=%02x)\n",
errcount, r);
printf("ZIPCTRL = 0x%08x", s);
if ((s & 0x0200)==0) printf(" STALL");
if (s & 0x0400) printf(" HALTED");
if ((s & 0x03000)==0x01000)
printf(" SW-HALT");
else {
if (s & 0x01000) printf(" SLEEPING");
if (s & 0x02000) printf(" GIE(UsrMode)");
} printf("\n");
exit(EXIT_FAILURE);
} return fpga->readio(R_ZIPDATA);
}
 
void usage(void) {
printf("USAGE: zipstate\n");
}
 
int main(int argc, char **argv) {
int skp=0, port = FPGAPORT;
bool long_state = false;
unsigned int v;
 
skp=1;
for(int argn=0; argn<argc-skp; argn++) {
if (argv[argn+skp][0] == '-') {
if (argv[argn+skp][1] == 'l')
long_state = true;
skp++; argn--;
} else
argv[argn] = argv[argn+skp];
} argc -= skp;
 
FPGAOPEN(m_fpga);
 
if (!long_state) {
v = m_fpga->readio(R_ZIPCTRL);
 
printf("0x%08x: ", v);
if (v & 0x0080) printf("PINT ");
// if (v & 0x0100) printf("STEP "); // self resetting
if((v & 0x00200)==0) printf("STALL ");
if (v & 0x00400) printf("HALTED ");
if((v & 0x03000)==0x01000) {
printf("SW-HALT");
} else {
if (v & 0x01000) printf("SLEEPING ");
if (v & 0x02000) printf("GIE(UsrMode) ");
}
// if (v & 0x0800) printf("CLR-CACHE ");
printf("\n");
} else {
printf("Reading the long-state ...\n");
for(int i=0; i<14; i++) {
printf("sR%-2d: 0x%08x ", i, cmd_read(m_fpga, i));
if ((i&3)==3)
printf("\n");
} printf("sCC : 0x%08x ", cmd_read(m_fpga, 14));
printf("sPC : 0x%08x ", cmd_read(m_fpga, 15));
printf("\n\n");
 
for(int i=0; i<14; i++) {
printf("uR%-2d: 0x%08x ", i, cmd_read(m_fpga, i+16));
if ((i&3)==3)
printf("\n");
} printf("uCC : 0x%08x ", cmd_read(m_fpga, 14+16));
printf("uPC : 0x%08x ", cmd_read(m_fpga, 15+16));
printf("\n\n");
}
 
delete m_fpga;
}
 
/zprog.sh
0,0 → 1,99
#!/bin/bash
################################################################################
##
## Filename: zprog.sh
##
## Project: OpenArty, an entirely open SoC based upon the Arty platform
##
## Purpose: To install a new program into the Arty, using the main
## programming slot (slot 0).
##
## 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
##
##
################################################################################
##
##
export PATH=$PATH:.
export BINFILE=../../xilinx/openarty.runs/impl_1/toplevel.bin
 
WBREGS=wbregs
WBPROG=wbprogram
 
#
# $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
$WBREGS stopwatch 0 # Stop the stopwatch, we are done
$WBREGS stopwatch # Print out the time on the stopwatch
 
$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
 
 
zprog.sh Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

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