Commit 4e9aec746e8d87fbe8805b881d6dae898a75372b
1 parent
56b19403
Sparcf ESP dma fixes (Blue Swirl).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1776 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
46 additions
and
5 deletions
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,13 +38,18 @@ do { printf("ESP: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level) |
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,7 +60,10 @@ typedef struct ESPState { |
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,6 +225,19 @@ static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, |
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,6 +330,9 @@ static void handle_satn(ESPState *s) |
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,7 +352,13 @@ static void handle_satn(ESPState *s) |
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,6 +457,10 @@ static void handle_ti(ESPState *s) |
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,8 +478,15 @@ static void esp_reset(void *opaque) |
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) | ... | ... |