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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [sw/] [ziprun.cpp] - Rev 5

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);
	}
 
	// FPGAOPEN(m_fpga);
 
	printf("Halting the CPU\n");
	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++) {
		unsigned int	v;
		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);
		}
	} 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

powered by: WebSVN 2.1.0

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