Revision 4e9aec74 hw/esp.c
b/hw/esp.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU ESP emulation |
3 | 3 |
* |
4 |
* Copyright (c) 2005 Fabrice Bellard |
|
4 |
* Copyright (c) 2005-2006 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
38 | 38 |
#define ESPDMA_REGS 4 |
39 | 39 |
#define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1) |
40 | 40 |
#define ESP_MAXREG 0x3f |
41 |
#define TI_BUFSZ 65536
|
|
41 |
#define TI_BUFSZ 1024*1024 // XXX
|
|
42 | 42 |
#define DMA_VER 0xa0000000 |
43 | 43 |
#define DMA_INTR 1 |
44 | 44 |
#define DMA_INTREN 0x10 |
45 | 45 |
#define DMA_LOADED 0x04000000 |
46 |
typedef struct ESPState ESPState; |
|
46 | 47 |
|
47 |
typedef struct ESPState { |
|
48 |
typedef int ESPDMAFunc(ESPState *s, |
|
49 |
target_phys_addr_t phys_addr, |
|
50 |
int transfer_size1); |
|
51 |
|
|
52 |
struct ESPState { |
|
48 | 53 |
BlockDriverState **bd; |
49 | 54 |
uint8_t rregs[ESP_MAXREG]; |
50 | 55 |
uint8_t wregs[ESP_MAXREG]; |
... | ... | |
55 | 60 |
int ti_dir; |
56 | 61 |
uint8_t ti_buf[TI_BUFSZ]; |
57 | 62 |
int dma; |
58 |
} ESPState; |
|
63 |
ESPDMAFunc *dma_cb; |
|
64 |
int64_t offset, len; |
|
65 |
int target; |
|
66 |
}; |
|
59 | 67 |
|
60 | 68 |
#define STAT_DO 0x00 |
61 | 69 |
#define STAT_DI 0x01 |
... | ... | |
217 | 225 |
return len; |
218 | 226 |
} |
219 | 227 |
|
228 |
static int esp_write_dma_cb(ESPState *s, |
|
229 |
target_phys_addr_t phys_addr, |
|
230 |
int transfer_size1) |
|
231 |
{ |
|
232 |
DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n", |
|
233 |
s->offset, s->len, s->ti_size, transfer_size1); |
|
234 |
bdrv_write(s->bd[s->target], s->offset, s->ti_buf, s->len); |
|
235 |
s->offset = 0; |
|
236 |
s->len = 0; |
|
237 |
s->target = 0; |
|
238 |
return 0; |
|
239 |
} |
|
240 |
|
|
220 | 241 |
static void handle_satn(ESPState *s) |
221 | 242 |
{ |
222 | 243 |
uint8_t buf[32]; |
... | ... | |
309 | 330 |
s->ti_size = len * 512; |
310 | 331 |
} |
311 | 332 |
DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len); |
333 |
if (s->ti_size > TI_BUFSZ) { |
|
334 |
DPRINTF("size too large %d\n", s->ti_size); |
|
335 |
} |
|
312 | 336 |
bdrv_read(s->bd[target], offset, s->ti_buf, len); |
313 | 337 |
// XXX error handling |
314 | 338 |
s->ti_dir = 1; |
... | ... | |
328 | 352 |
s->ti_size = len * 512; |
329 | 353 |
} |
330 | 354 |
DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len); |
331 |
bdrv_write(s->bd[target], offset, s->ti_buf, len); |
|
355 |
if (s->ti_size > TI_BUFSZ) { |
|
356 |
DPRINTF("size too large %d\n", s->ti_size); |
|
357 |
} |
|
358 |
s->dma_cb = esp_write_dma_cb; |
|
359 |
s->offset = offset; |
|
360 |
s->len = len; |
|
361 |
s->target = target; |
|
332 | 362 |
// XXX error handling |
333 | 363 |
s->ti_dir = 0; |
334 | 364 |
break; |
... | ... | |
427 | 457 |
else |
428 | 458 |
cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1); |
429 | 459 |
} |
460 |
if (s->dma_cb) { |
|
461 |
s->dma_cb(s, s->espdmaregs[1], dmalen); |
|
462 |
s->dma_cb = NULL; |
|
463 |
} |
|
430 | 464 |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
431 | 465 |
s->rregs[5] = INTR_BS; |
432 | 466 |
s->rregs[6] = 0; |
... | ... | |
444 | 478 |
{ |
445 | 479 |
ESPState *s = opaque; |
446 | 480 |
memset(s->rregs, 0, ESP_MAXREG); |
481 |
memset(s->wregs, 0, ESP_MAXREG); |
|
447 | 482 |
s->rregs[0x0e] = 0x4; // Indicate fas100a |
448 | 483 |
memset(s->espdmaregs, 0, ESPDMA_REGS * 4); |
484 |
s->ti_size = 0; |
|
485 |
s->ti_rptr = 0; |
|
486 |
s->ti_wptr = 0; |
|
487 |
s->ti_dir = 0; |
|
488 |
s->dma = 0; |
|
489 |
s->dma_cb = NULL; |
|
449 | 490 |
} |
450 | 491 |
|
451 | 492 |
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) |
Also available in: Unified diff