Commit 28c5af54c661e73e5596918fa67a22b5e87c2022

Authored by j_mayer
1 parent aba9ee87

More generic boot devices specification, allowing more devices to be specified

and avoiding per-target hardcoded limitations.
The machine implementations can then check if the given devices match the
actual hardware implementation and firmware API.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3577 c046a42c-6fe2-441c-8c8c-71466251a162
... ... @@ -173,6 +173,7 @@ static int boot_device2nibble(char boot_device)
173 173 static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **hd_table)
174 174 {
175 175 RTCState *s = rtc_state;
  176 + int nbds, bds[3] = { 0, };
176 177 int val;
177 178 int fd0, fd1, nb;
178 179 int i;
... ... @@ -202,11 +203,22 @@ static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **
202 203 rtc_set_memory(s, 0x35, val >> 8);
203 204  
204 205 /* set boot devices, and disable floppy signature check if requested */
205   - rtc_set_memory(s, 0x3d,
206   - boot_device2nibble(boot_device[1]) << 4 |
207   - boot_device2nibble(boot_device[0]) );
208   - rtc_set_memory(s, 0x38,
209   - boot_device2nibble(boot_device[2]) << 4 | (fd_bootchk ? 0x0 : 0x1));
  206 +#define PC_MAX_BOOT_DEVICES 3
  207 + nbds = strlen(boot_device);
  208 + if (nbds > PC_MAX_BOOT_DEVICES) {
  209 + fprintf(stderr, "Too many boot devices for PC\n");
  210 + exit(1);
  211 + }
  212 + for (i = 0; i < nbds; i++) {
  213 + bds[i] = boot_device2nibble(boot_device[i]);
  214 + if (bds[i] == 0) {
  215 + fprintf(stderr, "Invalid boot device for PC: '%c'\n",
  216 + boot_device[i]);
  217 + exit(1);
  218 + }
  219 + }
  220 + rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
  221 + rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
210 222  
211 223 /* floppy type */
212 224  
... ...
hw/ppc_chrp.c
... ... @@ -74,7 +74,7 @@ static void ppc_core99_init (int ram_size, int vga_ram_size,
74 74 qemu_irq *dummy_irq;
75 75 int pic_mem_index, dbdma_mem_index, cuda_mem_index;
76 76 int ide_mem_index[2];
77   - int ppc_boot_device = boot_device[0];
  77 + int ppc_boot_device;
78 78  
79 79 linux_boot = (kernel_filename != NULL);
80 80  
... ... @@ -175,6 +175,19 @@ static void ppc_core99_init (int ram_size, int vga_ram_size,
175 175 kernel_size = 0;
176 176 initrd_base = 0;
177 177 initrd_size = 0;
  178 + ppc_boot_device = '\0';
  179 + /* We consider that NewWorld PowerMac never have any floppy drive
  180 + * For now, OHW cannot boot from the network.
  181 + */
  182 + for (i = 0; i < boot_device[i] != '\0'; i++) {
  183 + ppc_boot_device = boot_device[i];
  184 + if (ppc_boot_device >= 'c' && ppc_boot_device <= 'f')
  185 + break;
  186 + }
  187 + if (ppc_boot_device == '\0') {
  188 + fprintf(stderr, "No valid boot device for Mac99 machine\n");
  189 + exit(1);
  190 + }
178 191 }
179 192  
180 193 isa_mem_base = 0x80000000;
... ...
hw/ppc_oldworld.c
... ... @@ -113,7 +113,7 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size,
113 113 int vga_bios_size, bios_size;
114 114 qemu_irq *dummy_irq;
115 115 int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
116   - int ppc_boot_device = boot_device[0];
  116 + int ppc_boot_device;
117 117  
118 118 linux_boot = (kernel_filename != NULL);
119 119  
... ... @@ -212,6 +212,25 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size,
212 212 kernel_size = 0;
213 213 initrd_base = 0;
214 214 initrd_size = 0;
  215 + ppc_boot_device = '\0';
  216 + for (i = 0; i < boot_device[i] != '\0'; i++) {
  217 + ppc_boot_device = boot_device[i];
  218 + /* TOFIX: for now, the second IDE channel is not properly
  219 + * emulated. The Mac floppy disk are not emulated.
  220 + * For now, OHW cannot boot from the network.
  221 + */
  222 +#if 0
  223 + if (ppc_boot_device >= 'a' && ppc_boot_device <= 'f')
  224 + break;
  225 +#else
  226 + if (ppc_boot_device >= 'c' && ppc_boot_device <= 'd')
  227 + break;
  228 +#endif
  229 + }
  230 + if (ppc_boot_device == '\0') {
  231 + fprintf(stderr, "No valid boot device for Mac99 machine\n");
  232 + exit(1);
  233 + }
215 234 }
216 235  
217 236 isa_mem_base = 0x80000000;
... ... @@ -272,7 +291,7 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size,
272 291 pmac_format_nvram_partition(nvr, 0x2000);
273 292  
274 293 dbdma_init(&dbdma_mem_index);
275   -
  294 +
276 295 macio_init(pci_bus, 0x0017, 1, pic_mem_index, dbdma_mem_index,
277 296 cuda_mem_index, nvr, 0, NULL);
278 297  
... ...
hw/ppc_prep.c
... ... @@ -521,7 +521,8 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = {
521 521 #define NVRAM_SIZE 0x2000
522 522  
523 523 /* PowerPC PREP hardware initialisation */
524   -static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_device,
  524 +static void ppc_prep_init (int ram_size, int vga_ram_size,
  525 + const char *boot_device,
525 526 DisplayState *ds, const char **fd_filename,
526 527 int snapshot, const char *kernel_filename,
527 528 const char *kernel_cmdline,
... ... @@ -538,7 +539,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
538 539 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
539 540 PCIBus *pci_bus;
540 541 qemu_irq *i8259;
541   - int ppc_boot_device = boot_device[0];
  542 + int ppc_boot_device;
542 543  
543 544 sysctrl = qemu_mallocz(sizeof(sysctrl_t));
544 545 if (sysctrl == NULL)
... ... @@ -611,6 +612,17 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, const char *boot_devi
611 612 kernel_size = 0;
612 613 initrd_base = 0;
613 614 initrd_size = 0;
  615 + ppc_boot_device = '\0';
  616 + /* For now, OHW cannot boot from the network. */
  617 + for (i = 0; i < boot_device[i] != '\0'; i++) {
  618 + ppc_boot_device = boot_device[i];
  619 + if (ppc_boot_device >= 'a' && ppc_boot_device <= 'f')
  620 + break;
  621 + }
  622 + if (ppc_boot_device == '\0') {
  623 + fprintf(stderr, "No valid boot device for Mac99 machine\n");
  624 + exit(1);
  625 + }
614 626 }
615 627  
616 628 isa_mem_base = 0xc0000000;
... ...
... ... @@ -162,12 +162,6 @@ static DisplayState display_state;
162 162 int nographic;
163 163 const char* keyboard_layout = NULL;
164 164 int64_t ticks_per_sec;
165   -#if defined(TARGET_I386)
166   -#define MAX_BOOT_DEVICES 3
167   -#else
168   -#define MAX_BOOT_DEVICES 1
169   -#endif
170   -static char boot_device[MAX_BOOT_DEVICES + 1];
171 165 int ram_size;
172 166 int pit_min_timer_count = 0;
173 167 int nb_nics;
... ... @@ -7587,14 +7581,16 @@ int main(int argc, char **argv)
7587 7581 int use_gdbstub;
7588 7582 const char *gdbstub_port;
7589 7583 #endif
  7584 + uint32_t boot_devices_bitmap = 0;
7590 7585 int i, cdrom_index, pflash_index;
7591   - int snapshot, linux_boot;
  7586 + int snapshot, linux_boot, net_boot;
7592 7587 const char *initrd_filename;
7593 7588 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
7594 7589 const char *pflash_filename[MAX_PFLASH];
7595 7590 const char *sd_filename;
7596 7591 const char *mtd_filename;
7597 7592 const char *kernel_filename, *kernel_cmdline;
  7593 + const char *boot_devices = "";
7598 7594 DisplayState *ds = &display_state;
7599 7595 int cyls, heads, secs, translation;
7600 7596 char net_clients[MAX_NET_CLIENTS][256];
... ... @@ -7846,20 +7842,34 @@ int main(int argc, char **argv)
7846 7842 }
7847 7843 break;
7848 7844 case QEMU_OPTION_boot:
7849   - if (strlen(optarg) > MAX_BOOT_DEVICES) {
7850   - fprintf(stderr, "qemu: too many boot devices\n");
7851   - exit(1);
7852   - }
7853   - strncpy(boot_device, optarg, MAX_BOOT_DEVICES);
7854   -#if defined(TARGET_SPARC) || defined(TARGET_I386)
7855   -#define BOOTCHARS "acdn"
7856   -#else
7857   -#define BOOTCHARS "acd"
7858   -#endif
7859   - if (strlen(boot_device) != strspn(boot_device, BOOTCHARS)) {
7860   - fprintf(stderr, "qemu: invalid boot device "
7861   - "sequence '%s'\n", boot_device);
7862   - exit(1);
  7845 + boot_devices = optarg;
  7846 + /* We just do some generic consistency checks */
  7847 + {
  7848 + /* Could easily be extended to 64 devices if needed */
  7849 + const unsigned char *p;
  7850 +
  7851 + boot_devices_bitmap = 0;
  7852 + for (p = boot_devices; *p != '\0'; p++) {
  7853 + /* Allowed boot devices are:
  7854 + * a b : floppy disk drives
  7855 + * c ... f : IDE disk drives
  7856 + * g ... m : machine implementation dependant drives
  7857 + * n ... p : network devices
  7858 + * It's up to each machine implementation to check
  7859 + * if the given boot devices match the actual hardware
  7860 + * implementation and firmware features.
  7861 + */
  7862 + if (*p < 'a' || *p > 'q') {
  7863 + fprintf(stderr, "Invalid boot device '%c'\n", *p);
  7864 + exit(1);
  7865 + }
  7866 + if (boot_devices_bitmap & (1 << (*p - 'a'))) {
  7867 + fprintf(stderr,
  7868 + "Boot device '%c' was given twice\n",*p);
  7869 + exit(1);
  7870 + }
  7871 + boot_devices_bitmap |= 1 << (*p - 'a');
  7872 + }
7863 7873 }
7864 7874 break;
7865 7875 case QEMU_OPTION_fda:
... ... @@ -8243,23 +8253,23 @@ int main(int argc, char **argv)
8243 8253 kqemu_allowed = 0;
8244 8254 #endif
8245 8255 linux_boot = (kernel_filename != NULL);
8246   -
8247   - if (!linux_boot &&
8248   - (!strchr(boot_device, 'n')) &&
  8256 + net_boot = (boot_devices_bitmap >> ('n' - 'a')) && 0xF;
  8257 +
  8258 + /* XXX: this should not be: some embedded targets just have flash */
  8259 + if (!linux_boot && net_boot == 0 &&
8249 8260 hd_filename[0] == '\0' &&
8250 8261 (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
8251 8262 fd_filename[0] == '\0')
8252 8263 help(1);
8253 8264  
8254 8265 /* boot to floppy or the default cd if no hard disk defined yet */
8255   - if (!boot_device[0]) {
  8266 + if (!boot_devices[0]) {
8256 8267 if (hd_filename[0] != '\0')
8257   - boot_device[0] = 'c';
  8268 + boot_devices = "c";
8258 8269 else if (fd_filename[0] != '\0')
8259   - boot_device[0] = 'a';
  8270 + boot_devices = "a";
8260 8271 else
8261   - boot_device[0] = 'd';
8262   - boot_device[1] = 0;
  8272 + boot_devices = "d";
8263 8273 }
8264 8274 setvbuf(stdout, NULL, _IOLBF, 0);
8265 8275  
... ... @@ -8299,20 +8309,28 @@ int main(int argc, char **argv)
8299 8309 }
8300 8310  
8301 8311 #ifdef TARGET_I386
8302   - if (strchr(boot_device, 'n')) {
8303   - for (i = 0; i < nb_nics; i++) {
  8312 + /* XXX: this should be moved in the PC machine instanciation code */
  8313 + if (net_boot != 0) {
  8314 + int netroms = 0;
  8315 + for (i = 0; i < nb_nics && i < 4; i++) {
8304 8316 const char *model = nd_table[i].model;
8305 8317 char buf[1024];
8306   - if (model == NULL)
8307   - model = "ne2k_pci";
8308   - snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8309   - if (get_image_size(buf) > 0) {
8310   - option_rom[nb_option_roms] = strdup(buf);
8311   - nb_option_roms++;
8312   - break;
8313   - }
  8318 + if (net_boot & (1 << i)) {
  8319 + if (model == NULL)
  8320 + model = "ne2k_pci";
  8321 + snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
  8322 + if (get_image_size(buf) > 0) {
  8323 + if (nb_option_roms >= MAX_OPTION_ROMS) {
  8324 + fprintf(stderr, "Too many option ROMs\n");
  8325 + exit(1);
  8326 + }
  8327 + option_rom[nb_option_roms] = strdup(buf);
  8328 + nb_option_roms++;
  8329 + netroms++;
  8330 + }
  8331 + }
8314 8332 }
8315   - if (i == nb_nics) {
  8333 + if (netroms == 0) {
8316 8334 fprintf(stderr, "No valid PXE rom found for network device\n");
8317 8335 exit(1);
8318 8336 }
... ... @@ -8492,7 +8510,7 @@ int main(int argc, char **argv)
8492 8510 }
8493 8511 }
8494 8512  
8495   - machine->init(ram_size, vga_ram_size, boot_device,
  8513 + machine->init(ram_size, vga_ram_size, boot_devices,
8496 8514 ds, fd_filename, snapshot,
8497 8515 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
8498 8516  
... ...