committing a bit more frequently because my HDD clicks strangely and

replacement only arrives tomorrow...
This commit is contained in:
Wolfgang Spraul 2012-06-27 09:28:24 +02:00
parent 8a0bff748d
commit 80459797ed

279
bit2txt.c
View File

@ -32,20 +32,33 @@ typedef struct
uint32_t code;
} IDCODE_S;
#define XC6SLX4 0x04000093
#define XC6SLX9 0x04001093
#define XC6SLX16 0x04002093
#define XC6SLX25 0x04004093
#define XC6SLX25T 0x04024093
#define XC6SLX45 0x04008093
#define XC6SLX45T 0x04028093
#define XC6SLX75 0x0400E093
#define XC6SLX75T 0x0402E093
#define XC6SLX100 0x04011093
#define XC6SLX100T 0x04031093
#define XC6SLX150 0x0401D093
const IDCODE_S idcodes[] =
{
{"XC6SLX4", 0x04000093},
{"XC6SLX9", 0x04001093},
{"XC6SLX16", 0x04002093},
{"XC6SLX25", 0x04004093},
{"XC6SLX25T", 0x04024093},
{"XC6SLX45", 0x04008093},
{"XC6SLX45T", 0x04028093},
{"XC6SLX75", 0x0400E093},
{"XC6SLX75T", 0x0402E093},
{"XC6SLX100", 0x04011093},
{"XC6SLX100T", 0x04031093},
{"XC6SLX150", 0x0401D093}
{"XC6SLX4", XC6SLX4},
{"XC6SLX9", XC6SLX9},
{"XC6SLX16", XC6SLX16},
{"XC6SLX25", XC6SLX25},
{"XC6SLX25T", XC6SLX25T},
{"XC6SLX45", XC6SLX45},
{"XC6SLX45T", XC6SLX45T},
{"XC6SLX75", XC6SLX75},
{"XC6SLX75T", XC6SLX75T},
{"XC6SLX100", XC6SLX100},
{"XC6SLX100T", XC6SLX100T},
{"XC6SLX150", XC6SLX150}
};
enum {
@ -270,13 +283,181 @@ void print_ramb16_cfg(ramb16_cfg_t* cfg)
printf("}\n");
}
int g_FLR_value = -1;
int full_map(uint8_t* bit_file, int bf_len, int first_FAR_off,
uint8_t** bits, int* bits_len, int idcode, int FLR_len, int* outdelta)
{
int src_off, packet_hdr_type, packet_hdr_opcode;
int packet_hdr_register, packet_hdr_wordcount;
int FAR_block, FAR_row, FAR_major, FAR_minor, i, j;
int offset_in_bits;
uint16_t u16;
uint32_t u32;
*bits = 0;
if (idcode != XC6SLX4) goto fail;
if (FLR_len != 896) goto fail;
*bits_len = 4*505 + 4*144 + 896*2;
*bits = calloc(*bits_len, 1 /* elsize */);
if (!(*bits)) {
fprintf(stderr, "#E Cannot allocate %i bytes for bits.\n",
*bits_len);
goto fail;
}
FAR_block = -1;
FAR_row = -1;
FAR_major = -1;
FAR_minor = -1;
// Go through bit_file from first_FAR_off until last byte of
// IOB was read, plus padding, plus CRC verification.
src_off = first_FAR_off;
while (src_off < bf_len) {
if (src_off + 2 > bf_len) goto fail;
u16 = __be16_to_cpu(*(uint16_t*)&bit_file[src_off]);
src_off += 2;
// 3 bits: 001 = Type 1; 010 = Type 2
packet_hdr_type = (u16 & 0xE000) >> 13;
if (packet_hdr_type != 1 && packet_hdr_type != 2)
goto fail;
// 2 bits: 00 = noop; 01 = read; 10 = write; 11 = reserved
packet_hdr_opcode = (u16 & 0x1800) >> 11;
if (packet_hdr_opcode == 3) goto fail;
if (packet_hdr_opcode == 0) { // noop
if (packet_hdr_type != 1 || u16 & 0x07FF) goto fail;
continue;
}
// Now we must look at a Type 1 command
packet_hdr_register = (u16 & 0x07E0) >> 5;
packet_hdr_wordcount = u16 & 0x001F;
if (src_off + packet_hdr_wordcount*2 > bf_len) goto fail;
src_off += 2;
if (packet_hdr_type == 1) {
if (packet_hdr_register == CMD) {
if (packet_hdr_wordcount != 1) goto fail;
u16 = __be16_to_cpu(
*(uint16_t*)&bit_file[src_off]);
if (u16 == CMD_GRESTORE || u16 == CMD_LFRM) {
src_off -= 2;
goto success;
}
if (u16 != CMD_MFW && u16 != CMD_WCFG)
goto fail;
src_off += 2;
continue;
}
if (packet_hdr_register == FAR_MAJ) {
uint16_t maj, min;
if (packet_hdr_wordcount != 2) goto fail;
maj = __be16_to_cpu(*(uint16_t*)
&bit_file[src_off]);
min = __be16_to_cpu(*(uint16_t*)
&bit_file[src_off+2]);
FAR_block = (maj & 0xF000) >> 12;
if (FAR_block > 7) goto fail;
FAR_row = (maj & 0x0F00) >> 8;
FAR_major = maj & 0x00FF;
// MINOR
FAR_minor = min & 0x03FF;
continue;
}
if (packet_hdr_register == MFWR) {
uint32_t first_dword, second_dword;
if (packet_hdr_wordcount != 4) goto fail;
first_dword = __be32_to_cpu(
*(uint32_t*)&bit_file[src_off]);
second_dword = __be32_to_cpu(
*(uint32_t*)&bit_file[src_off+4]);
if (first_dword || second_dword) goto fail;
src_off += 8;
continue;
}
goto fail;
}
// packet type must be 2 here
if (packet_hdr_wordcount != 0) goto fail;
if (packet_hdr_register != FDRI) goto fail;
if (src_off + 4 > bf_len) goto fail;
u32 = __be32_to_cpu(*(uint32_t*)&bit_file[src_off]);
src_off += 4;
if (src_off+2*u32 > bf_len) goto fail;
if (2*u32 < 130) goto fail;
// fdri words u32
if (FAR_block == -1 || FAR_row == -1
|| FAR_major == -1 || FAR_minor == -1)
goto fail;
if (!FAR_block) {
if (FAR_row > 3 || FAR_major > 17
|| FAR_minor >= majors[FAR_major].minors)
goto fail;
if (u32 % 65) goto fail;
offset_in_bits = FAR_row * 505*130;
for (i = 0; i < FAR_major; i++)
offset_in_bits += majors[i].minors*130;
offset_in_bits += FAR_minor*130;
for (i = 0; i < u32/65; i++) {
if (i && i+1 == u32/65) {
for (j = 0; j < 130; j++) {
if (bit_file[src_off+i*130+j]
!= 0xFF) goto fail;
}
break;
}
if (!FAR_major && !FAR_minor
&& (i%507 == 505)) {
for (j = 0; j < 2*130; j++) {
if (bit_file[src_off+i*130+j]
!= 0xFF) goto fail;
}
i++;
continue;
}
memcpy(&(*bits)[offset_in_bits],
&bit_file[src_off + i*130], 130);
}
} else if (FAR_block == 1) {
int bram_data_words = 4*144*65 + 896;
if (u32 != bram_data_words + 1) goto fail;
offset_in_bits = 4*505*130;
memcpy(&(*bits)[offset_in_bits],
&bit_file[src_off], bram_data_words*2);
u16 = __be16_to_cpu(*(uint16_t*)&bit_file[src_off+bram_data_words*2]);
if (u16 != 0xFFFF) goto fail;
} else goto fail;
src_off += 2*u32;
// CRC word?
}
fail:
free(*bits);
*bits = 0;
return -1;
success:
*outdelta = src_off - first_FAR_off;
return 0;
}
void printf_bits(uint8_t* bits, int bits_len, int idcode)
{
printf("\nbits\n");
}
int main(int argc, char** argv)
{
uint8_t* bit_data = 0;
uint8_t* bit_data = 0; // file contents
uint8_t* bits = 0; // bits in chip layout
FILE* bitf = 0;
int bit_cur;
int bit_cur, try_full_map, first_FAR_off, bits_len;
uint32_t bit_eof, cmd_len, u32, u16_off, bit_off;
uint32_t last_processed_pos;
uint16_t u16, packet_hdr_type, packet_hdr_opcode;
@ -285,6 +466,10 @@ int main(int argc, char** argv)
char* bit_path = 0;
int i, j, k, l, num_frames, max_frames_to_scan, offset_in_frame, times;
// state machine driven from file input
int m_FLR_value = -1;
int m_idcode = -1; // offset into idcodes
//
// parse command line
//
@ -323,7 +508,7 @@ int main(int argc, char** argv)
bit_data = malloc(BITSTREAM_READ_MAXPAGES * BITSTREAM_READ_PAGESIZE);
if (!bit_data) {
fprintf(stderr, "#E Cannot allocate %i bytes for bitstream.\n",
fprintf(stderr, "#E Cannot allocate %i bytes for filebuf.\n",
BITSTREAM_READ_MAXPAGES * BITSTREAM_READ_PAGESIZE);
goto fail;
}
@ -353,7 +538,8 @@ int main(int argc, char** argv)
printf("bit2txt_format 1\n");
if (printf_header(bit_data, bit_eof, 0 /* inpos */, &bit_cur)) goto fail;
if (printf_header(bit_data, bit_eof, 0 /* inpos */, &bit_cur))
goto fail;
//
// commands
@ -393,6 +579,8 @@ int main(int argc, char** argv)
}
printf("sync_word\n");
try_full_map = 1;
first_FAR_off = -1;
while (bit_cur < bit_eof) {
// 8 is 2 padding frames between each row and 2 at the end
static const int type1_bram_data_start_frame = 4*505+8;
@ -458,9 +646,6 @@ int main(int argc, char** argv)
if (bit_cur + packet_hdr_wordcount*2 > bit_eof) goto fail_eof;
bit_cur += packet_hdr_wordcount*2;
// Check whether register and r/w action on register
// looks valid.
if (packet_hdr_type == 1) {
if (packet_hdr_register == IDCODE) {
if (packet_hdr_wordcount != 2) {
@ -473,6 +658,7 @@ int main(int argc, char** argv)
for (i = 0; i < sizeof(idcodes)/sizeof(idcodes[0]); i++) {
if ((u32 & 0x0FFFFFFF) == idcodes[i].code) {
printf("T1 IDCODE %s\n", idcodes[i].name);
m_idcode = i;
break;
}
}
@ -480,6 +666,11 @@ int main(int argc, char** argv)
printf("#W Unknown IDCODE 0x%x.\n", u32);
else if (u32 & 0xF0000000)
printf("#W Unexpected revision bits in IDCODE 0x%x.\n", u32);
if (idcodes[m_idcode].code == XC6SLX4
&& m_FLR_value != 896)
printf("#W Unexpected FLR value %i on "
"idcode %s.\n", m_FLR_value,
idcodes[m_idcode].name);
continue;
}
if (packet_hdr_register == CMD) {
@ -509,10 +700,10 @@ int main(int argc, char** argv)
u16 = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
u16_off+=2;
printf("T1 FLR %u\n", u16);
g_FLR_value = u16;
if ((g_FLR_value*2) % 8)
m_FLR_value = u16;
if ((m_FLR_value*2) % 8)
printf("#W FLR*2 should be multiple of "
"8, but modulo 8 is %i\n", (g_FLR_value*2) % 8);
"8, but modulo 8 is %i\n", (m_FLR_value*2) % 8);
// First come the type 0 frames (clb, bram
// config, dsp, etc). Then type 1 (bram data),
// then type 2, the IOB config data block.
@ -631,6 +822,9 @@ int main(int argc, char** argv)
uint16_t maj, min;
int unexpected_blk_bit4 = 0;
if (first_FAR_off == -1)
first_FAR_off = u16_off;
maj = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+2]);
min = __be16_to_cpu(*(uint16_t*)&bit_data[u16_off+4]);
printf("T1 FAR_MAJ");
@ -659,8 +853,7 @@ int main(int argc, char** argv)
if (unexpected_blk_bit4)
printf("#W Unexpected BLK bit 4 set.\n");
// Reserved min bits 13:10 should be 000
// according to documentation.
// Reserved min bits 13:10 should be 000.
if (min & 0x3C00)
printf("#W Expected reserved 0, got 0x%x.\n", (min & 0x3C00) > 10);
continue;
@ -1082,16 +1275,30 @@ int main(int argc, char** argv)
}
if (bit_cur + 4 > bit_eof) goto fail_eof;
u32 = __be32_to_cpu(*(uint32_t*)&bit_data[bit_cur]);
bit_cur += 4;
printf("T2 FDRI words=%i\n", u32);
if (bit_cur + 2*u32 > bit_eof) goto fail_eof;
if (bit_cur+4+2*u32 > bit_eof) goto fail_eof;
if (2*u32 < 130) {
fprintf(stderr, "#E 0x%x=0x%x Unexpected Type2"
" length %u.\n", u16_off, u16, 2*u32);
goto fail;
}
printf("T2 FDRI words=%i\n", u32);
bit_cur += 4;
if (try_full_map) {
try_full_map = 0;
if (0&&first_FAR_off != -1) {
int outdelta;
if (!full_map(bit_data, bit_eof, first_FAR_off,
&bits, &bits_len, idcodes[m_idcode].code,
m_FLR_value, &outdelta)) {
printf_bits(bits, bits_len,
idcodes[m_idcode].code);
bit_cur = first_FAR_off + outdelta;
continue;
}
}
}
num_frames = (2*u32)/130;
for (i = 0; i < num_frames; i++) {
int first64_all_zero, last64_all_zero;
@ -1424,20 +1631,20 @@ int main(int argc, char** argv)
printf("\n");
if (info) printf("#D type 2 iob start frame %i\n", i);
iob_end_pos = (type2_iob_start_frame*130 + (g_FLR_value+1)*2);
iob_end_pos = (type2_iob_start_frame*130 + (m_FLR_value+1)*2);
if (g_FLR_value == -1)
if (m_FLR_value == -1)
printf("#W No FLR value set, cannot process IOB block.\n");
else if (iob_end_pos > 2*u32)
printf("#W Expected %i bytes IOB data, only got %i.\n",
(g_FLR_value+1)*2, 2*u32 - (g_FLR_value+1)*2);
(m_FLR_value+1)*2, 2*u32 - (m_FLR_value+1)*2);
else {
uint16_t post_iob_padding;
printf_iob(bit_data, bit_eof, bit_cur + type2_iob_start_frame*130, g_FLR_value*2/8);
printf_iob(bit_data, bit_eof, bit_cur + type2_iob_start_frame*130, m_FLR_value*2/8);
if (info) hexdump(1, &bit_data[bit_cur+type2_iob_start_frame*130], g_FLR_value*2);
post_iob_padding = __be16_to_cpu(*(uint16_t*)&bit_data[bit_cur+type2_iob_start_frame*130+g_FLR_value*2]);
if (info) hexdump(1, &bit_data[bit_cur+type2_iob_start_frame*130], m_FLR_value*2);
post_iob_padding = __be16_to_cpu(*(uint16_t*)&bit_data[bit_cur+type2_iob_start_frame*130+m_FLR_value*2]);
if (post_iob_padding)
printf("#W Unexpected post IOB padding 0x%x.\n", post_iob_padding);
if (iob_end_pos < 2*u32)
@ -1460,12 +1667,14 @@ int main(int argc, char** argv)
if (info) printf("#I 0x%x=0x%x Ignoring Auto-CRC.\n", bit_cur, u32);
bit_cur += 4;
}
free(bits);
free(bit_data);
return EXIT_SUCCESS;
fail_eof:
fprintf(stderr, "#E Unexpected EOF.\n");
fail:
free(bits);
free(bit_data);
return EXIT_FAILURE;
}