1 /*
2  * Cisco router simulation platform.
3  * Copyright (c) 2006 Christophe Fillot.  All rights reserved.
4  *
5  * RAM emulation.
6  */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <errno.h>
13 #include <unistd.h>
14 
15 #include "cpu.h"
16 #include "vm.h"
17 #include "dynamips.h"
18 #include "memory.h"
19 #include "device.h"
20 
21 /* RAM private data */
22 struct ram_data {
23    vm_obj_t vm_obj;
24    struct vdevice *dev;
25    char *filename;
26    int delete_file;
27 };
28 
29 /* Shutdown a RAM device */
dev_ram_shutdown(vm_instance_t * vm,struct ram_data * d)30 void dev_ram_shutdown(vm_instance_t *vm,struct ram_data *d)
31 {
32    if (d != NULL) {
33       /* Remove the device */
34       dev_remove(vm,d->dev);
35       free(d->dev);
36 
37       /* Remove filename used to virtualize RAM */
38       if (d->filename) {
39          if (d->delete_file)
40             unlink(d->filename);
41          free(d->filename);
42       }
43 
44       /* Free the structure itself */
45       free(d);
46    }
47 }
48 
49 /* Initialize a RAM zone */
dev_ram_init(vm_instance_t * vm,char * name,int use_mmap,int delete_file,char * alternate_name,int sparse,m_uint64_t paddr,m_uint32_t len)50 int dev_ram_init(vm_instance_t *vm,char *name,int use_mmap,int delete_file,
51                  char *alternate_name,int sparse,
52                  m_uint64_t paddr,m_uint32_t len)
53 {
54    struct ram_data *d;
55 
56    /* allocate the private data structure */
57    if (!(d = malloc(sizeof(*d)))) {
58       fprintf(stderr,"RAM: unable to create device.\n");
59       return(-1);
60    }
61 
62    memset(d,0,sizeof(*d));
63    d->delete_file = delete_file;
64 
65    vm_object_init(&d->vm_obj);
66    d->vm_obj.name = name;
67    d->vm_obj.data = d;
68    d->vm_obj.shutdown = (vm_shutdown_t)dev_ram_shutdown;
69 
70    if (use_mmap) {
71       if (!alternate_name)
72          d->filename = vm_build_filename(vm,name);
73       else
74          d->filename = strdup(alternate_name);
75 
76       if (!d->filename) {
77          fprintf(stderr,"RAM: unable to create filename.\n");
78          goto err_filename;
79       }
80    }
81 
82    if (!(d->dev = dev_create_ram(vm,name,sparse,d->filename,paddr,len))) {
83       fprintf(stderr,"RAM: unable to create device.\n");
84       goto err_dev_create;
85    }
86 
87    vm_object_add(vm,&d->vm_obj);
88    return(0);
89 
90  err_dev_create:
91    free(d->filename);
92  err_filename:
93    free(d);
94    return(-1);
95 }
96 
97 /* Initialize a ghosted RAM zone */
dev_ram_ghost_init(vm_instance_t * vm,char * name,int sparse,char * filename,m_uint64_t paddr,m_uint32_t len)98 int dev_ram_ghost_init(vm_instance_t *vm,char *name,int sparse,char *filename,
99                        m_uint64_t paddr,m_uint32_t len)
100 {
101    struct ram_data *d;
102 
103    /* allocate the private data structure */
104    if (!filename || !(d = malloc(sizeof(*d)))) {
105       vm_error(vm,"RAM_ghost: unable to create device (filename=%s).\n",filename);
106       return(-1);
107    }
108 
109    memset(d,0,sizeof(*d));
110    d->delete_file = FALSE;
111 
112    if (!(d->filename = strdup(filename)))
113       goto err_filename;
114 
115    vm_object_init(&d->vm_obj);
116    d->vm_obj.name = name;
117    d->vm_obj.data = d;
118    d->vm_obj.shutdown = (vm_shutdown_t)dev_ram_shutdown;
119 
120    if (!(d->dev = dev_create_ghost_ram(vm,name,sparse,d->filename,
121                                        paddr,len)))
122    {
123       vm_error(vm,"RAM_ghost: unable to create device (filename=%s)\n",d->filename);
124       goto err_dev_create;
125    }
126 
127    vm_object_add(vm,&d->vm_obj);
128    return(0);
129 
130  err_dev_create:
131    free(d->filename);
132  err_filename:
133    free(d);
134    return(-1);
135 }
136