From 2c92a188926ffa705c20100a8e2c2f2139d2b322 Mon Sep 17 00:00:00 2001 From: Martijn de Vos Date: Wed, 12 Jul 2023 20:38:20 +0200 Subject: [PATCH] Multiple fixes for SPI --- hw/arm/ipod_touch_2g.c | 2 +- hw/arm/ipod_touch_fmss.c | 7 +----- hw/arm/ipod_touch_nor_spi.c | 34 ++++++++++++++++++++++++----- hw/arm/ipod_touch_spi.c | 18 ++++++++------- include/hw/arm/ipod_touch_nor_spi.h | 6 +++++ 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/hw/arm/ipod_touch_2g.c b/hw/arm/ipod_touch_2g.c index 90a9502e26..d700677441 100644 --- a/hw/arm/ipod_touch_2g.c +++ b/hw/arm/ipod_touch_2g.c @@ -250,7 +250,7 @@ static void ipod_touch_machine_init(MachineState *machine) dev = sysbus_create_simple("ipodtouch.spi", SPI1_MEM_BASE, s5l8900_get_irq(nms, S5L8720_SPI1_IRQ)); IPodTouchSPIState *spi1_state = IPOD_TOUCH_SPI(dev); nms->spi1_state = spi1_state; - strcpy(spi1_state->nor->nor_path, nms->nor_path); + //strcpy(spi1_state->nor->nor_path, nms->nor_path); set_spi_base(2); sysbus_create_simple("ipodtouch.spi", SPI2_MEM_BASE, s5l8900_get_irq(nms, S5L8720_SPI2_IRQ)); diff --git a/hw/arm/ipod_touch_fmss.c b/hw/arm/ipod_touch_fmss.c index 1075110946..48d88587fb 100644 --- a/hw/arm/ipod_touch_fmss.c +++ b/hw/arm/ipod_touch_fmss.c @@ -68,13 +68,8 @@ static void read_nand_pages(IPodTouchFMSSState *s) // aux_data[1] = 0xc0db0640; // NAND FTL object cpu_physical_memory_write(0x858fdd4 + 0x5C, (uint8_t *)aux_data, 4); - // TEMP - replace the IOService wait - data[0] = 0x00BF; - cpu_physical_memory_write(0x8176482, (uint8_t *)data, 2); - - // boot args - char *boot_args = "kextlog=0xfff debug=0x8 cpus=1 rd=disk0s1 serial=1 io=0xffffffff debug-usb=0xffffffff"; + char *boot_args = "kextlog=0xfff debug=0x8 cpus=1 rd=disk0s1 serial=1 io=0xffff8fff debug-usb=0xffffffff"; cpu_physical_memory_write(0x0ff2a584, boot_args, strlen(boot_args)); for(int page_ind = 0; page_ind < s->reg_num_pages; page_ind++) { diff --git a/hw/arm/ipod_touch_nor_spi.c b/hw/arm/ipod_touch_nor_spi.c index 4305ee9d46..aedd2b6c38 100644 --- a/hw/arm/ipod_touch_nor_spi.c +++ b/hw/arm/ipod_touch_nor_spi.c @@ -13,10 +13,6 @@ static uint32_t ipod_touch_nor_spi_transfer(SSIPeripheral *dev, uint32_t value) { IPodTouchNORSPIState *s = IPOD_TOUCH_NOR_SPI(dev); - if(value == NOR_GET_JEDECID) { - printf("RECEIVED JEDCID VALUE\n"); - } - if(s->cur_cmd == NOR_READ_DATA_CMD && s->in_buf_cur_ind == s->in_buf_size && value != 0xFF) { // if we are currently reading from the NOR data and we receive a value that's not the sentinel, reset the current command. s->cur_cmd = 0; @@ -25,23 +21,48 @@ static uint32_t ipod_touch_nor_spi_transfer(SSIPeripheral *dev, uint32_t value) if(s->cur_cmd == 0) { // this is a new command -> set it s->cur_cmd = value; + printf("NEW CMD %d\n", s->cur_cmd); s->out_buf = malloc(0x1000); - s->in_buf = malloc(0x100); + s->in_buf = malloc(0x1000); s->in_buf[0] = value; s->in_buf_size = 0; s->in_buf_cur_ind = 1; s->out_buf_cur_ind = 0; - if(value == NOR_GET_STATUS_CMD) { + if(value == NOR_WRITE_TO_STATUS_REG) { s->in_buf_size = 1; s->out_buf_size = 1; s->out_buf[0] = 0; } + else if(value == NOR_GET_STATUS_CMD) { + printf("GET STATUS\n"); + s->in_buf_size = 1; + s->out_buf_size = 1; + s->out_buf[0] = 0; + } + else if(value == NOR_WRITE_DATA_CMD) { + s->in_buf_size = 4; + s->out_buf_size = 256; + for(int i = 0; i < 256; i++) { s->out_buf[i] = 0; }; // TODO we ignore this command for now + } else if(value == NOR_READ_DATA_CMD) { printf("Received read command!\n"); s->in_buf_size = 4; s->out_buf_size = 4096; } + else if(value == NOR_ERASE_BLOCK) { + s->in_buf_size = 1; + s->out_buf_size = 3; + for(int i = 0; i < 3; i++) { s->out_buf[i] = 0x0; } // TODO we ignore this command for now + } + else if(value == NOR_ENABLE_WRITE) { + s->write_enabled = 1; + s->cur_cmd = 0; + } + else if(value == NOR_DISABLE_WRITE) { + s->write_enabled = 0; + s->cur_cmd = 0; + } else if(value == NOR_GET_JEDECID) { s->in_buf_size = 1; s->out_buf_size = 3; @@ -50,6 +71,7 @@ static uint32_t ipod_touch_nor_spi_transfer(SSIPeripheral *dev, uint32_t value) s->out_buf[2] = 0x02; } else { + printf("Unknown command %d!\n", value); hw_error("Unknown command 0x%02x!", value); } diff --git a/hw/arm/ipod_touch_spi.c b/hw/arm/ipod_touch_spi.c index 4de86d0928..a8b1cabb4c 100644 --- a/hw/arm/ipod_touch_spi.c +++ b/hw/arm/ipod_touch_spi.c @@ -94,6 +94,9 @@ static void apple_spi_run(IPodTouchSPIState *s) apple_spi_update_xfer_tx(s); + //printf("TX queue: %d, RX queue: %d\n", REG(s, R_TXCNT), REG(s, R_RXCNT)); + //printf("TX buffer size: %d, RX buffer size: %d\n", fifo8_num_used(&s->tx_fifo), fifo8_num_used(&s->rx_fifo)); + while (REG(s, R_TXCNT) && !fifo8_is_empty(&s->tx_fifo)) { tx = (uint32_t)fifo8_pop(&s->tx_fifo); rx = ssi_transfer(s->spi, tx); @@ -129,6 +132,8 @@ static void apple_spi_run(IPodTouchSPIState *s) if (REG(s, R_RXCNT) == 0 && REG(s, R_TXCNT) == 0) { REG(s, R_STATUS) |= R_STATUS_COMPLETE; } + + //printf(" TX buffer size: %d, RX buffer size: %d\n", fifo8_num_used(&s->tx_fifo), fifo8_num_used(&s->rx_fifo)); } static uint64_t ipod_touch_spi_read(void *opaque, hwaddr addr, unsigned size) @@ -201,6 +206,7 @@ static void ipod_touch_spi_write(void *opaque, hwaddr addr, uint64_t data, unsig } break; case R_STATUS: + run = true; r = old & (~r); break; case R_PIN: @@ -208,12 +214,8 @@ static void ipod_touch_spi_write(void *opaque, hwaddr addr, uint64_t data, unsig break; case R_TXDATA ... R_TXDATA + 3: { int word_size = apple_spi_word_size(s); - if ((fifo8_is_full(&s->tx_fifo)) - || (fifo8_num_free(&s->tx_fifo) < word_size)) { + if (fifo8_is_full(&s->tx_fifo) || fifo8_num_free(&s->tx_fifo) < word_size) { hw_error("Tx buffer overflow: %d\n", fifo8_num_free(&s->tx_fifo)); - qemu_log_mask(LOG_GUEST_ERROR, "%s: tx overflow\n", __func__); - r = 0; - break; } fifo8_push_all(&s->tx_fifo, (uint8_t *)&r, word_size); break; @@ -292,9 +294,9 @@ static void ipod_touch_spi_realize(DeviceState *dev, struct Error **errp) s->nor = nor; break; case 1: - ssi_create_peripheral(s->spi, TYPE_IPOD_TOUCH_NOR_SPI); - nor = IPOD_TOUCH_NOR_SPI(dev); - s->nor = nor; + //ssi_create_peripheral(s->spi, TYPE_IPOD_TOUCH_NOR_SPI); + //nor = IPOD_TOUCH_NOR_SPI(dev); + //s->nor = nor; break; case 4: { diff --git a/include/hw/arm/ipod_touch_nor_spi.h b/include/hw/arm/ipod_touch_nor_spi.h index 6e48d9634d..1f4a87d497 100644 --- a/include/hw/arm/ipod_touch_nor_spi.h +++ b/include/hw/arm/ipod_touch_nor_spi.h @@ -10,8 +10,13 @@ #define TYPE_IPOD_TOUCH_NOR_SPI "ipodtouch.norspi" OBJECT_DECLARE_SIMPLE_TYPE(IPodTouchNORSPIState, IPOD_TOUCH_NOR_SPI) +#define NOR_WRITE_TO_STATUS_REG 0x1 +#define NOR_WRITE_DATA_CMD 0x2 #define NOR_READ_DATA_CMD 0x3 +#define NOR_DISABLE_WRITE 0x4 #define NOR_GET_STATUS_CMD 0x5 +#define NOR_ENABLE_WRITE 0x6 +#define NOR_ERASE_BLOCK 0x20 #define NOR_GET_JEDECID 0x9F typedef struct IPodTouchNORSPIState { @@ -24,6 +29,7 @@ typedef struct IPodTouchNORSPIState { uint32_t in_buf_cur_ind; uint32_t out_buf_cur_ind; uint8_t *nor_data; + uint8_t write_enabled; uint32_t nor_read_ind; char nor_path[1024]; bool nor_initialized;