Add Makefile for fpga directory (Windows codepath is untested, in any case, go.bat is still there)

Retire rbt2c.pl, instead use objcopy to directly convert the .bit file into an .o that can be linked with the flash image
Rename armsrc/fpga.c to armsrc/fpgaloader.c (since there is now a new fpga.o, created from fpga.bit)
Remove fpgaimg.c from subversion, add fpga.bit
Instead of creating fpgaimage.elf and osimage.elf separately, now create a joined fullimage.elf 
  first (obsoleting ldscript-full), then extract only the fpga and os sections with objcopy
  (This creates unspecific warnings about an empty segment, need to investigate)
Implement a rudimentary .bit parser in the firmware, use that to locate the bitstream in the new
  fpgaimage (which is just a plain copy of the fpga.bit file) and send it to the FPGA
  The code will check the format that's in flash and fall back to the legacy format
This commit is contained in:
henryk@ploetzli.ch 2009-08-27 23:29:49 +00:00
commit e73e717239
12 changed files with 178 additions and 10651 deletions

View file

@ -3,41 +3,40 @@
APP_INCLUDES = apps.h
# Add the "-DWITH_LCD" flag in APP_CLFAGS to add support for LCD
# and add SRC_LCD to SRC_MAIN
# and add SRC_LCD to THUMBSRC
APP_CFLAGS = -O6
SRC_LCD = fonts.c LCD.c
SRC_MAIN = start.c \
THUMBSRC = start.c \
appmain.c \
fpga.c \
lfops.c \
iso15693.c \
util.c \
usb.c
# These are to be compiled in ARM mode
SRC_MAIN_FAST = iso14443.c \
iso14443a.c
ARMSRC = iso14443.c \
iso14443a.c \
fpgaloader.c
SRC_FPGA = fpgaimg.c
THUMBSRC = $(SRC_MAIN) $(SRC_FPGA)
ARMSRC = $(SRC_MAIN_FAST)
MAIN_OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(SRC_MAIN) $(SRC_MAIN_FAST))
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}{OBJ,SRC}
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common/Makefile.common
all: $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fpgaimg.o
$(LD) -g -Tldscript-fpga -Map=$(patsubst %.elf,%.map,$@) -o $@ $^
$(OBJDIR)/fpga.o: fpga.bit
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_bit_start=_binary_fpga_bit_start --redefine-sym _binary____fpga_fpga_bit_end=_binary_fpga_bit_end --prefix-sections=fpga_bit $^ $@
$(OBJDIR)/osimage.elf: $(MAIN_OBJ) $(ARMLIB)/libgcc.a
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fpga.o $(THUMBOBJ) $(ARMOBJ) $(ARMLIB)/libgcc.a
$(LD) -g -Tldscript -Map=$(patsubst %.elf,%.map,$@) -o $@ $^
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf
$(OBJCOPY) -F elf32-littlearm --only-section fpgaimage $^ $@
$(OBJDIR)/osimage.elf: $(OBJDIR)/fullimage.elf
$(OBJCOPY) -F elf32-littlearm --remove-section fpgaimage $^ $@
clean:
$(DELETE) $(OBJDIR)$(PATHSEP)*.o
$(DELETE) $(OBJDIR)$(PATHSEP)*.elf

File diff suppressed because it is too large Load diff

View file

