Skip to content

Commit

Permalink
WIP: gets through some bootrom, stuck at reading from SPI
Browse files Browse the repository at this point in the history
it looks like some work was done on the Touch 2G that might help me set this up...
  • Loading branch information
lemonjesus committed Jan 8, 2023
1 parent 7c360ac commit 2c7a61f
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 34 deletions.
11 changes: 11 additions & 0 deletions .gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,14 @@

# Load QEMU-specific sub-commands and settings
source scripts/qemu-gdb.py

set pagination off
target remote localhost:1234

tui new-layout vmdebug {-horizontal asm 1 regs 1} 2 cmd 1
layout vmdebug
focus cmd
set confirm off

break *0x20003010
continue
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ GTAGS
*.depend_raw
*.swp
*.patch
settings.json
5 changes: 5 additions & 0 deletions TuckerNotes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Run it with:
```
./arm-softmmu/qemu-system-arm -M iPod-Touch,bootrom=/home/tucker/Development/qemu-ipod-nano/build/s5l8702-bootrom.bin,iboot=/home/tucker/Development/qemu-ipod-nano/build/iboot_204_n45ap.bin,nand=/home/tucker/Development/qemu-ipod-nano/build/nand -serial mon:stdio -cpu max -m 1G -d unimp -pflash /home/tucker/Development/qemu-ipod-nano/build/nor_n45ap.bin
```

Run the iPhone code with:
```
./arm-softmmu/qemu-system-arm -M iPod-Touch,bootrom=/home/tucker/Development/qemu-ipod-nano/build/bootrom_s5l8900,iboot=/home/tucker/Development/qemu-ipod-nano/build/iboot_204_n45ap.bin,nand=/home/tucker/Development/qemu-ipod-nano/build/nand -serial mon:stdio -cpu max -m 1G -d unimp -pflash /home/tucker/Development/qemu-ipod-nano/build/nor_n45ap.bin
```

Expand Down
61 changes: 32 additions & 29 deletions hw/arm/ipod_touch.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static void ipod_touch_cpu_reset(void *opaque)

