From 564786677924d181e7cf67c2f6afbb79eed0aaed Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 18 Jul 2014 15:37:19 +0800 Subject: [PATCH] iram: work in progress --- README.md | 10 +- main.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++----- start.S | 13 +++ vectors.c | 10 +- 4 files changed, 327 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 9d12a21..9622282 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Memory Map +------------+------------+------------+-------------------------------------+ | ?????????? | ?????????? | ?????????? | ??????????????????????????????????? | +------------+------------+------------+-------------------------------------+ -| 0x70000000 | 0x7000ffff | 0xffff | On-chip SRAM (maybe cache?) | +| 0x70000000 | 0x7000cfff | 0xcfff | On-chip SRAM (maybe cache?) | +------------+------------+------------+-------------------------------------+ | ?????????? | ?????????? | ?????????? | ??????????????????????????????????? | +------------+------------+------------+-------------------------------------+ @@ -51,6 +51,8 @@ Memory Map | 0xa0020000 | 0xa0020e10 | 0x0e10 | GPIO control block | +------------+------------+------------+-------------------------------------+ | 0xa0030000 | 0xa0030040 | 0x40 | WDT block | +| | | | + 0x08 -> WDT register (?) | +| | | | + 0x18 -> Boot src (?) | +------------+------------+------------+-------------------------------------+ | 0xa0030800 | ?????????? | ?????????? | ???????????????????????????? | +------------+------------+------------+-------------------------------------+ @@ -84,7 +86,7 @@ Memory Map +------------+------------+------------+-------------------------------------+ | 0xa0120000 | 0xa0120074 | 0x74 | I2C block | +------------+------------+------------+-------------------------------------+ -| 0xa0130000 | 0xa0130098 | 0x98 | SD1 block | +| 0xa0130000 | 0xa0130098 | 0x98 | SD1 block (MSDC) | +------------+------------+------------+-------------------------------------+ | 0xa0140000 | ?????????? | ?????????? | ??????????????????????????????????? | +------------+------------+------------+-------------------------------------+ @@ -112,7 +114,9 @@ Memory Map +------------+------------+------------+-------------------------------------+ | 0xa0270000 | 0xa0270098 | 0x98 | SD2 block | +------------+------------+------------+-------------------------------------+ -| 0xa0410000 | ?????????? | ?????????? | ??????????????????????????????????? | +| 0xa0400000 | ?????????? | ?????????? | IMGDMA block | ++------------+------------+------------+-------------------------------------+ +| 0xa0410000 | ?????????? | ?????????? | IDP RESZ CR2 | +------------+------------+------------+-------------------------------------+ | 0xa0420000 | 0xa04201d8 | 0x01d8 | CAM interface block | +------------+------------+------------+-------------------------------------+ diff --git a/main.c b/main.c index 2fdb258..b769108 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,7 @@ #include "utils.h" #include "bionic.h" -//#define AUTOMATED +#define AUTOMATED #if defined(AUTOMATED) #define PROMPT "fernly> \n" @@ -11,6 +11,39 @@ #define PROMPT "fernly> " #endif +/* memcpy utils, from extbl */ +const char iram_utils_0[] = + "\x02\x00\x51\xe1\x04\x30\x90\x34\x04\x30\x81\x34\xfb\xff\xff\x3a" + "\x0e\xf0\xa0\xe1\x01\x00\x50\xe1\xf8\xff\xff\x8a\x0e\xf0\xa0\x01" + "\x01\x30\x42\xe0\x04\x30\x43\xe2\x01\x20\xa0\xe1\x03\x00\x80\xe0" + "\x03\x10\x81\xe0\x02\x00\x51\xe1\x04\x30\x10\xa4\x04\x30\x01\xa4" + "\xfb\xff\xff\xaa\x0e\xf0\xa0\xe1\x00\x20\xa0\xe3\x01\x00\x50\xe1" + "\x04\x20\x80\x34\xfb\xff" + ; +const int iram_utils_0_size = 86; + +const char iram_utils_1[] = + "\xf8\xb5\x00\x10\xd0\x73\x00\x70\xe8\x00\x00\x00\xb4\x10\x00\x00" + "\xb8\x74\x00\x70\x28\x92\x00\x10\x00\x50\x00\x70\x74\x23\x00\x00" + "\x00\x00\x00\x00\x74\x73\x00\x70\x50\x91\x00\x10\x00\x20\x01\x00" + "\xd8\x00\x00\x00\x8c\x0d\x00\x00\xd8\x20\x01\x00\x9c\xb5\x00\x10" + "\x74\x73\x00\x70\x5c\x00\x00\x00\x30\xb5\x08\x00\x80\x30\xc2\x6a" + "\x01\x24\x02\x23\x14\x70\x53\x70\x80\x23\x93\x70\x3c\x25\xd3\x70" + "\x15\x71\x53\x71\x03\x6b\x9f\x22\x9a\x72\x03\x6b\x35\x22\xda\x73" + "\x03\x6b\xc0\x31\x5a\x73\x03\x6b\x05\x22\xda\x72\x02\x6b\x14\x73" + "\x03\x6b\x75\x22\x9a\x70\x00\x6b\x7a\x22\xc2\x70\x16\x20\x08\x70" + "\x9e\x48\x48\x61\x00\x20\x30\xbd\x00\x20\x70\x47\x30\xb5\x0d\x00" + "\x80\x31\xcc\x6a\x29\x00\xff\xf7\xcf\xff\x00\x20\xa0\x70\xe0\x70" + "\x02\x20\xc0\x35\x28\x70\x00\x20\x30\xbd\x02\x00\xc0\x32\x10\xb5" + "\x00\x29\x02\xd1\x51\x69\x88\x47\x0c\xe0\x01\x29\x0a\xd1\x51\x78" + "\xc2\x29\x07\xd1\x41\x69\x01\x20\x09\x68\x80\x04\x81\x42\x01\xd1" + "\xc2\x20\x10\xbd\x00\x20\x10\xbd" + ; + +extern void ram_memcpy(const void *src, int dest_start, int dest_end); +extern void ram_bzero(int dest_start, int dest_end); +#define RAM_MEMCPY_OFFSET ((void *)0x70007374) + static int serial_get_line(uint8_t *bfr, int len) { int cur = 0; @@ -82,6 +115,16 @@ static int serial_get_line(uint8_t *bfr, int len) return -1; } +static void writeb(uint8_t value, uint32_t addr) +{ + *((volatile uint8_t *)addr) = value; +} + +static uint8_t readb(uint32_t addr) +{ + return *(volatile uint8_t *)addr; +} + static void writew(uint16_t value, uint32_t addr) { *((volatile uint16_t *)addr) = value; @@ -128,9 +171,7 @@ static int memory_test(uint32_t start, uint32_t length) static int wdt_kick(void) { -// writel(0x808, 0xa0030004); writel(0x1971, 0xa0030008); -// writel(readl(0xa0030000) | 0x2201, 0xa0030000); return 0; } @@ -140,7 +181,7 @@ static int wdt_reboot(void) return 0; } -static int memory_search(uint32_t start, uint32_t length, uint32_t nonce, uint32_t mask) +int memory_search(uint32_t start, uint32_t length, uint32_t nonce, uint32_t mask) { int addr; register uint32_t test; @@ -269,8 +310,32 @@ static int list_registers(void) static int read_address(uint8_t *arg) { - uint32_t addr = _strtoul(arg, 0, 16); - printf("%08x: %08x\n", addr, readl(addr)); + int bytes = 4; + uint32_t addr; + + /* If the address begins with 'o', read one byte, 't' two, 'f' four */ + if (*arg == 't') { + bytes = 2; + arg++; + } + else if (*arg == 'o') { + bytes = 1; + arg++; + } + else if (*arg == 'f') { + bytes = 4; + arg++; + } + + addr = _strtoul(arg, 0, 16); + + if (bytes == 1) + printf("%08x: %02x\n", addr, readb(addr)); + else if (bytes == 2) + printf("%08x: %04x\n", addr, readw(addr)); + else + printf("%08x: %08x\n", addr, readl(addr)); + return 0; } @@ -278,10 +343,39 @@ static int write_address(uint8_t *arg) { uint8_t *valpos; uint32_t val; - uint32_t addr = _strtoul(arg, (void **)&valpos, 16); + uint32_t addr; + int bytes = 4; + + /* If the address begins with 'o', read one byte, 't' two, 'f' four */ + if (*arg == 't') { + bytes = 2; + arg++; + } + else if (*arg == 'o') { + bytes = 1; + arg++; + } + else if (*arg == 'f') { + bytes = 4; + arg++; + } + + addr = _strtoul(arg, (void **)&valpos, 16); val = _strtoul(valpos, 0, 16); - printf("%08x: %08x\n", addr, val); - writel(val, addr); + + if (bytes == 1) { + printf("%08x: %02x\n", addr, val); + writeb(val, addr); + } + else if (bytes == 2) { + printf("%08x: %04x\n", addr, val); + writew(val, addr); + } + else if (bytes == 4) { + printf("%08x: %08x\n", addr, val); + writel(val, addr); + } + return 0; } @@ -336,7 +430,7 @@ static int find_irqs(void) written to, sets the mask register to 0x00000000 again. */ - int base_num; + //int base_num; uint32_t base = 0xa0050000; printf("Trying to look for IRQ tables...\n"); @@ -484,6 +578,166 @@ static int enable_fiq(void) return 0; } +static void gpio_set(unsigned int gpio, int value) +{ + uint32_t gpio_dr_reg; + uint32_t gpio_dr_mask; + uint32_t gpio_dr_val; + + uint32_t gpio_dout_reg; + uint32_t gpio_dout_mask; + uint32_t gpio_dout_val; + + uint32_t val; + + if (gpio < 16) { + gpio_dr_reg = 0xa0020000; + gpio_dout_reg = 0xa0020300; + } + else if (gpio < 32) { + gpio_dr_reg = 0xa0020010; + gpio_dout_reg = 0xa0020310; + } + else if (gpio < 48) { + gpio_dr_reg = 0xa0020020; + gpio_dout_reg = 0xa0020320; + } + else if (gpio < 64) { + gpio_dr_reg = 0xa0020030; + gpio_dout_reg = 0xa0020330; + } + else if (gpio < 73) { + gpio_dr_reg = 0xa0020040; + gpio_dout_reg = 0xa0020340; + } + else { + printf("Invalid GPIO selected: %d\n", gpio); + return; + } + + gpio_dr_mask = ~(1 << (gpio & 15)); + gpio_dout_mask = ~(1 << (gpio & 15)); + + /* Values less than 0 indicate input */ + if (value < 0) { + gpio_dr_val = 0; + gpio_dout_val = 0; /* Value doesn't matter */ + } + else { + gpio_dr_val = 1 << (gpio & 15); + if (value > 0) + gpio_dout_val = 1 << (gpio & 15); + else + gpio_dout_val = 0; + } + +// printf("Setting GPIO%d -> %d\n", gpio, value); + + val = (readw(gpio_dout_reg) & gpio_dout_mask) | gpio_dout_val; +// printf(" DOUT 0x%04x: 0x%04x -> 0x%04x\n", +// gpio_dout_reg, readw(gpio_dout_reg), val); + writew(val, gpio_dout_reg); + + val = (readw(gpio_dr_reg) & gpio_dr_mask) | gpio_dr_val; +// printf(" DR 0x%04x: 0x%04x -> 0x%04x\n", +// gpio_dr_reg, readw(gpio_dr_reg), val); + writew(val, gpio_dr_reg); +} + +static const uint8_t gpio_step_vals[] = { + 50, 27, 26, 10, 3, 4, 25, +}; + +/* Connector pinout: + 1 - + 2 - + 3 - GPIO27 / MCCM0 / JTDO + 4 - (pwr?) + 5 - GPIO25 / MCCK / JTRCK + 6 - GND + 7 - GPIO26 / MCDA0 / JTRSTB + 8 - +*/ +static int step_gpio(int step) +{ + gpio_set(gpio_step_vals[step], 0); + step++; + if (step > 6) + step = 0; + + if (step == 0) + printf("Step %d GPIO%d - MC2CM (JRTCK)\n", + step, gpio_step_vals[step]); + else if (step == 1) // Pin 3 + printf("Step %d GPIO%d - MCCM0 (JTDO), pin 3\n", + step, gpio_step_vals[step]); + else if (step == 2) // Pin 7 + printf("Step %d GPIO%d - MCDA0 (JTRSTB)\n", + step, gpio_step_vals[step]); + else if (step == 3) + printf("Step %d GPIO%d - MCDA3 (JTCK)\n", + step, gpio_step_vals[step]); + else if (step == 4) + printf("Step %d GPIO%d - MCDA1 (JTDI)\n", + step, gpio_step_vals[step]); + else if (step == 5) + printf("Step %d GPIO%d - MCDA2 (NONE)\n", + step, gpio_step_vals[step]); + else if (step == 6) + printf("Step %d GPIO%d - MCCK (JTRCK)\n", + step, gpio_step_vals[step]); + + gpio_set(gpio_step_vals[step], 1); + + return step; +} + +#define set_gpio_mode(addr, offset, value) \ + writel((readl(addr) & ~(0xf << offset)) | (value << offset), addr) +static int enable_jtag(void) +{ + int mode; + + mode = 0; + + if (mode == 0) { + printf("Setting up JTAG using SD connector\n"); + + printf("\tGPIO50 (MC2CM) -> JRTCK\n"); + set_gpio_mode(0xa0020c60, 8, 5); + + printf("\tGPIO27 (MCCM0) -> JTDO\n"); + set_gpio_mode(0xa0020c30, 12, 5); + + printf("\tGPIO26 (MCDA0) -> JTRSTB\n"); + set_gpio_mode(0xa0020c30, 8, 5); + + printf("\tGPIO25 (MCCK) -> JTRCK\n"); + set_gpio_mode(0xa0020c30, 4, 5); + + printf("\tGPIO10 (MCDA3) -> JTCK\n"); + set_gpio_mode(0xa0020c10, 8, 5); + + printf("\tGPIO3 (MCDA1) -> JTDI\n"); + set_gpio_mode(0xa0020c00, 12, 5); + } + else { + printf("Setting up JTAG using camera module\n"); + + printf("\tGPIO48 CMDAT1 -> JTMS\n"); + printf("\tGPIO49 CMDAT2 -> JTCK\n"); + printf("\tGPIO50 CMDAT3 -> JRTCK\n"); + printf("\tGPIO51 CMDAT4 -> JTRST_B\n"); + printf("\tGPIO52 CMDAT5 -> JTDO\n"); + + writel(0x00055555, 0xa0020c60); + } + + printf("\tDone.\n"); + return 0; +} + + static int setup_priorities(void) { writel(0x43415453, 0xf0244a88); @@ -513,13 +767,38 @@ static int do_init(void) { void *rv_start = (void *)0x10003460; void *rv_end = (void *)0x100034e0; + int i; + serial_init(); - setup_priorities(); + //setup_priorities(); /* Kick WDT */ writel(0x1971, 0xa0030008); + /* Disable WDT */ + writel(0x2200, 0xa0030000); + printf("\n\nFernly shell\n"); + + /* Copy some utils to iram */ + printf("Installing iram utils memcpy"); + _memcpy(RAM_MEMCPY_OFFSET, iram_utils_0, iram_utils_0_size); + + printf(" ram_memcpy(0)"); + ram_memcpy(0, 0, 0); + + printf(" ram_bzero(0)"); + ram_bzero(0, 0); + + printf(" ram_memcpy(0x700073d0)"); + ram_memcpy(iram_utils_1, 0x700073d0, 0x700074b8); + + printf(" ram_bzero(0x700074b8)"); + ram_bzero(0x700074b8, 0x7000856c); + + printf(" ok.\n"); + + /* Copy exception vectors to address 0 */ printf("Copying vectors"); printf(" Src: %p", rv_start); printf(" Src end: %p", rv_end); @@ -529,11 +808,14 @@ static int do_init(void) enable_irq(); enable_fiq(); + return 0; } -int main(int argc, char **argv) +int main(void) { + int step = 0; + list_registers(); do_init(); while (1) { @@ -554,19 +836,6 @@ int main(int argc, char **argv) memory_test(0x0ffe0000, 0x40000000); break; - case 's': - memory_search(0xa0000020, 0x2f000000, -// (0x2f << 24) | (0x2e << 16) | -// (0x2d << 8) | (0x2c << 0), - -// (0x0b << 24) | (0x0a << 16) | -// (0x09 << 8) | (0x08 << 0), - - 0x00000401, - 0x0000ffff); - break; - - case 'h': hex_print(line + 1); break; @@ -579,6 +848,10 @@ int main(int argc, char **argv) find_irqs(); break; + case 'j': + enable_jtag(); + break; + case 'r': read_address(line + 1); break; @@ -601,6 +874,10 @@ int main(int argc, char **argv) asm volatile ("swi 3"); break; + case 's': + step = step_gpio(step); + break; + default: printf("Unknown command\n"); break; diff --git a/start.S b/start.S index ec80afc..1b2d31f 100644 --- a/start.S +++ b/start.S @@ -66,3 +66,16 @@ __udiv64: adcs r0,r0,r0 bx lr + +.global ram_memcpy +ram_memcpy: + ldr pc, =ram_memcpy_addr +ram_memcpy_addr: + .long 0x70007388 + +.global ram_bzero +ram_bzero: + ldr pc, =ram_bzero_addr +ram_bzero_addr: + .long 0x700073bc + diff --git a/vectors.c b/vectors.c index 9997af3..ef0520c 100644 --- a/vectors.c +++ b/vectors.c @@ -1,12 +1,14 @@ #include "serial.h" #include "utils.h" +/* Reset handler calls main() directly */ +/* void reset_handler(void) { extern int main(int argc, char **argv); - printf("Reset exception\n"); main(1, 0); return; } +*/ void undef_handler(void) { printf("Undefined instruction exception\n"); @@ -34,13 +36,11 @@ void reserved_handler(void) { } void irq_handler(void) { - while(1) - printf("Handled IRQ\n"); + printf("Handled IRQ\n"); return; } void fiq_handler(void) { - while(1) - printf("Handled FIQ\n"); + printf("Handled FIQ\n"); return; }