URL
https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk
Subversion Repositories xulalx25soc
[/] [xulalx25soc/] [trunk/] [sw/] [ziprun.cpp] - Rev 25
Go to most recent revision | Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////////////// // // Filename: ziprun.cpp // // Project: XuLA2 board // // Purpose: To load a program for the ZipCPU into memory. // // Steps: // 1. Halt and reset the CPU // 2. Load memory // 3. Clear the cache // 4. Clear any registers // 5. Set the PC to point to the FPGA local memory // THIS DOES NOT START THE PROGRAM!! The CPU is left in the halt state. // To actually start the program, execute a ./wbregs cpu 0. (Actually, // any value between 0x0 and 0x1f will work, the difference being what // register you will be able to inspect while the CPU is running.) // // // Creator: Dan Gisselquist, Ph.D. // Gisselquist Technology, LLC // //////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015, 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. // // 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 "usbi.h" #include "port.h" #include "regdefs.h" FPGA *m_fpga; int main(int argc, char **argv) { FILE *fp; int nr, pos=0; const int BUFLN = 128; FPGA::BUSW *buf = new FPGA::BUSW[BUFLN]; int skp=0, port = FPGAPORT; bool use_usb = true; 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; if (use_usb) m_fpga = new FPGA(new USBI()); else m_fpga = new FPGA(new NETCOMMS(FPGAHOST, port)); if ((argc<=0)||(access(argv[0],R_OK)!=0)) { printf("Usage: ziprun obj-file\n"); printf("\n" "\tziprun loads the object file into memory, resets the CPU, and leaves it\n" "\tin a halted state ready to start running the object file.\n"); exit(-1); } printf("Halting the CPU\n"); m_fpga->usleep(5); m_fpga->writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT); fp = fopen(argv[0], "r"); if (fp == NULL) { fprintf(stderr, "Could not open: %s\n", argv[0]); exit(-1); } try { pos = RAMBASE; while((nr=fread(buf, sizeof(FPGA::BUSW), BUFLN, fp))>0) { // printf("Writing %4d values, pos = %08x\n", nr, pos); m_fpga->writei(pos, nr, buf); // printf("\tWritten\n"); pos += nr; } printf("Successfully wrote %04x (%6d) words into memory\n", pos-RAMBASE, pos-RAMBASE); m_fpga->readio(R_ZIPCTRL); // Do we want to zero out all other RAM addresses? #define ZERO_RAM #ifdef ZERO_RAM unsigned int MAXRAM=2*RAMBASE; for(int i=0; i<BUFLN; i++) buf[i] = 0; printf("***********************\n"); while(pos < (int)MAXRAM-BUFLN-1) { m_fpga->writei(pos, BUFLN, buf); m_fpga->readio(R_ZIPCTRL); pos += BUFLN; } m_fpga->writei(pos, MAXRAM-pos-1, buf); pos += MAXRAM-pos-1; m_fpga->usleep(500); printf("Zerod rest of RAM - to %06x\n", pos); #endif } catch(BUSERR a) { fprintf(stderr, "BUS Err at address 0x%08x\n", a.addr); fprintf(stderr, "... is your program too long for this memory?\n"); m_fpga->writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT|CPU_CLRCACHE); exit(-2); } try { m_fpga->readio(R_ZIPCTRL); } catch(BUSERR a) { fprintf(stderr, "Bus-Err? (%08x)\n", a.addr); } // Clear any buffers printf("Clearing the cache\n"); m_fpga->writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT|CPU_CLRCACHE); printf("Clearing all registers to zero, PC regs to MEMBASE\n"); // Clear all registers to zero for(int i=0; i<32; i++) { try { m_fpga->writeio(R_ZIPCTRL, CPU_HALT|i); m_fpga->readio(R_ZIPCTRL); } catch(BUSERR a) { fprintf(stderr, "Bus-ERR while trying to set CPUCTRL to %x\n", CPU_HALT|i); } try { if ((i&0x0f)==0x0f) m_fpga->writeio(R_ZIPDATA, RAMBASE); else m_fpga->writeio(R_ZIPDATA, 0); // printf("REG[%2x] <= %08x\n", i, ((i&0x0f)==0x0f)?RAMBASE:0); // m_fpga->readio(R_ZIPDATA); // printf("\t= %08x\n", m_fpga->readio(R_ZIPDATA)); } catch(BUSERR a) { fprintf(stderr, "Bus-ERR while trying to clear reg %x\n", i); } } printf("Clearing all peripherals\n"); for(int i=32; i<32+16; i++) { try { if (i==33) continue; // Don't start the watchdog if (i==34) continue; // Don't start the flash cache if (i==39) continue; // Jiffies don't clear, don't set the intrupt m_fpga->writeio(R_ZIPCTRL, CPU_HALT|i); m_fpga->writeio(R_ZIPDATA, 0); } catch (BUSERR a) { fprintf(stderr, "Bus-ERR while trying to clear peripheral %d\n", i); } } printf("Starting CPU\n"); try { m_fpga->writeio(R_ZIPCTRL, CPU_HALT|CPU_sCC); // Start in interrupt mode m_fpga->writeio(R_ZIPDATA, 0x000); printf("SCC <= 0x%08x\n", m_fpga->readio(R_ZIPDATA)); } catch (BUSERR a) { fprintf(stderr, "Bus Err while trying to set CC register\n"); } try { m_fpga->writeio(R_ZIPCTRL, CPU_HALT|CPU_sPC); printf("CPU <= 0x%08x\n", m_fpga->readio(R_ZIPCTRL)); m_fpga->writeio(R_ZIPDATA, RAMBASE); // Start at the base of RAM printf("SPC <= 0x%08x\n", m_fpga->readio(R_ZIPDATA)); } catch (BUSERR a) { fprintf(stderr, "Bus Err while trying to set PC register\n"); } printf("PC set to start at %08x\n", m_fpga->readio(R_ZIPDATA)); // m_fpga->writeio(R_ZIPCTRL, CPU_GO); // Release the CPU to start delete m_fpga; }
Go to most recent revision | Compare with Previous | Blame | View Log