/[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

Contents of /trunk/dev_remote.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
2 * Cisco router simulation platform.
3 * Copyright (C) 2006 Christophe Fillot. All rights reserved.
4 *
5 * Remote control module.
6 */
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 #include "cpu.h"
20 #include "vm.h"
21 #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 #include "dev_c2691.h"
31 #include "dev_c3725.h"
32 #include "dev_c3745.h"
33 #include "dev_c2600.h"
34
35 #define DEBUG_ACCESS 0
36
37 #define ROMMON_SET_VAR 0x01
38 #define ROMMON_GET_VAR 0x02
39 #define ROMMON_CLEAR_VAR_STAT 0x03
40
41 /* Remote control private data */
42 struct remote_data {
43 vm_obj_t vm_obj;
44 struct vdevice dev;
45
46 /* Console buffer */
47 char con_buffer[512];
48 u_int con_buf_pos;
49
50 /* 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 u_int cookie_pos;
57 };
58
59 /*
60 * dev_remote_control_access()
61 */
62 void *dev_remote_control_access(cpu_gen_t *cpu,struct vdevice *dev,
63 m_uint32_t offset,u_int op_size,u_int op_type,
64 m_uint64_t *data)
65 {
66 vm_instance_t *vm = cpu->vm;
67 struct remote_data *d = dev->priv_data;
68 struct vdevice *storage_dev;
69 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 cpu_log(cpu,"REMOTE","reading reg 0x%x at pc=0x%llx\n",
77 offset,cpu_get_pc(cpu));
78 } else {
79 cpu_log(cpu,"REMOTE","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",
80 offset,cpu_get_pc(cpu),*data);
81 }
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 cpu->reg_dump(cpu);
101 break;
102
103 /* Display CPU memory info */
104 case 0x00c:
105 if (op_type == MTS_WRITE)
106 cpu->mmu_dump(cpu);
107 break;
108
109 /* Reserved/Unused */
110 case 0x010:
111 break;
112
113 /* RAM size */
114 case 0x014:
115 if (op_type == MTS_READ)
116 *data = vm->ram_size;
117 break;
118
119 /* ROM size */
120 case 0x018:
121 if (op_type == MTS_READ)
122 *data = vm->rom_size;
123 break;
124
125 /* NVRAM size */
126 case 0x01c:
127 if (op_type == MTS_READ)
128 *data = vm->nvram_size;
129 break;
130
131 /* IOMEM size */
132 case 0x020:
133 if (op_type == MTS_READ)
134 *data = vm->iomem_size;
135 break;
136
137 /* Config Register */
138 case 0x024:
139 if (op_type == MTS_READ)
140 *data = vm->conf_reg;
141 break;
142
143 /* ELF entry point */
144 case 0x028:
145 if (op_type == MTS_READ)
146 *data = vm->ios_entry_point;
147 break;
148
149 /* ELF machine id */
150 case 0x02c:
151 if (op_type == MTS_READ)
152 *data = vm->elf_machine_id;
153 break;
154
155 /* Restart IOS Image */
156 case 0x030:
157 /* not implemented */
158 break;
159
160 /* Stop the virtual machine */
161 case 0x034:
162 vm->status = VM_STATUS_SHUTDOWN;
163 break;
164
165 /* Debugging/Log message: /!\ physical address */
166 case 0x038:
167 if (op_type == MTS_WRITE) {
168 len = physmem_strlen(vm,*data);
169 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 }
173 }
174 break;
175
176 /* Console Buffering */
177 case 0x03c:
178 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
183 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 break;
191
192 /* Console output */
193 case 0x040:
194 if (op_type == MTS_WRITE)
195 vtty_put_char(vm->vtty_con,(char)*data);
196 break;
197
198 /* NVRAM address */
199 case 0x044:
200 if (op_type == MTS_READ) {
201 if ((storage_dev = dev_get_by_name(vm,"nvram")))
202 *data = storage_dev->phys_addr;
203
204 if ((storage_dev = dev_get_by_name(vm,"ssa")))
205 *data = storage_dev->phys_addr;
206
207 if (cpu->type == CPU_TYPE_MIPS64)
208 *data += MIPS_KSEG1_BASE;
209 }
210 break;
211
212 /* IO memory size for Smart-Init (C3600, others ?) */
213 case 0x048:
214 if (op_type == MTS_READ)
215 *data = vm->nm_iomem_size;
216 break;
217
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
226 /* 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
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 }
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