Commit 4e9aec746e8d87fbe8805b881d6dae898a75372b

Authored by pbrook
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)
... ...