add: hw ver: show FPGA versions for both HF and LF FPGA configs

add: hw ver: show used and free flash memory
chg: prepare fpgaloader for compressed FPGA configs
This commit is contained in:
pwpiwi 2015-04-05 19:15:02 +02:00
commit e61530408c
19 changed files with 5137 additions and 134 deletions

View file

@ -30,7 +30,8 @@ THUMBSRC = start.c \
util.c \
string.c \
usb_cdc.c \
cmd.c
cmd.c \
inflate.c
# These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \

View file

@ -310,7 +310,7 @@ void ReadMem(int addr)
/* osimage version information is linked in */
extern struct version_information version_information;
/* bootrom version information is pointed to from _bootphase1_version_pointer */
extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __os_size__;
void SendVersion(void)
{
char temp[512]; /* Limited data payload in USB packets */
@ -331,10 +331,13 @@ void SendVersion(void)
FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
DbpString(temp);
FpgaGatherVersion(temp, sizeof(temp));
FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
DbpString(temp);
// Send Chip ID
cmd_send(CMD_ACK,*(AT91C_DBGU_CIDR),0,0,NULL,0);
FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
DbpString(temp);
// Send Chip ID and used flash memory
cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), (uint32_t)&_bootrom_end - (uint32_t)&_bootrom_start + (uint32_t)&__os_size__, 0, NULL, 0);
}
#ifdef WITH_LF

View file

@ -55,7 +55,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v);
void FpgaWriteConfWord(uint8_t v);
void FpgaDownloadAndGo(int bitstream_version);
int FpgaGatherBitstreamVersion();
void FpgaGatherVersion(char *dst, int len);
void FpgaGatherVersion(int bitstream_version, char *dst, int len);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, int len);

BIN
armsrc/fpga_hf.bit.gz Normal file

Binary file not shown.

BIN
armsrc/fpga_lf.bit.gz Normal file

Binary file not shown.

View file

