version 1.1.1.6, 2018/04/24 16:48:52
|
version 1.1.1.7, 2018/04/24 16:53:45
|
Line 21
|
Line 21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
* THE SOFTWARE. |
* THE SOFTWARE. |
*/ |
*/ |
|
|
#include "hw.h" |
#include "hw.h" |
#include "block.h" |
|
#include "scsi-disk.h" |
#include "scsi-disk.h" |
#include "sun4m.h" |
#include "scsi.h" |
/* FIXME: Only needed for MAX_DISKS, which is probably wrong. */ |
|
#include "sysemu.h" |
|
|
|
/* debug ESP card */ |
/* debug ESP card */ |
//#define DEBUG_ESP |
//#define DEBUG_ESP |
Line 43
|
Line 41
|
#define DPRINTF(fmt, args...) \ |
#define DPRINTF(fmt, args...) \ |
do { printf("ESP: " fmt , ##args); } while (0) |
do { printf("ESP: " fmt , ##args); } while (0) |
#else |
#else |
#define DPRINTF(fmt, args...) |
#define DPRINTF(fmt, args...) do {} while (0) |
#endif |
#endif |
|
|
#define ESP_MASK 0x3f |
#define ESP_ERROR(fmt, args...) \ |
|
do { printf("ESP ERROR: %s: " fmt, __func__ , ##args); } while (0) |
|
|
#define ESP_REGS 16 |
#define ESP_REGS 16 |
#define ESP_SIZE (ESP_REGS * 4) |
#define TI_BUFSZ 16 |
#define TI_BUFSZ 32 |
|
|
|
typedef struct ESPState ESPState; |
typedef struct ESPState ESPState; |
|
|
struct ESPState { |
struct ESPState { |
|
uint32_t it_shift; |
qemu_irq irq; |
qemu_irq irq; |
uint8_t rregs[ESP_REGS]; |
uint8_t rregs[ESP_REGS]; |
uint8_t wregs[ESP_REGS]; |
uint8_t wregs[ESP_REGS]; |
int32_t ti_size; |
int32_t ti_size; |
uint32_t ti_rptr, ti_wptr; |
uint32_t ti_rptr, ti_wptr; |
uint8_t ti_buf[TI_BUFSZ]; |
uint8_t ti_buf[TI_BUFSZ]; |
int sense; |
uint32_t sense; |
int dma; |
uint32_t dma; |
SCSIDevice *scsi_dev[ESP_MAX_DEVS]; |
SCSIDevice *scsi_dev[ESP_MAX_DEVS]; |
SCSIDevice *current_dev; |
SCSIDevice *current_dev; |
uint8_t cmdbuf[TI_BUFSZ]; |
uint8_t cmdbuf[TI_BUFSZ]; |
int cmdlen; |
uint32_t cmdlen; |
int do_cmd; |
uint32_t do_cmd; |
|
|
/* The amount of data left in the current DMA transfer. */ |
/* The amount of data left in the current DMA transfer. */ |
uint32_t dma_left; |
uint32_t dma_left; |
Line 75 struct ESPState {
|
Line 75 struct ESPState {
|
uint32_t dma_counter; |
uint32_t dma_counter; |
uint8_t *async_buf; |
uint8_t *async_buf; |
uint32_t async_len; |
uint32_t async_len; |
|
|
|
espdma_memory_read_write dma_memory_read; |
|
espdma_memory_read_write dma_memory_write; |
void *dma_opaque; |
void *dma_opaque; |
}; |
}; |
|
|
Line 120 struct ESPState {
|
Line 123 struct ESPState {
|
#define STAT_DI 0x01 |
#define STAT_DI 0x01 |
#define STAT_CD 0x02 |
#define STAT_CD 0x02 |
#define STAT_ST 0x03 |
#define STAT_ST 0x03 |
#define STAT_MI 0x06 |
#define STAT_MO 0x06 |
#define STAT_MO 0x07 |
#define STAT_MI 0x07 |
#define STAT_PIO_MASK 0x06 |
#define STAT_PIO_MASK 0x06 |
|
|
#define STAT_TC 0x10 |
#define STAT_TC 0x10 |
#define STAT_PE 0x20 |
#define STAT_PE 0x20 |
#define STAT_GE 0x40 |
#define STAT_GE 0x40 |
#define STAT_IN 0x80 |
#define STAT_INT 0x80 |
|
|
|
#define BUSID_DID 0x07 |
|
|
#define INTR_FC 0x08 |
#define INTR_FC 0x08 |
#define INTR_BS 0x10 |
#define INTR_BS 0x10 |
Line 139 struct ESPState {
|
Line 144 struct ESPState {
|
|
|
#define CFG1_RESREPT 0x40 |
#define CFG1_RESREPT 0x40 |
|
|
#define CFG2_MASK 0x15 |
|
|
|
#define TCHI_FAS100A 0x4 |
#define TCHI_FAS100A 0x4 |
|
|
static int get_cmd(ESPState *s, uint8_t *buf) |
static void esp_raise_irq(ESPState *s) |
|
{ |
|
if (!(s->rregs[ESP_RSTAT] & STAT_INT)) { |
|
s->rregs[ESP_RSTAT] |= STAT_INT; |
|
qemu_irq_raise(s->irq); |
|
} |
|
} |
|
|
|
static void esp_lower_irq(ESPState *s) |
|
{ |
|
if (s->rregs[ESP_RSTAT] & STAT_INT) { |
|
s->rregs[ESP_RSTAT] &= ~STAT_INT; |
|
qemu_irq_lower(s->irq); |
|
} |
|
} |
|
|
|
static uint32_t get_cmd(ESPState *s, uint8_t *buf) |
{ |
{ |
uint32_t dmalen; |
uint32_t dmalen; |
int target; |
int target; |
|
|
dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8); |
target = s->wregs[ESP_WBUSID] & BUSID_DID; |
target = s->wregs[ESP_WBUSID] & 7; |
|
DPRINTF("get_cmd: len %d target %d\n", dmalen, target); |
|
if (s->dma) { |
if (s->dma) { |
espdma_memory_read(s->dma_opaque, buf, dmalen); |
dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8); |
|
s->dma_memory_read(s->dma_opaque, buf, dmalen); |
} else { |
} else { |
|
dmalen = s->ti_size; |
|
memcpy(buf, s->ti_buf, dmalen); |
buf[0] = 0; |
buf[0] = 0; |
memcpy(&buf[1], s->ti_buf, dmalen); |
|
dmalen++; |
|
} |
} |
|
DPRINTF("get_cmd: len %d target %d\n", dmalen, target); |
|
|
s->ti_size = 0; |
s->ti_size = 0; |
s->ti_rptr = 0; |
s->ti_rptr = 0; |
Line 171 static int get_cmd(ESPState *s, uint8_t
|
Line 190 static int get_cmd(ESPState *s, uint8_t
|
|
|
if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) { |
if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) { |
// No such drive |
// No such drive |
s->rregs[ESP_RSTAT] = STAT_IN; |
s->rregs[ESP_RSTAT] = 0; |
s->rregs[ESP_RINTR] = INTR_DC; |
s->rregs[ESP_RINTR] = INTR_DC; |
s->rregs[ESP_RSEQ] = SEQ_0; |
s->rregs[ESP_RSEQ] = SEQ_0; |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
return 0; |
return 0; |
} |
} |
s->current_dev = s->scsi_dev[target]; |
s->current_dev = s->scsi_dev[target]; |
Line 191 static void do_cmd(ESPState *s, uint8_t
|
Line 210 static void do_cmd(ESPState *s, uint8_t
|
datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun); |
datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun); |
s->ti_size = datalen; |
s->ti_size = datalen; |
if (datalen != 0) { |
if (datalen != 0) { |
s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC; |
s->rregs[ESP_RSTAT] = STAT_TC; |
s->dma_left = 0; |
s->dma_left = 0; |
s->dma_counter = 0; |
s->dma_counter = 0; |
if (datalen > 0) { |
if (datalen > 0) { |
Line 204 static void do_cmd(ESPState *s, uint8_t
|
Line 223 static void do_cmd(ESPState *s, uint8_t
|
} |
} |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
|
|
static void handle_satn(ESPState *s) |
static void handle_satn(ESPState *s) |
Line 223 static void handle_satn_stop(ESPState *s
|
Line 242 static void handle_satn_stop(ESPState *s
|
if (s->cmdlen) { |
if (s->cmdlen) { |
DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen); |
DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen); |
s->do_cmd = 1; |
s->do_cmd = 1; |
s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_CD; |
s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
} |
} |
|
|
Line 236 static void write_response(ESPState *s)
|
Line 255 static void write_response(ESPState *s)
|
s->ti_buf[0] = s->sense; |
s->ti_buf[0] = s->sense; |
s->ti_buf[1] = 0; |
s->ti_buf[1] = 0; |
if (s->dma) { |
if (s->dma) { |
espdma_memory_write(s->dma_opaque, s->ti_buf, 2); |
s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); |
s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_ST; |
s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
s->rregs[ESP_RSEQ] = SEQ_CD; |
} else { |
} else { |
Line 246 static void write_response(ESPState *s)
|
Line 265 static void write_response(ESPState *s)
|
s->ti_wptr = 0; |
s->ti_wptr = 0; |
s->rregs[ESP_RFLAGS] = 2; |
s->rregs[ESP_RFLAGS] = 2; |
} |
} |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
|
|
static void esp_dma_done(ESPState *s) |
static void esp_dma_done(ESPState *s) |
{ |
{ |
s->rregs[ESP_RSTAT] |= STAT_IN | STAT_TC; |
s->rregs[ESP_RSTAT] |= STAT_TC; |
s->rregs[ESP_RINTR] = INTR_BS; |
s->rregs[ESP_RINTR] = INTR_BS; |
s->rregs[ESP_RSEQ] = 0; |
s->rregs[ESP_RSEQ] = 0; |
s->rregs[ESP_RFLAGS] = 0; |
s->rregs[ESP_RFLAGS] = 0; |
s->rregs[ESP_TCLO] = 0; |
s->rregs[ESP_TCLO] = 0; |
s->rregs[ESP_TCMID] = 0; |
s->rregs[ESP_TCMID] = 0; |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
|
|
static void esp_do_dma(ESPState *s) |
static void esp_do_dma(ESPState *s) |
Line 269 static void esp_do_dma(ESPState *s)
|
Line 288 static void esp_do_dma(ESPState *s)
|
len = s->dma_left; |
len = s->dma_left; |
if (s->do_cmd) { |
if (s->do_cmd) { |
DPRINTF("command len %d + %d\n", s->cmdlen, len); |
DPRINTF("command len %d + %d\n", s->cmdlen, len); |
espdma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); |
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); |
s->ti_size = 0; |
s->ti_size = 0; |
s->cmdlen = 0; |
s->cmdlen = 0; |
s->do_cmd = 0; |
s->do_cmd = 0; |
Line 284 static void esp_do_dma(ESPState *s)
|
Line 303 static void esp_do_dma(ESPState *s)
|
len = s->async_len; |
len = s->async_len; |
} |
} |
if (to_device) { |
if (to_device) { |
espdma_memory_read(s->dma_opaque, s->async_buf, len); |
s->dma_memory_read(s->dma_opaque, s->async_buf, len); |
} else { |
} else { |
espdma_memory_write(s->dma_opaque, s->async_buf, len); |
s->dma_memory_write(s->dma_opaque, s->async_buf, len); |
} |
} |
s->dma_left -= len; |
s->dma_left -= len; |
s->async_buf += len; |
s->async_buf += len; |
Line 302 static void esp_do_dma(ESPState *s)
|
Line 321 static void esp_do_dma(ESPState *s)
|
} else { |
} else { |
s->current_dev->read_data(s->current_dev, 0); |
s->current_dev->read_data(s->current_dev, 0); |
/* If there is still data to be read from the device then |
/* If there is still data to be read from the device then |
complete the DMA operation immeriately. Otherwise defer |
complete the DMA operation immediately. Otherwise defer |
until the scsi layer has completed. */ |
until the scsi layer has completed. */ |
if (s->dma_left == 0 && s->ti_size > 0) { |
if (s->dma_left == 0 && s->ti_size > 0) { |
esp_dma_done(s); |
esp_dma_done(s); |
Line 381 static void esp_reset(void *opaque)
|
Line 400 static void esp_reset(void *opaque)
|
{ |
{ |
ESPState *s = opaque; |
ESPState *s = opaque; |
|
|
|
esp_lower_irq(s); |
|
|
memset(s->rregs, 0, ESP_REGS); |
memset(s->rregs, 0, ESP_REGS); |
memset(s->wregs, 0, ESP_REGS); |
memset(s->wregs, 0, ESP_REGS); |
s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a |
s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a |
Line 389 static void esp_reset(void *opaque)
|
Line 410 static void esp_reset(void *opaque)
|
s->ti_wptr = 0; |
s->ti_wptr = 0; |
s->dma = 0; |
s->dma = 0; |
s->do_cmd = 0; |
s->do_cmd = 0; |
|
|
|
s->rregs[ESP_CFG1] = 7; |
} |
} |
|
|
static void parent_esp_reset(void *opaque, int irq, int level) |
static void parent_esp_reset(void *opaque, int irq, int level) |
Line 402 static uint32_t esp_mem_readb(void *opaq
|
Line 425 static uint32_t esp_mem_readb(void *opaq
|
ESPState *s = opaque; |
ESPState *s = opaque; |
uint32_t saddr; |
uint32_t saddr; |
|
|
saddr = (addr & ESP_MASK) >> 2; |
saddr = addr >> s->it_shift; |
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); |
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); |
switch (saddr) { |
switch (saddr) { |
case ESP_FIFO: |
case ESP_FIFO: |
if (s->ti_size > 0) { |
if (s->ti_size > 0) { |
s->ti_size--; |
s->ti_size--; |
if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { |
if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { |
/* Data in/out. */ |
/* Data out. */ |
fprintf(stderr, "esp: PIO data read not implemented\n"); |
ESP_ERROR("PIO data read not implemented\n"); |
s->rregs[ESP_FIFO] = 0; |
s->rregs[ESP_FIFO] = 0; |
} else { |
} else { |
s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; |
s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; |
} |
} |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
if (s->ti_size == 0) { |
if (s->ti_size == 0) { |
s->ti_rptr = 0; |
s->ti_rptr = 0; |
Line 424 static uint32_t esp_mem_readb(void *opaq
|
Line 447 static uint32_t esp_mem_readb(void *opaq
|
break; |
break; |
case ESP_RINTR: |
case ESP_RINTR: |
// Clear interrupt/error status bits |
// Clear interrupt/error status bits |
s->rregs[ESP_RSTAT] &= ~(STAT_IN | STAT_GE | STAT_PE); |
s->rregs[ESP_RSTAT] &= ~(STAT_GE | STAT_PE); |
qemu_irq_lower(s->irq); |
esp_lower_irq(s); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 438 static void esp_mem_writeb(void *opaque,
|
Line 461 static void esp_mem_writeb(void *opaque,
|
ESPState *s = opaque; |
ESPState *s = opaque; |
uint32_t saddr; |
uint32_t saddr; |
|
|
saddr = (addr & ESP_MASK) >> 2; |
saddr = addr >> s->it_shift; |
DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], |
DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], |
val); |
val); |
switch (saddr) { |
switch (saddr) { |
Line 449 static void esp_mem_writeb(void *opaque,
|
Line 472 static void esp_mem_writeb(void *opaque,
|
case ESP_FIFO: |
case ESP_FIFO: |
if (s->do_cmd) { |
if (s->do_cmd) { |
s->cmdbuf[s->cmdlen++] = val & 0xff; |
s->cmdbuf[s->cmdlen++] = val & 0xff; |
} else if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { |
} else if (s->ti_size == TI_BUFSZ - 1) { |
uint8_t buf; |
ESP_ERROR("fifo overrun\n"); |
buf = val & 0xff; |
|
s->ti_size--; |
|
fprintf(stderr, "esp: PIO data write not implemented\n"); |
|
} else { |
} else { |
s->ti_size++; |
s->ti_size++; |
s->ti_buf[s->ti_wptr++] = val & 0xff; |
s->ti_buf[s->ti_wptr++] = val & 0xff; |
Line 478 static void esp_mem_writeb(void *opaque,
|
Line 498 static void esp_mem_writeb(void *opaque,
|
//s->ti_size = 0; |
//s->ti_size = 0; |
s->rregs[ESP_RINTR] = INTR_FC; |
s->rregs[ESP_RINTR] = INTR_FC; |
s->rregs[ESP_RSEQ] = 0; |
s->rregs[ESP_RSEQ] = 0; |
|
s->rregs[ESP_RFLAGS] = 0; |
break; |
break; |
case CMD_RESET: |
case CMD_RESET: |
DPRINTF("Chip reset (%2.2x)\n", val); |
DPRINTF("Chip reset (%2.2x)\n", val); |
Line 487 static void esp_mem_writeb(void *opaque,
|
Line 508 static void esp_mem_writeb(void *opaque,
|
DPRINTF("Bus reset (%2.2x)\n", val); |
DPRINTF("Bus reset (%2.2x)\n", val); |
s->rregs[ESP_RINTR] = INTR_RST; |
s->rregs[ESP_RINTR] = INTR_RST; |
if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { |
if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { |
qemu_irq_raise(s->irq); |
esp_raise_irq(s); |
} |
} |
break; |
break; |
case CMD_TI: |
case CMD_TI: |
Line 496 static void esp_mem_writeb(void *opaque,
|
Line 517 static void esp_mem_writeb(void *opaque,
|
case CMD_ICCS: |
case CMD_ICCS: |
DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); |
DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); |
write_response(s); |
write_response(s); |
|
s->rregs[ESP_RINTR] = INTR_FC; |
|
s->rregs[ESP_RSTAT] |= STAT_MI; |
break; |
break; |
case CMD_MSGACC: |
case CMD_MSGACC: |
DPRINTF("Message Accepted (%2.2x)\n", val); |
DPRINTF("Message Accepted (%2.2x)\n", val); |
Line 516 static void esp_mem_writeb(void *opaque,
|
Line 539 static void esp_mem_writeb(void *opaque,
|
break; |
break; |
case CMD_ENSEL: |
case CMD_ENSEL: |
DPRINTF("Enable selection (%2.2x)\n", val); |
DPRINTF("Enable selection (%2.2x)\n", val); |
|
s->rregs[ESP_RINTR] = 0; |
break; |
break; |
default: |
default: |
DPRINTF("Unhandled ESP command (%2.2x)\n", val); |
ESP_ERROR("Unhandled ESP command (%2.2x)\n", val); |
break; |
break; |
} |
} |
break; |
break; |
Line 529 static void esp_mem_writeb(void *opaque,
|
Line 553 static void esp_mem_writeb(void *opaque,
|
break; |
break; |
case ESP_WCCF ... ESP_WTEST: |
case ESP_WCCF ... ESP_WTEST: |
break; |
break; |
case ESP_CFG2: |
case ESP_CFG2 ... ESP_RES4: |
s->rregs[saddr] = val & CFG2_MASK; |
|
break; |
|
case ESP_CFG3 ... ESP_RES4: |
|
s->rregs[saddr] = val; |
s->rregs[saddr] = val; |
break; |
break; |
default: |
default: |
break; |
ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr); |
|
return; |
} |
} |
s->wregs[saddr] = val; |
s->wregs[saddr] = val; |
} |
} |
Line 550 static CPUReadMemoryFunc *esp_mem_read[3
|
Line 572 static CPUReadMemoryFunc *esp_mem_read[3
|
static CPUWriteMemoryFunc *esp_mem_write[3] = { |
static CPUWriteMemoryFunc *esp_mem_write[3] = { |
esp_mem_writeb, |
esp_mem_writeb, |
NULL, |
NULL, |
NULL, |
esp_mem_writeb, |
}; |
}; |
|
|
static void esp_save(QEMUFile *f, void *opaque) |
static void esp_save(QEMUFile *f, void *opaque) |
Line 559 static void esp_save(QEMUFile *f, void *
|
Line 581 static void esp_save(QEMUFile *f, void *
|
|
|
qemu_put_buffer(f, s->rregs, ESP_REGS); |
qemu_put_buffer(f, s->rregs, ESP_REGS); |
qemu_put_buffer(f, s->wregs, ESP_REGS); |
qemu_put_buffer(f, s->wregs, ESP_REGS); |
qemu_put_be32s(f, &s->ti_size); |
qemu_put_sbe32s(f, &s->ti_size); |
qemu_put_be32s(f, &s->ti_rptr); |
qemu_put_be32s(f, &s->ti_rptr); |
qemu_put_be32s(f, &s->ti_wptr); |
qemu_put_be32s(f, &s->ti_wptr); |
qemu_put_buffer(f, s->ti_buf, TI_BUFSZ); |
qemu_put_buffer(f, s->ti_buf, TI_BUFSZ); |
Line 581 static int esp_load(QEMUFile *f, void *o
|
Line 603 static int esp_load(QEMUFile *f, void *o
|
|
|
qemu_get_buffer(f, s->rregs, ESP_REGS); |
qemu_get_buffer(f, s->rregs, ESP_REGS); |
qemu_get_buffer(f, s->wregs, ESP_REGS); |
qemu_get_buffer(f, s->wregs, ESP_REGS); |
qemu_get_be32s(f, &s->ti_size); |
qemu_get_sbe32s(f, &s->ti_size); |
qemu_get_be32s(f, &s->ti_rptr); |
qemu_get_be32s(f, &s->ti_rptr); |
qemu_get_be32s(f, &s->ti_wptr); |
qemu_get_be32s(f, &s->ti_wptr); |
qemu_get_buffer(f, s->ti_buf, TI_BUFSZ); |
qemu_get_buffer(f, s->ti_buf, TI_BUFSZ); |
Line 601 void esp_scsi_attach(void *opaque, Block
|
Line 623 void esp_scsi_attach(void *opaque, Block
|
|
|
if (id < 0) { |
if (id < 0) { |
for (id = 0; id < ESP_MAX_DEVS; id++) { |
for (id = 0; id < ESP_MAX_DEVS; id++) { |
|
if (id == (s->rregs[ESP_CFG1] & 0x7)) |
|
continue; |
if (s->scsi_dev[id] == NULL) |
if (s->scsi_dev[id] == NULL) |
break; |
break; |
} |
} |
Line 620 void esp_scsi_attach(void *opaque, Block
|
Line 644 void esp_scsi_attach(void *opaque, Block
|
s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s); |
s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s); |
} |
} |
|
|
void *esp_init(target_phys_addr_t espaddr, |
void *esp_init(target_phys_addr_t espaddr, int it_shift, |
|
espdma_memory_read_write dma_memory_read, |
|
espdma_memory_read_write dma_memory_write, |
void *dma_opaque, qemu_irq irq, qemu_irq *reset) |
void *dma_opaque, qemu_irq irq, qemu_irq *reset) |
{ |
{ |
ESPState *s; |
ESPState *s; |
int esp_io_memory; |
int esp_io_memory; |
|
|
s = qemu_mallocz(sizeof(ESPState)); |
s = qemu_mallocz(sizeof(ESPState)); |
if (!s) |
|
return NULL; |
|
|
|
s->irq = irq; |
s->irq = irq; |
|
s->it_shift = it_shift; |
|
s->dma_memory_read = dma_memory_read; |
|
s->dma_memory_write = dma_memory_write; |
s->dma_opaque = dma_opaque; |
s->dma_opaque = dma_opaque; |
|
|
esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s); |
esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s); |
cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory); |
cpu_register_physical_memory(espaddr, ESP_REGS << it_shift, esp_io_memory); |
|
|
esp_reset(s); |
esp_reset(s); |
|
|