int stage_1_prep (libusb_device_handle *handle, uchar *buf) { int x; ShowURB (5); version = aw_fel_get_version (handle); if (IsA10 (version)) // 0x1623 = A10 { printf ("Detected A10 (ID 0x%04X)\n", version); FN = &FN_sun4i; } else if (IsA20 (version)) // 0x1651 = A20 { printf ("Detected A20 (ID 0x%04X)\n", version); FN = &FN_sun7i; } else if (IsH3 (version)) // 0x1680 = H3 printf ("Detected H3 (ID 0x%04X)\n", version); else { printf ("Unknown processor ID 0x%04X\n", version); PerhapsQuit (); } ShowURB (14); version = aw_fel_get_version (handle); // URB 23 - 27 ShowURB (23); aw_fel_read (handle, 0x7e00, buf, 256); // get 256 0xCC for (x = 0; x < 256; x++) { if (buf [x] != 0xCC) { printf ("Non 0xCC at entry %d\n", x); hexdump (buf, 0, 256); save_file ((char *) "Dump1_000023", buf, 256); PerhapsQuit (); break; } } ShowURB (32); version = aw_fel_get_version (handle); ShowURB (41); PutNulls (buf, 4); aw_fel_write (handle, 0x7e00, buf, 256); ShowURB (50); version = aw_fel_get_version (handle); return 0; }
int install_fes_1_2 (libusb_device_handle *handle, uchar *buf) { int len; ShowURB (105); PutNulls (buf, 16); aw_fel_write (handle, 0x7210, buf, 0x10); ShowURB (114); aw_fel_send_file (handle, 0x2000, FN->fes_1_2); ShowURB (120); aw_fel_execute (handle, 0x2000); ShowURB (129); len = 16; if (IsH3 (version)) len = 256; aw_fel_read (handle, 0x7210, buf, len); // expect 'DRAM', 0x01 then nulls if (memcmp (buf, "DRAM\x01\x00\x00\x00", 8)) { perror ("Compare to DRAM1 lit failed"); hexdump (buf, 0, len); save_file ((char *) "Dump1_000129", buf, 16); PerhapsQuit (); } ShowURB (138); aw_fel_read (handle, 0x7010, buf, 0x200); // expect as per URB 138 memcpy (&DramInfo, buf, sizeof (DramInfo)); // save DRAM details. if (IsA20 (version)) printf ("%dMB RAM detected\n", DramInfo.dram_size); if (forceable) save_file ((char *) "Dump1_000138", buf, 0x200); return 0; }
int do_dram_test (libusb_device_handle *handle, uchar *buf) { int x; ShowURB (147); for (x = 0; x < 0x2000; x++) buf [x] = random (); aw_fel_write (handle, 0x40100000, buf, 0x2000); ShowURB (153); // read it back to make sure it's correct aw_fel_read (handle, 0x40100000, buf + 0x2000, 0x2000); if (memcmp (buf, buf + 0x2000, 0x2000)) { perror ("Compare to DRAM test data failed"); save_file ((char *) "Dump1_DRAM_test", buf + 0x2000, 0x2000); PerhapsQuit (); } return 0; }
int main(int argc, char **argv) { int rc; libusb_device_handle *handle = NULL; int iface_detached = -1; rc = libusb_init(NULL); assert(rc == 0); if (argc <= 1) { printf("Usage: %s command arguments... [command...]\n" " hex[dump] address length Dumps memory region in hex\n" " dump address length Binary memory dump\n" " exe[cute] address Call function address\n" " read address length file Write memory contents into file\n" " write address file Store file contents into memory\n" " ver[sion] Show BROM version\n" " clear address length Clear memory\n" " fill address length value Fill memory\n" , argv[0] ); } handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); if (!handle) { fprintf(stderr, "ERROR: Allwinner USB FEL device not found!\n"); exit(1); } rc = libusb_claim_interface(handle, 0); #if defined(__linux__) if (rc != LIBUSB_SUCCESS) { libusb_detach_kernel_driver(handle, 0); iface_detached = 0; rc = libusb_claim_interface(handle, 0); } #endif assert(rc == 0); while (argc > 1 ) { int skip = 1; if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) { aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if (strncmp(argv[1], "dump", 4) == 0 && argc > 3) { aw_fel_dump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if ((strncmp(argv[1], "exe", 3) == 0 && argc > 2) ) { aw_fel_execute(handle, strtoul(argv[2], NULL, 0)); skip=3; } else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) { aw_fel_get_version(handle); skip=1; } else if (strcmp(argv[1], "write") == 0 && argc > 3) { size_t size; void *buf = load_file(argv[3], &size); aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size); free(buf); skip=3; } else if (strcmp(argv[1], "read") == 0 && argc > 4) { size_t size = strtoul(argv[3], NULL, 0); void *buf = malloc(size); aw_fel_read(handle, strtoul(argv[2], NULL, 0), buf, size); save_file(argv[4], buf, size); free(buf); skip=4; } else if (strcmp(argv[1], "clear") == 0 && argc > 2) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), 0); skip=3; } else if (strcmp(argv[1], "fill") == 0 && argc > 3) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), (unsigned char)strtoul(argv[4], NULL, 0)); skip=4; } else { fprintf(stderr,"Invalid command %s\n", argv[1]); exit(1); } argc-=skip; argv+=skip; } #if defined(__linux__) if (iface_detached >= 0) libusb_attach_kernel_driver(handle, iface_detached); #endif return 0; }
void aw_fel_dump(libusb_device_handle *usb, uint32_t offset, size_t size) { unsigned char buf[size]; aw_fel_read(usb, offset, buf, size); fwrite(buf, size, 1, stdout); }
void aw_fel_hexdump(libusb_device_handle *usb, uint32_t offset, size_t size) { unsigned char buf[size]; aw_fel_read(usb, offset, buf, size); hexdump(buf, offset, size); }
int install_fes_1_1 (libusb_device_handle *handle, uchar *buf) { rAWSysPar *pDI; int len = 0x200; ShowURB (63); PutNulls (buf, 512); pDI = (rAWSysPar*) buf; pDI->unk_6 = 0x007C4AC1; // UART 0 TX pin specs if (IsA10 (version)) // A10 defaults { pDI->unk_0 = 0x02000000; // chip pDI->unk_1 = 0x02000000; // pid pDI->unk_2 = 0x02000100; // sid pDI->unk_3 = 0x80; // bid // pDI->dram_baseaddr = 0x40000000; // from Ronald T. // pDI->dram_clk = 480; // pDI->dram_type = 3; // pDI->dram_rank_num = 1; // pDI->dram_chip_density = 4096; // pDI->dram_io_width = 16; // pDI->dram_bus_width = 32; // pDI->dram_cas = 6; // pDI->dram_zq = 0x7b; // pDI->dram_odt_en = 0; // pDI->dram_size = 1024; // pDI->dram_tpr0 = 0x30926692; // pDI->dram_tpr1 = 0x1090; // pDI->dram_tpr2 = 0x1a0c8; // pDI->dram_tpr3 = 0x0; pDI->dram_tpr4 = 0x40000000; // from USB trace. pDI->dram_tpr5 = 480; // all values here pDI->dram_emr1 = 3; // are 60 bytes after pDI->dram_emr2 = 1; // expected location. pDI->dram_emr3 = 4096; pDI->dram_spare [0] = 16; pDI->dram_spare [1] = 32; pDI->dram_spare [2] = 6; pDI->dram_spare [3] = 0x7B; pDI->dram_spare [4] = 0; pDI->dram_spare [5] = 1024; pDI->dram_spare [6] = 0x30926692; pDI->dram_spare [7] = 0x1090; pDI->dram_spare [8] = 0x01A0C8; pDI->dram_spare [9] = 0; // read_log (buf, 0xB4, FN->DRAM_specs); // DRAM access specs len = 0xB4; } if (IsA20 (version)) // A20 defaults { pDI->dram_baseaddr = 0x40000000; // from CT script.fex pDI->dram_clk = 432; pDI->dram_type = 3; pDI->dram_rank_num = 0xFFFFFFFF; pDI->dram_chip_density = 0xFFFFFFFF; pDI->dram_io_width = 0xFFFFFFFF; pDI->dram_bus_width = 0xFFFFFFFF; pDI->dram_cas = 9; pDI->dram_zq = 0x7f; pDI->dram_odt_en = 0; pDI->dram_size = 0xFFFFFFFF; pDI->dram_tpr0 = 0x42d899b7; pDI->dram_tpr1 = 0xa090; pDI->dram_tpr2 = 0x22a00; pDI->dram_tpr3 = 0x0; pDI->dram_tpr4 = 0x1; pDI->dram_tpr5 = 0x0; pDI->dram_emr1 = 0x4; pDI->dram_emr2 = 0x10; pDI->dram_emr3 = 0x0; // read_log (buf, 0x200, FN->DRAM_specs); // DRAM access specs len = 0x200; } if (IsH3 (version)) // H3 defaults { pDI->dram_baseaddr = 0x40000000; // from H3 script.fex // pDI->dram_clk = 672; pDI->dram_clk = 480; pDI->dram_type = 3; pDI->dram_zq = 0x3b3bfb; pDI->dram_odt_en = 0x1; // pDI->dram_para1 = 0x10E40000; // pDI->dram_para2 = 0x0000; // pDI->dram_mr0 = 0x1840; pDI->dram_emr1 = 0x40; pDI->dram_emr2 = 0x18; pDI->dram_emr3 = 0x2; pDI->dram_tpr0 = 0x0048A192; pDI->dram_tpr1 = 0x01C2418D; pDI->dram_tpr2 = 0x00076051; pDI->dram_tpr3 = 0; pDI->dram_tpr4 = 0; pDI->dram_tpr5 = 0; // pDI->dram_tpr6 = 100; // pDI->dram_tpr7 = 0; // pDI->dram_tpr8 = 0; // pDI->dram_tpr9 = 0; // pDI->dram_tpr10 = 0; // pDI->dram_tpr11 = 0x6aaa0000; // pDI->dram_tpr12 = 0x7979; // pDI->dram_tpr13 = 0x800800; } aw_fel_write (handle, 0x7010, buf, len); ShowURB (72); PutNulls (buf, 16); // clear error log aw_fel_write (handle, 0x7210, buf, 0x10); ShowURB (77); #ifdef OLD_EXTRAS // Load buffer as per URB 81 (0xae0 = 2784) FES_1-1 with nulls after. // We do lots of sanity checks here (relic from testing). PutNulls (buf, 65536); read_log (buf, 0x0ae0, (char*) "pt1_000081"); // data from log FILE *fin; if (NULL == (fin = fopen (FN->fes_1_1, "rb"))) { perror ("Failed to open file to send: "); exit (1); } fread (buf + 2784, 1, 2784, fin); // data from file fclose (fin); if (memcmp (buf, buf + 2784, 2784)) // shouldn't happen { printf ("Dump / fes_1-1 file mismatch\n"); save_file ((char *) "Dump1_000077", buf, 5568); PerhapsQuit (); } #endif if (IsH3 (version)) return 0; aw_fel_send_file (handle, 0x7220, FN->fes_1_1, 2784, 2784); #ifdef OLD_EXTRAS aw_fel_read (handle, 0x7220, buf + 2784, 2784); // sanity test if (memcmp (buf, buf + 2784, 2784)) { printf ("Readback mismatch of fes_1-1\n"); save_file ((char *) "Dump1_000081", buf + 2784, 2784); PerhapsQuit (); } #endif ShowURB (87); aw_fel_execute (handle, 0x7220); usleep (500000); // need this to avoid error on next USB I/O ShowURB (96); aw_fel_read (handle, 0x7210, buf, 256); // expect 'DRAM' then nulls if (memcmp (buf, "DRAM\x00\x00\x00\x00", 8)) { perror ("Compare to DRAM lit failed"); hexdump (buf, 0, 256); save_file ((char *) "Dump1_000096", buf, 256); PerhapsQuit (); } return 0; }