/[dynamips]/trunk/dev_remote.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/dev_remote.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 8059 byte(s)
make working copy

1 dpavlin 1 /*
2 dpavlin 7 * Cisco router simulation platform.
3 dpavlin 1 * Copyright (C) 2006 Christophe Fillot. All rights reserved.
4 dpavlin 7 *
5     * Remote control module.
6 dpavlin 1 */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11     #include <stdarg.h>
12     #include <unistd.h>
13     #include <time.h>
14     #include <errno.h>
15     #include <pthread.h>
16     #include <assert.h>
17    
18     #include "utils.h"
19 dpavlin 7 #include "cpu.h"
20     #include "vm.h"
21 dpavlin 1 #include "dynamips.h"
22     #include "memory.h"
23     #include "device.h"
24     #include "net.h"
25     #include "net_io.h"
26     #include "registry.h"
27     #include "ptask.h"
28     #include "dev_c7200.h"
29     #include "dev_c3600.h"
30 dpavlin 4 #include "dev_c2691.h"
31     #include "dev_c3725.h"
32     #include "dev_c3745.h"
33 dpavlin 7 #include "dev_c2600.h"
34 dpavlin 1
35     #define DEBUG_ACCESS 0
36    
37 dpavlin 11 #define ROMMON_SET_VAR 0x01
38     #define ROMMON_GET_VAR 0x02
39     #define ROMMON_CLEAR_VAR_STAT 0x03
40    
41 dpavlin 1 /* Remote control private data */
42     struct remote_data {
43     vm_obj_t vm_obj;
44     struct vdevice dev;
45    
46 dpavlin 11 /* Console buffer */
47     char con_buffer[512];
48     u_int con_buf_pos;
49 dpavlin 7
50 dpavlin 11 /* ROMMON variables buffer */
51     char var_buffer[512];
52     u_int var_buf_pos;
53     u_int var_status;
54    
55     /* Position for cookie reading */
56 dpavlin 7 u_int cookie_pos;
57 dpavlin 1 };
58    
59     /*
60     * dev_remote_control_access()
61     */
62 dpavlin 7 void *dev_remote_control_access(cpu_gen_t *cpu,struct vdevice *dev,
63 dpavlin 1 m_uint32_t offset,u_int op_size,u_int op_type,
64     m_uint64_t *data)
65     {
66 dpavlin 7 vm_instance_t *vm = cpu->vm;
67 dpavlin 1 struct remote_data *d = dev->priv_data;
68 dpavlin 4 struct vdevice *storage_dev;
69 dpavlin 1 size_t len;
70    
71     if (op_type == MTS_READ)
72     *data = 0;
73    
74     #if DEBUG_ACCESS
75     if (op_type == MTS_READ) {
76 dpavlin 7 cpu_log(cpu,"REMOTE","reading reg 0x%x at pc=0x%llx\n",
77     offset,cpu_get_pc(cpu));
78 dpavlin 1 } else {
79     cpu_log(cpu,"REMOTE","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",
80 dpavlin 7 offset,cpu_get_pc(cpu),*data);
81 dpavlin 1 }
82     #endif
83    
84     switch(offset) {
85     /* ROM Identification tag */
86     case 0x000:
87     if (op_type == MTS_READ)
88     *data = ROM_ID;
89     break;
90    
91     /* CPU ID */
92     case 0x004:
93     if (op_type == MTS_READ)
94     *data = cpu->id;
95     break;
96    
97     /* Display CPU registers */
98     case 0x008:
99     if (op_type == MTS_WRITE)
100 dpavlin 7 cpu->reg_dump(cpu);
101 dpavlin 1 break;
102    
103 dpavlin 7 /* Display CPU memory info */
104 dpavlin 1 case 0x00c:
105     if (op_type == MTS_WRITE)
106 dpavlin 7 cpu->mmu_dump(cpu);
107 dpavlin 1 break;
108    
109     /* Reserved/Unused */
110     case 0x010:
111     break;
112    
113     /* RAM size */
114     case 0x014:
115     if (op_type == MTS_READ)
116 dpavlin 7 *data = vm->ram_size;
117 dpavlin 1 break;
118    
119     /* ROM size */
120     case 0x018:
121     if (op_type == MTS_READ)
122 dpavlin 7 *data = vm->rom_size;
123 dpavlin 1 break;
124    
125     /* NVRAM size */
126     case 0x01c:
127     if (op_type == MTS_READ)
128 dpavlin 7 *data = vm->nvram_size;
129 dpavlin 1 break;
130    
131     /* IOMEM size */
132     case 0x020:
133     if (op_type == MTS_READ)
134 dpavlin 7 *data = vm->iomem_size;
135 dpavlin 1 break;
136    
137     /* Config Register */
138     case 0x024:
139     if (op_type == MTS_READ)
140 dpavlin 7 *data = vm->conf_reg;
141 dpavlin 1 break;
142    
143     /* ELF entry point */
144     case 0x028:
145     if (op_type == MTS_READ)
146 dpavlin 7 *data = vm->ios_entry_point;
147 dpavlin 1 break;
148    
149     /* ELF machine id */
150     case 0x02c:
151     if (op_type == MTS_READ)
152 dpavlin 7 *data = vm->elf_machine_id;
153 dpavlin 1 break;
154    
155     /* Restart IOS Image */
156     case 0x030:
157     /* not implemented */
158     break;
159    
160     /* Stop the virtual machine */
161     case 0x034:
162 dpavlin 7 vm->status = VM_STATUS_SHUTDOWN;
163 dpavlin 1 break;
164    
165     /* Debugging/Log message: /!\ physical address */
166     case 0x038:
167     if (op_type == MTS_WRITE) {
168 dpavlin 7 len = physmem_strlen(vm,*data);
169 dpavlin 11 if (len < sizeof(d->con_buffer)) {
170     physmem_copy_from_vm(vm,d->con_buffer,*data,len+1);
171     vm_log(vm,"ROM",d->con_buffer);
172 dpavlin 1 }
173     }
174     break;
175    
176 dpavlin 11 /* Console Buffering */
177 dpavlin 1 case 0x03c:
178 dpavlin 11 if (op_type == MTS_WRITE) {
179     if (d->con_buf_pos < (sizeof(d->con_buffer)-1)) {
180     d->con_buffer[d->con_buf_pos++] = *data & 0xFF;
181     d->con_buffer[d->con_buf_pos] = 0;
182 dpavlin 1
183 dpavlin 11 if (d->con_buffer[d->con_buf_pos-1] == '\n') {
184     vm_log(vm,"ROM","%s",d->con_buffer);
185     d->con_buf_pos = 0;
186     }
187     } else
188     d->con_buf_pos = 0;
189     }
190 dpavlin 1 break;
191    
192     /* Console output */
193     case 0x040:
194     if (op_type == MTS_WRITE)
195 dpavlin 7 vtty_put_char(vm->vtty_con,(char)*data);
196 dpavlin 1 break;
197    
198     /* NVRAM address */
199     case 0x044:
200     if (op_type == MTS_READ) {
201 dpavlin 7 if ((storage_dev = dev_get_by_name(vm,"nvram")))
202 dpavlin 4 *data = storage_dev->phys_addr;
203    
204 dpavlin 7 if ((storage_dev = dev_get_by_name(vm,"ssa")))
205 dpavlin 4 *data = storage_dev->phys_addr;
206 dpavlin 7
207     if (cpu->type == CPU_TYPE_MIPS64)
208     *data += MIPS_KSEG1_BASE;
209 dpavlin 1 }
210     break;
211    
212     /* IO memory size for Smart-Init (C3600, others ?) */
213     case 0x048:
214 dpavlin 11 if (op_type == MTS_READ)
215     *data = vm->nm_iomem_size;
216 dpavlin 1 break;
217 dpavlin 7
218     /* Cookie position selector */
219     case 0x04c:
220     if (op_type == MTS_READ)
221     *data = d->cookie_pos;
222     else
223     d->cookie_pos = *data;
224     break;
225 dpavlin 1
226 dpavlin 7 /* Cookie data */
227     case 0x050:
228     if ((op_type == MTS_READ) && (d->cookie_pos < 64))
229     *data = vm->chassis_cookie[d->cookie_pos];
230     break;
231 dpavlin 11
232     /* ROMMON variable */
233     case 0x054:
234     if (op_type == MTS_WRITE) {
235     if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) {
236     d->var_buffer[d->var_buf_pos++] = *data & 0xFF;
237     d->var_buffer[d->var_buf_pos] = 0;
238     } else
239     d->var_buf_pos = 0;
240     } else {
241     if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) {
242     *data = d->var_buffer[d->var_buf_pos++];
243     } else {
244     d->var_buf_pos = 0;
245     *data = 0;
246     }
247     }
248     break;
249    
250     /* ROMMON variable command */
251     case 0x058:
252     if (op_type == MTS_WRITE) {
253     switch(*data & 0xFF) {
254     case ROMMON_SET_VAR:
255     d->var_status = rommon_var_add_str(&vm->rommon_vars,
256     d->var_buffer);
257     d->var_buf_pos = 0;
258     break;
259     case ROMMON_GET_VAR:
260     d->var_status = rommon_var_get(&vm->rommon_vars,
261     d->var_buffer,
262     d->var_buffer,
263     sizeof(d->var_buffer));
264     d->var_buf_pos = 0;
265     break;
266     case ROMMON_CLEAR_VAR_STAT:
267     d->var_buf_pos = 0;
268     break;
269     default:
270     d->var_status = -1;
271     }
272     } else {
273     *data = d->var_status;
274     }
275     break;
276 dpavlin 1 }
277    
278     return NULL;
279     }
280    
281     /* Shutdown a remote control device */
282     void dev_remote_control_shutdown(vm_instance_t *vm,struct remote_data *d)
283     {
284     if (d != NULL) {
285     dev_remove(vm,&d->dev);
286     free(d);
287     }
288     }
289    
290     /* remote control device */
291     int dev_remote_control_init(vm_instance_t *vm,m_uint64_t paddr,m_uint32_t len)
292     {
293     struct remote_data *d;
294    
295     if (!(d = malloc(sizeof(*d)))) {
296     fprintf(stderr,"Remote Control: unable to create device.\n");
297     return(-1);
298     }
299    
300     memset(d,0,sizeof(*d));
301    
302     vm_object_init(&d->vm_obj);
303     d->vm_obj.name = "remote_ctrl";
304     d->vm_obj.data = d;
305     d->vm_obj.shutdown = (vm_shutdown_t)dev_remote_control_shutdown;
306    
307     dev_init(&d->dev);
308     d->dev.name = "remote_ctrl";
309     d->dev.phys_addr = paddr;
310     d->dev.phys_len = len;
311     d->dev.handler = dev_remote_control_access;
312     d->dev.priv_data = d;
313    
314     /* Map this device to the VM */
315     vm_bind_device(vm,&d->dev);
316     vm_object_add(vm,&d->vm_obj);
317     return(0);
318     }

  ViewVC Help
Powered by ViewVC 1.1.26