version 1.1.1.2, 2018/04/24 16:39:23
|
version 1.1.1.3, 2018/04/24 16:41:32
|
Line 1
|
Line 1
|
/* |
/* |
* QEMU ESP emulation |
* QEMU ESP emulation |
* |
* |
* Copyright (c) 2005 Fabrice Bellard |
* Copyright (c) 2005-2006 Fabrice Bellard |
* |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to deal |
* of this software and associated documentation files (the "Software"), to deal |
Line 38 do { printf("ESP: set_irq(%d): %d\n", (i
|
Line 38 do { printf("ESP: set_irq(%d): %d\n", (i
|
#define ESPDMA_REGS 4 |
#define ESPDMA_REGS 4 |
#define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1) |
#define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1) |
#define ESP_MAXREG 0x3f |
#define ESP_MAXREG 0x3f |
#define TI_BUFSZ 65536 |
#define TI_BUFSZ 1024*1024 // XXX |
#define DMA_VER 0xa0000000 |
#define DMA_VER 0xa0000000 |
#define DMA_INTR 1 |
#define DMA_INTR 1 |
#define DMA_INTREN 0x10 |
#define DMA_INTREN 0x10 |
#define DMA_LOADED 0x04000000 |
#define DMA_LOADED 0x04000000 |
|
typedef struct ESPState ESPState; |
|
|
typedef struct ESPState { |
typedef int ESPDMAFunc(ESPState *s, |
|
target_phys_addr_t phys_addr, |
|
int transfer_size1); |
|
|
|
struct ESPState { |
BlockDriverState **bd; |
BlockDriverState **bd; |
uint8_t rregs[ESP_MAXREG]; |
uint8_t rregs[ESP_MAXREG]; |
uint8_t wregs[ESP_MAXREG]; |
uint8_t wregs[ESP_MAXREG]; |
Line 55 typedef struct ESPState {
|
Line 60 typedef struct ESPState {
|
int ti_dir; |
int ti_dir; |
uint8_t ti_buf[TI_BUFSZ]; |
uint8_t ti_buf[TI_BUFSZ]; |
int dma; |
int dma; |
} ESPState; |
ESPDMAFunc *dma_cb; |
|
int64_t offset, len; |
|
int target; |
|
}; |
|
|
#define STAT_DO 0x00 |
#define STAT_DO 0x00 |
#define STAT_DI 0x01 |
#define STAT_DI 0x01 |
Line 217 static int cdrom_read_toc_raw(int nb_sec
|
Line 225 static int cdrom_read_toc_raw(int nb_sec
|
return len; |
return len; |
} |
} |
|
|
|
static int esp_write_dma_cb(ESPState *s, |
|
target_phys_addr_t phys_addr, |
|
int transfer_size1) |
|
{ |
|
DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n", |
|
s->offset, s->len, s->ti_size, transfer_size1); |
|
bdrv_write(s->bd[s->target], s->offset, s->ti_buf, s->len); |
|
s->offset = 0; |
|
s->len = 0; |
|
s->target = 0; |
|
return 0; |
|
} |
|
|
static void handle_satn(ESPState *s) |
static void handle_satn(ESPState *s) |
{ |
{ |
uint8_t buf[32]; |
uint8_t buf[32]; |
Line 309 static void handle_satn(ESPState *s)
|
Line 330 static void handle_satn(ESPState *s)
|
s->ti_size = len * 512; |
s->ti_size = len * 512; |
} |
} |
DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len); |
DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len); |
|
if (s->ti_size > TI_BUFSZ) { |
|
DPRINTF("size too large %d\n", s->ti_size); |
|
} |
bdrv_read(s->bd[target], offset, s->ti_buf, len); |
bdrv_read(s->bd[target], offset, s->ti_buf, len); |
// XXX error handling |
// XXX error handling |
s->ti_dir = 1; |
s->ti_dir = 1; |
Line 328 static void handle_satn(ESPState *s)
|
Line 352 static void handle_satn(ESPState *s)
|
s->ti_size = len * 512; |
s->ti_size = len * 512; |
} |
} |
DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len); |
DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len); |
bdrv_write(s->bd[target], offset, s->ti_buf, len); |
if (s->ti_size > TI_BUFSZ) { |
|
DPRINTF("size too large %d\n", s->ti_size); |
|
} |
|
s->dma_cb = esp_write_dma_cb; |
|
s->offset = offset; |
|
s->len = len; |
|
s->target = target; |
// XXX error handling |
// XXX error handling |
s->ti_dir = 0; |
s->ti_dir = 0; |
break; |
break; |
Line 427 static void handle_ti(ESPState *s)
|
Line 457 static void handle_ti(ESPState *s)
|
else |
else |
cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1); |
cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1); |
} |
} |
|
if (s->dma_cb) { |
|
s->dma_cb(s, s->espdmaregs[1], dmalen); |
|
s->dma_cb = NULL; |
|
} |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
s->rregs[5] = INTR_BS; |
s->rregs[5] = INTR_BS; |
s->rregs[6] = 0; |
s->rregs[6] = 0; |
Line 444 static void esp_reset(void *opaque)
|
Line 478 static void esp_reset(void *opaque)
|
{ |
{ |
ESPState *s = opaque; |
ESPState *s = opaque; |
memset(s->rregs, 0, ESP_MAXREG); |
memset(s->rregs, 0, ESP_MAXREG); |
|
memset(s->wregs, 0, ESP_MAXREG); |
s->rregs[0x0e] = 0x4; // Indicate fas100a |
s->rregs[0x0e] = 0x4; // Indicate fas100a |
memset(s->espdmaregs, 0, ESPDMA_REGS * 4); |
memset(s->espdmaregs, 0, ESPDMA_REGS * 4); |
|
s->ti_size = 0; |
|
s->ti_rptr = 0; |
|
s->ti_wptr = 0; |
|
s->ti_dir = 0; |
|
s->dma = 0; |
|
s->dma_cb = NULL; |
} |
} |
|
|
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) |
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) |