Multiple fixes for SPI

This commit is contained in:
Martijn de Vos committed 2023-12-31 14:44:36 +01:00
1 parent 5a756faaa0
commit 2c92a18892
5 files changed
+46 -21

No files matched your search

+1 -1
View File
@@ -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));
+1 -6
View File
@@ -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++) {
+28 -6
View File
@@ -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);
}
+10 -8
View File
@@ -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("<after> 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:
{
+6
View File
@@ -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;