Commit e4bcb14c79fb63a35aef3eb39e02c16c19b8b28d
1 parent
7233b355
Add -drive parameter, by Laurent Vivier.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3759 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
27 changed files
with
873 additions
and
315 deletions
hw/esp.c
... | ... | @@ -50,14 +50,11 @@ do { printf("ESP: " fmt , ##args); } while (0) |
50 | 50 | #define ESP_REGS 16 |
51 | 51 | #define ESP_SIZE (ESP_REGS * 4) |
52 | 52 | #define TI_BUFSZ 32 |
53 | -/* The HBA is ID 7, so for simplicitly limit to 7 devices. */ | |
54 | -#define ESP_MAX_DEVS 7 | |
55 | 53 | |
56 | 54 | typedef struct ESPState ESPState; |
57 | 55 | |
58 | 56 | struct ESPState { |
59 | 57 | qemu_irq irq; |
60 | - BlockDriverState **bd; | |
61 | 58 | uint8_t rregs[ESP_REGS]; |
62 | 59 | uint8_t wregs[ESP_REGS]; |
63 | 60 | int32_t ti_size; |
... | ... | @@ -65,7 +62,7 @@ struct ESPState { |
65 | 62 | uint8_t ti_buf[TI_BUFSZ]; |
66 | 63 | int sense; |
67 | 64 | int dma; |
68 | - SCSIDevice *scsi_dev[MAX_DISKS]; | |
65 | + SCSIDevice *scsi_dev[ESP_MAX_DEVS]; | |
69 | 66 | SCSIDevice *current_dev; |
70 | 67 | uint8_t cmdbuf[TI_BUFSZ]; |
71 | 68 | int cmdlen; |
... | ... | @@ -172,7 +169,7 @@ static int get_cmd(ESPState *s, uint8_t *buf) |
172 | 169 | s->async_len = 0; |
173 | 170 | } |
174 | 171 | |
175 | - if (target >= MAX_DISKS || !s->scsi_dev[target]) { | |
172 | + if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) { | |
176 | 173 | // No such drive |
177 | 174 | s->rregs[ESP_RSTAT] = STAT_IN; |
178 | 175 | s->rregs[ESP_RINTR] = INTR_DC; |
... | ... | @@ -621,7 +618,7 @@ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id) |
621 | 618 | s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s); |
622 | 619 | } |
623 | 620 | |
624 | -void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, | |
621 | +void *esp_init(target_phys_addr_t espaddr, | |
625 | 622 | void *dma_opaque, qemu_irq irq, qemu_irq *reset) |
626 | 623 | { |
627 | 624 | ESPState *s; |
... | ... | @@ -631,7 +628,6 @@ void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, |
631 | 628 | if (!s) |
632 | 629 | return NULL; |
633 | 630 | |
634 | - s->bd = bd; | |
635 | 631 | s->irq = irq; |
636 | 632 | s->dma_opaque = dma_opaque; |
637 | 633 | ... | ... |
hw/gumstix.c
... | ... | @@ -47,6 +47,7 @@ static void connex_init(int ram_size, int vga_ram_size, |
47 | 47 | const char *initrd_filename, const char *cpu_model) |
48 | 48 | { |
49 | 49 | struct pxa2xx_state_s *cpu; |
50 | + int index; | |
50 | 51 | |
51 | 52 | uint32_t connex_rom = 0x01000000; |
52 | 53 | uint32_t connex_ram = 0x04000000; |
... | ... | @@ -59,14 +60,15 @@ static void connex_init(int ram_size, int vga_ram_size, |
59 | 60 | |
60 | 61 | cpu = pxa255_init(connex_ram, ds); |
61 | 62 | |
62 | - if (pflash_table[0] == NULL) { | |
63 | + index = drive_get_index(IF_PFLASH, 0, 0); | |
64 | + if (index == -1) { | |
63 | 65 | fprintf(stderr, "A flash image must be given with the " |
64 | 66 | "'pflash' parameter\n"); |
65 | 67 | exit(1); |
66 | 68 | } |
67 | 69 | |
68 | 70 | if (!pflash_register(0x00000000, qemu_ram_alloc(connex_rom), |
69 | - pflash_table[0], sector_len, connex_rom / sector_len, | |
71 | + drives_table[index].bdrv, sector_len, connex_rom / sector_len, | |
70 | 72 | 2, 0, 0, 0, 0)) { |
71 | 73 | fprintf(stderr, "qemu: Error registering flash memory.\n"); |
72 | 74 | exit(1); |
... | ... | @@ -85,6 +87,7 @@ static void verdex_init(int ram_size, int vga_ram_size, |
85 | 87 | const char *initrd_filename, const char *cpu_model) |
86 | 88 | { |
87 | 89 | struct pxa2xx_state_s *cpu; |
90 | + int index; | |
88 | 91 | |
89 | 92 | uint32_t verdex_rom = 0x02000000; |
90 | 93 | uint32_t verdex_ram = 0x10000000; |
... | ... | @@ -97,14 +100,15 @@ static void verdex_init(int ram_size, int vga_ram_size, |
97 | 100 | |
98 | 101 | cpu = pxa270_init(verdex_ram, ds, cpu_model ?: "pxa270-c0"); |
99 | 102 | |
100 | - if (pflash_table[0] == NULL) { | |
103 | + index = drive_get_index(IF_PFLASH, 0, 0); | |
104 | + if (index == -1) { | |
101 | 105 | fprintf(stderr, "A flash image must be given with the " |
102 | 106 | "'pflash' parameter\n"); |
103 | 107 | exit(1); |
104 | 108 | } |
105 | 109 | |
106 | 110 | if (!pflash_register(0x00000000, qemu_ram_alloc(verdex_rom), |
107 | - pflash_table[0], sector_len, verdex_rom / sector_len, | |
111 | + drives_table[index].bdrv, sector_len, verdex_rom / sector_len, | |
108 | 112 | 2, 0, 0, 0, 0)) { |
109 | 113 | fprintf(stderr, "qemu: Error registering flash memory.\n"); |
110 | 114 | exit(1); | ... | ... |
hw/integratorcp.c
... | ... | @@ -478,6 +478,7 @@ static void integratorcp_init(int ram_size, int vga_ram_size, |
478 | 478 | uint32_t bios_offset; |
479 | 479 | qemu_irq *pic; |
480 | 480 | qemu_irq *cpu_pic; |
481 | + int sd; | |
481 | 482 | |
482 | 483 | if (!cpu_model) |
483 | 484 | cpu_model = "arm926"; |
... | ... | @@ -506,7 +507,12 @@ static void integratorcp_init(int ram_size, int vga_ram_size, |
506 | 507 | icp_control_init(0xcb000000); |
507 | 508 | pl050_init(0x18000000, pic[3], 0); |
508 | 509 | pl050_init(0x19000000, pic[4], 1); |
509 | - pl181_init(0x1c000000, sd_bdrv, pic[23], pic[24]); | |
510 | + sd = drive_get_index(IF_SD, 0, 0); | |
511 | + if (sd == -1) { | |
512 | + fprintf(stderr, "qemu: missing SecureDigital card\n"); | |
513 | + exit(1); | |
514 | + } | |
515 | + pl181_init(0x1c000000, drives_table[sd].bdrv, pic[23], pic[24]); | |
510 | 516 | if (nd_table[0].vlan) { |
511 | 517 | if (nd_table[0].model == NULL |
512 | 518 | || strcmp(nd_table[0].model, "smc91c111") == 0) { | ... | ... |
hw/lsi53c895a.c
... | ... | @@ -151,9 +151,6 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ##args);} while (0) |
151 | 151 | #define PHASE_MI 7 |
152 | 152 | #define PHASE_MASK 7 |
153 | 153 | |
154 | -/* The HBA is ID 7, so for simplicitly limit to 7 devices. */ | |
155 | -#define LSI_MAX_DEVS 7 | |
156 | - | |
157 | 154 | /* Maximum length of MSG IN data. */ |
158 | 155 | #define LSI_MAX_MSGIN_LEN 8 |
159 | 156 | ... | ... |
hw/mainstone.c
... | ... | @@ -29,6 +29,7 @@ static void mainstone_common_init(int ram_size, int vga_ram_size, |
29 | 29 | uint32_t mainstone_rom = 0x00800000; |
30 | 30 | struct pxa2xx_state_s *cpu; |
31 | 31 | qemu_irq *mst_irq; |
32 | + int index; | |
32 | 33 | |
33 | 34 | if (!cpu_model) |
34 | 35 | cpu_model = "pxa270-c5"; |
... | ... | @@ -47,18 +48,32 @@ static void mainstone_common_init(int ram_size, int vga_ram_size, |
47 | 48 | /* Setup initial (reset) machine state */ |
48 | 49 | cpu->env->regs[15] = PXA2XX_SDRAM_BASE; |
49 | 50 | |
50 | - /* There are two 32MiB flash devices on the board */ | |
51 | - if (!pflash_register(MST_FLASH_0, mainstone_ram + PXA2XX_INTERNAL_SIZE, | |
52 | - pflash_table[0], 256 * 1024, 128, 4, 0, 0, 0, 0)) { | |
53 | - fprintf(stderr, "qemu: Error register flash memory.\n"); | |
54 | - exit(1); | |
55 | - } | |
51 | + /* There are two 32MiB flash devices on the board */ | |
52 | + index = drive_get_index(IF_PFLASH, 0, 0); | |
53 | + if (index == -1) { | |
54 | + fprintf(stderr, "Two flash images must be given with the " | |
55 | + "'pflash' parameter\n"); | |
56 | + exit(1); | |
57 | + } | |
58 | + if (!pflash_register(MST_FLASH_0, mainstone_ram + PXA2XX_INTERNAL_SIZE, | |
59 | + drives_table[index].bdrv, | |
60 | + 256 * 1024, 128, 4, 0, 0, 0, 0)) { | |
61 | + fprintf(stderr, "qemu: Error registering flash memory.\n"); | |
62 | + exit(1); | |
63 | + } | |
56 | 64 | |
57 | - if (!pflash_register(MST_FLASH_1, mainstone_ram + PXA2XX_INTERNAL_SIZE, | |
58 | - pflash_table[1], 256 * 1024, 128, 4, 0, 0, 0, 0)) { | |
59 | - fprintf(stderr, "qemu: Error register flash memory.\n"); | |
60 | - exit(1); | |
61 | - } | |
65 | + index = drive_get_index(IF_PFLASH, 0, 1); | |
66 | + if (index == -1) { | |
67 | + fprintf(stderr, "Two flash images must be given with the " | |
68 | + "'pflash' parameter\n"); | |
69 | + exit(1); | |
70 | + } | |
71 | + if (!pflash_register(MST_FLASH_1, mainstone_ram + PXA2XX_INTERNAL_SIZE, | |
72 | + drives_table[index].bdrv, | |
73 | + 256 * 1024, 128, 4, 0, 0, 0, 0)) { | |
74 | + fprintf(stderr, "qemu: Error registering flash memory.\n"); | |
75 | + exit(1); | |
76 | + } | |
62 | 77 | |
63 | 78 | mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0); |
64 | 79 | smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]); | ... | ... |
hw/mips_malta.c
... | ... | @@ -53,6 +53,8 @@ |
53 | 53 | #define ENVP_NB_ENTRIES 16 |
54 | 54 | #define ENVP_ENTRY_SIZE 256 |
55 | 55 | |
56 | +#define MAX_IDE_BUS 2 | |
57 | + | |
56 | 58 | extern FILE *logfile; |
57 | 59 | |
58 | 60 | typedef struct { |
... | ... | @@ -776,6 +778,9 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
776 | 778 | uint8_t *eeprom_buf; |
777 | 779 | i2c_bus *smbus; |
778 | 780 | int i; |
781 | + int index; | |
782 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
783 | + BlockDriverState *fd[MAX_FD]; | |
779 | 784 | |
780 | 785 | /* init CPUs */ |
781 | 786 | if (cpu_model == NULL) { |
... | ... | @@ -862,8 +867,22 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
862 | 867 | pci_bus = pci_gt64120_init(i8259); |
863 | 868 | |
864 | 869 | /* Southbridge */ |
870 | + | |
871 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
872 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
873 | + exit(1); | |
874 | + } | |
875 | + | |
876 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
877 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
878 | + if (index != -1) | |
879 | + hd[i] = drives_table[index].bdrv; | |
880 | + else | |
881 | + hd[i] = NULL; | |
882 | + } | |
883 | + | |
865 | 884 | piix4_devfn = piix4_init(pci_bus, 80); |
866 | - pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259); | |
885 | + pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1, i8259); | |
867 | 886 | usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); |
868 | 887 | smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100); |
869 | 888 | eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ |
... | ... | @@ -883,7 +902,14 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
883 | 902 | serial_init(0x2f8, i8259[3], serial_hds[1]); |
884 | 903 | if (parallel_hds[0]) |
885 | 904 | parallel_init(0x378, i8259[7], parallel_hds[0]); |
886 | - floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); | |
905 | + for(i = 0; i < MAX_FD; i++) { | |
906 | + index = drive_get_index(IF_FLOPPY, 0, i); | |
907 | + if (index != -1) | |
908 | + fd[i] = drives_table[index].bdrv; | |
909 | + else | |
910 | + fd[i] = NULL; | |
911 | + } | |
912 | + floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); | |
887 | 913 | |
888 | 914 | /* Sound card */ |
889 | 915 | #ifdef HAS_AUDIO | ... | ... |
hw/mips_pica61.c
... | ... | @@ -44,6 +44,9 @@ |
44 | 44 | |
45 | 45 | #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) |
46 | 46 | |
47 | +#define MAX_IDE_BUS 2 | |
48 | +#define MAX_FD 2 | |
49 | + | |
47 | 50 | static const int ide_iobase[2] = { 0x1f0, 0x170 }; |
48 | 51 | static const int ide_iobase2[2] = { 0x3f6, 0x376 }; |
49 | 52 | static const int ide_irq[2] = { 14, 15 }; |
... | ... | @@ -72,6 +75,8 @@ void mips_pica61_init (int ram_size, int vga_ram_size, |
72 | 75 | int i; |
73 | 76 | int available_ram; |
74 | 77 | qemu_irq *i8259; |
78 | + int index; | |
79 | + BlockDriverState *fd[MAX_FD]; | |
75 | 80 | |
76 | 81 | /* init CPUs */ |
77 | 82 | if (cpu_model == NULL) { |
... | ... | @@ -141,9 +146,20 @@ void mips_pica61_init (int ram_size, int vga_ram_size, |
141 | 146 | i8042_mm_init(i8259[6], i8259[7], 0x80005060, 0); |
142 | 147 | |
143 | 148 | /* IDE controller */ |
144 | - for(i = 0; i < 2; i++) | |
149 | + | |
150 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
151 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
152 | + exit(1); | |
153 | + } | |
154 | + | |
155 | + for(i = 0; i < MAX_IDE_BUS; i++) { | |
156 | + int hd0, hd1; | |
157 | + hd0 = drive_get_index(IF_IDE, i, 0); | |
158 | + hd1 = drive_get_index(IF_IDE, i, 1); | |
145 | 159 | isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], |
146 | - bs_table[2 * i], bs_table[2 * i + 1]); | |
160 | + hd0 == -1 ? NULL : drives_table[hd0].bdrv, | |
161 | + hd1 == -1 ? NULL : drives_table[hd1].bdrv); | |
162 | + } | |
147 | 163 | |
148 | 164 | /* Network controller */ |
149 | 165 | /* FIXME: missing NS SONIC DP83932 */ |
... | ... | @@ -152,7 +168,14 @@ void mips_pica61_init (int ram_size, int vga_ram_size, |
152 | 168 | /* FIXME: missing NCR 53C94 */ |
153 | 169 | |
154 | 170 | /* ISA devices (floppy, serial, parallel) */ |
155 | - fdctrl_init(i8259[1], 1, 1, 0x80003000, fd_table); | |
171 | + | |
172 | + for (i = 0; i < MAX_FD; i++) { | |
173 | + index = drive_get_index(IF_FLOPPY, 0, i); | |
174 | + if (index == -1) | |
175 | + continue; | |
176 | + fd[i] = drives_table[index].bdrv; | |
177 | + } | |
178 | + fdctrl_init(i8259[1], 1, 1, 0x80003000, fd); | |
156 | 179 | for(i = 0; i < MAX_SERIAL_PORTS; i++) { |
157 | 180 | if (serial_hds[i]) { |
158 | 181 | serial_mm_init(serial_base[i], 0, i8259[serial_irq[i]], serial_hds[i], 1); | ... | ... |
hw/mips_r4k.c
... | ... | @@ -25,6 +25,8 @@ |
25 | 25 | |
26 | 26 | #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) |
27 | 27 | |
28 | +#define MAX_IDE_BUS 2 | |
29 | + | |
28 | 30 | static const int ide_iobase[2] = { 0x1f0, 0x170 }; |
29 | 31 | static const int ide_iobase2[2] = { 0x3f6, 0x376 }; |
30 | 32 | static const int ide_irq[2] = { 14, 15 }; |
... | ... | @@ -155,6 +157,8 @@ void mips_r4k_init (int ram_size, int vga_ram_size, |
155 | 157 | RTCState *rtc_state; |
156 | 158 | int i; |
157 | 159 | qemu_irq *i8259; |
160 | + int index; | |
161 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
158 | 162 | |
159 | 163 | /* init CPUs */ |
160 | 164 | if (cpu_model == NULL) { |
... | ... | @@ -245,9 +249,23 @@ void mips_r4k_init (int ram_size, int vga_ram_size, |
245 | 249 | } |
246 | 250 | } |
247 | 251 | |
248 | - for(i = 0; i < 2; i++) | |
252 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
253 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
254 | + exit(1); | |
255 | + } | |
256 | + | |
257 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
258 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
259 | + if (index != -1) | |
260 | + hd[i] = drives_table[index].bdrv; | |
261 | + else | |
262 | + hd[i] = NULL; | |
263 | + } | |
264 | + | |
265 | + for(i = 0; i < MAX_IDE_BUS; i++) | |
249 | 266 | isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], |
250 | - bs_table[2 * i], bs_table[2 * i + 1]); | |
267 | + hd[MAX_IDE_DEVS * i], | |
268 | + hd[MAX_IDE_DEVS * i + 1]); | |
251 | 269 | |
252 | 270 | i8042_init(i8259[1], i8259[12], 0x60); |
253 | 271 | ds1225y_init(0x9000, "nvram"); | ... | ... |
hw/nand.c
... | ... | @@ -444,14 +444,20 @@ struct nand_flash_s *nand_init(int manf_id, int chip_id) |
444 | 444 | { |
445 | 445 | int pagesize; |
446 | 446 | struct nand_flash_s *s; |
447 | + int index; | |
447 | 448 | |
448 | 449 | if (nand_flash_ids[chip_id].size == 0) { |
449 | 450 | cpu_abort(cpu_single_env, "%s: Unsupported NAND chip ID.\n", |
450 | 451 | __FUNCTION__); |
451 | 452 | } |
453 | + index = drive_get_index(IF_MTD, 0, 0); | |
454 | + if (index == -1) { | |
455 | + cpu_abort(cpu_single_env, "%s: missing MTD device\n", | |
456 | + __FUNCTION__); | |
457 | + } | |
452 | 458 | |
453 | 459 | s = (struct nand_flash_s *) qemu_mallocz(sizeof(struct nand_flash_s)); |
454 | - s->bdrv = mtd_bdrv; | |
460 | + s->bdrv = drives_table[index].bdrv; | |
455 | 461 | s->manf_id = manf_id; |
456 | 462 | s->chip_id = chip_id; |
457 | 463 | s->size = nand_flash_ids[s->chip_id].size << 20; | ... | ... |
hw/omap.c
... | ... | @@ -4901,6 +4901,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
4901 | 4901 | struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) |
4902 | 4902 | qemu_mallocz(sizeof(struct omap_mpu_state_s)); |
4903 | 4903 | ram_addr_t imif_base, emiff_base; |
4904 | + int index; | |
4904 | 4905 | |
4905 | 4906 | if (!core) |
4906 | 4907 | core = "ti925t"; |
... | ... | @@ -4997,7 +4998,13 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
4997 | 4998 | omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2")); |
4998 | 4999 | omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3")); |
4999 | 5000 | |
5000 | - s->mmc = omap_mmc_init(0xfffb7800, sd_bdrv, s->irq[1][OMAP_INT_OQN], | |
5001 | + index = drive_get_index(IF_SD, 0, 0); | |
5002 | + if (index == -1) { | |
5003 | + fprintf(stderr, "qemu: missing SecureDigital device\n"); | |
5004 | + exit(1); | |
5005 | + } | |
5006 | + s->mmc = omap_mmc_init(0xfffb7800, drives_table[index].bdrv, | |
5007 | + s->irq[1][OMAP_INT_OQN], | |
5001 | 5008 | &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck")); |
5002 | 5009 | |
5003 | 5010 | s->mpuio = omap_mpuio_init(0xfffb5000, | ... | ... |
hw/pc.c
... | ... | @@ -42,6 +42,8 @@ |
42 | 42 | /* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */ |
43 | 43 | #define ACPI_DATA_SIZE 0x10000 |
44 | 44 | |
45 | +#define MAX_IDE_BUS 2 | |
46 | + | |
45 | 47 | static fdctrl_t *floppy_controller; |
46 | 48 | static RTCState *rtc_state; |
47 | 49 | static PITState *pit; |
... | ... | @@ -381,8 +383,10 @@ static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip) |
381 | 383 | { |
382 | 384 | uint8_t bootsect[512], *p; |
383 | 385 | int i; |
386 | + int hda; | |
384 | 387 | |
385 | - if (bs_table[0] == NULL) { | |
388 | + hda = drive_get_index(IF_IDE, 0, 0); | |
389 | + if (hda == -1) { | |
386 | 390 | fprintf(stderr, "A disk image must be given for 'hda' when booting " |
387 | 391 | "a Linux kernel\n"); |
388 | 392 | exit(1); |
... | ... | @@ -391,7 +395,7 @@ static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip) |
391 | 395 | memset(bootsect, 0, sizeof(bootsect)); |
392 | 396 | |
393 | 397 | /* Copy the MSDOS partition table if possible */ |
394 | - bdrv_read(bs_table[0], 0, bootsect, 1); | |
398 | + bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1); | |
395 | 399 | |
396 | 400 | /* Make sure we have a partition signature */ |
397 | 401 | bootsect[510] = 0x55; |
... | ... | @@ -428,7 +432,7 @@ static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip) |
428 | 432 | *p++ = segs[1]; /* CS */ |
429 | 433 | *p++ = segs[1] >> 8; |
430 | 434 | |
431 | - bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect)); | |
435 | + bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect)); | |
432 | 436 | } |
433 | 437 | |
434 | 438 | static int load_kernel(const char *filename, uint8_t *addr, |
... | ... | @@ -709,6 +713,9 @@ static void pc_init1(int ram_size, int vga_ram_size, |
709 | 713 | NICInfo *nd; |
710 | 714 | qemu_irq *cpu_irq; |
711 | 715 | qemu_irq *i8259; |
716 | + int index; | |
717 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
718 | + BlockDriverState *fd[MAX_FD]; | |
712 | 719 | |
713 | 720 | linux_boot = (kernel_filename != NULL); |
714 | 721 | |
... | ... | @@ -926,12 +933,25 @@ static void pc_init1(int ram_size, int vga_ram_size, |
926 | 933 | } |
927 | 934 | } |
928 | 935 | |
936 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
937 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
938 | + exit(1); | |
939 | + } | |
940 | + | |
941 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
942 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
943 | + if (index != -1) | |
944 | + hd[i] = drives_table[index].bdrv; | |
945 | + else | |
946 | + hd[i] = NULL; | |
947 | + } | |
948 | + | |
929 | 949 | if (pci_enabled) { |
930 | - pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1, i8259); | |
950 | + pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259); | |
931 | 951 | } else { |
932 | - for(i = 0; i < 2; i++) { | |
952 | + for(i = 0; i < MAX_IDE_BUS; i++) { | |
933 | 953 | isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], |
934 | - bs_table[2 * i], bs_table[2 * i + 1]); | |
954 | + hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); | |
935 | 955 | } |
936 | 956 | } |
937 | 957 | |
... | ... | @@ -941,9 +961,16 @@ static void pc_init1(int ram_size, int vga_ram_size, |
941 | 961 | audio_init(pci_enabled ? pci_bus : NULL, i8259); |
942 | 962 | #endif |
943 | 963 | |
944 | - floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); | |
964 | + for(i = 0; i < MAX_FD; i++) { | |
965 | + index = drive_get_index(IF_FLOPPY, 0, i); | |
966 | + if (index != -1) | |
967 | + fd[i] = drives_table[index].bdrv; | |
968 | + else | |
969 | + fd[i] = NULL; | |
970 | + } | |
971 | + floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); | |
945 | 972 | |
946 | - cmos_init(ram_size, boot_device, bs_table); | |
973 | + cmos_init(ram_size, boot_device, hd); | |
947 | 974 | |
948 | 975 | if (pci_enabled && usb_enabled) { |
949 | 976 | usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); |
... | ... | @@ -963,23 +990,24 @@ static void pc_init1(int ram_size, int vga_ram_size, |
963 | 990 | if (i440fx_state) { |
964 | 991 | i440fx_init_memory_mappings(i440fx_state); |
965 | 992 | } |
966 | -#if 0 | |
967 | - /* ??? Need to figure out some way for the user to | |
968 | - specify SCSI devices. */ | |
993 | + | |
969 | 994 | if (pci_enabled) { |
995 | + int max_bus; | |
996 | + int bus, unit; | |
970 | 997 | void *scsi; |
971 | - BlockDriverState *bdrv; | |
972 | 998 | |
973 | - scsi = lsi_scsi_init(pci_bus, -1); | |
974 | - bdrv = bdrv_new("scsidisk"); | |
975 | - bdrv_open(bdrv, "scsi_disk.img", 0); | |
976 | - lsi_scsi_attach(scsi, bdrv, -1); | |
977 | - bdrv = bdrv_new("scsicd"); | |
978 | - bdrv_open(bdrv, "scsi_cd.iso", 0); | |
979 | - bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM); | |
980 | - lsi_scsi_attach(scsi, bdrv, -1); | |
999 | + max_bus = drive_get_max_bus(IF_SCSI); | |
1000 | + | |
1001 | + for (bus = 0; bus <= max_bus; bus++) { | |
1002 | + scsi = lsi_scsi_init(pci_bus, -1); | |
1003 | + for (unit = 0; unit < LSI_MAX_DEVS; unit++) { | |
1004 | + index = drive_get_index(IF_SCSI, bus, unit); | |
1005 | + if (index == -1) | |
1006 | + continue; | |
1007 | + lsi_scsi_attach(scsi, drives_table[index].bdrv, unit); | |
1008 | + } | |
1009 | + } | |
981 | 1010 | } |
982 | -#endif | |
983 | 1011 | } |
984 | 1012 | |
985 | 1013 | static void pc_init_pci(int ram_size, int vga_ram_size, | ... | ... |
hw/pci.h
... | ... | @@ -97,6 +97,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, |
97 | 97 | pci_map_irq_fn map_irq, const char *name); |
98 | 98 | |
99 | 99 | /* lsi53c895a.c */ |
100 | +#define LSI_MAX_DEVS 7 | |
100 | 101 | void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id); |
101 | 102 | void *lsi_scsi_init(PCIBus *bus, int devfn); |
102 | 103 | ... | ... |
hw/ppc405_boards.c
... | ... | @@ -197,6 +197,7 @@ static void ref405ep_init (int ram_size, int vga_ram_size, |
197 | 197 | int linux_boot; |
198 | 198 | int fl_idx, fl_sectors, len; |
199 | 199 | int ppc_boot_device = boot_device[0]; |
200 | + int index; | |
200 | 201 | |
201 | 202 | /* XXX: fix this */ |
202 | 203 | ram_bases[0] = 0x00000000; |
... | ... | @@ -223,17 +224,18 @@ static void ref405ep_init (int ram_size, int vga_ram_size, |
223 | 224 | bios_offset = sram_offset + sram_size; |
224 | 225 | fl_idx = 0; |
225 | 226 | #ifdef USE_FLASH_BIOS |
226 | - if (pflash_table[fl_idx] != NULL) { | |
227 | - bios_size = bdrv_getlength(pflash_table[fl_idx]); | |
227 | + index = drive_get_index(IF_PFLASH, 0, fl_idx); | |
228 | + if (index != -1) { | |
229 | + bios_size = bdrv_getlength(drives_table[index].bdrv); | |
228 | 230 | fl_sectors = (bios_size + 65535) >> 16; |
229 | 231 | #ifdef DEBUG_BOARD_INIT |
230 | 232 | printf("Register parallel flash %d size " ADDRX " at offset %08lx " |
231 | 233 | " addr " ADDRX " '%s' %d\n", |
232 | 234 | fl_idx, bios_size, bios_offset, -bios_size, |
233 | - bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors); | |
235 | + bdrv_get_device_name(drives_table[index].bdrv), fl_sectors); | |
234 | 236 | #endif |
235 | 237 | pflash_register((uint32_t)(-bios_size), bios_offset, |
236 | - pflash_table[fl_idx], 65536, fl_sectors, 2, | |
238 | + drives_table[index].bdrv, 65536, fl_sectors, 2, | |
237 | 239 | 0x0001, 0x22DA, 0x0000, 0x0000); |
238 | 240 | fl_idx++; |
239 | 241 | } else |
... | ... | @@ -519,6 +521,7 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size, |
519 | 521 | int linux_boot; |
520 | 522 | int fl_idx, fl_sectors; |
521 | 523 | int ppc_boot_device = boot_device[0]; |
524 | + int index; | |
522 | 525 | |
523 | 526 | /* RAM is soldered to the board so the size cannot be changed */ |
524 | 527 | ram_bases[0] = 0x00000000; |
... | ... | @@ -536,8 +539,9 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size, |
536 | 539 | #endif |
537 | 540 | fl_idx = 0; |
538 | 541 | #if defined(USE_FLASH_BIOS) |
539 | - if (pflash_table[fl_idx] != NULL) { | |
540 | - bios_size = bdrv_getlength(pflash_table[fl_idx]); | |
542 | + index = drive_get_index(IF_PFLASH, 0, fl_idx); | |
543 | + if (index != -1) { | |
544 | + bios_size = bdrv_getlength(drives_table[index].bdrv); | |
541 | 545 | /* XXX: should check that size is 2MB */ |
542 | 546 | // bios_size = 2 * 1024 * 1024; |
543 | 547 | fl_sectors = (bios_size + 65535) >> 16; |
... | ... | @@ -545,10 +549,10 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size, |
545 | 549 | printf("Register parallel flash %d size " ADDRX " at offset %08lx " |
546 | 550 | " addr " ADDRX " '%s' %d\n", |
547 | 551 | fl_idx, bios_size, bios_offset, -bios_size, |
548 | - bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors); | |
552 | + bdrv_get_device_name(drives_table[index].bdrv), fl_sectors); | |
549 | 553 | #endif |
550 | 554 | pflash_register((uint32_t)(-bios_size), bios_offset, |
551 | - pflash_table[fl_idx], 65536, fl_sectors, 4, | |
555 | + drives_table[index].bdrv, 65536, fl_sectors, 4, | |
552 | 556 | 0x0001, 0x22DA, 0x0000, 0x0000); |
553 | 557 | fl_idx++; |
554 | 558 | } else |
... | ... | @@ -571,8 +575,9 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size, |
571 | 575 | } |
572 | 576 | bios_offset += bios_size; |
573 | 577 | /* Register Linux flash */ |
574 | - if (pflash_table[fl_idx] != NULL) { | |
575 | - bios_size = bdrv_getlength(pflash_table[fl_idx]); | |
578 | + index = drive_get_index(IF_PFLASH, 0, fl_idx); | |
579 | + if (index != -1) { | |
580 | + bios_size = bdrv_getlength(drives_table[index].bdrv); | |
576 | 581 | /* XXX: should check that size is 32MB */ |
577 | 582 | bios_size = 32 * 1024 * 1024; |
578 | 583 | fl_sectors = (bios_size + 65535) >> 16; |
... | ... | @@ -580,9 +585,9 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size, |
580 | 585 | printf("Register parallel flash %d size " ADDRX " at offset %08lx " |
581 | 586 | " addr " ADDRX " '%s'\n", |
582 | 587 | fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000, |
583 | - bdrv_get_device_name(pflash_table[fl_idx])); | |
588 | + bdrv_get_device_name(drives_table[index].bdrv)); | |
584 | 589 | #endif |
585 | - pflash_register(0xfc000000, bios_offset, pflash_table[fl_idx], | |
590 | + pflash_register(0xfc000000, bios_offset, drives_table[index].bdrv, | |
586 | 591 | 65536, fl_sectors, 4, |
587 | 592 | 0x0001, 0x22DA, 0x0000, 0x0000); |
588 | 593 | fl_idx++; | ... | ... |
hw/ppc_chrp.c
... | ... | @@ -32,6 +32,8 @@ |
32 | 32 | #include "sysemu.h" |
33 | 33 | #include "boards.h" |
34 | 34 | |
35 | +#define MAX_IDE_BUS 2 | |
36 | + | |
35 | 37 | /* UniN device */ |
36 | 38 | static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
37 | 39 | { |
... | ... | @@ -81,6 +83,8 @@ static void ppc_core99_init (int ram_size, int vga_ram_size, |
81 | 83 | int pic_mem_index, dbdma_mem_index, cuda_mem_index; |
82 | 84 | int ide_mem_index[2]; |
83 | 85 | int ppc_boot_device; |
86 | + int index; | |
87 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
84 | 88 | |
85 | 89 | linux_boot = (kernel_filename != NULL); |
86 | 90 | |
... | ... | @@ -266,11 +270,22 @@ static void ppc_core99_init (int ram_size, int vga_ram_size, |
266 | 270 | nd_table[i].model = "ne2k_pci"; |
267 | 271 | pci_nic_init(pci_bus, &nd_table[i], -1); |
268 | 272 | } |
273 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
274 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
275 | + exit(1); | |
276 | + } | |
277 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
278 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
279 | + if (index != -1) | |
280 | + hd[i] = drives_table[index].bdrv; | |
281 | + else | |
282 | + hd[i] = NULL; | |
283 | + } | |
269 | 284 | #if 1 |
270 | - ide_mem_index[0] = pmac_ide_init(&bs_table[0], pic[0x13]); | |
271 | - ide_mem_index[1] = pmac_ide_init(&bs_table[2], pic[0x14]); | |
285 | + ide_mem_index[0] = pmac_ide_init(&hd[0], pic[0x13]); | |
286 | + ide_mem_index[1] = pmac_ide_init(&hd[2], pic[0x14]); | |
272 | 287 | #else |
273 | - pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); | |
288 | + pci_cmd646_ide_init(pci_bus, &hd[0], 0); | |
274 | 289 | #endif |
275 | 290 | /* cuda also initialize ADB */ |
276 | 291 | cuda_init(&cuda_mem_index, pic[0x19]); | ... | ... |
hw/ppc_oldworld.c
... | ... | @@ -33,6 +33,8 @@ |
33 | 33 | #include "pci.h" |
34 | 34 | #include "boards.h" |
35 | 35 | |
36 | +#define MAX_IDE_BUS 2 | |
37 | + | |
36 | 38 | /* temporary frame buffer OSI calls for the video.x driver. The right |
37 | 39 | solution is to modify the driver to use VGA PCI I/Os */ |
38 | 40 | /* XXX: to be removed. This is no way related to emulation */ |
... | ... | @@ -123,6 +125,8 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size, |
123 | 125 | int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index; |
124 | 126 | int ide_mem_index[2]; |
125 | 127 | int ppc_boot_device; |
128 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
129 | + int index; | |
126 | 130 | |
127 | 131 | linux_boot = (kernel_filename != NULL); |
128 | 132 | |
... | ... | @@ -292,10 +296,37 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size, |
292 | 296 | } |
293 | 297 | |
294 | 298 | /* First IDE channel is a CMD646 on the PCI bus */ |
295 | - pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); | |
299 | + | |
300 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
301 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
302 | + exit(1); | |
303 | + } | |
304 | + index = drive_get_index(IF_IDE, 0, 0); | |
305 | + if (index == -1) | |
306 | + hd[0] = NULL; | |
307 | + else | |
308 | + hd[0] = drives_table[index].bdrv; | |
309 | + index = drive_get_index(IF_IDE, 0, 1); | |
310 | + if (index == -1) | |
311 | + hd[1] = NULL; | |
312 | + else | |
313 | + hd[1] = drives_table[index].bdrv; | |
314 | + hd[3] = hd[2] = NULL; | |
315 | + pci_cmd646_ide_init(pci_bus, hd, 0); | |
316 | + | |
296 | 317 | /* Second IDE channel is a MAC IDE on the MacIO bus */ |
318 | + index = drive_get_index(IF_IDE, 1, 0); | |
319 | + if (index == -1) | |
320 | + hd[0] = NULL; | |
321 | + else | |
322 | + hd[0] = drives_table[index].bdrv; | |
323 | + index = drive_get_index(IF_IDE, 1, 1); | |
324 | + if (index == -1) | |
325 | + hd[1] = NULL; | |
326 | + else | |
327 | + hd[1] = drives_table[index].bdrv; | |
297 | 328 | ide_mem_index[0] = -1; |
298 | - ide_mem_index[1] = pmac_ide_init(&bs_table[2], pic[0x0D]); | |
329 | + ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D]); | |
299 | 330 | |
300 | 331 | /* cuda also initialize ADB */ |
301 | 332 | cuda_init(&cuda_mem_index, pic[0x12]); | ... | ... |
hw/ppc_prep.c
... | ... | @@ -38,6 +38,8 @@ |
38 | 38 | /* SMP is not enabled, for now */ |
39 | 39 | #define MAX_CPUS 1 |
40 | 40 | |
41 | +#define MAX_IDE_BUS 2 | |
42 | + | |
41 | 43 | #define BIOS_FILENAME "ppc_rom.bin" |
42 | 44 | #define KERNEL_LOAD_ADDR 0x01000000 |
43 | 45 | #define INITRD_LOAD_ADDR 0x01800000 |
... | ... | @@ -551,6 +553,9 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, |
551 | 553 | PCIBus *pci_bus; |
552 | 554 | qemu_irq *i8259; |
553 | 555 | int ppc_boot_device; |
556 | + int index; | |
557 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
558 | + BlockDriverState *fd[MAX_FD]; | |
554 | 559 | |
555 | 560 | sysctrl = qemu_mallocz(sizeof(sysctrl_t)); |
556 | 561 | if (sysctrl == NULL) |
... | ... | @@ -675,16 +680,37 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, |
675 | 680 | } |
676 | 681 | } |
677 | 682 | |
678 | - for(i = 0; i < 2; i++) { | |
683 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
684 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
685 | + exit(1); | |
686 | + } | |
687 | + | |
688 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
689 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
690 | + if (index != -1) | |
691 | + hd[i] = drives_table[index].bdrv; | |
692 | + else | |
693 | + hd[i] = NULL; | |
694 | + } | |
695 | + | |
696 | + for(i = 0; i < MAX_IDE_BUS; i++) { | |
679 | 697 | isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], |
680 | - bs_table[2 * i], bs_table[2 * i + 1]); | |
698 | + hd[2 * i], | |
699 | + hd[2 * i + 1]); | |
681 | 700 | } |
682 | 701 | i8042_init(i8259[1], i8259[12], 0x60); |
683 | 702 | DMA_init(1); |
684 | 703 | // AUD_init(); |
685 | 704 | // SB16_init(); |
686 | 705 | |
687 | - fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); | |
706 | + for(i = 0; i < MAX_FD; i++) { | |
707 | + index = drive_get_index(IF_FLOPPY, 0, i); | |
708 | + if (index != -1) | |
709 | + fd[i] = drives_table[index].bdrv; | |
710 | + else | |
711 | + fd[i] = NULL; | |
712 | + } | |
713 | + fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); | |
688 | 714 | |
689 | 715 | /* Register speaker port */ |
690 | 716 | register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL); | ... | ... |
hw/pxa2xx.c
... | ... | @@ -2036,6 +2036,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, |
2036 | 2036 | struct pxa2xx_state_s *s; |
2037 | 2037 | struct pxa2xx_ssp_s *ssp; |
2038 | 2038 | int iomemtype, i; |
2039 | + int index; | |
2039 | 2040 | s = (struct pxa2xx_state_s *) qemu_mallocz(sizeof(struct pxa2xx_state_s)); |
2040 | 2041 | |
2041 | 2042 | if (revision && strncmp(revision, "pxa27", 5)) { |
... | ... | @@ -2070,8 +2071,13 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, |
2070 | 2071 | |
2071 | 2072 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121); |
2072 | 2073 | |
2073 | - s->mmc = pxa2xx_mmci_init(0x41100000, sd_bdrv, s->pic[PXA2XX_PIC_MMC], | |
2074 | - s->dma); | |
2074 | + index = drive_get_index(IF_SD, 0, 0); | |
2075 | + if (index == -1) { | |
2076 | + fprintf(stderr, "qemu: missing SecureDigital device\n"); | |
2077 | + exit(1); | |
2078 | + } | |
2079 | + s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv, | |
2080 | + s->pic[PXA2XX_PIC_MMC], s->dma); | |
2075 | 2081 | |
2076 | 2082 | for (i = 0; pxa270_serial[i].io_base; i ++) |
2077 | 2083 | if (serial_hds[i]) |
... | ... | @@ -2160,6 +2166,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, |
2160 | 2166 | struct pxa2xx_state_s *s; |
2161 | 2167 | struct pxa2xx_ssp_s *ssp; |
2162 | 2168 | int iomemtype, i; |
2169 | + int index; | |
2163 | 2170 | |
2164 | 2171 | s = (struct pxa2xx_state_s *) qemu_mallocz(sizeof(struct pxa2xx_state_s)); |
2165 | 2172 | |
... | ... | @@ -2187,8 +2194,13 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, |
2187 | 2194 | |
2188 | 2195 | s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85); |
2189 | 2196 | |
2190 | - s->mmc = pxa2xx_mmci_init(0x41100000, sd_bdrv, s->pic[PXA2XX_PIC_MMC], | |
2191 | - s->dma); | |
2197 | + index = drive_get_index(IF_SD, 0, 0); | |
2198 | + if (index == -1) { | |
2199 | + fprintf(stderr, "qemu: missing SecureDigital device\n"); | |
2200 | + exit(1); | |
2201 | + } | |
2202 | + s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv, | |
2203 | + s->pic[PXA2XX_PIC_MMC], s->dma); | |
2192 | 2204 | |
2193 | 2205 | for (i = 0; pxa255_serial[i].io_base; i ++) |
2194 | 2206 | if (serial_hds[i]) | ... | ... |
hw/realview.c
... | ... | @@ -32,6 +32,7 @@ static void realview_init(int ram_size, int vga_ram_size, |
32 | 32 | int done_smc = 0; |
33 | 33 | qemu_irq cpu_irq[4]; |
34 | 34 | int ncpu; |
35 | + int index; | |
35 | 36 | |
36 | 37 | if (!cpu_model) |
37 | 38 | cpu_model = "arm926"; |
... | ... | @@ -89,7 +90,12 @@ static void realview_init(int ram_size, int vga_ram_size, |
89 | 90 | |
90 | 91 | pl110_init(ds, 0x10020000, pic[23], 1); |
91 | 92 | |
92 | - pl181_init(0x10005000, sd_bdrv, pic[17], pic[18]); | |
93 | + index = drive_get_index(IF_SD, 0, 0); | |
94 | + if (index == -1) { | |
95 | + fprintf(stderr, "qemu: missing SecureDigital card\n"); | |
96 | + exit(1); | |
97 | + } | |
98 | + pl181_init(0x10005000, drives_table[index].bdrv, pic[17], pic[18]); | |
93 | 99 | |
94 | 100 | pl031_init(0x10017000, pic[10]); |
95 | 101 | |
... | ... | @@ -97,11 +103,16 @@ static void realview_init(int ram_size, int vga_ram_size, |
97 | 103 | if (usb_enabled) { |
98 | 104 | usb_ohci_init_pci(pci_bus, 3, -1); |
99 | 105 | } |
106 | + if (drive_get_max_bus(IF_SCSI) > 0) { | |
107 | + fprintf(stderr, "qemu: too many SCSI bus\n"); | |
108 | + exit(1); | |
109 | + } | |
100 | 110 | scsi_hba = lsi_scsi_init(pci_bus, -1); |
101 | - for (n = 0; n < MAX_DISKS; n++) { | |
102 | - if (bs_table[n]) { | |
103 | - lsi_scsi_attach(scsi_hba, bs_table[n], n); | |
104 | - } | |
111 | + for (n = 0; n < LSI_MAX_DEVS; n++) { | |
112 | + index = drive_get_index(IF_SCSI, 0, n); | |
113 | + if (index == -1) | |
114 | + continue; | |
115 | + lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n); | |
105 | 116 | } |
106 | 117 | for(n = 0; n < nb_nics; n++) { |
107 | 118 | nd = &nd_table[n]; | ... | ... |
hw/spitz.c
... | ... | @@ -940,9 +940,14 @@ static void spitz_ssp_attach(struct pxa2xx_state_s *cpu) |
940 | 940 | static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu) |
941 | 941 | { |
942 | 942 | struct pcmcia_card_s *md; |
943 | - BlockDriverState *bs = bs_table[0]; | |
943 | + int index; | |
944 | + BlockDriverState *bs; | |
944 | 945 | |
945 | - if (bs && bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) { | |
946 | + index = drive_get_index(IF_IDE, 0, 0); | |
947 | + if (index == -1) | |
948 | + return; | |
949 | + bs = drives_table[index].bdrv; | |
950 | + if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) { | |
946 | 951 | md = dscm1xxxx_init(bs); |
947 | 952 | pxa2xx_pcmcia_attach(cpu->pcmcia[1], md); |
948 | 953 | } | ... | ... |
hw/stellaris.c
... | ... | @@ -1133,9 +1133,11 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, |
1133 | 1133 | void * oled; |
1134 | 1134 | void * sd; |
1135 | 1135 | void *ssi_bus; |
1136 | + int index; | |
1136 | 1137 | |
1137 | 1138 | oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]); |
1138 | - sd = ssi_sd_init(sd_bdrv); | |
1139 | + index = drive_get_index(IF_SD, 0, 0); | |
1140 | + sd = ssi_sd_init(drives_table[index].bdrv); | |
1139 | 1141 | |
1140 | 1142 | ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0], |
1141 | 1143 | ssi_sd_xfer, sd, | ... | ... |
hw/sun4m.c
... | ... | @@ -338,6 +338,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, |
338 | 338 | unsigned long prom_offset, kernel_size; |
339 | 339 | int ret; |
340 | 340 | char buf[1024]; |
341 | + BlockDriverState *fd[MAX_FD]; | |
342 | + int index; | |
341 | 343 | |
342 | 344 | /* init CPUs */ |
343 | 345 | if (!cpu_model) |
... | ... | @@ -440,16 +442,29 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, |
440 | 442 | slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], |
441 | 443 | serial_hds[1], serial_hds[0]); |
442 | 444 | |
443 | - if (hwdef->fd_base != (target_phys_addr_t)-1) | |
444 | - sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd_table); | |
445 | + if (hwdef->fd_base != (target_phys_addr_t)-1) { | |
446 | + /* there is zero or one floppy drive */ | |
447 | + fd[1] = fd[0] = NULL; | |
448 | + index = drive_get_index(IF_FLOPPY, 0, 0); | |
449 | + if (index != -1) | |
450 | + fd[0] = drives_table[index].bdrv; | |
445 | 451 | |
446 | - main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq, | |
452 | + sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd); | |
453 | + } | |
454 | + | |
455 | + if (drive_get_max_bus(IF_SCSI) > 0) { | |
456 | + fprintf(stderr, "qemu: too many SCSI bus\n"); | |
457 | + exit(1); | |
458 | + } | |
459 | + | |
460 | + main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, | |
447 | 461 | esp_reset); |
448 | 462 | |
449 | - for (i = 0; i < MAX_DISKS; i++) { | |
450 | - if (bs_table[i]) { | |
451 | - esp_scsi_attach(main_esp, bs_table[i], i); | |
452 | - } | |
463 | + for (i = 0; i < ESP_MAX_DEVS; i++) { | |
464 | + index = drive_get_index(IF_SCSI, 0, i); | |
465 | + if (index == -1) | |
466 | + continue; | |
467 | + esp_scsi_attach(main_esp, drives_table[index].bdrv, i); | |
453 | 468 | } |
454 | 469 | |
455 | 470 | slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base, | ... | ... |
hw/sun4m.h
... | ... | @@ -49,8 +49,9 @@ void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base, |
49 | 49 | void slavio_set_power_fail(void *opaque, int power_failing); |
50 | 50 | |
51 | 51 | /* esp.c */ |
52 | +#define ESP_MAX_DEVS 7 | |
52 | 53 | void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id); |
53 | -void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, | |
54 | +void *esp_init(target_phys_addr_t espaddr, | |
54 | 55 | void *dma_opaque, qemu_irq irq, qemu_irq *reset); |
55 | 56 | |
56 | 57 | /* cs4231.c */ | ... | ... |
hw/sun4u.c
... | ... | @@ -43,6 +43,7 @@ |
43 | 43 | #define VGA_BASE (APB_MEM_BASE + 0x400000ULL) |
44 | 44 | #define PROM_FILENAME "openbios-sparc64" |
45 | 45 | #define NVRAM_SIZE 0x2000 |
46 | +#define MAX_IDE_BUS 2 | |
46 | 47 | |
47 | 48 | /* TSC handling */ |
48 | 49 | |
... | ... | @@ -240,6 +241,9 @@ static void sun4u_init(int ram_size, int vga_ram_size, |
240 | 241 | PCIBus *pci_bus; |
241 | 242 | QEMUBH *bh; |
242 | 243 | qemu_irq *irq; |
244 | + int index; | |
245 | + BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | |
246 | + BlockDriverState *fd[MAX_FD]; | |
243 | 247 | |
244 | 248 | linux_boot = (kernel_filename != NULL); |
245 | 249 | |
... | ... | @@ -342,11 +346,30 @@ static void sun4u_init(int ram_size, int vga_ram_size, |
342 | 346 | } |
343 | 347 | |
344 | 348 | irq = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, 32); |
345 | - // XXX pci_cmd646_ide_init(pci_bus, bs_table, 1); | |
346 | - pci_piix3_ide_init(pci_bus, bs_table, -1, irq); | |
349 | + if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { | |
350 | + fprintf(stderr, "qemu: too many IDE bus\n"); | |
351 | + exit(1); | |
352 | + } | |
353 | + for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { | |
354 | + index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); | |
355 | + if (index != -1) | |
356 | + hd[i] = drives_table[index].bdrv; | |
357 | + else | |
358 | + hd[i] = NULL; | |
359 | + } | |
360 | + | |
361 | + // XXX pci_cmd646_ide_init(pci_bus, hd, 1); | |
362 | + pci_piix3_ide_init(pci_bus, hd, -1, irq); | |
347 | 363 | /* FIXME: wire up interrupts. */ |
348 | 364 | i8042_init(NULL/*1*/, NULL/*12*/, 0x60); |
349 | - floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); | |
365 | + for(i = 0; i < MAX_FD; i++) { | |
366 | + index = drive_get_index(IF_FLOPPY, 0, i); | |
367 | + if (index != -1) | |
368 | + fd[i] = drives_table[index].bdrv; | |
369 | + else | |
370 | + fd[i] = NULL; | |
371 | + } | |
372 | + floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd); | |
350 | 373 | nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); |
351 | 374 | sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_devices, |
352 | 375 | KERNEL_LOAD_ADDR, kernel_size, | ... | ... |
hw/versatilepb.c
... | ... | @@ -171,6 +171,7 @@ static void versatile_init(int ram_size, int vga_ram_size, |
171 | 171 | NICInfo *nd; |
172 | 172 | int n; |
173 | 173 | int done_smc = 0; |
174 | + int index; | |
174 | 175 | |
175 | 176 | if (!cpu_model) |
176 | 177 | cpu_model = "arm926"; |
... | ... | @@ -206,11 +207,16 @@ static void versatile_init(int ram_size, int vga_ram_size, |
206 | 207 | if (usb_enabled) { |
207 | 208 | usb_ohci_init_pci(pci_bus, 3, -1); |
208 | 209 | } |
210 | + if (drive_get_max_bus(IF_SCSI) > 0) { | |
211 | + fprintf(stderr, "qemu: too many SCSI bus\n"); | |
212 | + exit(1); | |
213 | + } | |
209 | 214 | scsi_hba = lsi_scsi_init(pci_bus, -1); |
210 | - for (n = 0; n < MAX_DISKS; n++) { | |
211 | - if (bs_table[n]) { | |
212 | - lsi_scsi_attach(scsi_hba, bs_table[n], n); | |
213 | - } | |
215 | + for (n = 0; n < LSI_MAX_DEVS; n++) { | |
216 | + index = drive_get_index(IF_SCSI, 0, n); | |
217 | + if (index == -1) | |
218 | + continue; | |
219 | + lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n); | |
214 | 220 | } |
215 | 221 | |
216 | 222 | pl011_init(0x101f1000, pic[12], serial_hds[0], PL011_ARM); |
... | ... | @@ -226,7 +232,13 @@ static void versatile_init(int ram_size, int vga_ram_size, |
226 | 232 | that includes hardware cursor support from the PL111. */ |
227 | 233 | pl110_init(ds, 0x10120000, pic[16], 1); |
228 | 234 | |
229 | - pl181_init(0x10005000, sd_bdrv, sic[22], sic[1]); | |
235 | + index = drive_get_index(IF_SD, 0, 0); | |
236 | + if (index == -1) { | |
237 | + fprintf(stderr, "qemu: missing SecureDigital card\n"); | |
238 | + exit(1); | |
239 | + } | |
240 | + | |
241 | + pl181_init(0x10005000, drives_table[index].bdrv, sic[22], sic[1]); | |
230 | 242 | #if 0 |
231 | 243 | /* Disabled because there's no way of specifying a block device. */ |
232 | 244 | pl181_init(0x1000b000, NULL, sic, 23, 2); | ... | ... |
monitor.c
... | ... | @@ -215,16 +215,11 @@ static void do_commit(const char *device) |
215 | 215 | int i, all_devices; |
216 | 216 | |
217 | 217 | all_devices = !strcmp(device, "all"); |
218 | - for (i = 0; i < MAX_DISKS; i++) { | |
219 | - if (bs_table[i]) { | |
218 | + for (i = 0; i < nb_drives; i++) { | |
220 | 219 | if (all_devices || |
221 | - !strcmp(bdrv_get_device_name(bs_table[i]), device)) | |
222 | - bdrv_commit(bs_table[i]); | |
223 | - } | |
220 | + !strcmp(bdrv_get_device_name(drives_table[i].bdrv), device)) | |
221 | + bdrv_commit(drives_table[i].bdrv); | |
224 | 222 | } |
225 | - if (mtd_bdrv) | |
226 | - if (all_devices || !strcmp(bdrv_get_device_name(mtd_bdrv), device)) | |
227 | - bdrv_commit(mtd_bdrv); | |
228 | 223 | } |
229 | 224 | |
230 | 225 | static void do_info(const char *item) | ... | ... |
sysemu.h
... | ... | @@ -116,15 +116,26 @@ extern unsigned int nb_prom_envs; |
116 | 116 | #define BIOS_SIZE (4 * 1024 * 1024) |
117 | 117 | #endif |
118 | 118 | |
119 | -#define MAX_DISKS 4 | |
120 | - | |
121 | -extern BlockDriverState *bs_table[MAX_DISKS + 1]; | |
122 | -extern BlockDriverState *sd_bdrv; | |
123 | -extern BlockDriverState *mtd_bdrv; | |
124 | - | |
125 | -/* NOR flash devices */ | |
126 | -#define MAX_PFLASH 4 | |
127 | -extern BlockDriverState *pflash_table[MAX_PFLASH]; | |
119 | +typedef enum { | |
120 | + IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD | |
121 | +} BlockInterfaceType; | |
122 | + | |
123 | +typedef struct DriveInfo { | |
124 | + BlockDriverState *bdrv; | |
125 | + BlockInterfaceType interface; | |
126 | + int bus; | |
127 | + int unit; | |
128 | +} DriveInfo; | |
129 | + | |
130 | +#define MAX_IDE_DEVS 2 | |
131 | +#define MAX_SCSI_DEVS 7 | |
132 | +#define MAX_DRIVES 32 | |
133 | + | |
134 | +int nb_drives; | |
135 | +DriveInfo drives_table[MAX_DRIVES+1]; | |
136 | + | |
137 | +extern int drive_get_index(BlockInterfaceType interface, int bus, int unit); | |
138 | +extern int drive_get_max_bus(BlockInterfaceType interface); | |
128 | 139 | |
129 | 140 | /* serial ports */ |
130 | 141 | ... | ... |
vl.c
... | ... | @@ -163,12 +163,10 @@ const char *bios_name = NULL; |
163 | 163 | void *ioport_opaque[MAX_IOPORTS]; |
164 | 164 | IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
165 | 165 | IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
166 | -/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available | |
166 | +/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available | |
167 | 167 | to store the VM snapshots */ |
168 | -BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD]; | |
169 | -BlockDriverState *pflash_table[MAX_PFLASH]; | |
170 | -BlockDriverState *sd_bdrv; | |
171 | -BlockDriverState *mtd_bdrv; | |
168 | +DriveInfo drives_table[MAX_DRIVES+1]; | |
169 | +int nb_drives; | |
172 | 170 | /* point to the block driver where the snapshots are managed */ |
173 | 171 | BlockDriverState *bs_snapshots; |
174 | 172 | int vga_ram_size; |
... | ... | @@ -232,6 +230,8 @@ int alt_grab = 0; |
232 | 230 | unsigned int nb_prom_envs = 0; |
233 | 231 | const char *prom_envs[MAX_PROM_ENVS]; |
234 | 232 | #endif |
233 | +int nb_drives_opt; | |
234 | +char drives_opt[MAX_DRIVES][1024]; | |
235 | 235 | |
236 | 236 | #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) |
237 | 237 | |
... | ... | @@ -1758,12 +1758,9 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) |
1758 | 1758 | case 's': |
1759 | 1759 | { |
1760 | 1760 | int i; |
1761 | - for (i = 0; i < MAX_DISKS; i++) { | |
1762 | - if (bs_table[i]) | |
1763 | - bdrv_commit(bs_table[i]); | |
1761 | + for (i = 0; i < nb_drives; i++) { | |
1762 | + bdrv_commit(drives_table[i].bdrv); | |
1764 | 1763 | } |
1765 | - if (mtd_bdrv) | |
1766 | - bdrv_commit(mtd_bdrv); | |
1767 | 1764 | } |
1768 | 1765 | break; |
1769 | 1766 | case 'b': |
... | ... | @@ -4554,38 +4551,51 @@ static int net_socket_mcast_init(VLANState *vlan, const char *host_str) |
4554 | 4551 | |
4555 | 4552 | } |
4556 | 4553 | |
4554 | +static const char *get_word(char *buf, int buf_size, const char *p) | |
4555 | +{ | |
4556 | + char *q; | |
4557 | + int substring; | |
4558 | + | |
4559 | + substring = 0; | |
4560 | + q = buf; | |
4561 | + while (*p != '\0') { | |
4562 | + if (*p == '\\') { | |
4563 | + p++; | |
4564 | + if (*p == '\0') | |
4565 | + break; | |
4566 | + } else if (*p == '\"') { | |
4567 | + substring = !substring; | |
4568 | + p++; | |
4569 | + continue; | |
4570 | + } else if (!substring && (*p == ',' || *p == '=')) | |
4571 | + break; | |
4572 | + if (q && (q - buf) < buf_size - 1) | |
4573 | + *q++ = *p; | |
4574 | + p++; | |
4575 | + } | |
4576 | + if (q) | |
4577 | + *q = '\0'; | |
4578 | + | |
4579 | + return p; | |
4580 | +} | |
4581 | + | |
4557 | 4582 | static int get_param_value(char *buf, int buf_size, |
4558 | 4583 | const char *tag, const char *str) |
4559 | 4584 | { |
4560 | 4585 | const char *p; |
4561 | - char *q; | |
4562 | 4586 | char option[128]; |
4563 | 4587 | |
4564 | 4588 | p = str; |
4565 | 4589 | for(;;) { |
4566 | - q = option; | |
4567 | - while (*p != '\0' && *p != '=') { | |
4568 | - if ((q - option) < sizeof(option) - 1) | |
4569 | - *q++ = *p; | |
4570 | - p++; | |
4571 | - } | |
4572 | - *q = '\0'; | |
4590 | + p = get_word(option, sizeof(option), p); | |
4573 | 4591 | if (*p != '=') |
4574 | 4592 | break; |
4575 | 4593 | p++; |
4576 | 4594 | if (!strcmp(tag, option)) { |
4577 | - q = buf; | |
4578 | - while (*p != '\0' && *p != ',') { | |
4579 | - if ((q - buf) < buf_size - 1) | |
4580 | - *q++ = *p; | |
4581 | - p++; | |
4582 | - } | |
4583 | - *q = '\0'; | |
4584 | - return q - buf; | |
4595 | + (void)get_word(buf, buf_size, p); | |
4596 | + return strlen(buf); | |
4585 | 4597 | } else { |
4586 | - while (*p != '\0' && *p != ',') { | |
4587 | - p++; | |
4588 | - } | |
4598 | + p = get_word(NULL, 0, p); | |
4589 | 4599 | } |
4590 | 4600 | if (*p != ',') |
4591 | 4601 | break; |
... | ... | @@ -4594,6 +4604,32 @@ static int get_param_value(char *buf, int buf_size, |
4594 | 4604 | return 0; |
4595 | 4605 | } |
4596 | 4606 | |
4607 | +static int check_params(char *buf, int buf_size, | |
4608 | + char **params, const char *str) | |
4609 | +{ | |
4610 | + const char *p; | |
4611 | + int i; | |
4612 | + | |
4613 | + p = str; | |
4614 | + for(;;) { | |
4615 | + p = get_word(buf, buf_size, p); | |
4616 | + if (*p != '=') | |
4617 | + return -1; | |
4618 | + p++; | |
4619 | + for(i = 0; params[i] != NULL; i++) | |
4620 | + if (!strcmp(params[i], buf)) | |
4621 | + break; | |
4622 | + if (params[i] == NULL) | |
4623 | + return -1; | |
4624 | + p = get_word(NULL, 0, p); | |
4625 | + if (*p != ',') | |
4626 | + break; | |
4627 | + p++; | |
4628 | + } | |
4629 | + return 0; | |
4630 | +} | |
4631 | + | |
4632 | + | |
4597 | 4633 | static int net_client_init(const char *str) |
4598 | 4634 | { |
4599 | 4635 | const char *p; |
... | ... | @@ -4744,6 +4780,323 @@ void do_info_network(void) |
4744 | 4780 | } |
4745 | 4781 | } |
4746 | 4782 | |
4783 | +#define HD_ALIAS "file=\"%s\",index=%d,media=disk" | |
4784 | +#ifdef TARGET_PPC | |
4785 | +#define CDROM_ALIAS "index=1,media=cdrom" | |
4786 | +#else | |
4787 | +#define CDROM_ALIAS "index=2,media=cdrom" | |
4788 | +#endif | |
4789 | +#define FD_ALIAS "index=%d,if=floppy" | |
4790 | +#define PFLASH_ALIAS "file=\"%s\",if=pflash" | |
4791 | +#define MTD_ALIAS "file=\"%s\",if=mtd" | |
4792 | +#define SD_ALIAS "file=\"%s\",if=sd" | |
4793 | + | |
4794 | +static int drive_add(const char *fmt, ...) | |
4795 | +{ | |
4796 | + va_list ap; | |
4797 | + | |
4798 | + if (nb_drives_opt >= MAX_DRIVES) { | |
4799 | + fprintf(stderr, "qemu: too many drives\n"); | |
4800 | + exit(1); | |
4801 | + } | |
4802 | + | |
4803 | + va_start(ap, fmt); | |
4804 | + vsnprintf(drives_opt[nb_drives_opt], sizeof(drives_opt[0]), fmt, ap); | |
4805 | + va_end(ap); | |
4806 | + | |
4807 | + return nb_drives_opt++; | |
4808 | +} | |
4809 | + | |
4810 | +int drive_get_index(BlockInterfaceType interface, int bus, int unit) | |
4811 | +{ | |
4812 | + int index; | |
4813 | + | |
4814 | + /* seek interface, bus and unit */ | |
4815 | + | |
4816 | + for (index = 0; index < nb_drives; index++) | |
4817 | + if (drives_table[index].interface == interface && | |
4818 | + drives_table[index].bus == bus && | |
4819 | + drives_table[index].unit == unit) | |
4820 | + return index; | |
4821 | + | |
4822 | + return -1; | |
4823 | +} | |
4824 | + | |
4825 | +int drive_get_max_bus(BlockInterfaceType interface) | |
4826 | +{ | |
4827 | + int max_bus; | |
4828 | + int index; | |
4829 | + | |
4830 | + max_bus = -1; | |
4831 | + for (index = 0; index < nb_drives; index++) { | |
4832 | + if(drives_table[index].interface == interface && | |
4833 | + drives_table[index].bus > max_bus) | |
4834 | + max_bus = drives_table[index].bus; | |
4835 | + } | |
4836 | + return max_bus; | |
4837 | +} | |
4838 | + | |
4839 | +static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | |
4840 | +{ | |
4841 | + char buf[128]; | |
4842 | + char file[1024]; | |
4843 | + BlockInterfaceType interface; | |
4844 | + enum { MEDIA_DISK, MEDIA_CDROM } media; | |
4845 | + int bus_id, unit_id; | |
4846 | + int cyls, heads, secs, translation; | |
4847 | + BlockDriverState *bdrv; | |
4848 | + int max_devs; | |
4849 | + int index; | |
4850 | + char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", | |
4851 | + "secs", "trans", "media", "snapshot", "file", NULL }; | |
4852 | + | |
4853 | + if (check_params(buf, sizeof(buf), params, str) < 0) { | |
4854 | + fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", | |
4855 | + buf, str); | |
4856 | + return -1; | |
4857 | + } | |
4858 | + | |
4859 | + file[0] = 0; | |
4860 | + cyls = heads = secs = 0; | |
4861 | + bus_id = 0; | |
4862 | + unit_id = -1; | |
4863 | + translation = BIOS_ATA_TRANSLATION_AUTO; | |
4864 | + index = -1; | |
4865 | + | |
4866 | + if (!strcmp(machine->name, "realview") || | |
4867 | + !strcmp(machine->name, "SS-5") || | |
4868 | + !strcmp(machine->name, "SS-10") || | |
4869 | + !strcmp(machine->name, "SS-600MP") || | |
4870 | + !strcmp(machine->name, "versatilepb") || | |
4871 | + !strcmp(machine->name, "versatileab")) { | |
4872 | + interface = IF_SCSI; | |
4873 | + max_devs = MAX_SCSI_DEVS; | |
4874 | + } else { | |
4875 | + interface = IF_IDE; | |
4876 | + max_devs = MAX_IDE_DEVS; | |
4877 | + } | |
4878 | + media = MEDIA_DISK; | |
4879 | + | |
4880 | + /* extract parameters */ | |
4881 | + | |
4882 | + if (get_param_value(buf, sizeof(buf), "bus", str)) { | |
4883 | + bus_id = strtol(buf, NULL, 0); | |
4884 | + if (bus_id < 0) { | |
4885 | + fprintf(stderr, "qemu: '%s' invalid bus id\n", str); | |
4886 | + return -1; | |
4887 | + } | |
4888 | + } | |
4889 | + | |
4890 | + if (get_param_value(buf, sizeof(buf), "unit", str)) { | |
4891 | + unit_id = strtol(buf, NULL, 0); | |
4892 | + if (unit_id < 0) { | |
4893 | + fprintf(stderr, "qemu: '%s' invalid unit id\n", str); | |
4894 | + return -1; | |
4895 | + } | |
4896 | + } | |
4897 | + | |
4898 | + if (get_param_value(buf, sizeof(buf), "if", str)) { | |
4899 | + if (!strcmp(buf, "ide")) { | |
4900 | + interface = IF_IDE; | |
4901 | + max_devs = MAX_IDE_DEVS; | |
4902 | + } else if (!strcmp(buf, "scsi")) { | |
4903 | + interface = IF_SCSI; | |
4904 | + max_devs = MAX_SCSI_DEVS; | |
4905 | + } else if (!strcmp(buf, "floppy")) { | |
4906 | + interface = IF_FLOPPY; | |
4907 | + max_devs = 0; | |
4908 | + } else if (!strcmp(buf, "pflash")) { | |
4909 | + interface = IF_PFLASH; | |
4910 | + max_devs = 0; | |
4911 | + } else if (!strcmp(buf, "mtd")) { | |
4912 | + interface = IF_MTD; | |
4913 | + max_devs = 0; | |
4914 | + } else if (!strcmp(buf, "sd")) { | |
4915 | + interface = IF_SD; | |
4916 | + max_devs = 0; | |
4917 | + } else { | |
4918 | + fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf); | |
4919 | + return -1; | |
4920 | + } | |
4921 | + } | |
4922 | + | |
4923 | + if (get_param_value(buf, sizeof(buf), "index", str)) { | |
4924 | + index = strtol(buf, NULL, 0); | |
4925 | + if (index < 0) { | |
4926 | + fprintf(stderr, "qemu: '%s' invalid index\n", str); | |
4927 | + return -1; | |
4928 | + } | |
4929 | + } | |
4930 | + | |
4931 | + if (get_param_value(buf, sizeof(buf), "cyls", str)) { | |
4932 | + cyls = strtol(buf, NULL, 0); | |
4933 | + } | |
4934 | + | |
4935 | + if (get_param_value(buf, sizeof(buf), "heads", str)) { | |
4936 | + heads = strtol(buf, NULL, 0); | |
4937 | + } | |
4938 | + | |
4939 | + if (get_param_value(buf, sizeof(buf), "secs", str)) { | |
4940 | + secs = strtol(buf, NULL, 0); | |
4941 | + } | |
4942 | + | |
4943 | + if (cyls || heads || secs) { | |
4944 | + if (cyls < 1 || cyls > 16383) { | |
4945 | + fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str); | |
4946 | + return -1; | |
4947 | + } | |
4948 | + if (heads < 1 || heads > 16) { | |
4949 | + fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str); | |
4950 | + return -1; | |
4951 | + } | |
4952 | + if (secs < 1 || secs > 63) { | |
4953 | + fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str); | |
4954 | + return -1; | |
4955 | + } | |
4956 | + } | |
4957 | + | |
4958 | + if (get_param_value(buf, sizeof(buf), "trans", str)) { | |
4959 | + if (!cyls) { | |
4960 | + fprintf(stderr, | |
4961 | + "qemu: '%s' trans must be used with cyls,heads and secs\n", | |
4962 | + str); | |
4963 | + return -1; | |
4964 | + } | |
4965 | + if (!strcmp(buf, "none")) | |
4966 | + translation = BIOS_ATA_TRANSLATION_NONE; | |
4967 | + else if (!strcmp(buf, "lba")) | |
4968 | + translation = BIOS_ATA_TRANSLATION_LBA; | |
4969 | + else if (!strcmp(buf, "auto")) | |
4970 | + translation = BIOS_ATA_TRANSLATION_AUTO; | |
4971 | + else { | |
4972 | + fprintf(stderr, "qemu: '%s' invalid translation type\n", str); | |
4973 | + return -1; | |
4974 | + } | |
4975 | + } | |
4976 | + | |
4977 | + if (get_param_value(buf, sizeof(buf), "media", str)) { | |
4978 | + if (!strcmp(buf, "disk")) { | |
4979 | + media = MEDIA_DISK; | |
4980 | + } else if (!strcmp(buf, "cdrom")) { | |
4981 | + if (cyls || secs || heads) { | |
4982 | + fprintf(stderr, | |
4983 | + "qemu: '%s' invalid physical CHS format\n", str); | |
4984 | + return -1; | |
4985 | + } | |
4986 | + media = MEDIA_CDROM; | |
4987 | + } else { | |
4988 | + fprintf(stderr, "qemu: '%s' invalid media\n", str); | |
4989 | + return -1; | |
4990 | + } | |
4991 | + } | |
4992 | + | |
4993 | + if (get_param_value(buf, sizeof(buf), "snapshot", str)) { | |
4994 | + if (!strcmp(buf, "on")) | |
4995 | + snapshot = 1; | |
4996 | + else if (!strcmp(buf, "off")) | |
4997 | + snapshot = 0; | |
4998 | + else { | |
4999 | + fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str); | |
5000 | + return -1; | |
5001 | + } | |
5002 | + } | |
5003 | + | |
5004 | + get_param_value(file, sizeof(file), "file", str); | |
5005 | + | |
5006 | + /* compute bus and unit according index */ | |
5007 | + | |
5008 | + if (index != -1) { | |
5009 | + if (bus_id != 0 || unit_id != -1) { | |
5010 | + fprintf(stderr, | |
5011 | + "qemu: '%s' index cannot be used with bus and unit\n", str); | |
5012 | + return -1; | |
5013 | + } | |
5014 | + if (max_devs == 0) | |
5015 | + { | |
5016 | + unit_id = index; | |
5017 | + bus_id = 0; | |
5018 | + } else { | |
5019 | + unit_id = index % max_devs; | |
5020 | + bus_id = index / max_devs; | |
5021 | + } | |
5022 | + } | |
5023 | + | |
5024 | + /* if user doesn't specify a unit_id, | |
5025 | + * try to find the first free | |
5026 | + */ | |
5027 | + | |
5028 | + if (unit_id == -1) { | |
5029 | + unit_id = 0; | |
5030 | + while (drive_get_index(interface, bus_id, unit_id) != -1) { | |
5031 | + unit_id++; | |
5032 | + if (max_devs && unit_id >= max_devs) { | |
5033 | + unit_id -= max_devs; | |
5034 | + bus_id++; | |
5035 | + } | |
5036 | + } | |
5037 | + } | |
5038 | + | |
5039 | + /* check unit id */ | |
5040 | + | |
5041 | + if (max_devs && unit_id >= max_devs) { | |
5042 | + fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n", | |
5043 | + str, unit_id, max_devs - 1); | |
5044 | + return -1; | |
5045 | + } | |
5046 | + | |
5047 | + /* | |
5048 | + * ignore multiple definitions | |
5049 | + */ | |
5050 | + | |
5051 | + if (drive_get_index(interface, bus_id, unit_id) != -1) | |
5052 | + return 0; | |
5053 | + | |
5054 | + /* init */ | |
5055 | + | |
5056 | + snprintf(buf, sizeof(buf), "drive%d", nb_drives); | |
5057 | + bdrv = bdrv_new(buf); | |
5058 | + drives_table[nb_drives].bdrv = bdrv; | |
5059 | + drives_table[nb_drives].interface = interface; | |
5060 | + drives_table[nb_drives].bus = bus_id; | |
5061 | + drives_table[nb_drives].unit = unit_id; | |
5062 | + nb_drives++; | |
5063 | + | |
5064 | + switch(interface) { | |
5065 | + case IF_IDE: | |
5066 | + case IF_SCSI: | |
5067 | + switch(media) { | |
5068 | + case MEDIA_DISK: | |
5069 | + if (cyls != 0) { | |
5070 | + bdrv_set_geometry_hint(bdrv, cyls, heads, secs); | |
5071 | + bdrv_set_translation_hint(bdrv, translation); | |
5072 | + } | |
5073 | + break; | |
5074 | + case MEDIA_CDROM: | |
5075 | + bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM); | |
5076 | + break; | |
5077 | + } | |
5078 | + break; | |
5079 | + case IF_SD: | |
5080 | + /* FIXME: This isn't really a floppy, but it's a reasonable | |
5081 | + approximation. */ | |
5082 | + case IF_FLOPPY: | |
5083 | + bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY); | |
5084 | + break; | |
5085 | + case IF_PFLASH: | |
5086 | + case IF_MTD: | |
5087 | + break; | |
5088 | + } | |
5089 | + if (!file[0]) | |
5090 | + return 0; | |
5091 | + if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || | |
5092 | + qemu_key_check(bdrv, file)) { | |
5093 | + fprintf(stderr, "qemu: could not open disk image %s\n", | |
5094 | + file); | |
5095 | + return -1; | |
5096 | + } | |
5097 | + return 0; | |
5098 | +} | |
5099 | + | |
4747 | 5100 | /***********************************************************/ |
4748 | 5101 | /* USB devices */ |
4749 | 5102 | |
... | ... | @@ -5526,8 +5879,8 @@ static BlockDriverState *get_bs_snapshots(void) |
5526 | 5879 | |
5527 | 5880 | if (bs_snapshots) |
5528 | 5881 | return bs_snapshots; |
5529 | - for(i = 0; i <= MAX_DISKS; i++) { | |
5530 | - bs = bs_table[i]; | |
5882 | + for(i = 0; i <= nb_drives; i++) { | |
5883 | + bs = drives_table[i].bdrv; | |
5531 | 5884 | if (bdrv_can_snapshot(bs)) |
5532 | 5885 | goto ok; |
5533 | 5886 | } |
... | ... | @@ -5635,8 +5988,8 @@ void do_savevm(const char *name) |
5635 | 5988 | |
5636 | 5989 | /* create the snapshots */ |
5637 | 5990 | |
5638 | - for(i = 0; i < MAX_DISKS; i++) { | |
5639 | - bs1 = bs_table[i]; | |
5991 | + for(i = 0; i < nb_drives; i++) { | |
5992 | + bs1 = drives_table[i].bdrv; | |
5640 | 5993 | if (bdrv_has_snapshot(bs1)) { |
5641 | 5994 | if (must_delete) { |
5642 | 5995 | ret = bdrv_snapshot_delete(bs1, old_sn->id_str); |
... | ... | @@ -5678,8 +6031,8 @@ void do_loadvm(const char *name) |
5678 | 6031 | saved_vm_running = vm_running; |
5679 | 6032 | vm_stop(0); |
5680 | 6033 | |
5681 | - for(i = 0; i <= MAX_DISKS; i++) { | |
5682 | - bs1 = bs_table[i]; | |
6034 | + for(i = 0; i <= nb_drives; i++) { | |
6035 | + bs1 = drives_table[i].bdrv; | |
5683 | 6036 | if (bdrv_has_snapshot(bs1)) { |
5684 | 6037 | ret = bdrv_snapshot_goto(bs1, name); |
5685 | 6038 | if (ret < 0) { |
... | ... | @@ -5739,8 +6092,8 @@ void do_delvm(const char *name) |
5739 | 6092 | return; |
5740 | 6093 | } |
5741 | 6094 | |
5742 | - for(i = 0; i <= MAX_DISKS; i++) { | |
5743 | - bs1 = bs_table[i]; | |
6095 | + for(i = 0; i <= nb_drives; i++) { | |
6096 | + bs1 = drives_table[i].bdrv; | |
5744 | 6097 | if (bdrv_has_snapshot(bs1)) { |
5745 | 6098 | ret = bdrv_snapshot_delete(bs1, name); |
5746 | 6099 | if (ret < 0) { |
... | ... | @@ -5768,8 +6121,8 @@ void do_info_snapshots(void) |
5768 | 6121 | return; |
5769 | 6122 | } |
5770 | 6123 | term_printf("Snapshot devices:"); |
5771 | - for(i = 0; i <= MAX_DISKS; i++) { | |
5772 | - bs1 = bs_table[i]; | |
6124 | + for(i = 0; i <= nb_drives; i++) { | |
6125 | + bs1 = drives_table[i].bdrv; | |
5773 | 6126 | if (bdrv_has_snapshot(bs1)) { |
5774 | 6127 | if (bs == bs1) |
5775 | 6128 | term_printf(" %s", bdrv_get_device_name(bs1)); |
... | ... | @@ -6519,15 +6872,14 @@ static void ram_save(QEMUFile *f, void *opaque) |
6519 | 6872 | /* find if the memory block is available on a virtual |
6520 | 6873 | block device */ |
6521 | 6874 | sector_num = -1; |
6522 | - for(j = 0; j < MAX_DISKS; j++) { | |
6523 | - if (bs_table[j]) { | |
6524 | - sector_num = bdrv_hash_find(bs_table[j], | |
6525 | - phys_ram_base + i, BDRV_HASH_BLOCK_SIZE); | |
6526 | - if (sector_num >= 0) | |
6527 | - break; | |
6528 | - } | |
6875 | + for(j = 0; j < nb_drives; j++) { | |
6876 | + sector_num = bdrv_hash_find(drives_table[j].bdrv, | |
6877 | + phys_ram_base + i, | |
6878 | + BDRV_HASH_BLOCK_SIZE); | |
6879 | + if (sector_num >= 0) | |
6880 | + break; | |
6529 | 6881 | } |
6530 | - if (j == MAX_DISKS) | |
6882 | + if (j == nb_drives) | |
6531 | 6883 | goto normal_compress; |
6532 | 6884 | buf[0] = 1; |
6533 | 6885 | buf[1] = j; |
... | ... | @@ -6578,11 +6930,12 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) |
6578 | 6930 | ram_decompress_buf(s, buf + 1, 9); |
6579 | 6931 | bs_index = buf[1]; |
6580 | 6932 | sector_num = be64_to_cpupu((const uint64_t *)(buf + 2)); |
6581 | - if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) { | |
6933 | + if (bs_index >= nb_drives) { | |
6582 | 6934 | fprintf(stderr, "Invalid block device index %d\n", bs_index); |
6583 | 6935 | goto error; |
6584 | 6936 | } |
6585 | - if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i, | |
6937 | + if (bdrv_read(drives_table[bs_index].bdrv, sector_num, | |
6938 | + phys_ram_base + i, | |
6586 | 6939 | BDRV_HASH_BLOCK_SIZE / 512) < 0) { |
6587 | 6940 | fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n", |
6588 | 6941 | bs_index, sector_num); |
... | ... | @@ -7079,6 +7432,9 @@ static void help(int exitcode) |
7079 | 7432 | "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" |
7080 | 7433 | "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" |
7081 | 7434 | "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" |
7435 | + "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" | |
7436 | + " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n" | |
7437 | + " use 'file' as a drive image\n" | |
7082 | 7438 | "-mtdblock file use 'file' as on-board Flash memory image\n" |
7083 | 7439 | "-sd file use 'file' as SecureDigital card image\n" |
7084 | 7440 | "-pflash file use 'file' as a parallel flash image\n" |
... | ... | @@ -7224,6 +7580,7 @@ enum { |
7224 | 7580 | QEMU_OPTION_hdb, |
7225 | 7581 | QEMU_OPTION_hdc, |
7226 | 7582 | QEMU_OPTION_hdd, |
7583 | + QEMU_OPTION_drive, | |
7227 | 7584 | QEMU_OPTION_cdrom, |
7228 | 7585 | QEMU_OPTION_mtdblock, |
7229 | 7586 | QEMU_OPTION_sd, |
... | ... | @@ -7313,6 +7670,7 @@ const QEMUOption qemu_options[] = { |
7313 | 7670 | { "hdb", HAS_ARG, QEMU_OPTION_hdb }, |
7314 | 7671 | { "hdc", HAS_ARG, QEMU_OPTION_hdc }, |
7315 | 7672 | { "hdd", HAS_ARG, QEMU_OPTION_hdd }, |
7673 | + { "drive", HAS_ARG, QEMU_OPTION_drive }, | |
7316 | 7674 | { "cdrom", HAS_ARG, QEMU_OPTION_cdrom }, |
7317 | 7675 | { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock }, |
7318 | 7676 | { "sd", HAS_ARG, QEMU_OPTION_sd }, |
... | ... | @@ -7425,16 +7783,9 @@ int qemu_key_check(BlockDriverState *bs, const char *name) |
7425 | 7783 | |
7426 | 7784 | static BlockDriverState *get_bdrv(int index) |
7427 | 7785 | { |
7428 | - BlockDriverState *bs; | |
7429 | - | |
7430 | - if (index < 4) { | |
7431 | - bs = bs_table[index]; | |
7432 | - } else if (index < 6) { | |
7433 | - bs = fd_table[index - 4]; | |
7434 | - } else { | |
7435 | - bs = NULL; | |
7436 | - } | |
7437 | - return bs; | |
7786 | + if (index > nb_drives) | |
7787 | + return NULL; | |
7788 | + return drives_table[index].bdrv; | |
7438 | 7789 | } |
7439 | 7790 | |
7440 | 7791 | static void read_passwords(void) |
... | ... | @@ -7637,19 +7988,16 @@ int main(int argc, char **argv) |
7637 | 7988 | const char *gdbstub_port; |
7638 | 7989 | #endif |
7639 | 7990 | uint32_t boot_devices_bitmap = 0; |
7640 | - int i, cdrom_index, pflash_index; | |
7991 | + int i; | |
7641 | 7992 | int snapshot, linux_boot, net_boot; |
7642 | 7993 | const char *initrd_filename; |
7643 | - const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; | |
7644 | - const char *pflash_filename[MAX_PFLASH]; | |
7645 | - const char *sd_filename; | |
7646 | - const char *mtd_filename; | |
7647 | 7994 | const char *kernel_filename, *kernel_cmdline; |
7648 | 7995 | const char *boot_devices = ""; |
7649 | 7996 | DisplayState *ds = &display_state; |
7650 | 7997 | int cyls, heads, secs, translation; |
7651 | 7998 | char net_clients[MAX_NET_CLIENTS][256]; |
7652 | 7999 | int nb_net_clients; |
8000 | + int hda_index; | |
7653 | 8001 | int optind; |
7654 | 8002 | const char *r, *optarg; |
7655 | 8003 | CharDriverState *monitor_hd; |
... | ... | @@ -7702,15 +8050,6 @@ int main(int argc, char **argv) |
7702 | 8050 | machine = first_machine; |
7703 | 8051 | cpu_model = NULL; |
7704 | 8052 | initrd_filename = NULL; |
7705 | - for(i = 0; i < MAX_FD; i++) | |
7706 | - fd_filename[i] = NULL; | |
7707 | - for(i = 0; i < MAX_DISKS; i++) | |
7708 | - hd_filename[i] = NULL; | |
7709 | - for(i = 0; i < MAX_PFLASH; i++) | |
7710 | - pflash_filename[i] = NULL; | |
7711 | - pflash_index = 0; | |
7712 | - sd_filename = NULL; | |
7713 | - mtd_filename = NULL; | |
7714 | 8053 | ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; |
7715 | 8054 | vga_ram_size = VGA_RAM_SIZE; |
7716 | 8055 | #ifdef CONFIG_GDBSTUB |
... | ... | @@ -7721,11 +8060,6 @@ int main(int argc, char **argv) |
7721 | 8060 | nographic = 0; |
7722 | 8061 | kernel_filename = NULL; |
7723 | 8062 | kernel_cmdline = ""; |
7724 | -#ifdef TARGET_PPC | |
7725 | - cdrom_index = 1; | |
7726 | -#else | |
7727 | - cdrom_index = 2; | |
7728 | -#endif | |
7729 | 8063 | cyls = heads = secs = 0; |
7730 | 8064 | translation = BIOS_ATA_TRANSLATION_AUTO; |
7731 | 8065 | pstrcpy(monitor_device, sizeof(monitor_device), "vc"); |
... | ... | @@ -7743,6 +8077,9 @@ int main(int argc, char **argv) |
7743 | 8077 | usb_devices_index = 0; |
7744 | 8078 | |
7745 | 8079 | nb_net_clients = 0; |
8080 | + nb_drives = 0; | |
8081 | + nb_drives_opt = 0; | |
8082 | + hda_index = -1; | |
7746 | 8083 | |
7747 | 8084 | nb_nics = 0; |
7748 | 8085 | /* default mac address of the first network interface */ |
... | ... | @@ -7753,7 +8090,7 @@ int main(int argc, char **argv) |
7753 | 8090 | break; |
7754 | 8091 | r = argv[optind]; |
7755 | 8092 | if (r[0] != '-') { |
7756 | - hd_filename[0] = argv[optind++]; | |
8093 | + hda_index = drive_add(HD_ALIAS, argv[optind++], 0); | |
7757 | 8094 | } else { |
7758 | 8095 | const QEMUOption *popt; |
7759 | 8096 | |
... | ... | @@ -7813,29 +8150,33 @@ int main(int argc, char **argv) |
7813 | 8150 | initrd_filename = optarg; |
7814 | 8151 | break; |
7815 | 8152 | case QEMU_OPTION_hda: |
8153 | + if (cyls == 0) | |
8154 | + hda_index = drive_add(HD_ALIAS, optarg, 0); | |
8155 | + else | |
8156 | + hda_index = drive_add(HD_ALIAS | |
8157 | + ",cyls=%d,heads=%d,secs=%d%s", | |
8158 | + optarg, 0, cyls, heads, secs, | |
8159 | + translation == BIOS_ATA_TRANSLATION_LBA ? | |
8160 | + ",trans=lba" : | |
8161 | + translation == BIOS_ATA_TRANSLATION_NONE ? | |
8162 | + ",trans=none" : ""); | |
8163 | + break; | |
7816 | 8164 | case QEMU_OPTION_hdb: |
7817 | 8165 | case QEMU_OPTION_hdc: |
7818 | 8166 | case QEMU_OPTION_hdd: |
7819 | - { | |
7820 | - int hd_index; | |
7821 | - hd_index = popt->index - QEMU_OPTION_hda; | |
7822 | - hd_filename[hd_index] = optarg; | |
7823 | - if (hd_index == cdrom_index) | |
7824 | - cdrom_index = -1; | |
7825 | - } | |
8167 | + drive_add(HD_ALIAS, optarg, popt->index - QEMU_OPTION_hda); | |
7826 | 8168 | break; |
8169 | + case QEMU_OPTION_drive: | |
8170 | + drive_add("%s", optarg); | |
8171 | + break; | |
7827 | 8172 | case QEMU_OPTION_mtdblock: |
7828 | - mtd_filename = optarg; | |
8173 | + drive_add(MTD_ALIAS, optarg); | |
7829 | 8174 | break; |
7830 | 8175 | case QEMU_OPTION_sd: |
7831 | - sd_filename = optarg; | |
8176 | + drive_add(SD_ALIAS, optarg); | |
7832 | 8177 | break; |
7833 | 8178 | case QEMU_OPTION_pflash: |
7834 | - if (pflash_index >= MAX_PFLASH) { | |
7835 | - fprintf(stderr, "qemu: too many parallel flash images\n"); | |
7836 | - exit(1); | |
7837 | - } | |
7838 | - pflash_filename[pflash_index++] = optarg; | |
8179 | + drive_add(PFLASH_ALIAS, optarg); | |
7839 | 8180 | break; |
7840 | 8181 | case QEMU_OPTION_snapshot: |
7841 | 8182 | snapshot = 1; |
... | ... | @@ -7874,6 +8215,17 @@ int main(int argc, char **argv) |
7874 | 8215 | fprintf(stderr, "qemu: invalid physical CHS format\n"); |
7875 | 8216 | exit(1); |
7876 | 8217 | } |
8218 | + if (hda_index != -1) | |
8219 | + snprintf(drives_opt[hda_index] + | |
8220 | + strlen(drives_opt[hda_index]), | |
8221 | + sizeof(drives_opt[0]) - | |
8222 | + strlen(drives_opt[hda_index]), | |
8223 | + ",cyls=%d,heads=%d,secs=%d%s", | |
8224 | + cyls, heads, secs, | |
8225 | + translation == BIOS_ATA_TRANSLATION_LBA ? | |
8226 | + ",trans=lba" : | |
8227 | + translation == BIOS_ATA_TRANSLATION_NONE ? | |
8228 | + ",trans=none" : ""); | |
7877 | 8229 | } |
7878 | 8230 | break; |
7879 | 8231 | case QEMU_OPTION_nographic: |
... | ... | @@ -7892,9 +8244,7 @@ int main(int argc, char **argv) |
7892 | 8244 | kernel_cmdline = optarg; |
7893 | 8245 | break; |
7894 | 8246 | case QEMU_OPTION_cdrom: |
7895 | - if (cdrom_index >= 0) { | |
7896 | - hd_filename[cdrom_index] = optarg; | |
7897 | - } | |
8247 | + drive_add("file=\"%s\"," CDROM_ALIAS, optarg); | |
7898 | 8248 | break; |
7899 | 8249 | case QEMU_OPTION_boot: |
7900 | 8250 | boot_devices = optarg; |
... | ... | @@ -7928,10 +8278,9 @@ int main(int argc, char **argv) |
7928 | 8278 | } |
7929 | 8279 | break; |
7930 | 8280 | case QEMU_OPTION_fda: |
7931 | - fd_filename[0] = optarg; | |
7932 | - break; | |
7933 | 8281 | case QEMU_OPTION_fdb: |
7934 | - fd_filename[1] = optarg; | |
8282 | + drive_add("file=\"%s\"," FD_ALIAS, optarg, | |
8283 | + popt->index - QEMU_OPTION_fda); | |
7935 | 8284 | break; |
7936 | 8285 | #ifdef TARGET_I386 |
7937 | 8286 | case QEMU_OPTION_no_fd_bootchk: |
... | ... | @@ -8312,20 +8661,12 @@ int main(int argc, char **argv) |
8312 | 8661 | |
8313 | 8662 | /* XXX: this should not be: some embedded targets just have flash */ |
8314 | 8663 | if (!linux_boot && net_boot == 0 && |
8315 | - hd_filename[0] == NULL && | |
8316 | - (cdrom_index >= 0 && hd_filename[cdrom_index] == NULL) && | |
8317 | - fd_filename[0] == NULL && | |
8318 | - pflash_filename[0] == NULL) | |
8664 | + nb_drives_opt == 0) | |
8319 | 8665 | help(1); |
8320 | 8666 | |
8321 | 8667 | /* boot to floppy or the default cd if no hard disk defined yet */ |
8322 | 8668 | if (!boot_devices[0]) { |
8323 | - if (hd_filename[0] != NULL) | |
8324 | - boot_devices = "c"; | |
8325 | - else if (fd_filename[0] != NULL) | |
8326 | - boot_devices = "a"; | |
8327 | - else | |
8328 | - boot_devices = "d"; | |
8669 | + boot_devices = "cad"; | |
8329 | 8670 | } |
8330 | 8671 | setvbuf(stdout, NULL, _IOLBF, 0); |
8331 | 8672 | |
... | ... | @@ -8402,97 +8743,23 @@ int main(int argc, char **argv) |
8402 | 8743 | exit(1); |
8403 | 8744 | } |
8404 | 8745 | |
8405 | - /* we always create the cdrom drive, even if no disk is there */ | |
8406 | 8746 | bdrv_init(); |
8407 | - if (cdrom_index >= 0) { | |
8408 | - bs_table[cdrom_index] = bdrv_new("cdrom"); | |
8409 | - bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM); | |
8410 | - } | |
8411 | 8747 | |
8412 | - /* open the virtual block devices */ | |
8413 | - for(i = 0; i < MAX_DISKS; i++) { | |
8414 | - if (hd_filename[i]) { | |
8415 | - if (!bs_table[i]) { | |
8416 | - char buf[64]; | |
8417 | - snprintf(buf, sizeof(buf), "hd%c", i + 'a'); | |
8418 | - bs_table[i] = bdrv_new(buf); | |
8419 | - } | |
8420 | - if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { | |
8421 | - fprintf(stderr, "qemu: could not open hard disk image '%s'\n", | |
8422 | - hd_filename[i]); | |
8423 | - exit(1); | |
8424 | - } | |
8425 | - if (i == 0 && cyls != 0) { | |
8426 | - bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs); | |
8427 | - bdrv_set_translation_hint(bs_table[i], translation); | |
8428 | - } | |
8429 | - } | |
8430 | - } | |
8748 | + /* we always create the cdrom drive, even if no disk is there */ | |
8431 | 8749 | |
8432 | - /* we always create at least one floppy disk */ | |
8433 | - fd_table[0] = bdrv_new("fda"); | |
8434 | - bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY); | |
8750 | + if (nb_drives_opt < MAX_DRIVES) | |
8751 | + drive_add(CDROM_ALIAS); | |
8435 | 8752 | |
8436 | - for(i = 0; i < MAX_FD; i++) { | |
8437 | - if (fd_filename[i]) { | |
8438 | - if (!fd_table[i]) { | |
8439 | - char buf[64]; | |
8440 | - snprintf(buf, sizeof(buf), "fd%c", i + 'a'); | |
8441 | - fd_table[i] = bdrv_new(buf); | |
8442 | - bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY); | |
8443 | - } | |
8444 | - if (fd_filename[i][0] != '\0') { | |
8445 | - if (bdrv_open(fd_table[i], fd_filename[i], | |
8446 | - snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { | |
8447 | - fprintf(stderr, "qemu: could not open floppy disk image '%s'\n", | |
8448 | - fd_filename[i]); | |
8449 | - exit(1); | |
8450 | - } | |
8451 | - } | |
8452 | - } | |
8453 | - } | |
8753 | + /* we always create at least on floppy */ | |
8454 | 8754 | |
8455 | - /* Open the virtual parallel flash block devices */ | |
8456 | - for(i = 0; i < MAX_PFLASH; i++) { | |
8457 | - if (pflash_filename[i]) { | |
8458 | - if (!pflash_table[i]) { | |
8459 | - char buf[64]; | |
8460 | - snprintf(buf, sizeof(buf), "fl%c", i + 'a'); | |
8461 | - pflash_table[i] = bdrv_new(buf); | |
8462 | - } | |
8463 | - if (bdrv_open(pflash_table[i], pflash_filename[i], | |
8464 | - snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { | |
8465 | - fprintf(stderr, "qemu: could not open flash image '%s'\n", | |
8466 | - pflash_filename[i]); | |
8467 | - exit(1); | |
8468 | - } | |
8469 | - } | |
8470 | - } | |
8755 | + if (nb_drives_opt < MAX_DRIVES) | |
8756 | + drive_add(FD_ALIAS, 0); | |
8471 | 8757 | |
8472 | - sd_bdrv = bdrv_new ("sd"); | |
8473 | - /* FIXME: This isn't really a floppy, but it's a reasonable | |
8474 | - approximation. */ | |
8475 | - bdrv_set_type_hint(sd_bdrv, BDRV_TYPE_FLOPPY); | |
8476 | - if (sd_filename) { | |
8477 | - if (bdrv_open(sd_bdrv, sd_filename, | |
8478 | - snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { | |
8479 | - fprintf(stderr, "qemu: could not open SD card image %s\n", | |
8480 | - sd_filename); | |
8481 | - } else | |
8482 | - qemu_key_check(sd_bdrv, sd_filename); | |
8483 | - } | |
8484 | - | |
8485 | - if (mtd_filename) { | |
8486 | - mtd_bdrv = bdrv_new ("mtd"); | |
8487 | - if (bdrv_open(mtd_bdrv, mtd_filename, | |
8488 | - snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || | |
8489 | - qemu_key_check(mtd_bdrv, mtd_filename)) { | |
8490 | - fprintf(stderr, "qemu: could not open Flash image %s\n", | |
8491 | - mtd_filename); | |
8492 | - bdrv_delete(mtd_bdrv); | |
8493 | - mtd_bdrv = 0; | |
8494 | - } | |
8495 | - } | |
8758 | + /* open the virtual block devices */ | |
8759 | + | |
8760 | + for(i = 0; i < nb_drives_opt; i++) | |
8761 | + if (drive_init(drives_opt[i], snapshot, machine) == -1) | |
8762 | + exit(1); | |
8496 | 8763 | |
8497 | 8764 | register_savevm("timer", 0, 2, timer_save, timer_load, NULL); |
8498 | 8765 | register_savevm("ram", 0, 2, ram_save, ram_load, NULL); | ... | ... |