xref: /qemu/hw/ide/ich.c (revision 03c7a6a8e7122b9c12a532577046094a69593116)
1*03c7a6a8SSebastian Herbszt #include <hw/hw.h>
2*03c7a6a8SSebastian Herbszt #include <hw/msi.h>
3*03c7a6a8SSebastian Herbszt #include <hw/pc.h>
4*03c7a6a8SSebastian Herbszt #include <hw/pci.h>
5*03c7a6a8SSebastian Herbszt #include <hw/isa.h>
6*03c7a6a8SSebastian Herbszt #include "block.h"
7*03c7a6a8SSebastian Herbszt #include "block_int.h"
8*03c7a6a8SSebastian Herbszt #include "sysemu.h"
9*03c7a6a8SSebastian Herbszt #include "dma.h"
10*03c7a6a8SSebastian Herbszt 
11*03c7a6a8SSebastian Herbszt #include <hw/ide/pci.h>
12*03c7a6a8SSebastian Herbszt #include <hw/ide/ahci.h>
13*03c7a6a8SSebastian Herbszt 
14*03c7a6a8SSebastian Herbszt static int pci_ich9_ahci_initfn(PCIDevice *dev)
15*03c7a6a8SSebastian Herbszt {
16*03c7a6a8SSebastian Herbszt     struct AHCIPCIState *d;
17*03c7a6a8SSebastian Herbszt     d = DO_UPCAST(struct AHCIPCIState, card, dev);
18*03c7a6a8SSebastian Herbszt 
19*03c7a6a8SSebastian Herbszt     pci_config_set_vendor_id(d->card.config, PCI_VENDOR_ID_INTEL);
20*03c7a6a8SSebastian Herbszt     pci_config_set_device_id(d->card.config, PCI_DEVICE_ID_INTEL_82801IR);
21*03c7a6a8SSebastian Herbszt 
22*03c7a6a8SSebastian Herbszt     pci_config_set_class(d->card.config, PCI_CLASS_STORAGE_SATA);
23*03c7a6a8SSebastian Herbszt     pci_config_set_revision(d->card.config, 0x02);
24*03c7a6a8SSebastian Herbszt     pci_config_set_prog_interface(d->card.config, AHCI_PROGMODE_MAJOR_REV_1);
25*03c7a6a8SSebastian Herbszt 
26*03c7a6a8SSebastian Herbszt     d->card.config[PCI_CACHE_LINE_SIZE] = 0x08;  /* Cache line size */
27*03c7a6a8SSebastian Herbszt     d->card.config[PCI_LATENCY_TIMER]   = 0x00;  /* Latency timer */
28*03c7a6a8SSebastian Herbszt     pci_config_set_interrupt_pin(d->card.config, 1);
29*03c7a6a8SSebastian Herbszt 
30*03c7a6a8SSebastian Herbszt     /* XXX Software should program this register */
31*03c7a6a8SSebastian Herbszt     d->card.config[0x90]   = 1 << 6; /* Address Map Register - AHCI mode */
32*03c7a6a8SSebastian Herbszt 
33*03c7a6a8SSebastian Herbszt     qemu_register_reset(ahci_reset, d);
34*03c7a6a8SSebastian Herbszt 
35*03c7a6a8SSebastian Herbszt     /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
36*03c7a6a8SSebastian Herbszt     pci_register_bar(&d->card, 5, 0x1000, PCI_BASE_ADDRESS_SPACE_MEMORY,
37*03c7a6a8SSebastian Herbszt                      ahci_pci_map);
38*03c7a6a8SSebastian Herbszt 
39*03c7a6a8SSebastian Herbszt     msi_init(dev, 0x50, 1, true, false);
40*03c7a6a8SSebastian Herbszt 
41*03c7a6a8SSebastian Herbszt     ahci_init(&d->ahci, &dev->qdev);
42*03c7a6a8SSebastian Herbszt     d->ahci.irq = d->card.irq[0];
43*03c7a6a8SSebastian Herbszt 
44*03c7a6a8SSebastian Herbszt     return 0;
45*03c7a6a8SSebastian Herbszt }
46*03c7a6a8SSebastian Herbszt 
47*03c7a6a8SSebastian Herbszt static PCIDeviceInfo ich_ahci_info[] = {
48*03c7a6a8SSebastian Herbszt     {
49*03c7a6a8SSebastian Herbszt         .qdev.name    = "ich9-ahci",
50*03c7a6a8SSebastian Herbszt         .qdev.size    = sizeof(AHCIPCIState),
51*03c7a6a8SSebastian Herbszt         .init         = pci_ich9_ahci_initfn,
52*03c7a6a8SSebastian Herbszt     },{
53*03c7a6a8SSebastian Herbszt         /* end of list */
54*03c7a6a8SSebastian Herbszt     }
55*03c7a6a8SSebastian Herbszt };
56*03c7a6a8SSebastian Herbszt 
57*03c7a6a8SSebastian Herbszt static void ich_ahci_register(void)
58*03c7a6a8SSebastian Herbszt {
59*03c7a6a8SSebastian Herbszt     pci_qdev_register_many(ich_ahci_info);
60*03c7a6a8SSebastian Herbszt }
61*03c7a6a8SSebastian Herbszt device_init(ich_ahci_register);
62