//env->regs[0] = nms->kbootargs_pa;
//cpu_set_pc(CPU(cpu), 0xc00607ec);
cpu_set_pc(CPU(cpu), IBOOT_BASE);
cpu_set_pc(CPU(cpu), 0);
//env->regs[0] = 0x9000000;
//cpu_set_pc(CPU(cpu), LLB_BASE + 0x100);
//cpu_set_pc(CPU(cpu), VROM_MEM_BASE);
Expand Down Expand Up @@ -178,40 +178,41 @@ static const MemoryRegionOps mbx_ops = {
static void ipod_touch_memory_setup(MachineState *machine, MemoryRegion *sysmem, AddressSpace *nsas)
{
IPodTouchMachineState *nms = IPOD_TOUCH_MACHINE(machine);
DriveInfo *dinfo;

allocate_ram(sysmem, "sram1", SRAM1_MEM_BASE, 0x10000);

// allocate UART ram
allocate_ram(sysmem, "ram", RAM_MEM_BASE, 0x8000000);

// load the bootrom (vrom)
// load the bootrom
uint8_t *file_data = NULL;
unsigned long fsize;
if (g_file_get_contents(nms->bootrom_path, (char **)&file_data, &fsize, NULL)) {
allocate_ram(sysmem, "vrom", VROM_MEM_BASE, 0x10000);
allocate_ram(sysmem, "vrom", 0, 0x10000);
address_space_rw(nsas, 0, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);

allocate_ram(sysmem, "vrom1", VROM_MEM_BASE, 0x10000);
address_space_rw(nsas, VROM_MEM_BASE, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);
}

// patch the address table to point to our own routines
uint32_t *data = malloc(4);
data[0] = LLB_BASE + 0x80;
address_space_rw(nsas, 0x2000008c, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, 4, 1);
data[0] = LLB_BASE + 0x100;
address_space_rw(nsas, 0x20000090, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, 4, 1);
// // patch the address table to point to our own routines
// uint32_t *data = malloc(4);
// data[0] = LLB_BASE + 0x80;
// address_space_rw(nsas, 0x2000008c, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, 4, 1);
// data[0] = LLB_BASE + 0x100;
// address_space_rw(nsas, 0x20000090, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, 4, 1);

// load iBoot
file_data = NULL;
if (g_file_get_contents(nms->iboot_path, (char **)&file_data, &fsize, NULL)) {
allocate_ram(sysmem, "iboot", IBOOT_BASE, 0x400000);
address_space_rw(nsas, IBOOT_BASE, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);
}
// file_data = NULL;
// if (g_file_get_contents(nms->iboot_path, (char **)&file_data, &fsize, NULL)) {

// }

// // load LLB
// file_data = NULL;
// if (g_file_get_contents("/Users/martijndevos/Documents/ipod_touch_emulation/LLB.n45ap.RELEASE", (char **)&file_data, &fsize, NULL)) {
// allocate_ram(sysmem, "llb", LLB_BASE, align_64k_high(fsize));
// address_space_rw(nsas, LLB_BASE, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);
allocate_ram(sysmem, "llb", LLB_BASE, align_64k_high(0x400000));
// address_space_rw(nsas, LLB_BASE, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);
// }

allocate_ram(sysmem, "edgeic", EDGEIC_MEM_BASE, 0x1000);
Expand All @@ -227,13 +228,13 @@ static void ipod_touch_memory_setup(MachineState *machine, MemoryRegion *sysmem,
allocate_ram(sysmem, "framebuffer", FRAMEBUFFER_MEM_BASE, align_64k_high(4 * 320 * 480));

// setup 1MB NOR
dinfo = drive_get(IF_PFLASH, 0, 0);
if (!dinfo) {
nms->nor_drive = drive_get(IF_PFLASH, 0, 0);
if (!nms->nor_drive) {
printf("A NOR image must be given with the -pflash parameter\n");
abort();
}

if(!pflash_cfi02_register(NOR_MEM_BASE, "nor", 1024 * 1024, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, 4096, 1, 2, 0x00bf, 0x273f, 0x0, 0x0, 0x555, 0x2aa, 0)) {
if(!pflash_cfi02_register(NOR_MEM_BASE, "nor", 1024 * 1024, nms->nor_drive ? blk_by_legacy_dinfo(nms->nor_drive) : NULL, 4096, 1, 2, 0x00bf, 0x273f, 0x0, 0x0, 0x555, 0x2aa, 0)) {
printf("Error registering NOR flash!\n");
abort();
}
Expand Down Expand Up @@ -457,7 +458,9 @@ static void ipod_touch_machine_init(MachineState *machine)

// init spis
set_spi_base(0);
sysbus_create_simple("s5l8900spi", SPI0_MEM_BASE, s5l8900_get_irq(nms, S5L8900_SPI0_IRQ));
dev = sysbus_create_simple("s5l8900spi", SPI0_MEM_BASE, s5l8900_get_irq(nms, S5L8900_SPI0_IRQ));
S5L8900SPIState *spi0_state = S5L8900SPI(dev);
spi0_state->nor_drive = nms->nor_drive;

set_spi_base(1);
sysbus_create_simple("s5l8900spi", SPI1_MEM_BASE, s5l8900_get_irq(nms, S5L8900_SPI1_IRQ));
Expand Down Expand Up @@ -532,14 +535,14 @@ static void ipod_touch_machine_init(MachineState *machine)
memory_region_init_io(iomem, OBJECT(s), &usb_phys_ops, usb_state, "usbphys", 0x40);
memory_region_add_subregion(sysmem, USBPHYS_MEM_BASE, iomem);

// init 8900 OPS
allocate_ram(sysmem, "8900ops", LLB_BASE, 0x1000);
// // init 8900 OPS
// allocate_ram(sysmem, "8900ops", LLB_BASE, 0x1000);

// patch the instructions related to 8900 decryption
// // patch the instructions related to 8900 decryption
uint32_t *data = malloc(sizeof(uint32_t) * 2);
data[0] = 0xe3b00001; // MOVS R0, #1
data[1] = 0xe12fff1e; // BX LR
address_space_rw(nsas, LLB_BASE + 0x80, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint32_t) * 2, 1);
// data[0] = 0xe3b00001; // MOVS R0, #1
// data[1] = 0xe12fff1e; // BX LR
// address_space_rw(nsas, LLB_BASE + 0x80, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint32_t) * 2, 1);

/*
load the decryption logic in memory. These bytes correspond to the following ARMv6 instructions:
Expand All @@ -554,7 +557,7 @@ static void ipod_touch_machine_init(MachineState *machine)
data[1] = 0xE5810000; // STR r0,[r1]
data[2] = 0xE3B00001; // MOVS R0, #1
data[3] = 0xE12FFF1E; // BX lr
address_space_rw(nsas, LLB_BASE + 0x100, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint32_t) * 4, 1);
// address_space_rw(nsas, LLB_BASE + 0x100, MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint32_t) * 4, 1);

// contains some constants
data = malloc(4);
Expand Down Expand Up @@ -658,7 +661,7 @@ static void ipod_touch_machine_class_init(ObjectClass *obj, void *data)
mc->desc = "iPod Touch";
mc->init = ipod_touch_machine_init;
mc->max_cpus = 1;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm1176");
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926ej-s");
}

static const TypeInfo ipod_touch_machine_info = {
Expand Down
12 changes: 9 additions & 3 deletions hw/arm/ipod_touch_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ static void apple_spi_run(S5L8900SPIState *s)
uint32_t tx;
uint32_t rx;

fprintf(stderr, "apple_spi_run\n");

if (!(REG(s, R_CTRL) & R_CTRL_RUN)) {
return;
fprintf(stderr, "apple_spi_run: not running\n");
// return;
}

while (!fifo8_is_empty(&s->tx_fifo)) {
Expand Down Expand Up @@ -127,7 +130,7 @@ static void apple_spi_run(S5L8900SPIState *s)
static uint64_t s5l8900_spi_read(void *opaque, hwaddr addr, unsigned size)
{
S5L8900SPIState *s = S5L8900SPI(opaque);
//fprintf(stderr, "%s (base %d): read from location 0x%08x\n", __func__, s->base, addr);
fprintf(stderr, "%s (base %d): read from location 0x%08x\n", __func__, s->base, addr);

uint32_t r;
bool run = false;
Expand Down Expand Up @@ -173,7 +176,7 @@ static uint64_t s5l8900_spi_read(void *opaque, hwaddr addr, unsigned size)
static void s5l8900_spi_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
{
S5L8900SPIState *s = S5L8900SPI(opaque);
//fprintf(stderr, "%s (base %d): writing 0x%08x to 0x%08x\n", __func__, s->base, data, addr);
fprintf(stderr, "%s (base %d): writing 0x%08x to 0x%08x\n", __func__, s->base, data, addr);

uint32_t r = data;
uint32_t *mmio = &REG(s, addr);
Expand Down Expand Up @@ -274,6 +277,9 @@ static void s5l8900_spi_realize(DeviceState *dev, struct Error **errp)
// create the peripheral
switch(s->base) {
case 0:
BlockBackend* blk = s->nor_drive ? blk_by_legacy_dinfo(s->nor_drive) : NULL;
qdev_prop_set_drive_err(s->spi, "drive", blk, NULL);
dev = ssi_create_peripheral(s->spi, "sst25vf080b");
break;
case 1:
ssi_create_peripheral(s->spi, TYPE_IPOD_TOUCH_LCD_PANEL);
Expand Down
5 changes: 3 additions & 2 deletions include/hw/arm/ipod_touch.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ const int S5L8900_GPIO_IRQS[7] = { S5L8900_GPIO_G0_IRQ, S5L8900_GPIO_G1_IRQ, S5L
#define TIMER1_MEM_BASE 0x3E200000
#define USBOTG_MEM_BASE 0x38400000
#define USBPHYS_MEM_BASE 0x3C400000
#define GPIO_MEM_BASE 0x3E400000
#define GPIO_MEM_BASE 0x3CF00000
#define I2C0_MEM_BASE 0x3C600000
#define I2C1_MEM_BASE 0x3C900000
#define SPI0_MEM_BASE 0x3C300000
#define SPI1_MEM_BASE 0x3CE00000
#define SPI2_MEM_BASE 0x3D200000
#define WATCHDOG_MEM_BASE 0x3E300000
#define WATCHDOG_MEM_BASE 0x3C800000
#define DISPLAY_MEM_BASE 0x38900000
#define CHIPID_MEM_BASE 0x3e500000
#define RAM_MEM_BASE 0x8000000
Expand Down Expand Up @@ -170,6 +170,7 @@ typedef struct {
char bootrom_path[1024];
char iboot_path[1024];
char nand_path[1024];
DriveInfo* nor_drive;
} IPodTouchMachineState;

#endif
2 changes: 2 additions & 0 deletions include/hw/arm/ipod_touch_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ typedef struct S5L8900SPIState {
uint32_t regs[MMIO_SIZE >> 2];
uint32_t mmio_size;
uint8_t base;

DriveInfo *nor_drive;
} S5L8900SPIState;

void set_spi_base(uint32_t base);
Expand Down

0 comments on commit 2c7a61f

Please sign in to comment.