From 635a9a2d4894e1ebac007b22092060cc905b4524 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 22 Feb 2019 17:18:41 +0800 Subject: [PATCH] rewrite-rom works, but maps things improperly sometimes Signed-off-by: Sean Cross --- rewrite-rom | Bin 19040 -> 24984 bytes rewrite-rom.c | 415 +++++++++++++++++++++++++++++++++++++++++++++++--- samerand | Bin 8680 -> 8784 bytes samerand.c | 7 +- top.bin | Bin 104090 -> 104090 bytes 5 files changed, 403 insertions(+), 19 deletions(-) diff --git a/rewrite-rom b/rewrite-rom index a0c784241dc3c149ead45ba95ce498c758c99886..3f2ae3c9009b4029ad590e5ba376c029feae1edc 100644 GIT binary patch literal 24984 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 VlxTgNs{W3fcrhzaD@?EdzW|Ie{IUQ5 diff --git a/rewrite-rom.c b/rewrite-rom.c index 9a30628..b23c748 100644 --- a/rewrite-rom.c +++ b/rewrite-rom.c @@ -5,6 +5,7 @@ #include #include #include +#include #define MAX(x, y) (x) > (y) ? (x) : (y) @@ -28,14 +29,6 @@ static void update_crc16(uint16_t *crc, uint8_t byte) } } -static uint8_t reverse_u8(uint8_t b) -{ - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return b; -} - struct irw_file *irw_open(const char *filename, const char *mode) { struct irw_file *f = malloc(sizeof(*f)); @@ -53,6 +46,11 @@ int irw_readb(struct irw_file *f) return val; } +int irw_writeb(struct irw_file *f, int c) { + update_crc16(&f->crc, c); + return fputc(c, f->f); +} + struct Ice40Bitstream { uint32_t offset; @@ -73,16 +71,14 @@ struct Ice40Bitstream uint8_t nosleep; uint8_t frequency_range; - - uint8_t bram_banks[4][2560 * 2]; }; -struct Ice40Bitstream bs; -int ice40_find_header(struct irw_file *f) +int ice40_parse(struct irw_file *f) { uint32_t preamble = 0; uint8_t wakeup = 0; + struct Ice40Bitstream bs; memset(&bs, 0, sizeof(bs)); @@ -186,8 +182,6 @@ int ice40_find_header(struct irw_file *f) // try_4[i] = try_4[i + 1]; // try_4[i + 1] = t; // } - printf("try 1:\n"); - print_hex(try_1, sizeof(try_1), 0); // printf("try 2:\n"); // print_hex(try_2, sizeof(try_2), 0); // printf("try 3:\n"); @@ -222,7 +216,7 @@ int ice40_find_header(struct irw_file *f) // printf("setting bank number to %d\n", bs.current_bank); break; case 2: - printf("crc check (%04x == %04x)\n", f->crc, 0); + printf("crc check (%04x == %04x)\n", f->crc, payload); break; case 5: switch (payload) @@ -287,14 +281,399 @@ int ice40_find_header(struct irw_file *f) return 0; } +struct mapping { + uint32_t count; + uint32_t *mappings; +}; + +static void add_mapping(struct mapping *mapping, uint32_t src, uint32_t dest) { + mapping->mappings = realloc(mapping->mappings, (mapping->count+1) * 2 * sizeof(uint32_t)); + mapping->mappings[mapping->count * 2] = src; + mapping->mappings[mapping->count * 2 + 1] = dest; + printf("creating mapping %08x -> %08x\n", src, dest); + mapping->count++; +} + +static uint32_t get_mapping(const struct mapping *mapping, uint32_t val) { + int i; + for (i = 0; i < mapping->count; i++) { + if (mapping->mappings[i * 2] == val) { + printf("found mapping for %08x: %08x\n", val, mapping->mappings[i * 2 + 1]); + return mapping->mappings[i * 2 + 1]; + } + } + printf("couldn't find mapping for %08x\n", val); + return -1; +} + +uint8_t get_bit(uint32_t *field, uint32_t offset) +{ + // printf("offset&31: %d\n", offset & 31); + // printf("offset/sizeof(*field): %d\n", offset >> 5); + assert(offset < 65536); + return !!(field[offset >> 5] & (1 << (offset & 31))); +} + +void set_bit(uint32_t *field, uint32_t offset) +{ + assert(offset < 65536); + field[offset >> 5] |= (1 << (offset & 31)); +} + +void clear_bit(uint32_t *field, uint32_t offset) +{ + assert(offset < 65536); + field[offset >> 5] &= ~(1 << (offset & 31)); +} + +static uint32_t get_bit_offset(int x, int total_bits) { + // return (8192 * (x & 7)) + (x >> 3); + int bitshift = ffs(total_bits)-1; + return ((x * 8192) % total_bits) + ((x*8192) >> bitshift); +} + +uint32_t xorshift32(uint32_t x) +{ + /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ + x = x ^ (x << 13); + x = x ^ (x >> 17); + x = x ^ (x << 5); + return x; +} + +uint32_t get_rand(uint32_t x) { + uint32_t out = 0; + int i; + for (i = 0; i < 32; i++) { + x = xorshift32(x); + if ((x & 1) == 1) + out = out | (1 << i); + } + return out; +} + +static uint32_t fill_rand(uint32_t *bfr, int count) { + int i; + uint32_t last = 1; + for (i = 0; i < count / 4; i++) { + last = get_rand(last); + bfr[i] = last; + } + return i; +} + +uint32_t swap_u32(uint32_t word) { + return (((word >> 24) & 0x000000ff) + | ((word >> 8) & 0x0000ff00) + | ((word << 8) & 0x00ff0000) + | ((word << 24) & 0xff000000)); +} + +// 1. Read ROM file into `input` +// 2. For each pair of bytes of input, +uint16_t mappings[65536]; +int ice40_patch(struct irw_file *f, struct irw_file *rom, struct irw_file *o) +{ + uint32_t preamble = 0; + uint8_t wakeup = 0; + struct Ice40Bitstream bs; + uint32_t input_rom[2048]; + uint32_t input_rand[2048]; + uint32_t output_rand[2048]; + uint32_t output_rom[2048]; + uint8_t *i8 = (uint8_t *)input_rom; + uint16_t *ora16 = (uint16_t *)output_rand; + uint16_t *oro16 = (uint16_t *)output_rom; + int b; + struct mapping mapping; + + memset(&mapping, 0, sizeof(mapping)); + memset(&bs, 0, sizeof(bs)); + + int input_ptr; + + // Read the ROM into a source buffer + memset(input_rom, 0, sizeof(input_rom)); + input_ptr = 0; + while ((b = irw_readb(rom)) != EOF) + i8[input_ptr++] = b; + printf("read %d bytes from rom\n", input_ptr); + + // Generate our reference pattern + memset(input_rand, 0, sizeof(input_rand)); + fill_rand(input_rand, sizeof(input_rand)); + + for (input_ptr = 0; input_ptr < sizeof(input_rom)/4; input_ptr++) { + // input_rand[input_ptr] = swap_u32(input_rand[input_ptr]); + // input_rom[input_ptr] = swap_u32(input_rom[input_ptr]); + } + + // Spray the reference pattern and ROM like they would exist in the FPGA + for (input_ptr = 0; input_ptr < sizeof(input_rom) * 8; input_ptr++) { + int bit; + bit = get_bit(input_rand, get_bit_offset(input_ptr, sizeof(input_rand)*8)); + if (bit) + set_bit(output_rand, input_ptr); + else + clear_bit(output_rand, input_ptr); + + bit = get_bit(input_rom, get_bit_offset(input_ptr, sizeof(input_rom)*8)); + if (bit) + set_bit(output_rom, input_ptr); + else + clear_bit(output_rom, input_ptr); + } + + // Finally, build a mapping from the random data to the replacement rom data. + uint32_t collisions = 0; + for (input_ptr = 0; input_ptr < 4096; input_ptr += 1) { + // uint32_t ra1 = (output_rand[input_ptr + 0] & 0xffff0000) + // | ((output_rand[input_ptr + 1] >> 16) & 0x0000ffff); + // uint32_t ra2 = (output_rand[input_ptr + 1] & 0xffff0000) + // | ((output_rand[input_ptr + 0] >> 16) & 0x0000ffff); + // add_mapping(&mapping, ra1, output_rom[input_ptr + 0]); + // add_mapping(&mapping, ra2, output_rom[input_ptr + 1]); + if (mappings[ora16[input_ptr]]) { + collisions++; + printf("mapping position %d not empty\n", input_ptr); + } + mappings[ora16[input_ptr]] = oro16[input_ptr]; + } + if (collisions) + printf("had %d collisions\n", collisions); + + while (1) + { + b = irw_readb(f); + if (b == EOF) + break; + irw_writeb(o, b); + + preamble = (preamble << 8) | b; + if (preamble == 0x7eaa997e) + { + // printf("found preamble at %d\n", bs.offset); + break; + } + } + + while (!wakeup) + { + int b = irw_readb(f); + if (b == EOF) + { + // printf("reached end of file\n"); + break; + } + irw_writeb(o, b); + + uint8_t cmd = b >> 4; + uint8_t payload_len = b & 0xf; + uint32_t payload = 0; + uint8_t last0, last1; + int i; + for (i = 0; i < payload_len; i++) + { + b = irw_readb(f); + payload = (payload << 8) | (b & 0xff); + + // Don't write the CRC16 out, since we'll do that later on. + if (cmd != 2) + irw_writeb(o, b); + } + + switch (cmd) + { + case 0: + switch (payload) + { + case 1: + printf("CRAM data (bank %d): %d x %d @ 0x%08x; %d bits = %d bytes\n", + bs.current_bank, + bs.current_width, + bs.current_height, + bs.current_offset, + bs.current_width * bs.current_height, + (bs.current_width * bs.current_height) / 8); + bs.cram_width = MAX(bs.cram_width, bs.current_width); + bs.cram_height = MAX(bs.cram_height, bs.current_height); + for (i = 0; i < ((bs.current_width * bs.current_height) / 8); i++) + { + irw_writeb(o, irw_readb(f)); + } + last0 = irw_readb(f); + last1 = irw_readb(f); + if (last0 || last1) + { + printf("expected 0x0000 after CRAM data, got %02x %02x\n", last0, last1); + } + irw_writeb(o, last0); + irw_writeb(o, last1); + break; + case 3: + printf("BRAM data (bank %d): %d x %d @ 0x%08x; %d bits = %d bytes\n", + bs.current_bank, + bs.current_width, + bs.current_height, + bs.current_offset, + bs.current_width * bs.current_height, + (bs.current_width * bs.current_height) / 8); + bs.bram_width = MAX(bs.bram_width, bs.current_width); + bs.bram_height = MAX(bs.bram_height, bs.current_height); + for (i = 0; i < ((bs.current_width * bs.current_height) / 8); i += 2) + { + uint32_t word = + // ((irw_readb(f) << 24) & 0xff000000) + // | + // ((irw_readb(f) << 16) & 0x00ff0000) + // | + ((irw_readb(f) << 8) & 0x0000ff00) + | + ((irw_readb(f) << 0) & 0x000000ff) + ; + // printf("%04x -> %04x\n", word, mapping[word]); + // word = get_mapping(&mapping, word); + // irw_writeb(o, word >> 24); + // irw_writeb(o, word >> 16); + word = mappings[word]; + irw_writeb(o, word >> 8); + irw_writeb(o, word); + } + last0 = irw_readb(f); + last1 = irw_readb(f); + if (last0 || last1) + { + printf("expected 0x0000 after BRAM data, got %02x %02x\n", last0, last1); + } + irw_writeb(o, last0); + irw_writeb(o, last1); + break; + + // Reset CRC + case 5: + f->crc = 0xffff; + o->crc = 0xffff; + break; + + // Wakeup + case 6: + wakeup = 1; + break; + + default: + printf("unrecognized command 0x%02x 0x%02x\n", cmd, payload); + break; + } + break; + + // Set current bank + case 1: + bs.current_bank = payload; + // printf("setting bank number to %d\n", bs.current_bank); + break; + + // Validate CRC16 + case 2: + printf("crc check (%04x == %04x)\n", f->crc, 0); + uint16_t crc16 = o->crc; + irw_writeb(o, crc16 >> 8); + irw_writeb(o, crc16); + break; + + // Set frequency range + case 5: + switch (payload) + { + case 0: + bs.frequency_range = 0; + break; + case 1: + bs.frequency_range = 1; + break; + case 2: + bs.frequency_range = 2; + break; + default: + printf("unknown frequency range payload: %02x\n", payload); + break; + } + break; + + // Set current width + case 6: + bs.current_width = payload + 1; + break; + + // Set current height + case 7: + bs.current_height = payload; + break; + + // Set current ofset + case 8: + bs.current_offset = payload; + break; + + // Set flags + case 9: + switch (payload) + { + case 0: + bs.warmboot = 0; + bs.nosleep = 0; + break; + case 1: + bs.warmboot = 0; + bs.nosleep = 1; + break; + case 32: + bs.warmboot = 1; + bs.nosleep = 0; + break; + case 33: + bs.warmboot = 1; + bs.nosleep = 1; + break; + default: + printf("unrecognized feature flags: %02x\n", payload); + break; + } + break; + + default: + printf("unrecognized command: %02x\n", cmd); + break; + } + } + + // Padding + irw_writeb(o, 0); + return 0; +} + int main(int argc, char **argv) { - struct irw_file *f = irw_open("memtest/memtest.bin", "r"); - if (!f) + + struct irw_file *input = irw_open("top.bin", "r"); + struct irw_file *output = irw_open("new.bin", "w"); + struct irw_file *rom = irw_open("rom.bin", "r"); + + // int i; + // for (i = 0; i < 32; i++) { + // printf("bit %d: %d\n", i, get_bit_offset(i, 8192*8)); + // } + + if (!input) { perror("couldn't open top.bin"); return 1; } - ice40_find_header(f); + + if (!output) { + perror("couldn't open new.bin"); + return 2; + } + + ice40_patch(input, rom, output); return 0; } \ No newline at end of file diff --git a/samerand b/samerand index 7dd5eb2a2ed92f2be921fc33a32d081d92afd00d..f6bd3d18053d7bfff294084ba7528f900a26c675 100644 GIT binary patch delta 2138 zcmZuyeQZ-z6u-A0d$d5?*LHLt-P)={AkdDlF(hWK(D+KGjE`Y5+}gpIRA8H9Xkx&9 z@!@kWb~(}bk-#6uVTcLC8Jzq9ofw+MM7!WeME+Qa#4b)#%%c0l@jUmvTbRR}ynF8X zo!>q8oOkcJH?ujtB~c(w7=nZ~ttTWgu>729dVz|O>4BdDrb?Zr1VN;y?Z*U7J0@r| zjtOv{-gG8P_iTOdRCmbZKHK`?*-K-OUD#O)@9HY)S{T>4AgwE)J~pBof$Ck<&BmSN zP<-z`|B+UI1&KzFbTsZe7~OZ^V6?e0eu%WT?QcPpF_@{nBYLi4RZH}(-ue(25<6nWCgcCbdR!L~&@-R6lXX`c0k7Y#PG;f?l<0UHKf`I0u({rxr+k#{Pv~BArZj7&Cj&DD{4|;F?BK z*7u-EDLa9^)f2=K(+@D?{X_-s3+5k(uqJj16WFvNtN&-(^)K&L#qA=>dgt% z)wcTgh&CsX87B1p|e~*eoK;%rkkWboXXae!!xUsmle$aN(ghl+JV8V z(PW;urzmoGIu)K`KPMH=vS@x=*%zLYQ<*w+D~G3~{%5B8!qb-xs;h70ls5I-Sw-m$ zXKDBGtb!Z)+SgiseUaLkCTXoxT^YCP3#5%P*!GX2)Igc=C_Mua!9zcSxZrX8h*RH3DhXL^r*xYa=jq-a z{y;csG!Ger3?>O96j_$qW4yBQgsZJdfE|_wD#1mIhc>{trHaNtw0cCsi7Y8i9+bEhI5jE+Sp3 zTujm^U37wJ)mGBPFB5Hjt=D6jw*4G1aZ)alp71i0;7YWf6E zqL&nsN)YoMuq)rWI*N!55mp6r+X}?(_3OQ zPS?ik$P{&jBskCi4TjJ8fvf;nyUjgkfi7`%*36qV#I3nEVTCq{{K@ejcs!4Dd=_yV z`!DnSn6Ogq_0&WqhuY9ST6Iu1#=8Dt8_cT!(FD;+$!J*5@qB(JcfF#KidDT<{N@djYTYlGLl<)++LNHFTH!h)i{D%t}fUzMqg Wzo8$4?Au^o=F*m^)4>}>rT+qFY2`Nn delta 1831 zcmZuyeN0J2l zVIMX?HauA*Mx!RiW%Cb1Fp3S8vDU7R%`M?03>?eI-<)LK#k>jTHw-hX%le}1vZ9INwc~1bNAQiwuQ2^$RzdO_ znM|3SQRQ1(Jf!DhAwcj>EH!sfPTiJ=eqMgAHI}~Kk6%MRl%6Jxr_BP90)dj8pC zb~h0+6}BWun_L@0CJ(KeG;;=S)6+@`=4zAUPqmVdPvNChokceR2z2)_ykVNu64fQzx?N<~6pVbn_}p z@tb$Jc`cRBokiPJ^BNOwUOR);t5xMHA1KOD^C~@kYE{t_^5!iS{(9!$k}!Mp`DlAI zr9|7Jtu3S82YL^dI9kj2{#fc>EcIg#C)=JkGUW=&B7;4nNye}cyhZn^+37~D1| znzo`TiJC0uG>yeN&9jrkhO^qY#T60Hf>E{zN=;SPSs^bLs~{l*I@o7ANL?^ta?>!( znZgts-Rzdexgo2NQ4*qNKTW_vnGEUUa2$6*?^0T`1UEoLkwqGsB-2-xt+|HUOz7{UMATS-O-k6S;X)i7^$ zLe{zsOtzV!ACYfB`{};;~KPI(BKX5mEEW5 z*TL`hDsc>(%tJ~@HB>rmaKmATgu@_h-r9Z$I-DghqpcNdc!nR*K3-hEs=a_(3yXxk zzmeVp>TnKzidsoiLIRt#Qw-nm(Tcchn&)B@%IL7V67n5#3+^kjDb6KsU$`H4a{KS| z_#RTli++SFZli()V#B$S?(#tFPGF?ADe^zqHp=yQx3O((_Oc<)E=!wnPW8v$5hhEW z2WV;haCg^07r!|pk*8W>dm7_)KD;d9ifeRIE_sVWmTD(6r5=iHxKieqTtb9pCN4o` zBn-jreyM|_9UL{lQA86QO>oo$6Wje_lA}pj+}^N08spq10Ksy4+Jax#zM2;XdbDkmkRBl)a9!;!UP%>njgFG*NS>$ zh97H2H@VY&j$-pqc<|T7&!QR@Jq=>v8;78#GE76zi>m{!REEWV{#Q8(E0qmmZd*Q4 JEd+PC{{c45hU@?U diff --git a/samerand.c b/samerand.c index 8dd7c14..5c62a1d 100644 --- a/samerand.c +++ b/samerand.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include uint32_t xorshift32(uint32_t x) { @@ -24,10 +27,12 @@ uint32_t get_rand(uint32_t x) { int main(int argc, char **argv) { int i; + int fd = open("rom.bin", O_WRONLY | O_CREAT | O_TRUNC, 0777); uint32_t init = 1; for (i = 0; i < 2048; i++) { init = get_rand(init); - printf("%08x\n", init); + // printf("%08x\n", init); + write(fd, &init, sizeof(init)); } return 0; diff --git a/top.bin b/top.bin index 00f69655b4c086d05be2ce41a7b17ad9c863c188..32222f42f64a9cce068a2c3203ebd41b927348a4 100644 GIT binary patch delta 12969 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 KuYkfK0RIEZ2rNMW delta 12969 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