1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
* QEMU low level functions
*
* Copyright ( c ) 2003 Fabrice Bellard
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
# include < stdlib . h >
# include < stdio . h >
# include < stdarg . h >
# include < string . h >
# include < errno . h >
# include < unistd . h >
ths
authored
18 years ago
30
31
32
33
# ifdef HOST_SOLARIS
# include < sys / types . h >
# include < sys / statvfs . h >
# endif
34
35
# include "cpu.h"
36
37
38
# if defined ( USE_KQEMU )
# include "vl.h"
# endif
39
40
41
42
# ifdef _WIN32
# include < windows . h >
# elif defined ( _BSD )
43
44
# include < stdlib . h >
# else
45
# include < malloc . h >
46
# endif
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
void * get_mmap_addr ( unsigned long size )
{
return NULL ;
}
void qemu_free ( void * ptr )
{
free ( ptr );
}
void * qemu_malloc ( size_t size )
{
return malloc ( size );
}
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# if defined ( _WIN32 )
void * qemu_vmalloc ( size_t size )
{
/* FIXME : this is not exactly optimal solution since VirtualAlloc
has 64 Kb granularity , but at least it guarantees us that the
memory is page aligned . */
return VirtualAlloc ( NULL , size , MEM_COMMIT , PAGE_READWRITE );
}
void qemu_vfree ( void * ptr )
{
VirtualFree ( ptr , 0 , MEM_RELEASE );
}
78
79
80
# else
# if defined ( USE_KQEMU )
81
82
# include < sys / vfs . h >
83
84
85
# include < sys / mman . h >
# include < fcntl . h >
86
void * kqemu_vmalloc ( size_t size )
87
88
89
90
91
92
{
static int phys_ram_fd = - 1 ;
static int phys_ram_size = 0 ;
const char * tmpdir ;
char phys_ram_file [ 1024 ];
void * ptr ;
ths
authored
18 years ago
93
94
95
# ifdef HOST_SOLARIS
struct statvfs stfs ;
# else
96
struct statfs stfs ;
ths
authored
18 years ago
97
# endif
98
99
100
101
if ( phys_ram_fd < 0 ) {
tmpdir = getenv ( "QEMU_TMPDIR" );
if ( ! tmpdir )
ths
authored
18 years ago
102
103
104
105
# ifdef HOST_SOLARIS
tmpdir = "/tmp" ;
if ( statvfs ( tmpdir , & stfs ) == 0 ) {
# else
106
tmpdir = "/dev/shm" ;
107
if ( statfs ( tmpdir , & stfs ) == 0 ) {
ths
authored
18 years ago
108
# endif
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
int64_t free_space ;
int ram_mb ;
extern int ram_size ;
free_space = ( int64_t ) stfs . f_bavail * stfs . f_bsize ;
if (( ram_size + 8192 * 1024 ) >= free_space ) {
ram_mb = ( ram_size / ( 1024 * 1024 ));
fprintf ( stderr ,
"You do not have enough space in '%s' for the %d MB of QEMU virtual RAM. \n " ,
tmpdir , ram_mb );
if ( strcmp ( tmpdir , "/dev/shm" ) == 0 ) {
fprintf ( stderr , "To have more space available provided you have enough RAM and swap, do as root: \n "
"umount /dev/shm \n "
"mount -t tmpfs -o size=%dm none /dev/shm \n " ,
ram_mb + 16 );
} else {
fprintf ( stderr ,
"Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the \n "
"QEMU_TMPDIR environment variable to set another directory where the QEMU \n "
"temporary RAM file will be opened. \n " );
}
130
fprintf ( stderr , "Or disable the accelerator module with -no-kqemu \n " );
131
132
133
exit ( 1 );
}
}
134
135
snprintf ( phys_ram_file , sizeof ( phys_ram_file ), "%s/qemuXXXXXX" ,
tmpdir );
136
137
phys_ram_fd = mkstemp ( phys_ram_file );
if ( phys_ram_fd < 0 ) {
138
139
140
141
142
143
144
fprintf ( stderr ,
"warning: could not create temporary file in '%s'. \n "
"Use QEMU_TMPDIR to select a directory in a tmpfs filesystem. \n "
"Using '/tmp' as fallback. \n " ,
tmpdir );
snprintf ( phys_ram_file , sizeof ( phys_ram_file ), "%s/qemuXXXXXX" ,
"/tmp" );
145
146
phys_ram_fd = mkstemp ( phys_ram_file );
if ( phys_ram_fd < 0 ) {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
fprintf ( stderr , "Could not create temporary memory file '%s' \n " ,
phys_ram_file );
exit ( 1 );
}
}
unlink ( phys_ram_file );
}
size = ( size + 4095 ) & ~ 4095 ;
ftruncate ( phys_ram_fd , phys_ram_size + size );
ptr = mmap ( NULL ,
size ,
PROT_WRITE | PROT_READ , MAP_SHARED ,
phys_ram_fd , phys_ram_size );
if ( ptr == MAP_FAILED ) {
fprintf ( stderr , "Could not map physical memory \n " );
exit ( 1 );
}
phys_ram_size += size ;
return ptr ;
}
168
void kqemu_vfree ( void * ptr )
169
170
171
172
{
/* may be useful some day, but currently we do not need to free */
}
173
# endif
174
175
176
177
/* alloc shared memory pages */
void * qemu_vmalloc ( size_t size )
{
178
179
180
181
# if defined ( USE_KQEMU )
if ( kqemu_allowed )
return kqemu_vmalloc ( size );
# endif
182
183
184
185
186
187
188
189
190
# ifdef _BSD
return valloc ( size );
# else
return memalign ( 4096 , size );
# endif
}
void qemu_vfree ( void * ptr )
{
191
192
193
194
# if defined ( USE_KQEMU )
if ( kqemu_allowed )
kqemu_vfree ( ptr );
# endif
195
196
197
198
199
free ( ptr );
}
# endif
200
201
202
203
204
205
206
207
208
209
void * qemu_mallocz ( size_t size )
{
void * ptr ;
ptr = qemu_malloc ( size );
if ( ! ptr )
return NULL ;
memset ( ptr , 0 , size );
return ptr ;
}
210
211
212
213
214
215
216
217
218
char * qemu_strdup ( const char * str )
{
char * ptr ;
ptr = qemu_malloc ( strlen ( str ) + 1 );
if ( ! ptr )
return NULL ;
strcpy ( ptr , str );
return ptr ;
}