Compare commits
2 Commits
v0.12.5-qe
...
stable-0.1
Author | SHA1 | Date | |
---|---|---|---|
|
6394bd0e05 | ||
|
fa719811ac |
13
hw/ide.h
13
hw/ide.h
@@ -1,17 +1,18 @@
|
||||
#ifndef HW_IDE_H
|
||||
#define HW_IDE_H
|
||||
|
||||
#include "qdev.h"
|
||||
#include "isa.h"
|
||||
#include "pci.h"
|
||||
|
||||
/* ide-isa.c */
|
||||
int isa_ide_init(int iobase, int iobase2, int isairq,
|
||||
DriveInfo *hd0, DriveInfo *hd1);
|
||||
ISADevice *isa_ide_init(int iobase, int iobase2, int isairq,
|
||||
DriveInfo *hd0, DriveInfo *hd1);
|
||||
|
||||
/* ide-pci.c */
|
||||
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
|
||||
int secondary_ide_enabled);
|
||||
void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
|
||||
/* ide-macio.c */
|
||||
int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
|
||||
@@ -22,4 +23,6 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
|
||||
qemu_irq irq, int shift,
|
||||
DriveInfo *hd0, DriveInfo *hd1);
|
||||
|
||||
void ide_get_bs(BlockDriverState *bs[], BusState *qbus);
|
||||
|
||||
#endif /* HW_IDE_H */
|
||||
|
@@ -75,8 +75,8 @@ static int isa_ide_initfn(ISADevice *dev)
|
||||
return 0;
|
||||
};
|
||||
|
||||
int isa_ide_init(int iobase, int iobase2, int isairq,
|
||||
DriveInfo *hd0, DriveInfo *hd1)
|
||||
ISADevice *isa_ide_init(int iobase, int iobase2, int isairq,
|
||||
DriveInfo *hd0, DriveInfo *hd1)
|
||||
{
|
||||
ISADevice *dev;
|
||||
ISAIDEState *s;
|
||||
@@ -86,14 +86,14 @@ int isa_ide_init(int iobase, int iobase2, int isairq,
|
||||
qdev_prop_set_uint32(&dev->qdev, "iobase2", iobase2);
|
||||
qdev_prop_set_uint32(&dev->qdev, "irq", isairq);
|
||||
if (qdev_init(&dev->qdev) < 0)
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
s = DO_UPCAST(ISAIDEState, dev, dev);
|
||||
if (hd0)
|
||||
ide_create_drive(&s->bus, 0, hd0);
|
||||
if (hd1)
|
||||
ide_create_drive(&s->bus, 1, hd1);
|
||||
return 0;
|
||||
return dev;
|
||||
}
|
||||
|
||||
static ISADeviceInfo isa_ide_info = {
|
||||
|
@@ -158,22 +158,24 @@ static int pci_piix4_ide_initfn(PCIDevice *dev)
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
|
||||
void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
|
||||
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
|
||||
{
|
||||
PCIDevice *dev;
|
||||
|
||||
dev = pci_create_simple(bus, devfn, "piix3-ide");
|
||||
pci_ide_create_devs(dev, hd_table);
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
/* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
|
||||
void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
|
||||
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
|
||||
{
|
||||
PCIDevice *dev;
|
||||
|
||||
dev = pci_create_simple(bus, devfn, "piix4-ide");
|
||||
pci_ide_create_devs(dev, hd_table);
|
||||
return dev;
|
||||
}
|
||||
|
||||
static PCIDeviceInfo piix_ide_info[] = {
|
||||
|
@@ -90,6 +90,13 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
|
||||
return DO_UPCAST(IDEDevice, qdev, dev);
|
||||
}
|
||||
|
||||
void ide_get_bs(BlockDriverState *bs[], BusState *qbus)
|
||||
{
|
||||
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qbus);
|
||||
bs[0] = bus->master ? bus->master->dinfo->bdrv : NULL;
|
||||
bs[1] = bus->slave ? bus->slave->dinfo->bdrv : NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------- */
|
||||
|
||||
typedef struct IDEDrive {
|
||||
|
105
hw/pc.c
105
hw/pc.c
@@ -24,6 +24,7 @@
|
||||
#include "hw.h"
|
||||
#include "pc.h"
|
||||
#include "fdc.h"
|
||||
#include "ide.h"
|
||||
#include "pci.h"
|
||||
#include "vmware_vga.h"
|
||||
#include "usb-uhci.h"
|
||||
@@ -244,15 +245,66 @@ static int pc_boot_set(void *opaque, const char *boot_device)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
typedef struct pc_cmos_init_late_arg {
|
||||
BusState *idebus0, *idebus1;
|
||||
} pc_cmos_init_late_arg;
|
||||
|
||||
static void pc_cmos_init_late(void *opaque)
|
||||
{
|
||||
pc_cmos_init_late_arg *arg = opaque;
|
||||
RTCState *s = rtc_state;
|
||||
int val;
|
||||
BlockDriverState *hd_table[4];
|
||||
int i;
|
||||
|
||||
ide_get_bs(hd_table, arg->idebus0);
|
||||
ide_get_bs(hd_table + 2, arg->idebus1);
|
||||
|
||||
rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
|
||||
if (hd_table[0])
|
||||
cmos_init_hd(0x19, 0x1b, hd_table[0]);
|
||||
if (hd_table[1])
|
||||
cmos_init_hd(0x1a, 0x24, hd_table[1]);
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (hd_table[i]) {
|
||||
int cylinders, heads, sectors, translation;
|
||||
/* NOTE: bdrv_get_geometry_hint() returns the physical
|
||||
geometry. It is always such that: 1 <= sects <= 63, 1
|
||||
<= heads <= 16, 1 <= cylinders <= 16383. The BIOS
|
||||
geometry can be different if a translation is done. */
|
||||
translation = bdrv_get_translation_hint(hd_table[i]);
|
||||
if (translation == BIOS_ATA_TRANSLATION_AUTO) {
|
||||
bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors);
|
||||
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
|
||||
/* No translation. */
|
||||
translation = 0;
|
||||
} else {
|
||||
/* LBA translation. */
|
||||
translation = 1;
|
||||
}
|
||||
} else {
|
||||
translation--;
|
||||
}
|
||||
val |= translation << (i * 2);
|
||||
}
|
||||
}
|
||||
rtc_set_memory(s, 0x39, val);
|
||||
|
||||
qemu_unregister_reset(pc_cmos_init_late, opaque);
|
||||
}
|
||||
|
||||
static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
|
||||
const char *boot_device, DriveInfo **hd_table)
|
||||
const char *boot_device,
|
||||
BusState *idebus0, BusState *idebus1)
|
||||
{
|
||||
RTCState *s = rtc_state;
|
||||
int nbds, bds[3] = { 0, };
|
||||
int val;
|
||||
int fd0, fd1, nb;
|
||||
int i;
|
||||
static pc_cmos_init_late_arg arg;
|
||||
|
||||
/* various important CMOS locations needed by PC/Bochs bios */
|
||||
|
||||
@@ -335,37 +387,9 @@ static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
|
||||
|
||||
/* hard drives */
|
||||
|
||||
rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
|
||||
if (hd_table[0])
|
||||
cmos_init_hd(0x19, 0x1b, hd_table[0]->bdrv);
|
||||
if (hd_table[1])
|
||||
cmos_init_hd(0x1a, 0x24, hd_table[1]->bdrv);
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (hd_table[i]) {
|
||||
int cylinders, heads, sectors, translation;
|
||||
/* NOTE: bdrv_get_geometry_hint() returns the physical
|
||||
geometry. It is always such that: 1 <= sects <= 63, 1
|
||||
<= heads <= 16, 1 <= cylinders <= 16383. The BIOS
|
||||
geometry can be different if a translation is done. */
|
||||
translation = bdrv_get_translation_hint(hd_table[i]->bdrv);
|
||||
if (translation == BIOS_ATA_TRANSLATION_AUTO) {
|
||||
bdrv_get_geometry_hint(hd_table[i]->bdrv, &cylinders, &heads, §ors);
|
||||
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
|
||||
/* No translation. */
|
||||
translation = 0;
|
||||
} else {
|
||||
/* LBA translation. */
|
||||
translation = 1;
|
||||
}
|
||||
} else {
|
||||
translation--;
|
||||
}
|
||||
val |= translation << (i * 2);
|
||||
}
|
||||
}
|
||||
rtc_set_memory(s, 0x39, val);
|
||||
arg.idebus0 = idebus0;
|
||||
arg.idebus1 = idebus1;
|
||||
qemu_register_reset(pc_cmos_init_late, &arg);
|
||||
}
|
||||
|
||||
void ioport_set_a20(int enable)
|
||||
@@ -994,6 +1018,7 @@ static void pc_init1(ram_addr_t ram_size,
|
||||
qemu_irq *i8259;
|
||||
IsaIrqState *isa_irq_state;
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
BusState *idebus[MAX_IDE_BUS];
|
||||
DriveInfo *fd[MAX_FD];
|
||||
void *fw_cfg;
|
||||
|
||||
@@ -1187,11 +1212,16 @@ static void pc_init1(ram_addr_t ram_size,
|
||||
}
|
||||
|
||||
if (pci_enabled) {
|
||||
pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
|
||||
PCIDevice *dev;
|
||||
dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
|
||||
idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
|
||||
idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
|
||||
} else {
|
||||
for(i = 0; i < MAX_IDE_BUS; i++) {
|
||||
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
||||
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
|
||||
ISADevice *dev;
|
||||
dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
||||
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
|
||||
idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1206,7 +1236,8 @@ static void pc_init1(ram_addr_t ram_size,
|
||||
}
|
||||
floppy_controller = fdctrl_init_isa(fd);
|
||||
|
||||
cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);
|
||||
cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
|
||||
idebus[0], idebus[1]);
|
||||
|
||||
if (pci_enabled && usb_enabled) {
|
||||
usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
|
||||
|
Reference in New Issue
Block a user