Commit 0371a420 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'lm32-elf-loader'

parents 9e31590c 1bb48fcb
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
@setchapternewpage off @setchapternewpage off
@set update-month August 2014 @set update-month September 2014
@c the release name below is substituted at build time @c the release name below is substituted at build time
@set release __RELEASE_GIT_ID__ @set release __RELEASE_GIT_ID__
...@@ -1346,8 +1346,11 @@ The most important tools in @file{userspace/tools} are the following: ...@@ -1346,8 +1346,11 @@ The most important tools in @file{userspace/tools} are the following:
@itemx load-lm32 @itemx load-lm32
They load into the FPGA the gateware and the LM32 application. They load into the FPGA the gateware and the LM32 application.
They are used by the init scripts of the Linux system. They are used by the init scripts of the Linux system. The LM32
loader can also change variables in the loaded binary, and
read or write variables without stopping the running CPU.
This is limited to 32-bit integer variaables, though. See the
commit message for details.
@item mapper @item mapper
@itemx wmapper @itemx wmapper
......
...@@ -59,7 +59,7 @@ spll_dbg_proxy: spll_dbg_proxy.o ...@@ -59,7 +59,7 @@ spll_dbg_proxy: spll_dbg_proxy.o
load-virtex: load-virtex.o load-fpga.o load-virtex: load-virtex.o load-fpga.o
${CC} -o $@ $^ $(LDFLAGS) ${CC} -o $@ $^ $(LDFLAGS)
load-lm32: load-lm32.o lm32-loader.o load-lm32: load-lm32.o
${CC} -o $@ $^ $(LDFLAGS) ${CC} -o $@ $^ $(LDFLAGS)
wrsw_version.o: wrsw_version.c wrsw_version.o: wrsw_version.c
......
extern int load_lm32_main(char *fname);
extern int load_fpga_main(char *fname); extern int load_fpga_main(char *fname);
/*
* Copyright (c) 2011 Grzegorz Daniluk <g.daniluk@elproma.com.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define BASE_FPGA 0x10000000
#define SIZE_FPGA 0x20000
#define LM32_RAM_BASE 0x0
#define GPIO_BASE 0x10300
#define GPIO_COR 0x0
#define GPIO_SOR 0x4
#define LM32_RESET_PIN 2
static void *base_fpga;
static void fpga_writel(uint32_t data, uint32_t addr)
{
*(volatile uint32_t *)(base_fpga + addr) = data;
}
static uint32_t fpga_readl(uint32_t addr)
{
return *(volatile uint32_t *)(base_fpga + addr);
}
int conv_endian(int x)
{
return ((x&0xff000000)>>24)
+ ((x&0x00ff0000)>>8)
+ ((x&0x0000ff00)<<8)
+ ((x&0x000000ff)<<24);
}
void rst_lm32(int rst)
{
fpga_writel(1 << LM32_RESET_PIN,
GPIO_BASE + (rst ? GPIO_SOR : GPIO_COR));
}
void copy_lm32(uint32_t *buf, int buf_nwords, uint32_t base_addr)
{
int i;
printf("Writing memory: ");
for(i=0;i<buf_nwords;i++)
{
fpga_writel(conv_endian(buf[i]), base_addr + i *4);
if(!(i & 0xfff)) { printf("."); fflush(stdout); }
}
printf("\nVerifing memory: ");
for(i=0;i<buf_nwords;i++)
{
uint32_t x = fpga_readl(base_addr+ i*4);
if(conv_endian(buf[i]) != x)
{
printf("Verify failed (%x vs %x)\n", conv_endian(buf[i]), x);
return ;
}
if(!(i & 0xfff)) { printf("."); fflush(stdout); }
}
printf("OK.\n");
}
int load_lm32_child(char *fname)
{
uint32_t *buf;
FILE *f;
int fdmem;
/* /dev/mem for mmap of both gpio and spi1 */
if ((fdmem = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: /dev/mem: %s\n", __func__,
strerror(errno));
exit(1);
}
/* map a whole page (4kB, but we called getpagesize to know it) */
base_fpga = mmap(0, SIZE_FPGA, PROT_READ | PROT_WRITE,
MAP_SHARED, fdmem,
BASE_FPGA);
if (base_fpga == MAP_FAILED) {
fprintf(stderr, "%s: mmap(/dev/mem): %s\n",
__func__, strerror(errno));
exit(1);
}
f=fopen(fname,"rb");
if(!f)
{
fprintf(stderr, "Input file not found.\n");
return -1;
}
fseek(f, 0, SEEK_END);
int size = ftell(f);
rewind(f);
buf = malloc(size + 4);
fread(buf, 1, size, f);
fclose(f);
rst_lm32(1);
copy_lm32(buf, (size + 3) / 4, 0);
rst_lm32(0);
// mbn_stats(mb_handle);
return 0;
}
int load_lm32_main(char *fname)
{
int pid = fork();
int status;
switch(pid) {
case -1:
fprintf(stderr, "fork(): %s\n", strerror(errno));
return -1;
case 0: /* child */
load_lm32_child(fname);
exit(0);
default: /* parent */
waitpid(pid, &status, 0);
if (!WEXITSTATUS(status))
return 0;
return -1;
}
}
...@@ -171,7 +171,7 @@ static int load_fpga_child(char *fname) ...@@ -171,7 +171,7 @@ static int load_fpga_child(char *fname)
/* enable SSC controller clock */ /* enable SSC controller clock */
__PMC(AT91_PMC_PCER) = 1<<AT91SAM9G45_ID_SSC0; __PMC(AT91_PMC_PCER) = 1<<AT91SAM9G45_ID_SSC0;
__SSC(AT91_SSC_CR) = AT91_SSC_SWRST; __SSC(AT91_SSC_CR) = AT91_SSC_SWRST;
__SSC(AT91_SSC_CR) = 0; __SSC(AT91_SSC_CR) = 0;
...@@ -313,7 +313,8 @@ int load_fpga_main(char *fname) ...@@ -313,7 +313,8 @@ int load_fpga_main(char *fname)
fprintf(stderr, "fork(): %s\n", strerror(errno)); fprintf(stderr, "fork(): %s\n", strerror(errno));
return -1; return -1;
case 0: /* child */ case 0: /* child */
load_fpga_child(fname); if (load_fpga_child(fname))
exit(1);
exit(0); exit(0);
default: /* parent */ default: /* parent */
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
......
/*
* Copyright (c) 2011 Grzegorz Daniluk <g.daniluk@elproma.com.pl>
* ELF support added by Alessandro Rubini for CERN, 2014
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <stdio.h> #include <stdio.h>
#include "libtools.h" #include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <elf.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <arpa/inet.h> /* htonl */
#define BASE_FPGA 0x10000000
#define SIZE_FPGA 0x20000
#define LM32_RAM_BASE 0x0
#define GPIO_BASE 0x10300
#define GPIO_COR 0x0
#define GPIO_SOR 0x4
#define LM32_RESET_PIN 2
static void *base_fpga;
static char *prgname;
static void fpga_writel(uint32_t data, uint32_t addr)
{
*(volatile uint32_t *)(base_fpga + addr) = data;
}
static uint32_t fpga_readl(uint32_t addr)
{
return *(volatile uint32_t *)(base_fpga + addr);
}
/* The original "conv_endian" was bound to 32 bits. This is any-size */
#define BE(datum) \
({ __typeof__(datum) result; \
switch(sizeof(datum)) { \
case 1: result = (datum); break; \
case 2: result = htons((datum)); break; \
case 4: result = htonl((datum)); break; \
default: kill(getpid(), SIGUSR1); \
} \
result; \
})
static void rst_lm32(int rst)
{
fpga_writel(1 << LM32_RESET_PIN,
GPIO_BASE + (rst ? GPIO_SOR : GPIO_COR));
}
static int copy_lm32(void *data, int noload, int size, uint32_t base_addr)
{
int i;
uint32_t *buf = data; /* be 32-bit oriented in writing */
int buf_nwords = (size + 3) / 4;
/* Do not actually load anything. This is used to read/write variables */
if (noload)
return 0;
printf("Writing memory (0x%04x bytes at 0x%04x): ", size, base_addr);
for(i=0;i<buf_nwords;i++)
{
fpga_writel(BE(buf[i]), base_addr + i *4);
if(!(i & 0xfff))
printf(".");
}
printf("\nVerifing memory: ");
for(i=0;i<buf_nwords;i++)
{
uint32_t x = fpga_readl(base_addr+ i*4);
if(BE(buf[i]) != x)
{
printf("Verify failed (%x vs %x)\n", BE(buf[i]), x);
return -1;
}
if(!(i & 0xfff))
printf(".");
}
printf(" OK.\n");
return 0;
}
static char *global_strptr;
static Elf32_Shdr *global_sh;
/* The elf loader relies on the binary loader above (and the global mmap) */
static int copy_lm32_elf(void *data, int noload, int size)
{
int i, flags, verbose = getenv("LOAD_LM32_VERBOSE") != NULL;
Elf32_Ehdr *eh;
Elf32_Phdr *ph;
Elf32_Shdr *sh;
char *strptr;
eh = data;
if (verbose) {
printf("type: %8i\n", BE(eh->e_type));
printf("machine: %8i\n", BE(eh->e_machine));
printf("version: %8i\n", BE(eh->e_version));
printf("entry: %08lx\n", (long)BE(eh->e_entry));
printf("phoff: %8i\n", BE(eh->e_phoff));
printf("shoff: %8i\n", BE(eh->e_shoff));
printf("ehsize: %8i\n", BE(eh->e_ehsize));
printf("shstrndx:%8i\n", BE(eh->e_shstrndx));
}
ph = (Elf32_Phdr *)((char *)eh + (int)(BE(eh->e_phoff)));
/* program headers. Irrelevant, actually... */
for (i = 0; i < BE(eh->e_phnum); i++) {
flags = BE(ph->p_flags);
if (verbose) {
printf("prg: %i 0x%08lx, 0x%08lx, 0x%08lx, %c%c%c "
"(%08x), %i, %i %i\n",
BE(ph->p_type),
(long)(BE(ph->p_offset)),
(long)(BE(ph->p_vaddr)),
(long)(BE(ph->p_paddr)),
flags & PF_R ? 'r' : '-',
flags & PF_W ? 'w' : '-',
flags & PF_X ? 'x' : '-',
flags,
BE(ph->p_filesz),
BE(ph->p_memsz),
BE(ph->p_align));
}
}
/* first loop: look for strtab */
sh = (Elf32_Shdr *)((char *)eh + (int)(BE(eh->e_shoff)));
for (i = 0; i < BE(eh->e_shstrndx); i++)
sh=(Elf32_Shdr *)((char *)sh + (int)BE(eh->e_shentsize));
strptr = (char *)eh + BE(sh->sh_offset);
sh = (Elf32_Shdr *)((char *)eh + (int)(BE(eh->e_shoff)));
/* Save them for later (setting vriables) */
global_strptr = strptr;
global_sh = sh;
/* Section headers: this is what we load */
for (i = 0; i < BE(eh->e_shnum); i++) {
unsigned long off, len, ram;
if (i) /* next header */
sh = (Elf32_Shdr *)((char *)sh
+ (int)BE(eh->e_shentsize));
if (verbose) {
printf("sect: %3i %-25.25s %2i 0x%08lx, 0x%08lx, (%i) %i %i\n",
BE(sh->sh_name),
strptr + BE(sh->sh_name),
BE(sh->sh_type),
(long)(BE(sh->sh_offset)),
(long)(BE(sh->sh_addr)),
BE(sh->sh_size),
BE(sh->sh_addralign),
BE(sh->sh_entsize));
}
off = BE(sh->sh_offset);
len = BE(sh->sh_size);
ram = BE(sh->sh_addr) & 0x0fffffff;
/* ignore unloadable sections */
if (BE(sh->sh_type) != SHT_PROGBITS)
continue;
if (!(BE(sh->sh_flags) & SHF_ALLOC))
continue;
if (len == 0)
continue;
/*
* First argument is base in file, third is offset
* in both fpga and file, so adjust file base (hack)
*/
if (copy_lm32(data + off, noload, len, ram))
return -1;
}
return 0;
}
int load_lm32(char *fname, int noload)
{
void *buf;
FILE *f;
int iself, ret;
f=fopen(fname,"rb");
if(!f)
{
fprintf(stderr, "%s: %s: %s\n", prgname,
fname, strerror(errno));
return -1;
}
fseek(f, 0, SEEK_END);
int size = ftell(f);
rewind(f);
buf = malloc(size + 4);
ret = fread(buf, 1, size, f);
fclose(f);
if (ret != size) {
fprintf(stderr, "%s: %s: read error (\n", prgname, fname);
return -1;
}
if (!memcmp(buf, ELFMAG, SELFMAG))
iself = 1;
else if (!memcmp(buf, "\x98\0\0\0", 4))
iself = 0;
else {
fprintf(stderr, "%s: %s: Unrecognized file type\n", prgname,
fname);
return -1;
}
/*
* If ELF, we need to call the function even if (noload)
* because the function parses ELF and sets global variables.
* To the same to the binary loader for symmetry.
*/
if (iself)
ret = copy_lm32_elf(buf, noload, size);
else
ret = copy_lm32(buf, noload, size, 0);
free(buf);
return ret;
}
/* Set, or read, a variable. We already loaded to memory the file */
static int varaction_lm32(char *fname, char *action)
{
char vname[64], sname[64];
char stmp[256];
int i, write, vvalue, saddr;
FILE *f;
char eq;
if (!global_strptr) {
fprintf(stderr, "%s: Can't execute \"%s\" on a non-elf file\n",
prgname, action);
return -1;
}
i = sscanf(action, "%[^=]%c%i", vname, &eq, &vvalue);
if (i < 2 || eq != '=') {
fprintf(stderr, "%s: Can't parse action \"%s\"\n",
prgname, action);
return -1;
}
if (i == 3)
write = 1;
else
write = 0;
/* Open "nm" (lazy me)" to find the variable's address */
sprintf(stmp, "nm %s", fname);
f = popen(stmp, "r");
if (!f) {
fprintf(stderr, "%s: Can't run \"%s\" (%s)\n",
prgname, stmp, strerror(errno));
return -1;
}
while (fgets(stmp, sizeof(stmp), f)) {
if (sscanf(stmp, "%x %*c %s", &saddr, sname) != 2)
continue;
if (!strcmp(vname, sname))
break;
}
if (feof(f)) {
fprintf(stderr, "%s: no symbol \"%s\" int \"%s\"\n",
prgname, sname, fname);
pclose(f);
return -1;
}
pclose(f);
/* NOTE: we must not convert endianness here: it's bitwise ok */
if (write) {
/* FIXME: check it is in a writable section */
fpga_writel(vvalue, saddr);
} else {
vvalue = fpga_readl(saddr);
printf("%s = %i (0x%08x)\n", vname, vvalue, vvalue);
}
return 0;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int fdmem, ret;
int i, noload = 0;
prgname = argv[0];
if (argc > 1 && !strcmp(argv[1], "-n")) {
noload = 1;
argv++;
argc--;
}
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "Use: \"%s <filename>\"\n", argv[0]); fprintf(stderr, "%s: Use: \"%s [-n] <filename> "
"[<var>=<value> ...]\"\n", prgname, prgname);
}
setbuffer(stdout, NULL, 0);
if ((fdmem = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: /dev/mem: %s\n", prgname,
strerror(errno));
exit(1);
} }
return load_lm32_main(argv[1]);
base_fpga = mmap(0, SIZE_FPGA, PROT_READ | PROT_WRITE,
MAP_SHARED, fdmem,
BASE_FPGA);
close(fdmem);
if (base_fpga == MAP_FAILED) {
fprintf(stderr, "%s: mmap(/dev/mem): %s\n",
prgname, strerror(errno));
exit(1);
}
if (!noload)
rst_lm32(1);
ret = load_lm32(argv[1], noload);
if (ret)
exit(1);
for (i = 2; i < argc; i++)
if (varaction_lm32(argv[1], argv[i]))
exit(1);
if (!noload)
rst_lm32(0);
return 0;
} }
...@@ -64,4 +64,3 @@ int main(int argc, char **argv) ...@@ -64,4 +64,3 @@ int main(int argc, char **argv)
} }
return 0; return 0;
} }
...@@ -89,8 +89,8 @@ void fetch_rtu_fd(rtudexp_fd_entry_t *d, int *n_entries) ...@@ -89,8 +89,8 @@ void fetch_rtu_fd(rtudexp_fd_entry_t *d, int *n_entries)
// printf("num_rules %d\n", list.num_rules); // printf("num_rules %d\n", list.num_rules);
memcpy( d+n, list.list, sizeof(rtudexp_fd_entry_t) * list.num_rules); memcpy( d+n, list.list, sizeof(rtudexp_fd_entry_t) * list.num_rules);
start=list.next; start=list.next;
n+=list.num_rules; n+=list.num_rules;
} while(start > 0); } while(start > 0);
// printf("%d rules \n", n); // printf("%d rules \n", n);
...@@ -142,8 +142,8 @@ char *decode_ports(int dpm) ...@@ -142,8 +142,8 @@ char *decode_ports(int dpm)
if((dpm & ((1<<plist.num_physical_ports)-1)) == ((1<<plist.num_physical_ports)-1)) if((dpm & ((1<<plist.num_physical_ports)-1)) == ((1<<plist.num_physical_ports)-1))
{ {
strcpy(str,"ALL"); strcpy(str,"ALL");
return str; return str;
} }
strcpy(str,""); strcpy(str,"");
...@@ -152,13 +152,13 @@ char *decode_ports(int dpm) ...@@ -152,13 +152,13 @@ char *decode_ports(int dpm)
{ {
sprintf(str2,"%d ", i); sprintf(str2,"%d ", i);
if(dpm&(1<<i)) strcat(str,str2); if(dpm&(1<<i)) strcat(str,str2);
} }
if(dpm & (1<<plist.num_physical_ports)) if(dpm & (1<<plist.num_physical_ports))
strcat(str, "CPU"); strcat(str, "CPU");
return str; return str;
} }
void show_help(char *prgname) void show_help(char *prgname)
{ {
...@@ -244,11 +244,11 @@ int main(int argc, char **argv) ...@@ -244,11 +244,11 @@ int main(int argc, char **argv)
for(i=0;i<n_fd_entries;i++) for(i=0;i<n_fd_entries;i++)
{ {
printf("%-25s %-12s %2d %s (hash %03x:%x) ", printf("%-25s %-12s %2d %s (hash %03x:%x) ",
mac_to_buffer(fd_list[i].mac,mac_buf), mac_to_buffer(fd_list[i].mac,mac_buf),
decode_ports(fd_list[i].dpm), decode_ports(fd_list[i].dpm),
fd_list[i].fid, fd_list[i].fid,
fd_list[i].dynamic ? "DYNAMIC":"STATIC ", fd_list[i].dynamic ? "DYNAMIC":"STATIC ",
fd_list[i].hash, fd_list[i].hash,
fd_list[i].bucket); fd_list[i].bucket);
if(fd_list[i].dynamic) if(fd_list[i].dynamic)
......
...@@ -64,4 +64,3 @@ int main(int argc, char **argv) ...@@ -64,4 +64,3 @@ int main(int argc, char **argv)
} }
return 0; return 0;
} }
...@@ -82,12 +82,12 @@ void show_ports() ...@@ -82,12 +82,12 @@ void show_ports()
hexp_port_state_t state; hexp_port_state_t state;
snprintf(if_name, 10, "wr%d", i); snprintf(if_name, 10, "wr%d", i);
for(j=0;j<port_list.num_ports;j++) for(j=0;j<port_list.num_ports;j++)
if(!strcmp(port_list.port_names[j], if_name)) { found = 1; break; } if(!strcmp(port_list.port_names[j], if_name)) { found = 1; break; }
if(!found) continue; if(!found) continue;
halexp_get_port_state(&state, if_name); halexp_get_port_state(&state, if_name);
if(state.up) if(state.up)
...@@ -133,10 +133,10 @@ void show_screen() ...@@ -133,10 +133,10 @@ void show_screen()
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int usecolor = 1; int usecolor = 1;
if(argc > 1){ if(argc > 1){
if(!strcmp(argv[1], "ports")){ if(!strcmp(argv[1], "ports")){
usecolor = 0; usecolor = 0;
init(usecolor); init(usecolor);
...@@ -157,10 +157,10 @@ int main(int argc, char **argv) ...@@ -157,10 +157,10 @@ int main(int argc, char **argv)
term_restore(); term_restore();
setlinebuf(stdout); setlinebuf(stdout);
printf("\n"); printf("\n");
}else if (!strcmp(argv[1], "fan")){ }else if (!strcmp(argv[1], "fan")){
}else{ }else{
printf("\nParam required: "); printf("\nParam required: ");
printf("\nProgram usage: %s [param]", argv[0]); printf("\nProgram usage: %s [param]", argv[0]);
...@@ -169,9 +169,9 @@ int main(int argc, char **argv) ...@@ -169,9 +169,9 @@ int main(int argc, char **argv)
}else{ }else{
printf("\nParam required: "); printf("\nParam required: ");
printf("\nProgram usage: %s [param]", argv[0]); printf("\nProgram usage: %s [param]", argv[0]);
printf("\tports\t-->\tWRS ports state\n"); printf("\tports\t-->\tWRS ports state\n");
} }
return 0; return 0;
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
WARNING: This is just my internal code for testing some timing-related stuff. WARNING: This is just my internal code for testing some timing-related stuff.
I'll document it and clean it up in the future, but for now, please I'll document it and clean it up in the future, but for now, please
don't ask questions. sorry don't ask questions. sorry
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -92,7 +92,7 @@ void dump_pcs_regs(int ep, int argc, char *argv[]) ...@@ -92,7 +92,7 @@ void dump_pcs_regs(int ep, int argc, char *argv[])
{ {
int i; int i;
printf("PCS registers dump for endpoint %d:\n", ep); printf("PCS registers dump for endpoint %d:\n", ep);
for(i=0;i<17;i++) for(i=0;i<17;i++)
printf("R%d = 0x%08x\n",i,pcs_read(ep, i)); printf("R%d = 0x%08x\n",i,pcs_read(ep, i));
} }
...@@ -110,15 +110,15 @@ void tx_cal(int ep, int argc, char *argv[]) ...@@ -110,15 +110,15 @@ void tx_cal(int ep, int argc, char *argv[])
{ {
int on_off = atoi(argv[3]) ? 1 : 0; int on_off = atoi(argv[3]) ? 1 : 0;
printf("TX cal pattern %s\n", on_off ? "ON":"OFF"); printf("TX cal pattern %s\n", on_off ? "ON":"OFF");
pcs_write(ep, 16, on_off); pcs_write(ep, 16, on_off);
printf("rdbk:%x\n",pcs_read(ep, 16)); printf("rdbk:%x\n",pcs_read(ep, 16));
} }
void try_autonegotiation(int ep, int argc, char *argv[]) void try_autonegotiation(int ep, int argc, char *argv[])
{ {
pcs_write(ep, MII_ADVERTISE, 0x1a0); pcs_write(ep, MII_ADVERTISE, 0x1a0);
pcs_write(ep, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); pcs_write(ep, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
printf("Autonegotiation: "); printf("Autonegotiation: ");
for(;;) for(;;)
...@@ -164,10 +164,10 @@ static struct { ...@@ -164,10 +164,10 @@ static struct {
int bslide_bins() int bslide_bins()
{ {
int i, hits = 0; int i, hits = 0;
for(i=0;i<MAX_BITSLIDES;i++) for(i=0;i<MAX_BITSLIDES;i++)
if(bslides[i].occupied) hits++; if(bslides[i].occupied) hits++;
return hits; return hits;
} }
...@@ -199,14 +199,14 @@ static void print_cal_stats() ...@@ -199,14 +199,14 @@ static void print_cal_stats()
for(i=0;i<MAX_BITSLIDES;i++) for(i=0;i<MAX_BITSLIDES;i++)
if(bslides[i].occupied) if(bslides[i].occupied)
{ {
printf("%-15d %-11d %-13d %-17d %-17d %-17d %-6d %d\n", printf("%-15d %-11d %-13d %-17d %-17d %-17d %-6d %d\n",
i, i,
bslides[i].delta, bslides[i].delta,
bslides[i].rx_ahead, bslides[i].rx_ahead,
bslides[i].phase_min, bslides[i].phase_min,
bslides[i].phase_max, bslides[i].phase_max,
bslides[i].phase_dev, bslides[i].phase_dev,
bslides[i].hits, bslides[i].hits,
(last_occupied >= 0) ? bslides[i].delta-bslides[last_occupied].delta:0 (last_occupied >= 0) ? bslides[i].delta-bslides[last_occupied].delta:0
); );
...@@ -218,9 +218,9 @@ static void print_cal_stats() ...@@ -218,9 +218,9 @@ static void print_cal_stats()
void calc_trans(int ep, int argc, char *argv[]) void calc_trans(int ep, int argc, char *argv[])
{ {
wr_timestamp_t ts_tx, ts_rx; wr_timestamp_t ts_tx, ts_rx;
wr_socket_t *sock; wr_socket_t *sock;
FILE *f_log = NULL; FILE *f_log = NULL;
wr_sockaddr_t sock_addr, from; wr_sockaddr_t sock_addr, from;
int bitslide,phase, i; int bitslide,phase, i;
signal (SIGINT, sighandler); signal (SIGINT, sighandler);
...@@ -233,18 +233,18 @@ void calc_trans(int ep, int argc, char *argv[]) ...@@ -233,18 +233,18 @@ void calc_trans(int ep, int argc, char *argv[])
if(argc >= 3) if(argc >= 3)
f_log = fopen(argv[3], "wb"); f_log = fopen(argv[3], "wb");
sprintf(sock_addr.if_name, "wr%d", ep); sprintf(sock_addr.if_name, "wr%d", ep);
sock_addr.family = PTPD_SOCK_RAW_ETHERNET; // socket type sock_addr.family = PTPD_SOCK_RAW_ETHERNET; // socket type
sock_addr.ethertype = 12345; sock_addr.ethertype = 12345;
memset(sock_addr.mac, 0xff, 6); memset(sock_addr.mac, 0xff, 6);
assert(ptpd_netif_init() == 0); assert(ptpd_netif_init() == 0);
sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr); sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr);
// fpga_writel(EP_DMCR_N_AVG_W(1024) | EP_DMCR_EN, IDX_TO_EP(ep) + EP_REG(DMCR)); // fpga_writel(EP_DMCR_N_AVG_W(1024) | EP_DMCR_EN, IDX_TO_EP(ep) + EP_REG(DMCR));
if( rts_connect() < 0) if( rts_connect() < 0)
{ {
printf("Can't connect to the RT subsys\n"); printf("Can't connect to the RT subsys\n");
return; return;
...@@ -259,7 +259,7 @@ void calc_trans(int ep, int argc, char *argv[]) ...@@ -259,7 +259,7 @@ void calc_trans(int ep, int argc, char *argv[])
pcs_write(ep, MII_BMCR, BMCR_PDOWN); pcs_write(ep, MII_BMCR, BMCR_PDOWN);
usleep(10000); usleep(10000);
pcs_write(ep, MII_BMCR, 0); //BMCR_ANENABLE | BMCR_ANRESTART); pcs_write(ep, MII_BMCR, 0); //BMCR_ANENABLE | BMCR_ANRESTART);
pcs_read(ep, MII_BMSR); pcs_read(ep, MII_BMSR);
...@@ -282,16 +282,16 @@ void calc_trans(int ep, int argc, char *argv[]) ...@@ -282,16 +282,16 @@ void calc_trans(int ep, int argc, char *argv[])
memset(to.mac, 0xff, 6); memset(to.mac, 0xff, 6);
to.ethertype = 12345; to.ethertype = 12345;
to.family = PTPD_SOCK_RAW_ETHERNET; // socket type to.family = PTPD_SOCK_RAW_ETHERNET; // socket type
ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx); ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx);
int n = ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx); int n = ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx);
if(n>0) if(n>0)
{ {
int delta = ts_rx.nsec * 1000 + ts_rx.phase - ts_tx.nsec * 1000; int delta = ts_rx.nsec * 1000 + ts_rx.phase - ts_tx.nsec * 1000;
bslide_update(phase, delta, ts_rx.raw_ahead, bitslide); bslide_update(phase, delta, ts_rx.raw_ahead, bitslide);
printf("delta %d (adv %d), bitslide: %d bins: %d phase %d, rxphase %d\n", delta, ts_rx.raw_ahead, bitslide, bslide_bins(), phase, ts_rx.phase); printf("delta %d (adv %d), bitslide: %d bins: %d phase %d, rxphase %d\n", delta, ts_rx.raw_ahead, bitslide, bslide_bins(), phase, ts_rx.phase);
...@@ -301,7 +301,7 @@ void calc_trans(int ep, int argc, char *argv[]) ...@@ -301,7 +301,7 @@ void calc_trans(int ep, int argc, char *argv[])
usleep(500000); usleep(500000);
} }
if(f_log) fclose(f_log); if(f_log) fclose(f_log);
print_cal_stats(); print_cal_stats();
} }
...@@ -318,7 +318,7 @@ void analyze_phase_log(int ep, int argc, char *argv[]) ...@@ -318,7 +318,7 @@ void analyze_phase_log(int ep, int argc, char *argv[])
trans_point = atoi(argv[4]); trans_point = atoi(argv[4]);
else else
trans_point = 1000; trans_point = 1000;
for(i=0;i<MAX_BITSLIDES;i++) for(i=0;i<MAX_BITSLIDES;i++)
{ {
bslides[i].occupied = 0; bslides[i].occupied = 0;
...@@ -326,7 +326,7 @@ void analyze_phase_log(int ep, int argc, char *argv[]) ...@@ -326,7 +326,7 @@ void analyze_phase_log(int ep, int argc, char *argv[])
bslides[i].phase_max= -1000000; bslides[i].phase_max= -1000000;
} }
while(!feof(f_log)) while(!feof(f_log))
{ {
wr_timestamp_t ts_tx, ts_rx; wr_timestamp_t ts_tx, ts_rx;
...@@ -334,36 +334,36 @@ void analyze_phase_log(int ep, int argc, char *argv[]) ...@@ -334,36 +334,36 @@ void analyze_phase_log(int ep, int argc, char *argv[])
ts_rx.nsec = ts_rx.raw_nsec; ts_rx.nsec = ts_rx.raw_nsec;
phase = ts_rx.raw_phase; phase = ts_rx.raw_phase;
ptpd_netif_linearize_rx_timestamp(&ts_rx, ts_rx.raw_phase, ts_rx.raw_ahead, trans_point, 16000); ptpd_netif_linearize_rx_timestamp(&ts_rx, ts_rx.raw_phase, ts_rx.raw_ahead, trans_point, 16000);
int delta = ts_rx.nsec * 1000 + ts_rx.phase - ts_tx.nsec * 1000; int delta = ts_rx.nsec * 1000 + ts_rx.phase - ts_tx.nsec * 1000;
bslide_update(phase, delta, ts_rx.raw_ahead, bitslide); bslide_update(phase, delta, ts_rx.raw_ahead, bitslide);
} }
printf("Transition point: %d ps. \n", trans_point); printf("Transition point: %d ps. \n", trans_point);
print_cal_stats(); print_cal_stats();
fclose(f_log); fclose(f_log);
} }
void pps_adjustment_test(int ep, int argc, char *argv[]) void pps_adjustment_test(int ep, int argc, char *argv[])
{ {
wr_timestamp_t ts_tx, ts_rx; wr_timestamp_t ts_tx, ts_rx;
wr_socket_t *sock; wr_socket_t *sock;
wr_sockaddr_t sock_addr, from; wr_sockaddr_t sock_addr, from;
int adjust_count = 0; int adjust_count = 0;
signal (SIGINT, sighandler); signal (SIGINT, sighandler);
sprintf(sock_addr.if_name, "wr%d", ep); sprintf(sock_addr.if_name, "wr%d", ep);
sock_addr.family = PTPD_SOCK_RAW_ETHERNET; // socket type sock_addr.family = PTPD_SOCK_RAW_ETHERNET; // socket type
sock_addr.ethertype = 12345; sock_addr.ethertype = 12345;
memset(sock_addr.mac, 0xff, 6); memset(sock_addr.mac, 0xff, 6);
assert(ptpd_netif_init() == 0); assert(ptpd_netif_init() == 0);
sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr); sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr);
while(!quit) while(!quit)
...@@ -371,9 +371,9 @@ void pps_adjustment_test(int ep, int argc, char *argv[]) ...@@ -371,9 +371,9 @@ void pps_adjustment_test(int ep, int argc, char *argv[])
char buf[64]; char buf[64];
wr_sockaddr_t to; wr_sockaddr_t to;
memset(to.mac, 0xff, 6); memset(to.mac, 0xff, 6);
to.ethertype = 12345; to.ethertype = 12345;
to.family = PTPD_SOCK_RAW_ETHERNET; // socket type to.family = PTPD_SOCK_RAW_ETHERNET; // socket type
if(adjust_count == 0) if(adjust_count == 0)
{ {
...@@ -382,14 +382,14 @@ void pps_adjustment_test(int ep, int argc, char *argv[]) ...@@ -382,14 +382,14 @@ void pps_adjustment_test(int ep, int argc, char *argv[])
} }
// if(!ptpd_netif_adjust_in_progress()) // if(!ptpd_netif_adjust_in_progress())
{ {
ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx); ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx);
ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx); ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx);
printf("TX timestamp: correct %d %12lld:%12d\n", ts_tx.correct, ts_tx.sec, ts_tx.nsec); printf("TX timestamp: correct %d %12lld:%12d\n", ts_tx.correct, ts_tx.sec, ts_tx.nsec);
printf("RX timestamp: correct %d %12lld:%12d\n", ts_rx.correct, ts_rx.sec, ts_rx.nsec); printf("RX timestamp: correct %d %12lld:%12d\n", ts_rx.correct, ts_rx.sec, ts_rx.nsec);
adjust_count --; adjust_count --;
}// else printf("AdjustInProgress\n"); }// else printf("AdjustInProgress\n");
sleep(1); sleep(1);
} }
} }
...@@ -399,7 +399,7 @@ void rt_command(int ep, int argc, char *argv[]) ...@@ -399,7 +399,7 @@ void rt_command(int ep, int argc, char *argv[])
struct rts_pll_state pstate; struct rts_pll_state pstate;
hexp_port_list_t plist; hexp_port_list_t plist;
int i; int i;
if( rts_connect() < 0) if( rts_connect() < 0)
{ {
printf("Can't connect to the RT subsys\n"); printf("Can't connect to the RT subsys\n");
...@@ -415,17 +415,17 @@ void rt_command(int ep, int argc, char *argv[]) ...@@ -415,17 +415,17 @@ void rt_command(int ep, int argc, char *argv[])
rts_get_state(&pstate); rts_get_state(&pstate);
// halexp_query_ports(&plist); // halexp_query_ports(&plist);
if(!strcmp(argv[3], "show")) if(!strcmp(argv[3], "show"))
{ {
printf("RTS State Dump [%d physical ports]: \n", plist.num_physical_ports); printf("RTS State Dump [%d physical ports]: \n", plist.num_physical_ports);
printf("CurrentRef: %d Mode: %d Flags: %x\n", pstate.current_ref, pstate.mode, pstate.flags); printf("CurrentRef: %d Mode: %d Flags: %x\n", pstate.current_ref, pstate.mode, pstate.flags);
for(i=0;i<plist.num_physical_ports;i++) for(i=0;i<plist.num_physical_ports;i++)
printf("wr%-2d: setpoint: %-8dps current: %-8dps loopback: %-8dps flags: %x\n", i, printf("wr%-2d: setpoint: %-8dps current: %-8dps loopback: %-8dps flags: %x\n", i,
pstate.channels[i].phase_setpoint, pstate.channels[i].phase_setpoint,
pstate.channels[i].phase_current, pstate.channels[i].phase_current,
pstate.channels[i].phase_loopback, pstate.channels[i].phase_loopback,
pstate.channels[i].flags); pstate.channels[i].flags);
} else if (!strcmp(argv[3], "lock")) } else if (!strcmp(argv[3], "lock"))
{ {
int i; int i;
...@@ -449,7 +449,7 @@ void rt_command(int ep, int argc, char *argv[]) ...@@ -449,7 +449,7 @@ void rt_command(int ep, int argc, char *argv[])
else if (!strcmp(argv[3], "track")) else if (!strcmp(argv[3], "track"))
{ {
printf("Enabling ptracker @ port %d\n", ep); printf("Enabling ptracker @ port %d\n", ep);
rts_enable_ptracker(ep, 1); rts_enable_ptracker(ep, 1);
} }
} }
...@@ -526,18 +526,18 @@ int main(int argc, char **argv) ...@@ -526,18 +526,18 @@ int main(int argc, char **argv)
printf("usage: %s endpoint command [parameters]\n", argv[0]); printf("usage: %s endpoint command [parameters]\n", argv[0]);
printf("Commands:\n"); printf("Commands:\n");
for(i=0; commands[i].cmd;i++) for(i=0; commands[i].cmd;i++)
printf("%-20s %-20s: %s\n", commands[i].cmd, commands[i].params, commands[i].desc); printf("%-20s %-20s: %s\n", commands[i].cmd, commands[i].params, commands[i].desc);
return 0; return 0;
} }
for(i=0; commands[i].cmd;i++) for(i=0; commands[i].cmd;i++)
if(!strcmp(commands[i].cmd, argv[2])) if(!strcmp(commands[i].cmd, argv[2]))
{ {
commands[i].func(atoi(argv[1]), argc, argv); commands[i].func(atoi(argv[1]), argc, argv);
return 0; return 0;
} }
printf("Unrecognized command '%s'\n", argv[2]); printf("Unrecognized command '%s'\n", argv[2]);
return -1; return -1;
} }
...@@ -154,7 +154,7 @@ void print_chosen_cnts( int cnts_list[], int n_cnts) ...@@ -154,7 +154,7 @@ void print_chosen_cnts( int cnts_list[], int n_cnts)
{ {
int cnt = 0; int cnt = 0;
int port = 0; int port = 0;
printf("P |"); printf("P |");
for(cnt=0; cnt<n_cnts; ++cnt) for(cnt=0; cnt<n_cnts; ++cnt)
printf("%2d:%s", cnts_list[cnt],info[cnts_list[cnt]]); printf("%2d:%s", cnts_list[cnt],info[cnts_list[cnt]]);
...@@ -214,7 +214,7 @@ int main(int argc, char **argv) ...@@ -214,7 +214,7 @@ int main(int argc, char **argv)
} }
if(pstats_init()) return -1; if(pstats_init()) return -1;
while(1) while(1)
{ {
printf("\033[2J\033[1;1H"); printf("\033[2J\033[1;1H");
......
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