Commit 406c8df3a96414c2c9602081727f0782369de699

Authored by Glauber Costa
Committed by Anthony Liguori
1 parent 4a244704

Make nic option rom loading less painful.

The code how it is today, is totally painful to read and keep.
To begin with, the code is duplicated with the option rom loading
code that linux_boot and vga are already using.

This patch introduces a "bootable" state in NICInfo structure,
that we can use to keep track of whether or not a given nic should
be bootable, avoiding the introduction of yet another global state.

With that in hands, we move the code in vl.c to hw/pc.c, and use
the already existing infra structure to load those option roms.

Error checking code suggested by Mark McLoughlin

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 4 changed files with 43 additions and 37 deletions
... ... @@ -977,8 +977,23 @@ static void pc_init1(ram_addr_t ram_size,
977 977 }
978 978  
979 979 for (i = 0; i < nb_option_roms; i++) {
980   - oprom_area_size += load_option_rom(option_rom[i],
981   - 0xc0000 + oprom_area_size, 0xe0000);
  980 + oprom_area_size += load_option_rom(option_rom[i], 0xc0000 + oprom_area_size,
  981 + 0xe0000);
  982 + }
  983 +
  984 + for (i = 0; i < nb_nics; i++) {
  985 + char nic_oprom[1024];
  986 + const char *model = nd_table[i].model;
  987 +
  988 + if (!nd_table[i].bootable)
  989 + continue;
  990 +
  991 + if (model == NULL)
  992 + model = "ne2k_pci";
  993 + snprintf(nic_oprom, sizeof(nic_oprom), "pxe-%s.bin", model);
  994 +
  995 + oprom_area_size += load_option_rom(nic_oprom, 0xc0000 + oprom_area_size,
  996 + 0xe0000);
982 997 }
983 998  
984 999 /* map all the bios at the top of memory */
... ...
... ... @@ -2457,6 +2457,26 @@ int net_client_parse(const char *str)
2457 2457 return net_client_init(NULL, device, p);
2458 2458 }
2459 2459  
  2460 +void net_set_boot_mask(int net_boot_mask)
  2461 +{
  2462 + int i;
  2463 +
  2464 + /* Only the first four NICs may be bootable */
  2465 + net_boot_mask = net_boot_mask & 0xF;
  2466 +
  2467 + for (i = 0; i < nb_nics; i++) {
  2468 + if (net_boot_mask & (1 << i)) {
  2469 + nd_table[i].bootable = 1;
  2470 + net_boot_mask &= ~(1 << i);
  2471 + }
  2472 + }
  2473 +
  2474 + if (net_boot_mask) {
  2475 + fprintf(stderr, "Cannot boot from non-existent NIC\n");
  2476 + exit(1);
  2477 + }
  2478 +}
  2479 +
2460 2480 void do_info_network(Monitor *mon)
2461 2481 {
2462 2482 VLANState *vlan;
... ...
... ... @@ -91,6 +91,7 @@ struct NICInfo {
91 91 VLANState *vlan;
92 92 void *private;
93 93 int used;
  94 + int bootable;
94 95 };
95 96  
96 97 extern int nb_nics;
... ... @@ -126,6 +127,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
126 127 void net_cleanup(void);
127 128 int slirp_is_inited(void);
128 129 void net_client_check(void);
  130 +void net_set_boot_mask(int boot_mask);
129 131 void net_host_device_add(Monitor *mon, const char *device, const char *opts);
130 132 void net_host_device_remove(Monitor *mon, int vlan_id, const char *device);
131 133  
... ...
... ... @@ -5801,7 +5801,6 @@ int main(int argc, char **argv, char **envp)
5801 5801 exit(1);
5802 5802 }
5803 5803 linux_boot = (kernel_filename != NULL);
5804   - net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
5805 5804  
5806 5805 if (!linux_boot && *kernel_cmdline != '\0') {
5807 5806 fprintf(stderr, "-append only allowed with -kernel option\n");
... ... @@ -5849,41 +5848,11 @@ int main(int argc, char **argv, char **envp)
5849 5848 if (net_client_parse(net_clients[i]) < 0)
5850 5849 exit(1);
5851 5850 }
5852   - net_client_check();
5853 5851  
5854   -#ifdef TARGET_I386
5855   - /* XXX: this should be moved in the PC machine instantiation code */
5856   - if (net_boot != 0) {
5857   - int netroms = 0;
5858   - for (i = 0; i < nb_nics && i < 4; i++) {
5859   - const char *model = nd_table[i].model;
5860   - char buf[1024];
5861   - char *filename;
5862   - if (net_boot & (1 << i)) {
5863   - if (model == NULL)
5864   - model = "ne2k_pci";
5865   - snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
5866   - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
5867   - if (filename && get_image_size(filename) > 0) {
5868   - if (nb_option_roms >= MAX_OPTION_ROMS) {
5869   - fprintf(stderr, "Too many option ROMs\n");
5870   - exit(1);
5871   - }
5872   - option_rom[nb_option_roms] = qemu_strdup(buf);
5873   - nb_option_roms++;
5874   - netroms++;
5875   - }
5876   - if (filename) {
5877   - qemu_free(filename);
5878   - }
5879   - }
5880   - }
5881   - if (netroms == 0) {
5882   - fprintf(stderr, "No valid PXE rom found for network device\n");
5883   - exit(1);
5884   - }
5885   - }
5886   -#endif
  5852 + net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
  5853 + net_set_boot_mask(net_boot);
  5854 +
  5855 + net_client_check();
5887 5856  
5888 5857 /* init the bluetooth world */
5889 5858 for (i = 0; i < nb_bt_opts; i++)
... ...