Revision cea936b1
b/hw/esp-pci.c | ||
---|---|---|
24 | 24 |
*/ |
25 | 25 |
|
26 | 26 |
#include "pci.h" |
27 |
#include "eeprom93xx.h" |
|
27 | 28 |
#include "esp.h" |
28 | 29 |
#include "trace.h" |
29 | 30 |
#include "qemu-log.h" |
30 | 31 |
|
32 |
#define TYPE_AM53C974_DEVICE "am53c974" |
|
33 |
|
|
31 | 34 |
#define DMA_CMD 0x0 |
32 | 35 |
#define DMA_STC 0x1 |
33 | 36 |
#define DMA_SPA 0x2 |
... | ... | |
382 | 385 |
} |
383 | 386 |
|
384 | 387 |
static const TypeInfo esp_pci_info = { |
385 |
.name = "am53c974",
|
|
388 |
.name = TYPE_AM53C974_DEVICE,
|
|
386 | 389 |
.parent = TYPE_PCI_DEVICE, |
387 | 390 |
.instance_size = sizeof(PCIESPState), |
388 | 391 |
.class_init = esp_pci_class_init, |
389 | 392 |
}; |
390 | 393 |
|
394 |
typedef struct { |
|
395 |
PCIESPState pci; |
|
396 |
eeprom_t *eeprom; |
|
397 |
} DC390State; |
|
398 |
|
|
399 |
#define TYPE_DC390_DEVICE "dc390" |
|
400 |
#define DC390(obj) \ |
|
401 |
OBJECT_CHECK(DC390State, obj, TYPE_DC390_DEVICE) |
|
402 |
|
|
403 |
#define EE_ADAPT_SCSI_ID 64 |
|
404 |
#define EE_MODE2 65 |
|
405 |
#define EE_DELAY 66 |
|
406 |
#define EE_TAG_CMD_NUM 67 |
|
407 |
#define EE_ADAPT_OPTIONS 68 |
|
408 |
#define EE_BOOT_SCSI_ID 69 |
|
409 |
#define EE_BOOT_SCSI_LUN 70 |
|
410 |
#define EE_CHKSUM1 126 |
|
411 |
#define EE_CHKSUM2 127 |
|
412 |
|
|
413 |
#define EE_ADAPT_OPTION_F6_F8_AT_BOOT 0x01 |
|
414 |
#define EE_ADAPT_OPTION_BOOT_FROM_CDROM 0x02 |
|
415 |
#define EE_ADAPT_OPTION_INT13 0x04 |
|
416 |
#define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 |
|
417 |
|
|
418 |
|
|
419 |
static uint32_t dc390_read_config(PCIDevice *dev, uint32_t addr, int l) |
|
420 |
{ |
|
421 |
DC390State *pci = DC390(dev); |
|
422 |
uint32_t val; |
|
423 |
|
|
424 |
val = pci_default_read_config(dev, addr, l); |
|
425 |
|
|
426 |
if (addr == 0x00 && l == 1) { |
|
427 |
/* First byte of address space is AND-ed with EEPROM DO line */ |
|
428 |
if (!eeprom93xx_read(pci->eeprom)) { |
|
429 |
val &= ~0xff; |
|
430 |
} |
|
431 |
} |
|
432 |
|
|
433 |
return val; |
|
434 |
} |
|
435 |
|
|
436 |
static void dc390_write_config(PCIDevice *dev, |
|
437 |
uint32_t addr, uint32_t val, int l) |
|
438 |
{ |
|
439 |
DC390State *pci = DC390(dev); |
|
440 |
if (addr == 0x80) { |
|
441 |
/* EEPROM write */ |
|
442 |
int eesk = val & 0x80 ? 1 : 0; |
|
443 |
int eedi = val & 0x40 ? 1 : 0; |
|
444 |
eeprom93xx_write(pci->eeprom, 1, eesk, eedi); |
|
445 |
} else if (addr == 0xc0) { |
|
446 |
/* EEPROM CS low */ |
|
447 |
eeprom93xx_write(pci->eeprom, 0, 0, 0); |
|
448 |
} else { |
|
449 |
pci_default_write_config(dev, addr, val, l); |
|
450 |
} |
|
451 |
} |
|
452 |
|
|
453 |
static int dc390_scsi_init(PCIDevice *dev) |
|
454 |
{ |
|
455 |
DC390State *pci = DC390(dev); |
|
456 |
uint8_t *contents; |
|
457 |
uint16_t chksum = 0; |
|
458 |
int i, ret; |
|
459 |
|
|
460 |
/* init base class */ |
|
461 |
ret = esp_pci_scsi_init(dev); |
|
462 |
if (ret < 0) { |
|
463 |
return ret; |
|
464 |
} |
|
465 |
|
|
466 |
/* EEPROM */ |
|
467 |
pci->eeprom = eeprom93xx_new(DEVICE(dev), 64); |
|
468 |
|
|
469 |
/* set default eeprom values */ |
|
470 |
contents = (uint8_t *)eeprom93xx_data(pci->eeprom); |
|
471 |
|
|
472 |
for (i = 0; i < 16; i++) { |
|
473 |
contents[i * 2] = 0x57; |
|
474 |
contents[i * 2 + 1] = 0x00; |
|
475 |
} |
|
476 |
contents[EE_ADAPT_SCSI_ID] = 7; |
|
477 |
contents[EE_MODE2] = 0x0f; |
|
478 |
contents[EE_TAG_CMD_NUM] = 0x04; |
|
479 |
contents[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT |
|
480 |
| EE_ADAPT_OPTION_BOOT_FROM_CDROM |
|
481 |
| EE_ADAPT_OPTION_INT13; |
|
482 |
|
|
483 |
/* update eeprom checksum */ |
|
484 |
for (i = 0; i < EE_CHKSUM1; i += 2) { |
|
485 |
chksum += contents[i] + (((uint16_t)contents[i + 1]) << 8); |
|
486 |
} |
|
487 |
chksum = 0x1234 - chksum; |
|
488 |
contents[EE_CHKSUM1] = chksum & 0xff; |
|
489 |
contents[EE_CHKSUM2] = chksum >> 8; |
|
490 |
|
|
491 |
return 0; |
|
492 |
} |
|
493 |
|
|
494 |
static void dc390_class_init(ObjectClass *klass, void *data) |
|
495 |
{ |
|
496 |
DeviceClass *dc = DEVICE_CLASS(klass); |
|
497 |
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
|
498 |
|
|
499 |
k->init = dc390_scsi_init; |
|
500 |
k->config_read = dc390_read_config; |
|
501 |
k->config_write = dc390_write_config; |
|
502 |
dc->desc = "Tekram DC-390 SCSI adapter"; |
|
503 |
} |
|
504 |
|
|
505 |
static const TypeInfo dc390_info = { |
|
506 |
.name = "dc390", |
|
507 |
.parent = TYPE_AM53C974_DEVICE, |
|
508 |
.instance_size = sizeof(DC390State), |
|
509 |
.class_init = dc390_class_init, |
|
510 |
}; |
|
511 |
|
|
391 | 512 |
static void esp_pci_register_types(void) |
392 | 513 |
{ |
393 | 514 |
type_register_static(&esp_pci_info); |
515 |
type_register_static(&dc390_info); |
|
394 | 516 |
} |
395 | 517 |
|
396 | 518 |
type_init(esp_pci_register_types) |
Also available in: Unified diff