@ -135,17 +135,10 @@ void FpgaSetupSscDma(BYTE *buf, int len)
PDC_CONTROL(SSC_BASE) = PDC_RX_ENABLE;
}
//-----------------------------------------------------------------------------
// Download the FPGA image stored in flash (slave serial).
//-----------------------------------------------------------------------------
void FpgaDownloadAndGo(void)
// Download the fpga image starting at FpgaImage and with length FpgaImageLen DWORDs (e.g. 4 bytes)
// If bytereversal is set: reverse the byte order in each 4-byte word
static void DownloadFPGA(const DWORD *FpgaImage, DWORD FpgaImageLen, int bytereversal)
{
// FPGA image lives in FLASH at base address 0x2000
// The current board design can not accomodate anything bigger than a XC2S30
// FPGA and the config file size is fixed at 336,768 bits = 10,524 DWORDs
const DWORD *FpgaImage=((DWORD *)0x2000);
const DWORD FpgaImageLen=10524;
int i, j;
PIO_OUTPUT_ENABLE = (1 << GPIO_FPGA_ON);
@ -170,21 +163,128 @@ void FpgaDownloadAndGo(void)
for(i = 0; i < FpgaImageLen; i++) {
DWORD v = FpgaImage[i];
for(j = 0; j < 32; j++) {
if(v & 0x80000000) {
HIGH(GPIO_FPGA_DIN);
} else {
LOW(GPIO_FPGA_DIN);
}
HIGH(GPIO_FPGA_CCLK);
LOW(GPIO_FPGA_CCLK);
v <<= 1;
unsigned char w;
for(j = 0; j < 4; j++) {
if(!bytereversal)
w = v >>(j*8);
else
w = v >>((3-j)*8);
#define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
SEND_BIT(7);
SEND_BIT(6);
SEND_BIT(5);
SEND_BIT(4);
SEND_BIT(3);
SEND_BIT(2);
SEND_BIT(1);
SEND_BIT(0);
}
}
LED_D_OFF();
}
static char *bitparse_headers_start;
static char *bitparse_bitstream_end;
static int bitparse_initialized;
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
* 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
* After that the format is 1 byte section type (ASCII character), 2 byte length
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
* length.
*/
static const char _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
static int bitparse_init(void * start_address, void *end_address)
{
bitparse_initialized = 0;
if(memcmp(_bitparse_fixed_header, start_address, sizeof(_bitparse_fixed_header)) != 0) {
return 0; /* Not matched */
} else {
bitparse_headers_start= ((char*)start_address) + sizeof(_bitparse_fixed_header);
bitparse_bitstream_end= (char*)end_address;
bitparse_initialized = 1;
return 1;
}
}
int bitparse_find_section(char section_name, void **section_start, unsigned int *section_length)
{
char *pos = bitparse_headers_start;
int result = 0;
if(!bitparse_initialized) return 0;
while(pos < bitparse_bitstream_end) {
char current_name = *pos++;
unsigned int current_length = 0;
if(current_name < 'a' || current_name > 'e') {
/* Strange section name, abort */
break;
}
current_length = 0;
switch(current_name) {
case 'e':
/* Four byte length field */
current_length += (*pos++) << 24;
current_length += (*pos++) << 16;
default: /* Fall through, two byte length field */
current_length += (*pos++) << 8;
current_length += (*pos++) << 0;
}
if(current_name != 'e' && current_length > 255) {
/* Maybe a parse error */
break;
}
if(current_name == section_name) {
/* Found it */
*section_start = pos;
*section_length = current_length;
result = 1;
break;
}
pos += current_length; /* Skip section */
}
return result;
}
//-----------------------------------------------------------------------------
// Find out which FPGA image format is stored in flash, then call DownloadFPGA
// with the right parameters to download the image
//-----------------------------------------------------------------------------
extern char _binary_fpga_bit_start, _binary_fpga_bit_end;
void FpgaDownloadAndGo(void)
{
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
*/
if(bitparse_init(&_binary_fpga_bit_start, &_binary_fpga_bit_end)) {
/* Successfully initialized the .bit parser. Find the 'e' section and
* send its contents to the FPGA.
*/
void *bitstream_start;
unsigned int bitstream_length;
if(bitparse_find_section('e', &bitstream_start, &bitstream_length)) {
DownloadFPGA((DWORD *)bitstream_start, bitstream_length/4, 0);
return; /* All done */
}
}
/* Fallback for the old flash image format: Check for the magic marker 0xFFFFFFFF
* 0xAA995566 at address 0x2000. This is raw bitstream with a size of 336,768 bits
* = 10,524 DWORDs, stored as DWORDS e.g. little-endian in memory, but each DWORD
* is still to be transmitted in MSBit first order. Set the invert flag to indicate
* that the DownloadFPGA function should invert every 4 byte sequence when doing
* the bytewise download.
*/
if( *(DWORD*)0x2000 == 0xFFFFFFFF && *(DWORD*)0x2004 == 0xAA995566 )
DownloadFPGA((DWORD *)0x2000, 10524, 1);
}
//-----------------------------------------------------------------------------
// Send a 16 bit command/data pair to the FPGA.
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

View file

@ -3,7 +3,10 @@ INCLUDE ../common/ldscript.common
ENTRY(Vector)
SECTIONS
{
.start : { obj/start.o(.text) } >osimage
fpgaimage : {
*(fpga_bit.data)
} >fpgaimage
.start : { *(.startos) } >osimage
.text : {
*(.text)
*(.text.*)

View file

@ -1,15 +0,0 @@
INCLUDE ../common/ldscript.common
SECTIONS
{
fpgaimage : {
obj/fpgaimg.o(.text) *(.text)
*(.rodata)
*(.glue_7)
*(.glue_7t)
} >fpgaimage
.data : { *(.data) } >ram
__bss_start__ = .;
.bss : { *(.bss) } >ram
__bss_end__ = .;
}

View file

@ -1,14 +0,0 @@
SECTIONS
{
. = 0x00002000;
.fpga : { obj/fpgaimg.o(.rodata) }
. = 0x00010000;
.start : { obj/start.o(.text) }
.text : { *(.text) }
.rodata : { *(.rodata) }
. = 0x00200000;
.data : { *(.data) }
__bss_start__ = .;
.bss : { *(.bss) }
__bss_end__ = .;
}

View file

@ -6,7 +6,7 @@
#include <proxmark3.h>
#include "apps.h"
void Vector(void)
void __attribute__((section(".startos"))) Vector(void)
{
AppMain();
}