@ -14,6 +14,19 @@
#include "util.h"
#include "string.h"
// remember which version of the bitstream we have already downloaded to the FPGA
static int downloaded_bitstream = FPGA_BITSTREAM_ERR;
// this is where the bitstreams are located in memory:
extern uint8_t _binary_fpga_lf_bit_start, _binary_fpga_lf_bit_end;
extern uint8_t _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
static uint8_t *fpga_image_ptr = NULL;
static const uint8_t _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
static const uint8_t _gzip_header[] = {0x1f, 0x8b, 0x08}; // including compression method 0x08 (deflate)
#define GZIP_HEADER_SIZE sizeof(_gzip_header)
#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(_bitparse_fixed_header)
//-----------------------------------------------------------------------------
// Set up the Serial Peripheral Interface as master
// Used to write the FPGA config word
@ -150,6 +163,19 @@ bool FpgaSetupSscDma(uint8_t *buf, int len)
return true;
}
void reset_fpga_stream(uint8_t *image_start)
{
fpga_image_ptr = image_start;
}
uint8_t get_from_fpga_stream(void)
{
return *fpga_image_ptr++;
}
static void DownloadFPGA_byte(unsigned char w)
{
#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); }
@ -163,9 +189,8 @@ static void DownloadFPGA_byte(unsigned char w)
SEND_BIT(0);
}
// Download the fpga image starting at FpgaImage and with length FpgaImageLen bytes
// If bytereversal is set: reverse the byte order in each 4-byte word
static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int bytereversal)
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
static void DownloadFPGA(int FpgaImageLen)
{
int i=0;
@ -218,21 +243,8 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
return;
}
if(bytereversal) {
/* This is only supported for uint32_t aligned images */
if( ((int)FpgaImage % sizeof(uint32_t)) == 0 ) {
i=0;
while(FpgaImageLen-->0)
DownloadFPGA_byte(FpgaImage[(i++)^0x3]);
/* Explanation of the magic in the above line:
* i^0x3 inverts the lower two bits of the integer i, counting backwards
* for each 4 byte increment. The generated sequence of (i++)^3 is
* 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 etc. pp.
*/
}
} else {
while(FpgaImageLen-->0)
DownloadFPGA_byte(*FpgaImage++);
while(FpgaImageLen-->0) {
DownloadFPGA_byte(get_from_fpga_stream());
}
// continue to clock FPGA until ready signal goes high
@ -250,39 +262,21 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
LED_D_OFF();
}
static char *bitparse_headers_start;
static char *bitparse_bitstream_end;
static int bitparse_initialized = 0;
/* 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)
int bitparse_find_section(char section_name, unsigned int *section_length)
{
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, char **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++;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
uint16_t numbytes = 0;
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
char current_name = get_from_fpga_stream();
numbytes++;
unsigned int current_length = 0;
if(current_name < 'a' || current_name > 'e') {
/* Strange section name, abort */
@ -292,11 +286,13 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
switch(current_name) {
case 'e':
/* Four byte length field */
current_length += (*pos++) << 24;
current_length += (*pos++) << 16;
current_length += get_from_fpga_stream() << 24;
current_length += get_from_fpga_stream() << 16;
numbytes += 2;
default: /* Fall through, two byte length field */
current_length += (*pos++) << 8;
current_length += (*pos++) << 0;
current_length += get_from_fpga_stream() << 8;
current_length += get_from_fpga_stream() << 0;
numbytes += 2;
}
if(current_name != 'e' && current_length > 255) {
@ -306,108 +302,136 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
if(current_name == section_name) {
/* Found it */
*section_start = pos;
*section_length = current_length;
result = 1;
break;
}
pos += current_length; /* Skip section */
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
get_from_fpga_stream();
numbytes++;
}
}
return result;
}
void init_fpga_inflate(void)
{
// initialize zlib for inflate
}
//-----------------------------------------------------------------------------
// 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_lf_bit_start, _binary_fpga_lf_bit_end;
extern char _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
void FpgaDownloadAndGo(int bitstream_version)
{
void *bit_start;
void *bit_end;
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
// check whether or not the bitstream is already loaded
if (FpgaGatherBitstreamVersion() == bitstream_version)
if (downloaded_bitstream == bitstream_version)
return;
if (bitstream_version == FPGA_BITSTREAM_LF) {
bit_start = &_binary_fpga_lf_bit_start;
bit_end = &_binary_fpga_lf_bit_end;
reset_fpga_stream(&_binary_fpga_lf_bit_start);
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
bit_start = &_binary_fpga_hf_bit_start;
bit_end = &_binary_fpga_hf_bit_end;
reset_fpga_stream(&_binary_fpga_hf_bit_start);
} else
return;
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
*/
if(bitparse_init(bit_start, bit_end)) {
/* Successfully initialized the .bit parser. Find the 'e' section and
* send its contents to the FPGA.
*/
char *bitstream_start;
unsigned int bitstream_length;
if(bitparse_find_section('e', &bitstream_start, &bitstream_length)) {
DownloadFPGA(bitstream_start, bitstream_length, 0);
uint16_t i = 0;
for (; i < GZIP_HEADER_SIZE; i++) {
header[i] = get_from_fpga_stream();
}
// Check for compressed new flash image format (starts with gzip header)
if(memcmp(_gzip_header, header, GZIP_HEADER_SIZE) == 0) {
init_fpga_inflate();
}
for (; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
header[i] = get_from_fpga_stream();
}
// Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
if(memcmp(_bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
unsigned int bitstream_length;
if(bitparse_find_section('e', &bitstream_length)) {
DownloadFPGA(bitstream_length);
downloaded_bitstream = bitstream_version;
return; /* All done */
}
}
/* Fallback for the old flash image format: Check for the magic marker 0xFFFFFFFF
* 0xAA995566 at address 0x102000. This is raw bitstream with a size of 336,768 bits
* = 10,524 uint32_t, stored as uint32_t 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( *(uint32_t*)0x102000 == 0xFFFFFFFF && *(uint32_t*)0x102004 == 0xAA995566 )
DownloadFPGA((char*)0x102000, 10524*4, 1);
}
}
int FpgaGatherBitstreamVersion()
{
char temp[256];
FpgaGatherVersion(temp, sizeof (temp));
if (!memcmp("LF", temp, 2))
return FPGA_BITSTREAM_LF;
else if (!memcmp("HF", temp, 2))
return FPGA_BITSTREAM_HF;
return FPGA_BITSTREAM_ERR;
return downloaded_bitstream;
}
void FpgaGatherVersion(char *dst, int len)
void FpgaGatherVersion(int bitstream_version, char *dst, int len)
{
char *fpga_info;
unsigned int fpga_info_len;
dst[0] = 0;
if(!bitparse_find_section('e', &fpga_info, &fpga_info_len)) {
strncat(dst, "FPGA image: legacy image without version information", len-1);
} else {
/* USB packets only have 48 bytes data payload, so be terse */
if(bitparse_find_section('a', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
if (!memcmp("fpga_lf", fpga_info, 7))
strncat(dst, "LF ", len-1);
else if (!memcmp("fpga_hf", fpga_info, 7))
strncat(dst, "HF ", len-1);
char tempstr[40];
dst[0] = '\0';
if (bitstream_version == FPGA_BITSTREAM_LF) {
reset_fpga_stream(&_binary_fpga_lf_bit_start);
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
reset_fpga_stream(&_binary_fpga_hf_bit_start);
} else
return;
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
get_from_fpga_stream();
}
if(bitparse_find_section('a', &fpga_info_len)) {
for (uint16_t i = 0; i < fpga_info_len; i++) {
char c = (char)get_from_fpga_stream();
if (i < sizeof(tempstr)) {
tempstr[i] = c;
}
}
strncat(dst, "FPGA image built", len-1);
#if 0
if(bitparse_find_section('b', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
strncat(dst, " for ", len-1);
strncat(dst, fpga_info, len-1);
if (!memcmp("fpga_lf", tempstr, 7))
strncat(dst, "LF ", len-1);
else if (!memcmp("fpga_hf", tempstr, 7))
strncat(dst, "HF ", len-1);
}
strncat(dst, "FPGA image built", len-1);
if(bitparse_find_section('b', &fpga_info_len)) {
strncat(dst, " for ", len-1);
for (uint16_t i = 0; i < fpga_info_len; i++) {
char c = (char)get_from_fpga_stream();
if (i < sizeof(tempstr)) {
tempstr[i] = c;
}
}
#endif
if(bitparse_find_section('c', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
strncat(dst, " on ", len-1);
strncat(dst, fpga_info, len-1);
strncat(dst, tempstr, len-1);
}
if(bitparse_find_section('c', &fpga_info_len)) {
strncat(dst, " on ", len-1);
for (uint16_t i = 0; i < fpga_info_len; i++) {
char c = (char)get_from_fpga_stream();
if (i < sizeof(tempstr)) {
tempstr[i] = c;
}
}
if(bitparse_find_section('d', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
strncat(dst, " at ", len-1);
strncat(dst, fpga_info, len-1);
strncat(dst, tempstr, len-1);
}
if(bitparse_find_section('d', &fpga_info_len)) {
strncat(dst, " at ", len-1);
for (uint16_t i = 0; i < fpga_info_len; i++) {
char c = (char)get_from_fpga_stream();
if (i < sizeof(tempstr)) {
tempstr[i] = c;
}
}
strncat(dst, tempstr, len-1);
}
}

11
armsrc/inffast.h Normal file
View file

@ -0,0 +1,11 @@
/* inffast.h -- header to use inffast.c
* Copyright (C) 1995-2003, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));

94
armsrc/inffixed.h Normal file
View file

@ -0,0 +1,94 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* WARNING: this file should *not* be used by applications.
It is part of the implementation of this library and is
subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};

1512
armsrc/inflate.c Normal file

File diff suppressed because it is too large Load diff

122
armsrc/inflate.h Normal file
View file

@ -0,0 +1,122 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2009 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN_, /* i: same as LEN below, but only first time in */
LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to BAD or MEM on error -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib) or (raw)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
(raw) -> TYPEDO
Read deflate blocks:
TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
STORED -> COPY_ -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN_
LEN_ -> LEN
Read deflate codes in fixed or dynamic block:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 10K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
int sane; /* if false, allow invalid distance too far */
int back; /* bits back of last unprocessed length/lit */
unsigned was; /* initial length of match */
};

62
armsrc/inftrees.h Normal file
View file

@ -0,0 +1,62 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2005, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
/* op values as set by inflate_table():
00000000 - literal
0000tttt - table link, tttt != 0 is the number of table index bits
0001eeee - length or distance, eeee is the number of extra bits
01100000 - end of block
01000000 - invalid code
*/
/* Maximum size of the dynamic table. The maximum number of code structures is
1444, which is the sum of 852 for literal/length codes and 592 for distance
codes. These values were found by exhaustive searches using the program
examples/enough.c found in the zlib distribtution. The arguments to that
program are the number of symbols, the initial root table size, and the
maximum bit length of a code. "enough 286 9 15" for literal/length codes
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
The initial root table size (9 or 6) is found in the fifth argument of the
inflate_table() calls in inflate.c and infback.c. If the root table size is
changed, then these maximum sizes would be need to be recalculated and
updated. */
#define ENOUGH_LENS 852
#define ENOUGH_DISTS 592
#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
/* Type of code to build for inflate_table() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));

View file

@ -51,6 +51,7 @@ SECTIONS
__data_src_start__ = LOADADDR(.data);
__data_start__ = ADDR(.data);
__data_end__ = __data_start__ + SIZEOF(.data);
__os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata);
.bss : {
__bss_start__ = .;

511
armsrc/zconf.h Normal file
View file

@ -0,0 +1,511 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
* Even better than compiling with -DZ_PREFIX would be to use configure to set
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
# define _tr_tally z__tr_tally
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
# ifndef Z_SOLO
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
# define deflate z_deflate
# define deflateBound z_deflateBound
# define deflateCopy z_deflateCopy
# define deflateEnd z_deflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
# ifndef Z_SOLO
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf
# define gzvprintf z_gzvprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzwrite z_gzwrite
# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define inflateBackInit_ z_inflateBackInit_
# define inflateCopy z_inflateCopy
# define inflateEnd z_inflateEnd
# define inflateGetHeader z_inflateGetHeader
# define inflateInit2_ z_inflateInit2_
# define inflateInit_ z_inflateInit_
# define inflateMark z_inflateMark
# define inflatePrime z_inflatePrime
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
# ifndef Z_SOLO
# define uncompress z_uncompress
# endif
# define zError z_zError
# ifndef Z_SOLO
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
/* all zlib typedefs in zlib.h and zconf.h */
# define Byte z_Byte
# define Bytef z_Bytef
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
# ifndef Z_SOLO
# define gzFile z_gzFile
# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
# define intf z_intf
# define out_func z_out_func
# define uInt z_uInt
# define uIntf z_uIntf
# define uLong z_uLong
# define uLongf z_uLongf
# define voidp z_voidp
# define voidpc z_voidpc
# define voidpf z_voidpf
/* all zlib structs in zlib.h and zconf.h */
# define gz_header_s z_gz_header_s
# define internal_state z_internal_state
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
* though the former does not conform to the LFS document), but considering
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif
#endif
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
#pragma map(deflateInit_,"DEIN")
#pragma map(deflateInit2_,"DEIN2")
#pragma map(deflateEnd,"DEEND")
#pragma map(deflateBound,"DEBND")
#pragma map(inflateInit_,"ININ")
#pragma map(inflateInit2_,"ININ2")
#pragma map(inflateEnd,"INEND")
#pragma map(inflateSync,"INSY")
#pragma map(inflateSetDictionary,"INSEDI")
#pragma map(compressBound,"CMBND")
#pragma map(inflate_table,"INTABL")
#pragma map(inflate_fast,"INFA")
#pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

1768
armsrc/zlib.h Normal file

File diff suppressed because it is too large Load diff

253
armsrc/zutil.h Normal file
View file

@ -0,0 +1,253 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
#endif
#include "zlib.h"
#if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# endif
# include <string.h>
# include <stdlib.h>
#endif
#ifdef Z_SOLO
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
typedef unsigned char uch;
typedef uch FAR uchf;
typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
#ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS
#endif
/* default windowBits for decompression. MAX_WBITS is for compression only */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default memLevel */
#define STORED_BLOCK 0
#define STATIC_TREES 1
#define DYN_TREES 2
/* The three kinds of block type */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
# ifndef Z_SOLO
# if defined(__TURBOC__) || defined(__BORLANDC__)
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
# endif
#endif
#ifdef AMIGA
# define OS_CODE 0x01
#endif
#if defined(VAXC) || defined(VMS)
# define OS_CODE 0x02
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
#if defined(ATARI) || defined(atarist)
# define OS_CODE 0x05
#endif
#ifdef OS2
# define OS_CODE 0x06
# if defined(M_I86) && !defined(Z_SOLO)
# include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07
# ifndef Z_SOLO
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fdopen */
# else
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif
# endif
#endif
#ifdef TOPS20
# define OS_CODE 0x0a
#endif
#ifdef WIN32
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
# define OS_CODE 0x0b
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0f
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif
#if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004
#pragma warn -8008
#pragma warn -8066
#endif
/* provide prototypes for these when building zlib without LFS */
#if !defined(_WIN32) && \
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
#endif
/* common defaults */
#ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */
#endif
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
#if defined(pyr) || defined(Z_SOLO)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* Use our own functions for small and medium model with MSC <= 5.0.
* You may have to use the same strategy for Borland C (untested).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
# define HAVE_MEMCPY
#endif
#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len)
# else
# define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef DEBUG
# include <stdio.h>
extern int ZLIB_INTERNAL z_verbose;
extern void ZLIB_INTERNAL z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
#ifndef Z_SOLO
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
unsigned size));
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
#endif
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
/* Reverse the bytes in a 32-bit value */
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
#endif /* ZUTIL_H */

View file

@ -12,7 +12,8 @@ CXX=g++
VPATH = ../common
OBJDIR = obj
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
LUALIB = ../liblua/liblua.a
LDFLAGS = $(COMMON_FLAGS)
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
LUAPLATFORM = generic
@ -108,15 +109,15 @@ COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
RM = rm -f
BINS = proxmark3 flasher #snooper cli
BINS = proxmark3 flasher fpga_compress #snooper cli
CLEAN = cli cli.exe flasher flasher.exe proxmark3 proxmark3.exe snooper snooper.exe $(CMDOBJS) $(OBJDIR)/*.o *.o *.moc.cpp
all: lua_build $(BINS)
all-static: LDLIBS:=-static $(LDLIBS)
all-static: snooper cli flasher
all-static: snooper cli flasher fpga_compress
proxmark3: LDLIBS+=$(QTLDLIBS)
proxmark3: LDLIBS+=$(QTLDLIBS) $(LUALIB)
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUI)
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
@ -129,6 +130,9 @@ cli: $(OBJDIR)/cli.o $(COREOBJS) $(CMDOBJS) $(OBJDIR)/guidummy.o
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
fpga_compress: $(OBJDIR)/fpga_compress.o
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<

408
client/cmdhftopaz.c Normal file
View file

@ -0,0 +1,408 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2015 Piwi
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// High frequency Topaz (NFC Type 1) commands
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cmdmain.h"
#include "cmdparser.h"
#include "cmdhftopaz.h"
#include "cmdhf14a.h"
#include "ui.h"
#include "mifare.h"
#include "proxmark3.h"
#include "iso14443crc.h"
#include "protocols.h"
#define TOPAZ_MAX_MEMORY 2048
static struct {
uint8_t HR01[2];
uint8_t uid[7];
uint8_t size;
uint8_t data_blocks[TOPAZ_MAX_MEMORY/8][8];
uint8_t *dynamic_lock_areas;
uint8_t *dynamic_reserved_areas;
} topaz_tag;
static void topaz_switch_on_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, 0, 0}};
SendCommand(&c);
}
static void topaz_switch_off_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
SendCommand(&c);
}
static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, len, 0}};
memcpy(c.d.asBytes, cmd, len);
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK, &resp);
if (resp.arg[0] > 0) {
memcpy(response, resp.d.asBytes, resp.arg[0]);
}
return resp.arg[0];
}
static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
{
if (len > 1) {
uint8_t first, second;
ComputeCrc14443(CRC_14443_B, cmd, len-2, &first, &second);
cmd[len-2] = first;
cmd[len-1] = second;
}
return topaz_send_cmd_raw(cmd, len, response);
}
static int topaz_select(uint8_t *atqa, uint8_t *rid_response)
{
// ToDo: implement anticollision
uint8_t wupa_cmd[] = {TOPAZ_WUPA};
uint8_t rid_cmd[] = {TOPAZ_RID, 0, 0, 0, 0, 0, 0, 0, 0};
topaz_switch_on_field();
if (!topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa)) {
topaz_switch_off_field();
return -1; // WUPA failed
}
if (!topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response)) {
topaz_switch_off_field();
return -2; // RID failed
}
return 0; // OK
}
static int topaz_rall(uint8_t *uid, uint8_t *response)
{
uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0};
memcpy(&rall_cmd[3], uid, 4);
if (!topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response)) {
topaz_switch_off_field();
return -1; // RALL failed
}
return 0;
}
static bool topaz_block_is_locked(uint8_t blockno, uint8_t *lockbits)
{
if(lockbits[blockno/8] >> (blockno % 8) & 0x01) {
return true;
} else {
return false;
}
}
static int topaz_print_CC(uint8_t *data)
{
if(data[0] != 0xe1) {
return -1; // no NDEF message
}
PrintAndLog("Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
PrintAndLog(" %02x: NDEF Magic Number", data[0]);
PrintAndLog(" %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
PrintAndLog(" %02x: Physical Memory Size of this tag: %d bytes", data[2], (data[2] + 1) * 8);
PrintAndLog(" %02x: %s / %s", data[3],
(data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
(data[3] & 0x0F)==0 ? "Write access granted without any security" : (data[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
return 0;
}
static void get_TLV(uint8_t **TLV_ptr, uint8_t *tag, uint16_t *length, uint8_t **value)
{
*length = 0;
*value = NULL;
*tag = **TLV_ptr;
*TLV_ptr += 1;
switch (*tag) {
case 0x00: // NULL TLV.
case 0xFE: // Terminator TLV.
break;
case 0x01: // Lock Control TLV
case 0x02: // Reserved Memory TLV
case 0x03: // NDEF message TLV
case 0xFD: // proprietary TLV
*length = **TLV_ptr;
*TLV_ptr += 1;
if (*length == 0xff) {
*length = **TLV_ptr << 8;
*TLV_ptr += 1;
*length |= **TLV_ptr;
*TLV_ptr += 1;
}
*value = *TLV_ptr;
*TLV_ptr += *length;
break;
default: // RFU
break;
}
}
static bool topaz_print_lock_control_TLVs(uint8_t *memory)
{
uint8_t *TLV_ptr = memory;
uint8_t tag = 0;
uint16_t length;
uint8_t *value;
bool lock_TLV_present = false;
while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
// all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV)
get_TLV(&TLV_ptr, &tag, &length, &value);
if (tag == 0x01) { // the Lock Control TLV
uint8_t pages_addr = value[0] >> 4;
uint8_t byte_offset = value[0] & 0x0f;
uint8_t size_in_bits = value[1] ? value[1] : 256;
uint8_t bytes_per_page = 1 << (value[2] & 0x0f);
uint8_t bytes_locked_per_bit = 1 << (value[2] >> 4);
PrintAndLog("Lock Area of %d bits at byte offset 0x%02x. Each Lock Bit locks %d bytes.",
size_in_bits,
pages_addr * bytes_per_page + byte_offset,
bytes_locked_per_bit);
lock_TLV_present = true;
}
}
if (!lock_TLV_present) {
PrintAndLog("(No Lock Control TLV present)");
return -1;
} else {
return 0;
}
}
static int topaz_print_reserved_memory_control_TLVs(uint8_t *memory)
{
uint8_t *TLV_ptr = memory;
uint8_t tag = 0;
uint16_t length;
uint8_t *value;
bool reserved_memory_control_TLV_present = false;
while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
// all Reserved Memory Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV)
get_TLV(&TLV_ptr, &tag, &length, &value);
if (tag == 0x02) { // the Reserved Memory Control TLV
uint8_t pages_addr = value[0] >> 4;
uint8_t byte_offset = value[0] & 0x0f;
uint8_t size_in_bytes = value[1] ? value[1] : 256;
uint8_t bytes_per_page = 1 << (value[2] & 0x0f);
PrintAndLog("Reserved Memory of %d bytes at byte offset 0x%02x.",
size_in_bytes,
pages_addr * bytes_per_page + byte_offset);
reserved_memory_control_TLV_present = true;
}
}
if (!reserved_memory_control_TLV_present) {
PrintAndLog("(No Reserved Memory Control TLV present)");
return -1;
} else {
return 0;
}
}
static void topaz_print_lifecycle_state(uint8_t *data)
{
}
static void topaz_print_NDEF(uint8_t *data)
{
}
int CmdHFTopazReader(const char *Cmd)
{
int status;
uint8_t atqa[2];
uint8_t rid_response[8];
uint8_t *uid_echo = &rid_response[2];
uint8_t rall_response[124];
status = topaz_select(atqa, rid_response);
if (status == -1) {
PrintAndLog("Error: couldn't receive ATQA");
return -1;
}
PrintAndLog("ATQA : %02x %02x", atqa[1], atqa[0]);
if (atqa[1] != 0x0c && atqa[0] != 0x00) {
PrintAndLog("Tag doesn't support the Topaz protocol.");
topaz_switch_off_field();
return -1;
}
if (status == -2) {
PrintAndLog("Error: tag didn't answer to RID");
topaz_switch_off_field();
return -1;
}
topaz_tag.HR01[0] = rid_response[0];
topaz_tag.HR01[1] = rid_response[1];
// ToDo: CRC check
PrintAndLog("HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", rid_response[0],
(rid_response[0] & 0xF0) == 0x10 ? "" : "not ",
(rid_response[0] & 0xF0) == 0x10 ? "" : "not ",
(rid_response[0] & 0x0F) == 0x10 ? "static" : "dynamic");
PrintAndLog("HR1 : %02x", rid_response[1]);
status = topaz_rall(uid_echo, rall_response);
if(status == -1) {
PrintAndLog("Error: tag didn't answer to RALL");
topaz_switch_off_field();
return -1;
}
memcpy(topaz_tag.uid, rall_response+2, 7);
PrintAndLog("UID : %02x %02x %02x %02x %02x %02x %02x",
topaz_tag.uid[6],
topaz_tag.uid[5],
topaz_tag.uid[4],
topaz_tag.uid[3],
topaz_tag.uid[2],
topaz_tag.uid[1],
topaz_tag.uid[0]);
PrintAndLog(" UID[6] (Manufacturer Byte) = %02x, Manufacturer: %s",
topaz_tag.uid[6],
getTagInfo(topaz_tag.uid[6]));
memcpy(topaz_tag.data_blocks, rall_response+2, 0x10*8);
PrintAndLog("");
PrintAndLog("Static Data blocks 00 to 0c:");
PrintAndLog("block# | offset | Data | Locked?");
char line[80];
for (uint16_t i = 0; i <= 0x0c; i++) {
for (uint16_t j = 0; j < 8; j++) {
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/);
}
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0d][0]) ? "yes" : "no");
}
PrintAndLog("");
PrintAndLog("Static Reserved block 0d:");
for (uint16_t j = 0; j < 8; j++) {
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[0x0d][j]);
}
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d*8, line, "n/a");
PrintAndLog("");
PrintAndLog("Static Lockbits and OTP Bytes:");
for (uint16_t j = 0; j < 8; j++) {
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[0x0e][j]);
}
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e*8, line, "n/a");
PrintAndLog("");
status = topaz_print_CC(&topaz_tag.data_blocks[1][0]);
if (status == -1) {
PrintAndLog("No NDEF message present");
topaz_switch_off_field();
return 0;
}
PrintAndLog("");
bool lock_TLV_present = topaz_print_lock_control_TLVs(&topaz_tag.data_blocks[1][4]);
PrintAndLog("");
bool reserved_mem_present = topaz_print_reserved_memory_control_TLVs(&topaz_tag.data_blocks[1][4]);
topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]);
topaz_print_NDEF(&topaz_tag.data_blocks[1][0]);
topaz_switch_off_field();
return 0;
}
int CmdHFTopazSim(const char *Cmd)
{
PrintAndLog("not yet implemented");
return 0;
}
int CmdHFTopazCmdRaw(const char *Cmd)
{
PrintAndLog("not yet implemented");
return 0;
}
static int CmdHelp(const char *Cmd);
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"reader", CmdHFTopazReader, 0, "Act like a Topaz reader"},
{"sim", CmdHFTopazSim, 0, "<UID> -- Simulate Topaz tag"},
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop a Topaz reader-tag communication"},
{"raw", CmdHFTopazCmdRaw, 0, "Send raw hex data to tag"},
{NULL, NULL, 0, NULL}
};
int CmdHFTopaz(const char *Cmd) {
// flush
WaitForResponseTimeout(CMD_ACK,NULL,100);
// parse
CmdsParse(CommandTable, Cmd);
return 0;
}
static int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -23,9 +23,11 @@
static int CmdHelp(const char *Cmd);
static void lookupChipID(uint32_t iChipID)
static void lookupChipID(uint32_t iChipID, uint32_t mem_used)
{
char asBuff[100];
uint32_t mem_avail = 0;
switch(iChipID)
{
case 0x270B0A40:
@ -103,37 +105,43 @@ static void lookupChipID(uint32_t iChipID)
switch((iChipID&0xF00)>>8)
{
case 0:
sprintf(asBuff,"None");
mem_avail = 0;
break;
case 1:
sprintf(asBuff,"8K bytes");
mem_avail = 8;
break;
case 2:
sprintf(asBuff,"16K bytes");
mem_avail = 16;
break;
case 3:
sprintf(asBuff,"32K bytes");
mem_avail = 32;
break;
case 5:
sprintf(asBuff,"64K bytes");
mem_avail = 64;
break;
case 7:
sprintf(asBuff,"128K bytes");
mem_avail = 128;
break;
case 9:
sprintf(asBuff,"256K bytes");
mem_avail = 256;
break;
case 10:
sprintf(asBuff,"512K bytes");
mem_avail = 512;
break;
case 12:
sprintf(asBuff,"1024K bytes");
mem_avail = 1024;
break;
case 14:
sprintf(asBuff,"2048K bytes");
mem_avail = 2048;
break;
}
PrintAndLog("Nonvolatile Program Memory Size: %s",asBuff);
PrintAndLog("Nonvolatile Program Memory Size: %dK bytes. Used: %d bytes (%2.0f\%). Free: %d bytes (%2.0f\%).",
mem_avail,
mem_used,
mem_avail == 0 ? 0 : (float)mem_used/(mem_avail*1024)*100,
mem_avail*1024 - mem_used,
mem_avail == 0 ? 0 : (float)(mem_avail*1024-mem_used)/(mem_avail*1024)*100
);
switch((iChipID&0xF000)>>12)
{
case 0:
@ -400,7 +408,7 @@ int CmdVersion(const char *Cmd)
UsbCommand resp;
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
lookupChipID(resp.arg[0]);
lookupChipID(resp.arg[0], resp.arg[1]);
}
return 0;
}

221
client/fpga_compress.c Normal file
View file

@ -0,0 +1,221 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Flasher frontend tool
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sleep.h"
#include "proxmark3.h"
#include "flash.h"
#include "uart.h"
#include "usb_cmd.h"
#define MAX(a,b) ((a)>(b)?(a):(b))
struct huffman_record {
int16_t symbol;
uint16_t count;
uint8_t code_size;
uint8_t code;
struct huffman_record *left;
struct huffman_record *right;
struct huffman_record *next;
};
typedef struct huffman_record huffman_record_t;
#define FPGA_CONFIG_SIZE 42175
static uint8_t fpga_config[FPGA_CONFIG_SIZE];
static huffman_record_t leaf_nodes[256];
static uint8_t start_code[256];
static void usage(char *argv0)
{
fprintf(stderr, "Usage: %s [-d] <infile> <outfile>\n\n", argv0);
fprintf(stderr, "\t-d\tdecompress\n\n");
}
void add_to_heap(huffman_record_t **heap, huffman_record_t *new_record)
{
huffman_record_t *succ = *heap;
huffman_record_t *pred = NULL;
// fprintf(stderr, "Adding symbol %d, count %d\n", new_record->symbol, new_record->count);
while (succ != NULL && new_record->count > succ->count) {
pred = succ;
succ = succ->next;
}
// insert new record
new_record->next = succ;
if (pred == NULL) { // first record in heap
*heap = new_record;
} else {
pred->next = new_record;
}
}
uint16_t set_codesize(huffman_record_t *tree_ptr, uint8_t depth)
{
uint16_t max_size = depth;
tree_ptr->code_size = depth;
if (tree_ptr->left != NULL) {
max_size = MAX(set_codesize(tree_ptr->left, depth+1), max_size);
}
if (tree_ptr->right != NULL) {
max_size = MAX(set_codesize(tree_ptr->right, depth+1), max_size);
}
return max_size;
}
int huffman_encode(FILE *infile, FILE *outfile)
{
int i;
// init leaf_nodes:
for (i = 0; i < 256; i++) {
leaf_nodes[i].count = 0;
leaf_nodes[i].symbol = i;
leaf_nodes[i].left = NULL;
leaf_nodes[i].right = NULL;
leaf_nodes[i].next = NULL;
}
// read the input file into fpga_config[] and count occurrences of each symbol:
i = 0;
while(!feof(infile)) {
uint8_t c;
c = fgetc(infile);
fpga_config[i++] = c;
leaf_nodes[c].count++;
if (i > FPGA_CONFIG_SIZE+1) {
fprintf(stderr, "Input file too big (> %d bytes). This is probably not a PM3 FPGA config file.", FPGA_CONFIG_SIZE);
fclose(infile);
fclose(outfile);
return -1;
}
}
fprintf(stderr, "\nStatistics: (symbol: count)\n");
for (i = 0; i < 256; i++) {
fprintf(stderr, "%3d: %5d\n", i, leaf_nodes[i].count);
}
// build the Huffman tree:
huffman_record_t *heap_ptr = NULL;
for (i = 0; i < 256; i++) {
add_to_heap(&heap_ptr, &leaf_nodes[i]);
}
fprintf(stderr, "\nSorted statistics: (symbol: count)\n");
for (huffman_record_t *p = heap_ptr; p != NULL; p = p->next) {
fprintf(stderr, "%3d: %5d\n", p->symbol, p->count);
}
for (i = 0; i < 255; i++) {
// remove and combine the first two nodes
huffman_record_t *p1, *p2;
p1 = heap_ptr;
p2 = heap_ptr->next;
heap_ptr = p2->next;
huffman_record_t *new_node = malloc(sizeof(huffman_record_t));
new_node->left = p1;
new_node->right = p2;
new_node->count = p1->count + p2->count;
add_to_heap(&heap_ptr, new_node);
}
uint16_t max_codesize = set_codesize(heap_ptr, 0);
fprintf(stderr, "\nStatistics: (symbol: count, codesize)\n");
uint32_t compressed_size = 0;
for (i = 0; i < 256; i++) {
fprintf(stderr, "%3d: %5d, %d\n", leaf_nodes[i].symbol, leaf_nodes[i].count, leaf_nodes[i].code_size);
compressed_size += leaf_nodes[i].count * leaf_nodes[i].code_size;
}
fprintf(stderr, "Compressed size = %ld (%f% of original size)", (compressed_size+7)/8, (float)(compressed_size)/(FPGA_CONFIG_SIZE * 8) * 100);
fprintf(stderr, "Max Codesize = %d bits", max_codesize);
uint8_t code = 0;
for (i = max_codesize; i > 0; i--) {
code = (code + 1) >> 1;
start_code[i] = code;
for (uint16_t j = 0; j < 256; j++) {
if (leaf_nodes[j].code_size == i) {
leaf_nodes[j].code = code;
code++;
}
}
}
fprintf(stderr, "\nStatistics: (symbol: count, codesize, code)\n");
for (i = 0; i < 256; i++) {
fprintf(stderr, "%3d: %5d, %d, %02x\n", leaf_nodes[i].symbol, leaf_nodes[i].count, leaf_nodes[i].code_size, leaf_nodes[i].code);
}
fclose(infile);
fclose(outfile);
return 0;
}
int huffman_decode(FILE *infile, FILE *outfile)
{
return 0;
}
int main(int argc, char **argv)
{
bool decode = false;
char *infilename;
char *outfilename;
if (argc < 3) {
usage(argv[0]);
return -1;
}
if (argc > 3) {
if (!strcmp(argv[1], "-d")) {
decode = true;
infilename = argv[2];
outfilename = argv[3];
} else {
usage(argv[0]);
return -1;
}
} else {
infilename = argv[1];
outfilename = argv[2];
}
FILE *infile = fopen(infilename, "rb");
if (infile == NULL) {
fprintf(stderr, "Error. Cannot open input file %s", infilename);
return -1;
}
FILE *outfile = fopen(outfilename, "wb");
if (outfile == NULL) {
fprintf(stderr, "Error. Cannot open output file %s", outfilename);
fclose(infile);
return -1;
}
if (decode) {
return huffman_decode(infile, outfile);
} else {
return huffman_encode(infile, outfile);
}
}