Commit 23e580cd authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

tools: crude etherbone LM32 loader.

parent 66373fd6
OBJS = simple-eb.o lm32-etherboot.o
CFLAGS = -g -Ietherbone -I.
LDFLAGS = -Letherbone -letherbone
all: $(OBJS)
gcc -o lm32-etherboot $(OBJS) $(LDFLAGS)
\ No newline at end of file
/* CRAP CODE. DO NOT MERGE. DO NOT USE. */
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include "simple-eb.h"
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) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
return NULL;
}
if (fstat(fileno(f), &stbuf) < 0) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
fclose(f);
return NULL;
}
if (!S_ISREG(stbuf.st_mode)) {
fprintf(stderr, "%s: not a regular file\n", filename);
fclose(f);
return NULL;
}
buf = malloc(stbuf.st_size);
if (!buf) {
fprintf(stderr, "loading %s: %s\n", filename, strerror(errno));
fclose(f);
return NULL;
}
i = fread(buf, 1, stbuf.st_size, f);
fclose(f);
if (i < 0) {
fprintf(stderr, "reading %s: %s\n", filename, strerror(errno));
free(buf);
return NULL;
}
if (i != stbuf.st_size) {
fprintf(stderr, "%s: short read\n", filename);
free(buf);
return NULL;
}
*size = stbuf.st_size;
return buf;
}
int eb_load_lm32(eb_device_t dev, 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 */
ebs_write(dev, base_addr + 0x20400, 0x1deadbee);
while ( ! (ebs_read(dev, base_addr + 0x20400) & (1<<28)) );
ibuf = (uint32_t *) buf;
for (i = 0; i < (size + 3) / 4; i++)
ebs_write(dev, base_addr + i*4, htonl(ibuf[i]));
for (i = 0; i < (size + 3) / 4; i++) {
uint32_t r = ebs_read(dev, 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;
}
}
ebs_write(dev, base_addr + 0x20400, 0x0deadbee);
return 0;
}
main(int argc, char *argv[])
{
if(argc < 3) {
printf("usage: %s address file.bin\n", argv[0]);
return 0;
}
eb_device_t dev;
ebs_init();
ebs_open(&dev, argv[1]);
eb_load_lm32(dev, argv[2], 0xc0000);
ebs_close(dev);
ebs_shutdown();
return 0;
}
\ No newline at end of file
/*
* main.c
*
* Created on: Aug 10, 2012
* Author: bbielawski
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>
#include "etherbone.h"
static eb_socket_t socket;
static inline void process_result(eb_status_t result)
{
if (result != EB_OK)
{
printf("Error: %s\n", eb_status(result));
// exit(1);
}
return;
}
eb_status_t ebs_block_write(eb_device_t device, eb_address_t address, eb_data_t* data, int count, int autoincrement_address)
{
int write_done = 0;
void wr_callback(eb_user_data_t data, eb_device_t device, eb_operation_t operation, eb_status_t status)
{
write_done = 1;
}
eb_cycle_t cycle;
eb_status_t status = eb_cycle_open(device, NULL, wr_callback, &cycle);
if (status != EB_OK)
return status;
int i;
for (i = 0; i < count; i++)
{
eb_cycle_write(cycle, address, EB_DATA32 | EB_LITTLE_ENDIAN, data[i]);
if (autoincrement_address)
address += 4;
}
eb_cycle_close(cycle);
status = eb_device_flush(device);
while (!write_done) eb_socket_run(socket, 10); //wait forever
return status;
}
eb_status_t ebs_block_read(eb_device_t device, eb_address_t read_address, eb_data_t *rdata, int count, int autoincrement_address)
{
int read_done = 0;
void rd_callback(eb_user_data_t data, eb_device_t device, eb_operation_t op, eb_status_t status)
{
static int c = 0;
if (status != EB_OK)
{
fprintf(stderr, "read failed: %s\n", eb_status(status));
exit(-1);
}
for(; op != EB_NULL; op = eb_operation_next(op)) {
/* We read low bits first */
*rdata++ = eb_operation_data(op);
}
read_done = 1;
}
eb_cycle_t cycle;
eb_status_t status = eb_cycle_open(device, NULL, rd_callback, &cycle);
if (status != EB_OK)
return status;
int i;
for (i = 0; i < count; i++)
{
eb_cycle_read(cycle, read_address, EB_DATA32 | EB_LITTLE_ENDIAN, NULL);
if(autoincrement_address)
read_address += 4;
}
eb_cycle_close(cycle);
status = eb_device_flush(device);
while (!read_done) eb_socket_run(socket, -1); //wait forever
return status;
}
uint32_t ebs_read(eb_device_t device, eb_address_t addr)
{
eb_data_t rdata;
ebs_block_read(device, addr, &rdata, 1, 0);
return rdata;
}
void ebs_write(eb_device_t device, eb_address_t addr, eb_data_t data)
{
ebs_block_write(device, addr, &data, 1, 0);
}
eb_status_t ebs_init()
{
eb_status_t status = EB_OK;
status = eb_socket_open(EB_ABI_CODE, 0, EB_DATA32 | EB_ADDR32, &socket);
process_result(status);
}
eb_status_t ebs_shutdown()
{
return eb_socket_close(socket);
}
eb_status_t ebs_open(eb_device_t *dev, const char *network_address)
{
eb_status_t status = EB_OK;
status = eb_device_open(socket, network_address, EB_DATA32 | EB_ADDR32, 5, dev);
process_result(status);
return status;
}
eb_status_t ebs_close(eb_device_t dev)
{
return eb_device_close(dev);
}
struct bus_record {
int i;
int stop;
eb_address_t addr_first, addr_last;
struct bus_record* parent;
};
int ebs_sdb_find_device(eb_device_t dev, uint32_t vendor, uint32_t device, int seq, uint32_t *base_addr)
{
struct bus_record br;
int done = 0, found = 0, n = 0;
void scan_cb(eb_user_data_t user, eb_device_t dev, sdb_t sdb, eb_status_t status) {
struct bus_record br;
int devices;
br.parent = (struct bus_record*)user;
br.parent->stop = 1;
if (status != EB_OK) {
fprintf(stderr, "failed to retrieve SDB: %s\n", eb_status(status));
exit(1);
}
devices = sdb->interconnect.sdb_records - 1;
for (br.i = 0; br.i < devices; ++br.i) {
sdb_record_t des;
des = &sdb->record[br.i];
if(des->empty.record_type == sdb_device)
{
if(des->device.sdb_component.product.vendor_id == vendor &&
des->device.sdb_component.product.device_id == device)
{
if(n == seq)
{
*base_addr = des->device.sdb_component.addr_first;
found = 1;
return;
}
n ++;
}
}
}
done = 1;
}
br.parent = 0;
br.i = -1;
br.stop = 0;
br.addr_first = 0;
br.addr_last = ~(eb_address_t)0;
br.addr_last >>= (sizeof(eb_address_t) - (eb_device_width(dev) >> 4))*8;
if(eb_sdb_scan_root(dev, &br, &scan_cb) != EB_OK)
return -1;
while(!done && !found) // fixme: crap code
eb_socket_run(eb_device_socket(dev), -1);
return found;
}
#if 0
main()
{
eb_device_t dev;
uint32_t base;
ebs_init();
ebs_open(&dev, "udp/192.168.10.11");
ebs_sdb_find_device(dev, 0xce42, 0xf19ede1a, 0, &base);
printf("base addr: %x\n", base);
}
#endif
#ifndef __SIMPLE_EB_H
#define __SIMPLE_EB_H
#include <stdint.h>
#include "etherbone.h"
eb_status_t ebs_block_write(eb_device_t device, eb_address_t address, eb_data_t* data, int count, int autoincrement_address);
eb_status_t ebs_block_read(eb_device_t device, eb_address_t read_address, eb_data_t *rdata, int count, int autoincrement_address);
uint32_t ebs_read(eb_device_t device, eb_address_t addr);
void ebs_write(eb_device_t device, eb_address_t addr, eb_data_t data);
eb_status_t ebs_init();
eb_status_t ebs_shutdown();
eb_status_t ebs_open(eb_device_t *dev, const char *network_address);
eb_status_t ebs_close(eb_device_t dev);
int ebs_sdb_find_device(eb_device_t dev, uint32_t vendor, uint32_t device, int seq, uint32_t *base_addr);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment