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); | ... | ... |