debuggers.hg

view tools/ioemu/memory/misc_mem.cc @ 3643:a920f0ced90f

bitkeeper revision 1.1159.212.66 (42001b6f4kUEhmWXQmgg_vNH-AqiWQ)

Right now, the memory for the 1:1 physical mode page tables comes from the
VMX domain's memory. With this change, when the user asks for a domain with
M Megabytes of memory, we actually allocate M+N megabytes in xend, where
N is the memory for the page table pages.

This simplifies the code in the device models that maps guest memory (we
now map all of it) and the E820 map can also give the full M megabytes to
the guest.

Signed-off-by: Xin B Li <xin.b.li@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: ian.pratt@cl.cam.ac.uk
author iap10@labyrinth.cl.cam.ac.uk
date Wed Feb 02 00:14:39 2005 +0000 (2005-02-02)
parents 2c56c6b39a48
children bbe8541361dd
line source
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: misc_mem.cc,v 1.41 2003/09/10 16:34:56 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
12 //
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
17 //
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
22 //
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "bochs.h"
34 #ifdef BX_USE_VMX
35 extern "C" {
36 #include <sys/mman.h>
37 }
38 #endif
40 #define LOG_THIS BX_MEM(0)->
42 #if BX_PROVIDE_CPU_MEMORY
43 Bit32u
44 BX_MEM_C::get_memory_in_k(void)
45 {
46 return(BX_MEM_THIS megabytes * 1024);
47 }
48 #endif // #if BX_PROVIDE_CPU_MEMORY
51 #if BX_PROVIDE_CPU_MEMORY
52 // BX_MEM_C constructor
53 BX_MEM_C::BX_MEM_C(void)
54 {
55 char mem[6];
56 snprintf(mem, 6, "MEM%d", BX_SIM_ID);
57 put(mem);
58 settype(MEMLOG);
60 vector = NULL;
61 actual_vector = NULL;
62 len = 0;
63 megabytes = 0;
64 }
65 #endif // #if BX_PROVIDE_CPU_MEMORY
69 #if BX_PROVIDE_CPU_MEMORY
70 void BX_CPP_AttrRegparmN(2)
71 BX_MEM_C::alloc_vector_aligned (size_t bytes, size_t alignment)
72 {
73 if (actual_vector != NULL) {
74 BX_INFO (("freeing existing memory vector"));
75 delete [] actual_vector;
76 actual_vector = NULL;
77 vector = NULL;
78 }
79 Bit64u test_mask = alignment - 1;
80 actual_vector = new Bit8u [bytes+test_mask];
81 // round address forward to nearest multiple of alignment. Alignment
82 // MUST BE a power of two for this to work.
83 unsigned long masked = ((unsigned long)(actual_vector + test_mask)) & ~test_mask;
84 vector = (Bit8u *)masked;
85 // sanity check: no lost bits during pointer conversion
86 BX_ASSERT (sizeof(masked) >= sizeof(vector));
87 // sanity check: after realignment, everything fits in allocated space
88 BX_ASSERT (vector+bytes <= actual_vector+bytes+test_mask);
89 BX_INFO (("allocated memory at %p. after alignment, vector=%p",
90 actual_vector, vector));
91 }
92 #endif
94 // We can't use this because alloc_vector_aligned uses BX_INFO, but the object does not yet exists
95 /*
96 #if BX_PROVIDE_CPU_MEMORY
97 // BX_MEM_C constructor
99 BX_MEM_C::BX_MEM_C(size_t memsize)
100 {
101 char mem[6];
102 snprintf(mem, 6, "MEM%d", BX_SIM_ID);
103 put(mem);
104 settype(MEMLOG);
106 vector = NULL;
107 actual_vector = NULL;
108 alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
109 len = memsize;
110 megabytes = len / (1024*1024);
111 }
112 #endif // #if BX_PROVIDE_CPU_MEMORY
113 */
116 #if BX_PROVIDE_CPU_MEMORY
117 // BX_MEM_C destructor
118 BX_MEM_C::~BX_MEM_C(void)
119 {
120 if (this-> vector != NULL) {
121 delete [] actual_vector;
122 actual_vector = NULL;
123 vector = NULL;
124 }
125 else {
126 BX_DEBUG(("(%u) memory not freed as it wasn't allocated!", BX_SIM_ID));
127 }
128 }
129 #endif // #if BX_PROVIDE_CPU_MEMORY
132 #if BX_PROVIDE_CPU_MEMORY
133 void
134 BX_MEM_C::init_memory(int memsize)
135 {
136 BX_DEBUG(("Init $Id: misc_mem.cc,v 1.41 2003/09/10 16:34:56 vruppert Exp $"));
137 // you can pass 0 if memory has been allocated already through
138 // the constructor, or the desired size of memory if it hasn't
139 // BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
141 #ifndef BX_USE_VMX
142 if (BX_MEM_THIS vector == NULL) {
143 // memory not already allocated, do now...
144 alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
145 #endif
146 BX_MEM_THIS len = memsize;
147 BX_MEM_THIS megabytes = memsize / (1024*1024);
148 BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
149 #ifndef BX_USE_VMX
150 }
151 #endif
153 #if BX_DEBUGGER
154 if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
155 BX_INFO(("Error: memory larger than dirty page table can handle"));
156 BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS"));
157 }
158 #endif
160 unsigned long nr_pages = megabytes * (1024 * 1024/getpagesize());
162 if ( (page_array = (unsigned long *)
163 malloc(nr_pages * sizeof(unsigned long))) == NULL)
164 {
165 BX_ERROR(("Could not allocate memory"));
166 return;
167 }
169 if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
170 {
171 BX_ERROR(("Could not get the page frame list"));
172 return;
173 }
175 #define PAGE_SHIFT 12
176 #define PAGE_SIZE (1 << PAGE_SHIFT)
178 if ((vector = (Bit8u *) xc_map_foreign_batch(xc_handle, domid,
179 PROT_READ|PROT_WRITE,
180 page_array,
181 nr_pages - 1)) == 0) {
182 BX_ERROR(("Could not map guest physical"));
183 return;
184 }
186 BX_MEM_THIS dma_limit = (nr_pages - 1) << PAGE_SHIFT;
187 BX_INFO(("DMA limit: %lx", BX_MEM_THIS dma_limit));
189 shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
190 PROT_READ|PROT_WRITE,
191 page_array[nr_pages - 1]);
193 /* Initialize shared page */
194 memset(shared_page, 0, PAGE_SIZE);
195 }
196 #endif // #if BX_PROVIDE_CPU_MEMORY
199 #if BX_PROVIDE_CPU_MEMORY
200 void
201 // Values for type :
202 // 0 : System Bios
203 // 1 : VGA Bios
204 // 2 : Optional ROM Bios
205 BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
206 {
207 struct stat stat_buf;
208 int fd, ret;
209 unsigned long size, offset;
211 if (*path == '\0') {
212 if (type == 2) {
213 BX_PANIC(( "ROM: Optional BIOS image undefined."));
214 }
215 else if (type == 1) {
216 BX_PANIC(( "ROM: VGA BIOS image undefined."));
217 }
218 else {
219 BX_PANIC(( "ROM: System BIOS image undefined."));
220 }
221 return;
222 }
223 // read in ROM BIOS image file
224 fd = open(path, O_RDONLY
225 #ifdef O_BINARY
226 | O_BINARY
227 #endif
228 );
229 if (fd < 0) {
230 if (type < 2) {
231 BX_PANIC(( "ROM: couldn't open ROM image file '%s'.", path));
232 }
233 else {
234 BX_ERROR(( "ROM: couldn't open ROM image file '%s'.", path));
235 }
236 return;
237 }
238 ret = fstat(fd, &stat_buf);
239 if (ret) {
240 if (type < 2) {
241 BX_PANIC(( "ROM: couldn't stat ROM image file '%s'.", path));
242 }
243 else {
244 BX_ERROR(( "ROM: couldn't stat ROM image file '%s'.", path));
245 }
246 return;
247 }
249 size = stat_buf.st_size;
251 if ( (romaddress + size) > BX_MEM_THIS len ) {
252 BX_PANIC(( "ROM: ROM address range > physical memsize!"));
253 return;
254 }
256 offset = 0;
257 while (size > 0) {
258 ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
259 if (ret <= 0) {
260 BX_PANIC(( "ROM: read failed on BIOS image: '%s'",path));
261 }
262 size -= ret;
263 offset += ret;
264 }
265 close(fd);
266 BX_INFO(("rom at 0x%05x/%u ('%s')",
267 (unsigned) romaddress,
268 (unsigned) stat_buf.st_size,
269 path
270 ));
271 }
272 #endif // #if BX_PROVIDE_CPU_MEMORY
274 #if BX_PCI_SUPPORT
275 Bit8u* BX_CPP_AttrRegparmN(1)
276 BX_MEM_C::pci_fetch_ptr(Bit32u addr)
277 {
278 if (bx_options.Oi440FXSupport->get ()) {
279 switch (DEV_pci_rd_memtype (addr)) {
280 case 0x1: // Read from ShadowRAM
281 return (&BX_MEM_THIS shadow[addr - 0xc0000]);
283 case 0x0: // Read from ROM
284 return (&BX_MEM_THIS vector[addr]);
285 default:
286 BX_PANIC(("pci_fetch_ptr(): default case"));
287 return(0);
288 }
289 }
290 else
291 return (&BX_MEM_THIS vector[addr]);
292 }
293 #endif
296 #if ( BX_DEBUGGER || BX_DISASM || BX_GDBSTUB)
297 bx_bool
298 BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
299 {
300 if ( (addr + len) > this->len ) {
301 BX_INFO(("dbg_fetch_mem out of range. 0x%x > 0x%x",
302 addr+len, this->len));
303 return(0); // error, beyond limits of memory
304 }
305 for (; len>0; len--) {
306 if ( (addr & 0xfffe0000) == 0x000a0000 ) {
307 *buf = DEV_vga_mem_read(addr);
308 }
309 else {
310 #if BX_PCI_SUPPORT == 0
311 *buf = vector[addr];
312 #else
313 if ( bx_options.Oi440FXSupport->get () &&
314 ((addr >= 0x000C0000) && (addr <= 0x000FFFFF)) ) {
315 switch (DEV_pci_rd_memtype (addr)) {
316 case 0x1: // Fetch from ShadowRAM
317 *buf = shadow[addr - 0xc0000];
318 // BX_INFO(("Fetching from ShadowRAM %06x, len %u !", (unsigned)addr, (unsigned)len));
319 break;
321 case 0x0: // Fetch from ROM
322 *buf = vector[addr];
323 // BX_INFO(("Fetching from ROM %06x, Data %02x ", (unsigned)addr, *buf));
324 break;
325 default:
326 BX_PANIC(("dbg_fetch_mem: default case"));
327 }
328 }
329 else
330 *buf = vector[addr];
331 #endif // #if BX_PCI_SUPPORT == 0
332 }
333 buf++;
334 addr++;
335 }
336 return(1);
337 }
338 #endif
340 #if BX_DEBUGGER || BX_GDBSTUB
341 bx_bool
342 BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
343 {
344 if ( (addr + len) > this->len ) {
345 return(0); // error, beyond limits of memory
346 }
347 for (; len>0; len--) {
348 if ( (addr & 0xfffe0000) == 0x000a0000 ) {
349 DEV_vga_mem_write(addr, *buf);
350 }
351 else
352 vector[addr] = *buf;
353 buf++;
354 addr++;
355 }
356 return(1);
357 }
358 #endif
360 bx_bool
361 BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
362 Bit32u addr1, Bit32u addr2, Bit32u *crc)
363 {
364 unsigned len;
366 *crc = 0;
367 if (addr1 > addr2)
368 return(0);
370 if (addr2 >= this->len) {
371 return(0); // error, specified address past last phy mem addr
372 }
374 len = 1 + addr2 - addr1;
375 *crc = f(vector + addr1, len);
377 return(1);
378 }
381 Bit8u * BX_CPP_AttrRegparmN(3)
382 BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op)
383 // Return a host address corresponding to the guest physical memory
384 // address (with A20 already applied), given that the calling
385 // code will perform an 'op' operation. This address will be
386 // used for direct access to guest memory as an acceleration by
387 // a few instructions, like REP {MOV, INS, OUTS, etc}.
388 // Values of 'op' are { BX_READ, BX_WRITE, BX_RW }.
390 // The other assumption is that the calling code _only_ accesses memory
391 // directly within the page that encompasses the address requested.
392 {
393 if ( a20Addr >= BX_MEM_THIS len )
394 return(NULL); // Error, requested addr is out of bounds.
395 if (op == BX_READ) {
396 if ( (a20Addr > 0x9ffff) && (a20Addr < 0xc0000) )
397 return(NULL); // Vetoed! Mem mapped IO (VGA)
398 #if !BX_PCI_SUPPORT
399 return( (Bit8u *) & vector[a20Addr] );
400 #else
401 else if ( (a20Addr < 0xa0000) || (a20Addr > 0xfffff)
402 || (!bx_options.Oi440FXSupport->get ()) )
403 return( (Bit8u *) & vector[a20Addr] );
404 else {
405 switch (DEV_pci_rd_memtype (a20Addr)) {
406 case 0x0: // Read from ROM
407 return ( (Bit8u *) & vector[a20Addr]);
408 case 0x1: // Read from ShadowRAM
409 return( (Bit8u *) & shadow[a20Addr - 0xc0000]);
410 default:
411 BX_PANIC(("getHostMemAddr(): default case"));
412 return(0);
413 }
414 }
415 #endif
416 }
417 else { // op == {BX_WRITE, BX_RW}
418 Bit8u *retAddr;
420 if ( (a20Addr < 0xa0000) || (a20Addr > 0xfffff) ) {
421 retAddr = (Bit8u *) & vector[a20Addr];
422 }
423 #if !BX_PCI_SUPPORT
424 else
425 return(NULL); // Vetoed! Mem mapped IO (VGA) and ROMs
426 #else
427 else if ( (a20Addr < 0xc0000) || (!bx_options.Oi440FXSupport->get ()) )
428 return(NULL); // Vetoed! Mem mapped IO (VGA) and ROMs
429 else if (DEV_pci_wr_memtype (a20Addr) == 1) {
430 // Write to ShadowRAM
431 retAddr = (Bit8u *) & shadow[a20Addr - 0xc0000];
432 }
433 else
434 return(NULL); // Vetoed! ROMs
435 #endif
437 #if BX_SupportICache
438 cpu->iCache.decWriteStamp(cpu, a20Addr);
439 #endif
441 return(retAddr);
442 }
443 }