Revision c0897e0c
b/hw/ide.h | ||
---|---|---|
24 | 24 |
qemu_irq irq, int shift, |
25 | 25 |
DriveInfo *hd0, DriveInfo *hd1); |
26 | 26 |
|
27 |
void ide_get_bs(BlockDriverState *bs[], BusState *qbus); |
|
28 |
|
|
27 | 29 |
#endif /* HW_IDE_H */ |
b/hw/ide/qdev.c | ||
---|---|---|
88 | 88 |
return DO_UPCAST(IDEDevice, qdev, dev); |
89 | 89 |
} |
90 | 90 |
|
91 |
void ide_get_bs(BlockDriverState *bs[], BusState *qbus) |
|
92 |
{ |
|
93 |
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qbus); |
|
94 |
bs[0] = bus->master ? bus->master->conf.bs : NULL; |
|
95 |
bs[1] = bus->slave ? bus->slave->conf.bs : NULL; |
|
96 |
} |
|
97 |
|
|
91 | 98 |
/* --------------------------------- */ |
92 | 99 |
|
93 | 100 |
typedef struct IDEDrive { |
b/hw/pc.c | ||
---|---|---|
25 | 25 |
#include "pc.h" |
26 | 26 |
#include "apic.h" |
27 | 27 |
#include "fdc.h" |
28 |
#include "ide.h" |
|
28 | 29 |
#include "pci.h" |
29 | 30 |
#include "vmware_vga.h" |
30 | 31 |
#include "monitor.h" |
... | ... | |
275 | 276 |
return set_boot_dev(opaque, boot_device, 0); |
276 | 277 |
} |
277 | 278 |
|
278 |
/* hd_table must contain 4 block drivers */ |
|
279 |
typedef struct pc_cmos_init_late_arg { |
|
280 |
ISADevice *rtc_state; |
|
281 |
BusState *idebus0, *idebus1; |
|
282 |
} pc_cmos_init_late_arg; |
|
283 |
|
|
284 |
static void pc_cmos_init_late(void *opaque) |
|
285 |
{ |
|
286 |
pc_cmos_init_late_arg *arg = opaque; |
|
287 |
ISADevice *s = arg->rtc_state; |
|
288 |
int val; |
|
289 |
BlockDriverState *hd_table[4]; |
|
290 |
int i; |
|
291 |
|
|
292 |
ide_get_bs(hd_table, arg->idebus0); |
|
293 |
ide_get_bs(hd_table + 2, arg->idebus1); |
|
294 |
|
|
295 |
rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0)); |
|
296 |
if (hd_table[0]) |
|
297 |
cmos_init_hd(0x19, 0x1b, hd_table[0], s); |
|
298 |
if (hd_table[1]) |
|
299 |
cmos_init_hd(0x1a, 0x24, hd_table[1], s); |
|
300 |
|
|
301 |
val = 0; |
|
302 |
for (i = 0; i < 4; i++) { |
|
303 |
if (hd_table[i]) { |
|
304 |
int cylinders, heads, sectors, translation; |
|
305 |
/* NOTE: bdrv_get_geometry_hint() returns the physical |
|
306 |
geometry. It is always such that: 1 <= sects <= 63, 1 |
|
307 |
<= heads <= 16, 1 <= cylinders <= 16383. The BIOS |
|
308 |
geometry can be different if a translation is done. */ |
|
309 |
translation = bdrv_get_translation_hint(hd_table[i]); |
|
310 |
if (translation == BIOS_ATA_TRANSLATION_AUTO) { |
|
311 |
bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors); |
|
312 |
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { |
|
313 |
/* No translation. */ |
|
314 |
translation = 0; |
|
315 |
} else { |
|
316 |
/* LBA translation. */ |
|
317 |
translation = 1; |
|
318 |
} |
|
319 |
} else { |
|
320 |
translation--; |
|
321 |
} |
|
322 |
val |= translation << (i * 2); |
|
323 |
} |
|
324 |
} |
|
325 |
rtc_set_memory(s, 0x39, val); |
|
326 |
|
|
327 |
qemu_unregister_reset(pc_cmos_init_late, opaque); |
|
328 |
} |
|
329 |
|
|
279 | 330 |
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, |
280 |
const char *boot_device, DriveInfo **hd_table, |
|
331 |
const char *boot_device, |
|
332 |
BusState *idebus0, BusState *idebus1, |
|
281 | 333 |
FDCtrl *floppy_controller, ISADevice *s) |
282 | 334 |
{ |
283 | 335 |
int val; |
284 | 336 |
int fd0, fd1, nb; |
285 |
int i;
|
|
337 |
static pc_cmos_init_late_arg arg;
|
|
286 | 338 |
|
287 | 339 |
/* various important CMOS locations needed by PC/Bochs bios */ |
288 | 340 |
|
... | ... | |
351 | 403 |
rtc_set_memory(s, REG_EQUIPMENT_BYTE, val); |
352 | 404 |
|
353 | 405 |
/* hard drives */ |
354 |
|
|
355 |
rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0)); |
|
356 |
if (hd_table[0]) |
|
357 |
cmos_init_hd(0x19, 0x1b, hd_table[0]->bdrv, s); |
|
358 |
if (hd_table[1]) |
|
359 |
cmos_init_hd(0x1a, 0x24, hd_table[1]->bdrv, s); |
|
360 |
|
|
361 |
val = 0; |
|
362 |
for (i = 0; i < 4; i++) { |
|
363 |
if (hd_table[i]) { |
|
364 |
int cylinders, heads, sectors, translation; |
|
365 |
/* NOTE: bdrv_get_geometry_hint() returns the physical |
|
366 |
geometry. It is always such that: 1 <= sects <= 63, 1 |
|
367 |
<= heads <= 16, 1 <= cylinders <= 16383. The BIOS |
|
368 |
geometry can be different if a translation is done. */ |
|
369 |
translation = bdrv_get_translation_hint(hd_table[i]->bdrv); |
|
370 |
if (translation == BIOS_ATA_TRANSLATION_AUTO) { |
|
371 |
bdrv_get_geometry_hint(hd_table[i]->bdrv, &cylinders, &heads, §ors); |
|
372 |
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { |
|
373 |
/* No translation. */ |
|
374 |
translation = 0; |
|
375 |
} else { |
|
376 |
/* LBA translation. */ |
|
377 |
translation = 1; |
|
378 |
} |
|
379 |
} else { |
|
380 |
translation--; |
|
381 |
} |
|
382 |
val |= translation << (i * 2); |
|
383 |
} |
|
384 |
} |
|
385 |
rtc_set_memory(s, 0x39, val); |
|
406 |
arg.rtc_state = s; |
|
407 |
arg.idebus0 = idebus0; |
|
408 |
arg.idebus1 = idebus1; |
|
409 |
qemu_register_reset(pc_cmos_init_late, &arg); |
|
386 | 410 |
} |
387 | 411 |
|
388 | 412 |
static void handle_a20_line_change(void *opaque, int irq, int level) |
b/hw/pc.h | ||
---|---|---|
104 | 104 |
void pc_audio_init (PCIBus *pci_bus, qemu_irq *pic); |
105 | 105 |
#endif |
106 | 106 |
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, |
107 |
const char *boot_device, DriveInfo **hd_table, |
|
107 |
const char *boot_device, |
|
108 |
BusState *ide0, BusState *ide1, |
|
108 | 109 |
FDCtrl *floppy_controller, ISADevice *s); |
109 | 110 |
void pc_pci_device_init(PCIBus *pci_bus); |
110 | 111 |
|
b/hw/pc_piix.c | ||
---|---|---|
79 | 79 |
IsaIrqState *isa_irq_state; |
80 | 80 |
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; |
81 | 81 |
FDCtrl *floppy_controller; |
82 |
BusState *idebus[MAX_IDE_BUS]; |
|
82 | 83 |
ISADevice *rtc_state; |
83 | 84 |
|
84 | 85 |
pc_cpus_init(cpu_model); |
... | ... | |
132 | 133 |
} |
133 | 134 |
|
134 | 135 |
if (pci_enabled) { |
135 |
pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); |
|
136 |
PCIDevice *dev; |
|
137 |
dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); |
|
138 |
idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); |
|
139 |
idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); |
|
136 | 140 |
} else { |
137 | 141 |
for(i = 0; i < MAX_IDE_BUS; i++) { |
138 |
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], |
|
139 |
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); |
|
142 |
ISADevice *dev; |
|
143 |
dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], |
|
144 |
hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); |
|
145 |
idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); |
|
140 | 146 |
} |
141 | 147 |
} |
142 | 148 |
|
143 | 149 |
pc_audio_init(pci_enabled ? pci_bus : NULL, isa_irq); |
144 | 150 |
|
145 |
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd,
|
|
146 |
floppy_controller, rtc_state); |
|
151 |
pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, |
|
152 |
idebus[0], idebus[1], floppy_controller, rtc_state);
|
|
147 | 153 |
|
148 | 154 |
if (pci_enabled && usb_enabled) { |
149 | 155 |
usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); |
Also available in: Unified diff