Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Factoring of BIOS setup so that it can be reused during reset
[palacios.git] / palacios / src / palacios / vmm_bios.c
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2015, The V3VEE Project <http://www.v3vee.org> 
11  * All rights reserved.
12  *
13  * Author: Peter Dinda <pdinda@northwestern.edu>
14  *
15  * This is free software.  You are permitted to use,
16  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
17  */
18
19 #include <palacios/vmm_bios.h>
20 #include <palacios/vm_guest_mem.h>
21 #include <palacios/vmm_xml.h>
22
23
24
25 int v3_setup_bioses(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 
26 {
27
28     v3_cfg_tree_t * bios_tree = NULL;
29     v3_cfg_tree_t * bios_list = NULL;
30     
31     bios_tree = v3_cfg_subtree(cfg, "bioses");
32     
33     
34     if (!v3_cfg_val(bios_tree, "disable_vgabios")) {
35         
36 #if defined(V3_CONFIG_SEABIOS) || defined(V3_CONFIG_BOCHSBIOS)
37
38 #define VGABIOS_START 0x000c0000
39         /* layout vgabios */
40         {
41             extern uint8_t v3_vgabios_start[];
42             extern uint8_t v3_vgabios_end[];
43             void * vgabios_dst = 0;
44
45             if (v3_gpa_to_hva(&(vm->cores[0]), VGABIOS_START, (addr_t *)&vgabios_dst) == -1) {
46                 PrintError(vm, VCORE_NONE, "Could not find VGABIOS destination address\n");
47                 return -1;
48             }
49
50             V3_Print(vm,VCORE_NONE,"Mapping VGA BIOS of %llu bytes at gpa %p (hva %p)\n", (uint64_t)(v3_vgabios_end-v3_vgabios_start), (void*)VGABIOS_START,vgabios_dst);
51             memcpy(vgabios_dst, v3_vgabios_start, v3_vgabios_end - v3_vgabios_start);   
52         }
53
54 #endif
55
56     }
57
58
59     if (!v3_cfg_val(bios_tree, "disable_rombios")) {
60
61         /* layout rombios */
62         {
63             extern uint8_t v3_rombios_start[];
64             extern uint8_t v3_rombios_end[];
65             void * rombios_dst = 0;
66
67
68
69             if (v3_gpa_to_hva(&(vm->cores[0]), V3_CONFIG_BIOS_START, (addr_t *)&rombios_dst) == -1) {
70                 PrintError(vm, VCORE_NONE, "Could not find ROMBIOS destination address\n");
71                 return -1;
72             }
73
74             V3_Print(vm,VCORE_NONE,"Mapping BIOS of %llu bytes at gpa %p (hva %p)\n", (uint64_t)(v3_rombios_end-v3_rombios_start), (void*)V3_CONFIG_BIOS_START,rombios_dst);
75             memcpy(rombios_dst, v3_rombios_start, v3_rombios_end - v3_rombios_start);
76
77 #ifdef V3_CONFIG_SEABIOS
78             
79 #define SEABIOS_HIGH_START 0xfffe0000
80 #define SEABIOS_HIGH_END   0xffffffff
81
82             if (v3_get_mem_region(vm,V3_MEM_CORE_ANY, SEABIOS_HIGH_START)) {
83                 // it is already mapped, we are done
84                 // note it's mapped to the same place as the low memory copy
85                 // so it's now pointing to the fresh copy
86                 V3_Print(vm,VCORE_NONE,"BIOS is already mapped\n");
87             } else {
88                 if (v3_add_shadow_mem(vm, V3_MEM_CORE_ANY, 
89                                       SEABIOS_HIGH_START, SEABIOS_HIGH_END,
90                                       (addr_t)V3_PAddr(rombios_dst)) == -1) {
91                     PrintError(vm, VCORE_NONE, "Error mapping SEABIOS to end of memory\n");
92                     return -1;
93                 }
94                 V3_Print(vm,VCORE_NONE,"BIOS  mapped\n");
95             }
96             
97             V3_Print(vm,VCORE_NONE,"Additionally mapping SEABIOS of %llu bytes at gpa %p\n", (uint64_t)(v3_rombios_end-v3_rombios_start), (void*)SEABIOS_HIGH_START);
98 #endif
99
100         }
101
102         {
103             void *ba;
104
105 // traditional BIOS data area (and IVT, etc).  Technically only 0x400-0x4ff is the BDA
106 #define BDA_START   0x0
107 #define BDA_END     0xfff
108
109 // Extended BDA and EBDA2.  Technically not standardized.  Usually at the
110 // end of the 640K chunk.  We're just using that last page to play it save
111 #define EBDA_START 0x9f000
112 #define EBDA_END   0x9ffff
113
114             if (v3_gpa_to_hva(&(vm->cores[0]), BDA_START, (addr_t *)&ba) == -1) {
115                 PrintError(vm, VCORE_NONE, "Could not find BDA destination address\n");
116                 return -1;
117             }
118             
119             memset(ba,0,(BDA_END-BDA_START+1));
120
121             V3_Print(vm,VCORE_NONE,"Cleared BDA %p (HVA %p) through %p\n",(void*)BDA_START,ba,(void*)BDA_END);
122
123             if (v3_gpa_to_hva(&(vm->cores[0]), EBDA_START, (addr_t *)&ba) == -1) {
124                 PrintError(vm, VCORE_NONE, "Could not find EBDA destination address\n");
125                 return -1;
126             }
127             
128             memset(ba,0,(EBDA_END-EBDA_START+1));
129
130             V3_Print(vm,VCORE_NONE,"Cleared EBDA %p (HVA %p) through %p\n",(void*)EBDA_START,ba,(void*)EBDA_END);
131         }
132
133     }
134
135     
136
137     bios_list = v3_cfg_subtree(bios_tree, "bios");
138
139     while (bios_list) {
140         char * id = v3_cfg_val(bios_list, "file");
141         char * addr = v3_cfg_val(bios_list, "address");
142         uint64_t file_ptr = 0;
143         void * dest = NULL;
144         struct v3_cfg_file * file = NULL;
145
146         if (!id) {
147             PrintError(vm, VCORE_NONE, "Could not find bios file\n");
148             continue;
149         }
150
151         if (!addr) {
152             PrintError(vm, VCORE_NONE, "Could not find bios address\n");
153             continue;
154         }
155
156         file = v3_cfg_get_file(vm, id);
157         if (!file) {
158             PrintError(vm, VCORE_NONE, "Invalid BIOS file: %s\n", id);
159             continue;
160         }
161
162         file_ptr = atox(addr);
163
164         V3_Print(vm, VCORE_NONE, "Copying BIOS ROM (%s) to %p (size=%lld)\n", 
165                  id,
166                  (void*)file_ptr,
167                  file->size);
168
169         if (v3_gpa_to_hva(&(vm->cores[0]), (addr_t)file_ptr, (addr_t *)&dest) == -1) {
170             PrintError(vm, VCORE_NONE, "Could not find BIOS (%s) destination address\n", id);
171             continue;
172         }
173
174         memcpy((void*)dest, file->data, file->size);
175
176         V3_Print(vm, VCORE_NONE, "Moving on to next BIOS file\n");
177         bios_list = v3_cfg_next_branch(bios_list);
178     }
179
180     // NOW BLOW AWAY BDA and EBDA here
181     // possibly also reset CMOS
182
183
184     return 0;
185 }