Commit df31f748 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

software: removed obsolete sveclib

parent 5fe127e2
*.o
svec-cl
svec-fwloader
svec-vuart
OBJS=sveclib.o libvmebus.o
CFLAGS=-I. -Wall
CC=gcc
all: cl fwloader vuart
cl: svec-cl.o $(OBJS)
gcc -o svec-cl $(OBJS) svec-cl.o
fwloader: svec-fwloader.o $(OBJS)
gcc -o svec-fwloader $(OBJS) svec-fwloader.o
vuart: svec-vuart.o $(OBJS)
gcc -o svec-vuart $(OBJS) svec-vuart.o
clean:
rm -f *.o svec-cl svec-test svec-fwloader svec-vuart
\ No newline at end of file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!! WARNING !!!!!!!!
!!!!!!!! DEVELOPER USE ONLY !!!!!!!!
!!!!!!!! DO NOT DEPLOY IN PRODUCTION ENVIRONMENTS !!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
sveclib - a tiny userspace library (and a set of tools) allowing developers to play with the svec.
The library provides:
- raw I/O to a spec in particular slot (uses geographical addressing). Currently, there's
a fixed A32/D32/SINGLE mapping available and the memory can be accesed by calling
svec_writel()/svec_readl()
- application FPGA firmware loader (svec-fwloader)
- LM32 CPU firmware loader (svec-cl)
- WR Core virtual UART console (svec-vuart)
All these tools require the slot location to be specified with -b command line switch.
Requirements: Requires vmebus driver to be installed (tested on MEN A20).
Compilation: just run make.
\ No newline at end of file
/*
* A tool to program our soft-core (LM32) within the SVEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "sveclib.h"
int main(int argc, char **argv)
{
int bus = -1, c;
uint32_t lm32_base = 0x00000;
void *card;
while ((c = getopt (argc, argv, "b:c:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'c':
sscanf(optarg, "%i", &lm32_base);
break;
default:
fprintf(stderr,
"Use: \"%s [-b slot] [-c lm32 base address] <lm32_program.bin>\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SVEC is used and the LM32 is assumed at 0x%x.\n", lm32_base);
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
card = svec_open(bus);
if(!card)
{
fprintf(stderr, "Can't detect a SVEC card under the given adress. Make sure a SVEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
fprintf(stderr,"Loading..\n");
if(svec_load_lm32(card, argv[optind], lm32_base) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
svec_close(card);
exit (0);
}
/*
* A tool to program the FPGA within the SPEC.
*
* Alessandro Rubini 2012 for CERN, GPLv2 or later.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include "sveclib.h"
int main(int argc, char **argv)
{
int bus = -1, c;
void *card;
while ((c = getopt (argc, argv, "b:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
default:
fprintf(stderr,
"Use: \"%s -b slot <fpga_bitstream.bin>\"\n", argv[0]);
exit(1);
}
}
if (optind >= argc) {
fprintf(stderr, "Expected binary name after options.\n");
exit(1);
}
if(bus < 0)
{
fprintf(stderr, "You must specify the slot number.\n");
return -1;
}
card = svec_open(bus);
if(!card)
{
fprintf(stderr, "Can't detect a SVEC card under the given adress. Make sure a SVEC card is present in your PC and the driver is loaded.\n");
exit(1);
}
if(svec_load_bitstream(card, argv[optind]) < 0)
{
fprintf(stderr, "Loader failure.\n");
exit(1);
}
svec_close(card);
exit (0);
}
#include <stdio.h>
#include "sveclib.h"
int main()
{
void *card =svec_open(8);
svec_writel(card, 0x1deadbee, 0x20400);
printf("readback:%x\n", svec_readl(card, 0x20400));
}
\ No newline at end of file
/* A simple console for accessing the SVEC virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <errno.h>
#include "sveclib.h"
static void *card;
static int transfer_byte(int from, int is_control) {
char c;
int ret;
do {
ret = read(from, &c, 1);
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
}
}
svec_vuart_tx(card, &c, 1);
} else {
fprintf(stderr, "\nnothing to read. probably port disconnected.\n");
return -2;
}
return 0;
}
void term_main(int keep_term)
{
struct termios oldkey, newkey; //place tor old and new port settings for keyboard teletype
int need_exit = 0;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
fd_set fds;
int ret;
char rx;
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
ret = select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, 1);
}
}
while((svec_vuart_rx(card, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
}
if(!keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
}
int main(int argc, char **argv)
{
int bus = -1, c;
uint32_t vuart_base = 0x20500;
int keep_term = 0;
while ((c = getopt (argc, argv, "b:u:k")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'u':
sscanf(optarg, "%i", &vuart_base);
break;
case 'k':
keep_term = 1;
break;
default:
fprintf(stderr,
"Use: \"%s [-b slot] [-u VUART base] [-k]\"\n", argv[0]);
fprintf(stderr,
"By default, the VUART is assumed at 0x%x.\n \
-k option keeps the terminal config unchanged.\n", vuart_base);
exit(1);
}
}
if(bus < 0)
{
fprintf(stderr, "Missing slot number.\n");
return -1;
}
card = svec_open(bus);
if(!card)
{
fprintf(stderr, "Can't detect a SVEC card under the given adress. Make sure a SVEC card is present in your PC and the driver is loaded.\n");
return -1;
}
svec_vuart_init(card, vuart_base);
term_main(keep_term);
svec_close(card);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "libvmebus.h"
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/signal.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include "sveclib.h"
#include "xloader_regs.h"
#include "wb_uart.h"
#define BASE_LOADER 0x70000
struct svec_private {
int slot;
void *base;
struct vme_mapping mapping;
uint32_t vuart_base;
};
void *svec_open(int slot)
{
struct svec_private *card = malloc(sizeof(struct svec_private));
if(!card)
return NULL;
struct vme_mapping *mapping = &card->mapping;
card->slot = slot;
mapping->am = 0x9;
mapping->data_width = VME_D32;
mapping->vme_addru = 0;
mapping->vme_addrl = (slot*2) * 0x80000;
mapping->sizeu = 0;
mapping->sizel = 0x80000;
mapping->read_prefetch_enabled = 0;
mapping->bcast_select = 0;
mapping->window_num = 0;
card->base = vme_map(mapping, 0);
if(!card->base)
{
fprintf(stderr, "mapping base I/O space failed\n");
// free(card);
// return NULL;
}
return card;
}
void svec_close(void *card)
{
struct svec_private *p = (struct svec_private *) card;
if(!card)
return;
vme_unmap(&p->mapping, 0);
free(card);
}
void svec_writel(void *card, uint32_t data, uint32_t addr)
{
struct svec_private *p = (struct svec_private *) card;
*(volatile uint32_t *) (p->base + addr) = swapbe32(data);
}
uint32_t svec_readl(void *card, uint32_t addr)
{
struct svec_private *p = (struct svec_private *) card;
uint32_t rv = swapbe32(*(volatile uint32_t *) (p->base + addr));
// printf("readl: addr %x data %x\n", addr, rv);
return rv;
}
static inline void csr_writel(void *csr, uint32_t data, uint32_t addr)
{
*(volatile uint32_t *) (csr + addr) = swapbe32(data);
}
static inline uint32_t csr_readl(void *csr, uint32_t addr)
{
uint32_t rv = swapbe32(*(volatile uint32_t *) (csr + addr));
return rv;
}
static char *load_binary_file(const char *filename, size_t *size)
{
int i;
struct stat stbuf;
char *buf;
FILE *f;
f = fopen(filename, "r");
if (!f)
return NULL;
if (fstat(fileno(f), &stbuf))
{
fclose(f);
return NULL;
}
if (!S_ISREG(stbuf.st_mode))
{
fclose(f);
return NULL;
}
buf = malloc(stbuf.st_size);
if (!buf)
{
fclose(f);
return NULL;
}
i = fread(buf, 1, stbuf.st_size, f);
if (i < 0) {
fclose(f);
free(buf);
return NULL;
}
if (i != stbuf.st_size) {
fclose(f);
free(buf);
return NULL;
}
fclose(f);
*size = stbuf.st_size;
return buf;
}
int svec_load_lm32(void *card, const char *filename, uint32_t base_addr)
{
char *buf;
uint32_t *ibuf;
size_t size;
int i;
buf = load_binary_file(filename, &size);
if(!buf)
return -1;
/* Phew... we are there, finally */
svec_writel(card, 0x1deadbee, base_addr + 0x20400);
while ( ! (svec_readl(card, base_addr + 0x20400) & (1<<28)) );
ibuf = (uint32_t *) buf;
for (i = 0; i < (size + 3) / 4; i++)
{
// fprintf(stderr, "i %x\n", i);
svec_writel(card, htonl(ibuf[i]), base_addr + i*4);
}
sync();
for (i = 0; i < (size + 3) / 4; i++) {
uint32_t r = svec_readl(card, base_addr + i * 4);
if (r != htonl(ibuf[i]))
{
fprintf(stderr, "programming error at %x "
"(expected %08x, found %08x)\n", i*4,
htonl(ibuf[i]), r);
return -1;
}
}
sync();
svec_writel(card, 0x0deadbee, base_addr + 0x20400);
return 0;
}
int svec_load_bitstream(void *card, const char *filename)
{
struct svec_private *p = (struct svec_private *) card;
int i = 0;
const uint32_t boot_seq[8] = {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe};
const char svec_idr[4] = "SVEC";
char idr[5];
uint32_t *buf;
size_t size;
void *csr;
struct vme_mapping mapping;
buf = (uint32_t * )load_binary_file(filename, &size);
if(!buf)
return -1;
mapping.am = 0x2f; /* CS/CSR space */
mapping.data_width = VME_D32;
mapping.vme_addru = 0;
mapping.vme_addrl = p->slot * 0x80000;
mapping.sizeu = 0;
mapping.sizel = 0x80000;
mapping.read_prefetch_enabled = 0;
mapping.bcast_select = 0;
mapping.window_num = 0;
csr = vme_map(&mapping, 0);
if(!csr)
{
fprintf(stderr,"Mapping CSR space failed.\n");
return -1;
free(buf);
}
/* magic sequence: unlock bootloader mode, disable application FPGA */
for(i=0;i<8;i++)
csr_writel(csr, boot_seq[i], BASE_LOADER + XLDR_REG_BTRIGR);
/* check if we are really talking to a SVEC */
uint32_t idc = csr_readl(csr, BASE_LOADER + XLDR_REG_IDR);
idr[0] = (idc >> 24) & 0xff;
idr[1] = (idc >> 16) & 0xff;
idr[2] = (idc >> 8) & 0xff;
idr[3] = (idc >> 0) & 0xff;
idr[4] = 0;
printf("IDCode: '%s'\n", idr);
if(strncmp(idr, svec_idr, 4))
{
fprintf(stderr,"Invalid IDCode value. \n");
free(buf);
return -1;
}
csr_writel(csr, XLDR_CSR_SWRST, BASE_LOADER + XLDR_REG_CSR);
csr_writel(csr, XLDR_CSR_START | XLDR_CSR_MSBF, BASE_LOADER + XLDR_REG_CSR);
while(i < size) {
if(! (csr_readl(csr, BASE_LOADER + XLDR_REG_FIFO_CSR) & XLDR_FIFO_CSR_FULL)) {
int n = (size-i>4?4:size-i);
csr_writel(csr, (n - 1) | ((n<4) ? XLDR_FIFO_R0_XLAST : 0), BASE_LOADER + XLDR_REG_FIFO_R0);
csr_writel(csr, htonl(buf[i>>2]), BASE_LOADER + XLDR_REG_FIFO_R1);
i+=n;
}
}
free(buf);
while(1)
{
uint32_t rval = csr_readl(csr, BASE_LOADER + XLDR_REG_CSR);
if(rval & XLDR_CSR_DONE) {
printf("Bitstream loaded, status: %s\n", (rval & XLDR_CSR_ERROR ? "ERROR" : "OK"));
/* give the VME bus control to App FPGA */
csr_writel(csr, XLDR_CSR_EXIT, BASE_LOADER + XLDR_REG_CSR);
vme_unmap(&mapping, 0);
return rval & XLDR_CSR_ERROR ? -1 : 0;
}
}
return -1;
};
static int vuart_rx(void *card)
{
struct svec_private *p = (struct svec_private *) card;
int rdr = svec_readl(card, p->vuart_base + UART_REG_HOST_RDR);
if(rdr & UART_HOST_RDR_RDY)
return UART_HOST_RDR_DATA_R(rdr);
else
return -1;
}
static void vuart_tx(void *card, int c)
{
struct svec_private *p = (struct svec_private *) card;
while( svec_readl(card, p->vuart_base + UART_REG_SR) & UART_SR_RX_RDY);
svec_writel(card, UART_HOST_TDR_DATA_W(c), p->vuart_base + UART_REG_HOST_TDR);
}
int svec_vuart_init(void *card, uint32_t base_addr)
{
struct svec_private *p = (struct svec_private *) card;
p->vuart_base = base_addr;
return 0;
}
size_t svec_vuart_rx(void *card, char *buffer, size_t size)
{
size_t s = size, n_rx = 0;
while(s--)
{
int c = vuart_rx(card);
if(c < 0)
return n_rx;
*buffer++ = (char) c;
n_rx ++;
}
return n_rx;
}
size_t svec_vuart_tx(void *card, char *buffer, size_t size)
{
size_t s = size;
while(s--)
vuart_tx(card, *buffer++);
return size;
}
#ifndef __SVECLIB_H
#define __SVECLIB_H
#include <stdint.h>
/* 'Opens' the SVEC card at VME slot [slot].
Returns a handle to the card or NULL in case of failure. */
void *svec_open(int slot);
/* Closes the SVEC handle [card] */
void svec_close(void *card);
/* Loads the FPGA bitstream into card [card] from file [filename].
Returns 0 on success. */
int svec_load_bitstream(void *card, const char *filename);
/* Loads the WRC LM32 firmware into card [card] from file [filename]. starting at
address [base_addr]. Returns 0 on success.
WARNING: using improper base address/FPGA firmware will freeze the computer. */
int svec_load_lm32(void *card, const char *filename, uint32_t base_addr);
/* Raw I/O to BAR4 (Wishbone) */
void svec_writel(void *card, uint32_t data, uint32_t addr);
uint32_t svec_readl(void *card, uint32_t addr);
/* Initializes a virtual UART at base address [base_addr]. */
int svec_vuart_init(void *card, uint32_t base_addr);
/* Virtual uart Rx (VUART->Host) and Tx (Host->VUART) functions */
size_t svec_vuart_rx(void *card, char *buffer, size_t size);
size_t svec_vuart_tx(void *card, char *buffer, size_t size);
int svec_flash_read(void *card, int flash_id, uint32_t offset, void *buffer, uint32_t size);
int svec_flash_write(void *card, int flash_id, uint32_t offset, void *buffer, uint32_t size);
int svec_flash_protect(void *card, int flash_id, uint32_t offset, uint32_t size, int on_off);
#endif
/*
Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Thu May 3 17:36:38 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#define __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */