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,8 +977,23 @@ static void pc_init1(ram_addr_t ram_size,
977 } 977 }
978 978
979 for (i = 0; i < nb_option_roms; i++) { 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 /* map all the bios at the top of memory */ 999 /* map all the bios at the top of memory */
@@ -2457,6 +2457,26 @@ int net_client_parse(const char *str) @@ -2457,6 +2457,26 @@ int net_client_parse(const char *str)
2457 return net_client_init(NULL, device, p); 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 void do_info_network(Monitor *mon) 2480 void do_info_network(Monitor *mon)
2461 { 2481 {
2462 VLANState *vlan; 2482 VLANState *vlan;
@@ -91,6 +91,7 @@ struct NICInfo { @@ -91,6 +91,7 @@ struct NICInfo {
91 VLANState *vlan; 91 VLANState *vlan;
92 void *private; 92 void *private;
93 int used; 93 int used;
  94 + int bootable;
94 }; 95 };
95 96
96 extern int nb_nics; 97 extern int nb_nics;
@@ -126,6 +127,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -126,6 +127,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
126 void net_cleanup(void); 127 void net_cleanup(void);
127 int slirp_is_inited(void); 128 int slirp_is_inited(void);
128 void net_client_check(void); 129 void net_client_check(void);
  130 +void net_set_boot_mask(int boot_mask);
129 void net_host_device_add(Monitor *mon, const char *device, const char *opts); 131 void net_host_device_add(Monitor *mon, const char *device, const char *opts);
130 void net_host_device_remove(Monitor *mon, int vlan_id, const char *device); 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,7 +5801,6 @@ int main(int argc, char **argv, char **envp)
5801 exit(1); 5801 exit(1);
5802 } 5802 }
5803 linux_boot = (kernel_filename != NULL); 5803 linux_boot = (kernel_filename != NULL);
5804 - net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;  
5805 5804
5806 if (!linux_boot && *kernel_cmdline != '\0') { 5805 if (!linux_boot && *kernel_cmdline != '\0') {
5807 fprintf(stderr, "-append only allowed with -kernel option\n"); 5806 fprintf(stderr, "-append only allowed with -kernel option\n");
@@ -5849,41 +5848,11 @@ int main(int argc, char **argv, char **envp) @@ -5849,41 +5848,11 @@ int main(int argc, char **argv, char **envp)
5849 if (net_client_parse(net_clients[i]) < 0) 5848 if (net_client_parse(net_clients[i]) < 0)
5850 exit(1); 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 /* init the bluetooth world */ 5857 /* init the bluetooth world */
5889 for (i = 0; i < nb_bt_opts; i++) 5858 for (i = 0; i < nb_bt_opts; i++)