first steps
This commit is contained in:
parent
185e5a05b7
commit
2490c266a0
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
bit2txt
|
bit2txt
|
||||||
bit2txt.o
|
draw_fpga
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -10,15 +10,13 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
CFLAGS = -Wall -g
|
CFLAGS = -Wall -g
|
||||||
TARGETS = bit2txt
|
TARGETS = bit2txt draw_fpga
|
||||||
OBJS = $(TARGETS:=.o)
|
OBJS = $(TARGETS:=.o)
|
||||||
|
LDLIBS = -lxml2
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
genex: $(OBJS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDLIBS)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) $(TARGETS)
|
rm -f $(OBJS) $(TARGETS)
|
||||||
|
|
4
README
4
README
|
@ -1,6 +1,6 @@
|
||||||
Design Goals
|
Design Principles
|
||||||
|
|
||||||
- small independent command line utilities
|
- small independent command line utilities, no GUI
|
||||||
- plain C, no C++
|
- plain C, no C++
|
||||||
- simple Makefiles
|
- simple Makefiles
|
||||||
- text-based file formats
|
- text-based file formats
|
||||||
|
|
157
bit2txt.c
157
bit2txt.c
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Authors: Wolfgang Spraul <wspraul@q-ag.de>
|
// Author: Wolfgang Spraul <wspraul@q-ag.de>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
|
@ -177,10 +177,11 @@ void hexdump(int offset, const uint8_t* data, int len)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
if (len) {
|
if (len) {
|
||||||
printf("#D hexdump offset %xh, len %i\n", offset, len);
|
printf("#D hexdump offset %xh, len 0x%x (%i)\n",
|
||||||
|
offset, len, len);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
printf("#D %04x: %02x", i, data[i]);
|
printf("#D %05x: %02x", i, data[i]);
|
||||||
for (j = 1; (j < 8) && (i + j < len); j++) {
|
for (j = 1; (j < 8) && (i + j < len); j++) {
|
||||||
if (i + j >= len) break;
|
if (i + j >= len) break;
|
||||||
printf(" %02x", data[i+j]);
|
printf(" %02x", data[i+j]);
|
||||||
|
@ -447,6 +448,11 @@ int main(int argc, char** argv)
|
||||||
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
||||||
u16_off+=2;
|
u16_off+=2;
|
||||||
printf("T1 FLR %u\n", u16);
|
printf("T1 FLR %u\n", u16);
|
||||||
|
// There are 3 types of frames. Type0 (clb, ioi
|
||||||
|
// and special blocks), type1 (bram) and type2
|
||||||
|
// (iob). The size of a type0 and type1 is
|
||||||
|
// fixed, only the size of a type2 (iob) is
|
||||||
|
// specified with the FLR register.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (packet_hdr_register == COR1) {
|
if (packet_hdr_register == COR1) {
|
||||||
|
@ -614,6 +620,151 @@ int main(int argc, char** argv)
|
||||||
printf("T1 MFWR\n");
|
printf("T1 MFWR\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (packet_hdr_register == CTL) {
|
||||||
|
if (packet_hdr_wordcount != 1) {
|
||||||
|
fprintf(stderr, "#E 0x%x=0x%x Unexpected CTL"
|
||||||
|
" wordcount %u.\n", u16_off,
|
||||||
|
u16, packet_hdr_wordcount);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
||||||
|
u16_off+=2;
|
||||||
|
printf("T1 CTL");
|
||||||
|
if (u16 & 0x0040) {
|
||||||
|
printf(" DECRYPT");
|
||||||
|
u16 &= ~0x0040;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0020) {
|
||||||
|
if (u16 & 0x0010)
|
||||||
|
printf(" SBITS=NO_RW");
|
||||||
|
else
|
||||||
|
printf(" SBITS=NO_READ");
|
||||||
|
u16 &= ~0x0030;
|
||||||
|
} else if (u16 & 0x0010) {
|
||||||
|
printf(" SBITS=ICAP_READ");
|
||||||
|
u16 &= ~0x0010;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0008) {
|
||||||
|
printf(" PERSIST");
|
||||||
|
u16 &= ~0x0008;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0004) {
|
||||||
|
printf(" USE_EFUSE_KEY");
|
||||||
|
u16 &= ~0x0004;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0002) {
|
||||||
|
printf(" CRC_EXTSTAT_DISABLE");
|
||||||
|
u16 &= ~0x0002;
|
||||||
|
}
|
||||||
|
if (u16)
|
||||||
|
printf(" 0x%x", u16);
|
||||||
|
printf("\n");
|
||||||
|
// bit0 is reserved as 1, and we have seen
|
||||||
|
// bit7 on as well.
|
||||||
|
if (u16 != 0x81)
|
||||||
|
printf("#W Expected reserved 0x%x, got 0x%x.\n", 0x0081, u16);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (packet_hdr_register == MASK) {
|
||||||
|
if (packet_hdr_wordcount != 1) {
|
||||||
|
fprintf(stderr, "#E 0x%x=0x%x Unexpected MASK"
|
||||||
|
" wordcount %u.\n", u16_off,
|
||||||
|
u16, packet_hdr_wordcount);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
||||||
|
u16_off+=2;
|
||||||
|
printf("T1 MASK");
|
||||||
|
if (u16 & 0x0040) {
|
||||||
|
printf(" DECRYPT");
|
||||||
|
u16 &= ~0x0040;
|
||||||
|
}
|
||||||
|
if ((u16 & 0x0030) == 0x0030) {
|
||||||
|
printf(" SECURITY");
|
||||||
|
u16 &= ~0x0030;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0008) {
|
||||||
|
printf(" PERSIST");
|
||||||
|
u16 &= ~0x0008;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0004) {
|
||||||
|
printf(" USE_EFUSE_KEY");
|
||||||
|
u16 &= ~0x0004;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0002) {
|
||||||
|
printf(" CRC_EXTSTAT_DISABLE");
|
||||||
|
u16 &= ~0x0002;
|
||||||
|
}
|
||||||
|
if (u16)
|
||||||
|
printf(" 0x%x", u16);
|
||||||
|
printf("\n");
|
||||||
|
// It seems bit7 and bit0 are always masked in.
|
||||||
|
if (u16 != 0x81)
|
||||||
|
printf("#W Expected reserved 0x%x, got 0x%x.\n", 0x0081, u16);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (packet_hdr_register == PWRDN_REG) {
|
||||||
|
if (packet_hdr_wordcount != 1) {
|
||||||
|
fprintf(stderr, "#E 0x%x=0x%x Unexpected PWRDN_REG"
|
||||||
|
" wordcount %u.\n", u16_off,
|
||||||
|
u16, packet_hdr_wordcount);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
||||||
|
u16_off+=2;
|
||||||
|
printf("T1 PWRDN_REG");
|
||||||
|
if (u16 & 0x4000) {
|
||||||
|
printf(" EN_EYES");
|
||||||
|
u16 &= ~0x4000;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0020) {
|
||||||
|
printf(" FILTER_B");
|
||||||
|
u16 &= ~0x0020;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0010) {
|
||||||
|
printf(" EN_PGSR");
|
||||||
|
u16 &= ~0x0010;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0004) {
|
||||||
|
printf(" EN_PWRDN");
|
||||||
|
u16 &= ~0x0004;
|
||||||
|
}
|
||||||
|
if (u16 & 0x0001) {
|
||||||
|
printf(" KEEP_SCLK");
|
||||||
|
u16 &= ~0x0001;
|
||||||
|
}
|
||||||
|
if (u16)
|
||||||
|
printf(" 0x%x", u16);
|
||||||
|
printf("\n");
|
||||||
|
// Reserved bits 13:6 should be 00100010
|
||||||
|
// according to documentation.
|
||||||
|
if (u16 != 0x0880)
|
||||||
|
printf("#W Expected reserved 0x%x, got 0x%x.\n", 0x0880, u16);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (packet_hdr_register == HC_OPT_REG) {
|
||||||
|
if (packet_hdr_wordcount != 1) {
|
||||||
|
fprintf(stderr, "#E 0x%x=0x%x Unexpected HC_OPT_REG"
|
||||||
|
" wordcount %u.\n", u16_off,
|
||||||
|
u16, packet_hdr_wordcount);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
|
||||||
|
u16_off+=2;
|
||||||
|
printf("T1 HC_OPT_REG");
|
||||||
|
if (u16 & 0x0040) {
|
||||||
|
printf(" INIT_SKIP");
|
||||||
|
u16 &= ~0x0040;
|
||||||
|
}
|
||||||
|
if (u16)
|
||||||
|
printf(" 0x%x", u16);
|
||||||
|
printf("\n");
|
||||||
|
// Reserved bits 5:0 should be 011111
|
||||||
|
// according to documentation.
|
||||||
|
if (u16 != 0x001F)
|
||||||
|
printf("#W Expected reserved 0x%x, got 0x%x.\n", 0x001F, u16);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
printf("#W T1 %s (%u words)",
|
printf("#W T1 %s (%u words)",
|
||||||
xc6_regs[packet_hdr_register].name,
|
xc6_regs[packet_hdr_register].name,
|
||||||
packet_hdr_wordcount);
|
packet_hdr_wordcount);
|
||||||
|
|
103
draw_fpga.c
Normal file
103
draw_fpga.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
//
|
||||||
|
// Author: Wolfgang Spraul <wspraul@q-ag.de>
|
||||||
|
//
|
||||||
|
// This program is free software; 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/xpath.h>
|
||||||
|
#include <libxml/xpathInternals.h>
|
||||||
|
|
||||||
|
static const char* empty_svg =
|
||||||
|
{
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||||
|
"<svg\n"
|
||||||
|
" xmlns=\"http://www.w3.org/2000/svg\"\n"
|
||||||
|
" version=\"2.0\"\n"
|
||||||
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
||||||
|
" viewBox=\"0 0 1000 1000\" width=\"1000\" height=\"1000\"\n"
|
||||||
|
" id=\"fpga\">\n"
|
||||||
|
" <g id=\"root\" transform=\"translate(0,1000) scale(1,-1)\">\n"
|
||||||
|
" </g>\n"
|
||||||
|
"</svg>\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
xmlDocPtr doc = 0;
|
||||||
|
xmlXPathContextPtr xpathCtx = 0;
|
||||||
|
xmlXPathObjectPtr xpathObj = 0;
|
||||||
|
|
||||||
|
// create or overwrite fpga.svg
|
||||||
|
{
|
||||||
|
FILE* f = fopen("fpga.svg", "w+");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Cannot create fpga.svg\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
fprintf(f, empty_svg);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
xmlInitParser();
|
||||||
|
doc = xmlParseFile("fpga.svg");
|
||||||
|
if (!doc) {
|
||||||
|
fprintf(stderr, "Unable to parse fpga.svg.\n");
|
||||||
|
goto fail_xml;
|
||||||
|
}
|
||||||
|
xpathCtx = xmlXPathNewContext(doc);
|
||||||
|
if (!xpathCtx) {
|
||||||
|
fprintf(stderr, "Cannot create XPath context.\n");
|
||||||
|
goto fail_xml;
|
||||||
|
}
|
||||||
|
xmlXPathRegisterNs(xpathCtx, BAD_CAST "svg", BAD_CAST "http://www.w3.org/2000/svg");
|
||||||
|
xpathObj = xmlXPathEvalExpression(BAD_CAST "//svg:*[@id='root']", xpathCtx);
|
||||||
|
if (!xpathObj) {
|
||||||
|
fprintf(stderr, "Cannot evaluate root expression.\n");
|
||||||
|
goto fail_xml;
|
||||||
|
}
|
||||||
|
if (!xpathObj->nodesetval) {
|
||||||
|
fprintf(stderr, "Cannot find root node.\n");
|
||||||
|
goto fail_xml;
|
||||||
|
}
|
||||||
|
if (xpathObj->nodesetval->nodeNr != 1) {
|
||||||
|
fprintf(stderr, "Found %i root nodes.\n", xpathObj->nodesetval->nodeNr);
|
||||||
|
goto fail_xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
xmlNodePtr new_node;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
new_node = xmlNewChild(xpathObj->nodesetval->nodeTab[0], 0 /* xmlNsPtr */, BAD_CAST "use", 0 /* content */);
|
||||||
|
xmlSetProp(new_node, BAD_CAST "xlink:href", BAD_CAST "lib.svg#square");
|
||||||
|
xmlSetProp(new_node, BAD_CAST "x", xmlXPathCastNumberToString(50+i*50));
|
||||||
|
xmlSetProp(new_node, BAD_CAST "y", BAD_CAST "50");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlSaveFile("fpga.svg", doc);
|
||||||
|
|
||||||
|
xmlXPathFreeObject(xpathObj);
|
||||||
|
xmlXPathFreeContext(xpathCtx);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlCleanupParser();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
fail_xml:
|
||||||
|
if (xpathObj) xmlXPathFreeObject(xpathObj);
|
||||||
|
if (xpathCtx) xmlXPathFreeContext(xpathCtx);
|
||||||
|
if (doc) xmlFreeDoc(doc);
|
||||||
|
xmlCleanupParser();
|
||||||
|
fail:
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user