iram: work in progress

This commit is contained in:
Sean Cross 2014-07-18 15:37:19 +08:00
parent 7cb334571e
commit 5647866779
4 changed files with 327 additions and 33 deletions

View file

@ -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 |
+------------+------------+------------+-------------------------------------+

327
main.c
View file

@ -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;

13
start.S
View file

@ -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

View file

@ -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;
}