Multiple fixes for SPI
This commit is contained in:
1 parent
5a756faaa0
commit
2c92a18892
5 files changed
+46
-21
No files matched your search
@@ -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));
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user