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 | * QEMU ESP emulation | 2 | * QEMU ESP emulation |
| 3 | * | 3 | * |
| 4 | - * Copyright (c) 2005 Fabrice Bellard | 4 | + * Copyright (c) 2005-2006 Fabrice Bellard |
| 5 | * | 5 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | * of this software and associated documentation files (the "Software"), to deal | 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,13 +38,18 @@ do { printf("ESP: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level) | ||
| 38 | #define ESPDMA_REGS 4 | 38 | #define ESPDMA_REGS 4 |
| 39 | #define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1) | 39 | #define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1) |
| 40 | #define ESP_MAXREG 0x3f | 40 | #define ESP_MAXREG 0x3f |
| 41 | -#define TI_BUFSZ 65536 | 41 | +#define TI_BUFSZ 1024*1024 // XXX |
| 42 | #define DMA_VER 0xa0000000 | 42 | #define DMA_VER 0xa0000000 |
| 43 | #define DMA_INTR 1 | 43 | #define DMA_INTR 1 |
| 44 | #define DMA_INTREN 0x10 | 44 | #define DMA_INTREN 0x10 |
| 45 | #define DMA_LOADED 0x04000000 | 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 | BlockDriverState **bd; | 53 | BlockDriverState **bd; |
| 49 | uint8_t rregs[ESP_MAXREG]; | 54 | uint8_t rregs[ESP_MAXREG]; |
| 50 | uint8_t wregs[ESP_MAXREG]; | 55 | uint8_t wregs[ESP_MAXREG]; |
| @@ -55,7 +60,10 @@ typedef struct ESPState { | @@ -55,7 +60,10 @@ typedef struct ESPState { | ||
| 55 | int ti_dir; | 60 | int ti_dir; |
| 56 | uint8_t ti_buf[TI_BUFSZ]; | 61 | uint8_t ti_buf[TI_BUFSZ]; |
| 57 | int dma; | 62 | int dma; |
| 58 | -} ESPState; | 63 | + ESPDMAFunc *dma_cb; |
| 64 | + int64_t offset, len; | ||
| 65 | + int target; | ||
| 66 | +}; | ||
| 59 | 67 | ||
| 60 | #define STAT_DO 0x00 | 68 | #define STAT_DO 0x00 |
| 61 | #define STAT_DI 0x01 | 69 | #define STAT_DI 0x01 |
| @@ -217,6 +225,19 @@ static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, | @@ -217,6 +225,19 @@ static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, | ||
| 217 | return len; | 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 | static void handle_satn(ESPState *s) | 241 | static void handle_satn(ESPState *s) |
| 221 | { | 242 | { |
| 222 | uint8_t buf[32]; | 243 | uint8_t buf[32]; |
| @@ -309,6 +330,9 @@ static void handle_satn(ESPState *s) | @@ -309,6 +330,9 @@ static void handle_satn(ESPState *s) | ||
| 309 | s->ti_size = len * 512; | 330 | s->ti_size = len * 512; |
| 310 | } | 331 | } |
| 311 | DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len); | 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 | bdrv_read(s->bd[target], offset, s->ti_buf, len); | 336 | bdrv_read(s->bd[target], offset, s->ti_buf, len); |
| 313 | // XXX error handling | 337 | // XXX error handling |
| 314 | s->ti_dir = 1; | 338 | s->ti_dir = 1; |
| @@ -328,7 +352,13 @@ static void handle_satn(ESPState *s) | @@ -328,7 +352,13 @@ static void handle_satn(ESPState *s) | ||
| 328 | s->ti_size = len * 512; | 352 | s->ti_size = len * 512; |
| 329 | } | 353 | } |
| 330 | DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len); | 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 | // XXX error handling | 362 | // XXX error handling |
| 333 | s->ti_dir = 0; | 363 | s->ti_dir = 0; |
| 334 | break; | 364 | break; |
| @@ -427,6 +457,10 @@ static void handle_ti(ESPState *s) | @@ -427,6 +457,10 @@ static void handle_ti(ESPState *s) | ||
| 427 | else | 457 | else |
| 428 | cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1); | 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 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; | 464 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
| 431 | s->rregs[5] = INTR_BS; | 465 | s->rregs[5] = INTR_BS; |
| 432 | s->rregs[6] = 0; | 466 | s->rregs[6] = 0; |
| @@ -444,8 +478,15 @@ static void esp_reset(void *opaque) | @@ -444,8 +478,15 @@ static void esp_reset(void *opaque) | ||
| 444 | { | 478 | { |
| 445 | ESPState *s = opaque; | 479 | ESPState *s = opaque; |
| 446 | memset(s->rregs, 0, ESP_MAXREG); | 480 | memset(s->rregs, 0, ESP_MAXREG); |
| 481 | + memset(s->wregs, 0, ESP_MAXREG); | ||
| 447 | s->rregs[0x0e] = 0x4; // Indicate fas100a | 482 | s->rregs[0x0e] = 0x4; // Indicate fas100a |
| 448 | memset(s->espdmaregs, 0, ESPDMA_REGS * 4); | 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 | static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) | 492 | static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) |