22 |
|
|
23 |
#define DEBUG_DEV_ACCESS 0 |
#define DEBUG_DEV_ACCESS 0 |
24 |
|
|
|
/* Map a memory zone from a file */ |
|
|
u_char *memzone_map_file(int fd,size_t len) |
|
|
{ |
|
|
return(mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(off_t)0)); |
|
|
} |
|
|
|
|
|
/* Create a file to serve as a memory zone */ |
|
|
int memzone_create_file(char *filename,size_t len,u_char **ptr) |
|
|
{ |
|
|
int fd; |
|
|
|
|
|
if ((fd = open(filename,O_CREAT|O_RDWR,S_IRWXU)) == -1) { |
|
|
perror("memzone_create_file: open"); |
|
|
return(-1); |
|
|
} |
|
|
|
|
|
if (ftruncate(fd,len) == -1) { |
|
|
perror("memzone_create_file: ftruncate"); |
|
|
return(-1); |
|
|
} |
|
|
|
|
|
*ptr = memzone_map_file(fd,len); |
|
|
|
|
|
if (!*ptr) { |
|
|
close(fd); |
|
|
fd = -1; |
|
|
} |
|
|
|
|
|
return(fd); |
|
|
} |
|
|
|
|
25 |
/* Get device by ID */ |
/* Get device by ID */ |
26 |
struct vdevice *dev_get_by_id(vm_instance_t *vm,u_int dev_id) |
struct vdevice *dev_get_by_id(vm_instance_t *vm,u_int dev_id) |
27 |
{ |
{ |
186 |
return(dev->handler(cpu,dev,offset,op_size,op_type,data)); |
return(dev->handler(cpu,dev,offset,op_size,op_type,data)); |
187 |
} |
} |
188 |
|
|
189 |
|
/* Synchronize memory for a memory-mapped (mmap) device */ |
190 |
|
int dev_sync(struct vdevice *dev) |
191 |
|
{ |
192 |
|
if (!dev || !dev->host_addr) |
193 |
|
return(-1); |
194 |
|
|
195 |
|
return(msync((void *)dev->host_addr,dev->phys_len,MS_SYNC)); |
196 |
|
} |
197 |
|
|
198 |
/* Remap a device at specified physical address */ |
/* Remap a device at specified physical address */ |
199 |
struct vdevice *dev_remap(char *name,struct vdevice *orig, |
struct vdevice *dev_remap(char *name,struct vdevice *orig, |
200 |
m_uint64_t paddr,m_uint32_t len) |
m_uint64_t paddr,m_uint32_t len) |
229 |
|
|
230 |
if (filename) { |
if (filename) { |
231 |
dev->fd = memzone_create_file(filename,dev->phys_len,&ram_ptr); |
dev->fd = memzone_create_file(filename,dev->phys_len,&ram_ptr); |
232 |
|
|
233 |
|
if (dev->fd == -1) { |
234 |
|
perror("dev_create_ram: mmap"); |
235 |
|
free(dev); |
236 |
|
return NULL; |
237 |
|
} |
238 |
|
|
239 |
dev->host_addr = (m_iptr_t)ram_ptr; |
dev->host_addr = (m_iptr_t)ram_ptr; |
240 |
} else { |
} else { |
241 |
dev->host_addr = (m_iptr_t)m_memalign(4096,dev->phys_len); |
dev->host_addr = (m_iptr_t)m_memalign(4096,dev->phys_len); |
242 |
} |
} |
243 |
|
|
244 |
|
if (!dev->host_addr) { |
245 |
|
free(dev); |
246 |
|
return NULL; |
247 |
|
} |
248 |
|
|
249 |
|
vm_bind_device(vm,dev); |
250 |
|
return dev; |
251 |
|
} |
252 |
|
|
253 |
|
/* Create a ghosted RAM device */ |
254 |
|
struct vdevice * |
255 |
|
dev_create_ghost_ram(vm_instance_t *vm,char *name,char *filename, |
256 |
|
m_uint64_t paddr,m_uint32_t len) |
257 |
|
{ |
258 |
|
struct vdevice *dev; |
259 |
|
u_char *ram_ptr; |
260 |
|
|
261 |
|
if (!(dev = dev_create(name))) |
262 |
|
return NULL; |
263 |
|
|
264 |
|
dev->phys_addr = paddr; |
265 |
|
dev->phys_len = len; |
266 |
|
dev->flags = VDEVICE_FLAG_CACHING; |
267 |
|
|
268 |
|
dev->fd = memzone_open_cow_file(filename,dev->phys_len,&ram_ptr); |
269 |
|
if (dev->fd == -1) { |
270 |
|
perror("dev_create_ghost_ram: mmap"); |
271 |
|
free(dev); |
272 |
|
return NULL; |
273 |
|
} |
274 |
|
|
275 |
|
if (!(dev->host_addr = (m_iptr_t)ram_ptr)) { |
276 |
|
free(dev); |
277 |
|
return NULL; |
278 |
|
} |
279 |
|
|
280 |
vm_bind_device(vm,dev); |
vm_bind_device(vm,dev); |
281 |
return dev; |
return dev; |
282 |
} |
} |