/[dynamips]/trunk/dev_pa_mc8te1.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_pa_mc8te1.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
2 * Cisco router simulation platform.
3 * Copyright (C) 2005-2006 Christophe Fillot. All rights reserved.
4 *
5 * PA-MC-8TE1 card. Doesn't work at this time.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <errno.h>
13 #include <pthread.h>
14 #include <assert.h>
15
16 #include "cpu.h"
17 #include "vm.h"
18 #include "dynamips.h"
19 #include "memory.h"
20 #include "device.h"
21 #include "net.h"
22 #include "net_io.h"
23 #include "ptask.h"
24 #include "dev_c7200.h"
25 #include "dev_plx.h"
26
27 /* Debugging flags */
28 #define DEBUG_ACCESS 1
29 #define DEBUG_UNKNOWN 1
30 #define DEBUG_TRANSMIT 1
31 #define DEBUG_RECEIVE 1
32
33 /* SSRAM */
34 #define SSRAM_START 0x10000
35 #define SSRAM_END 0x30000
36
37 /* PA-MC-8TE1 Data */
38 struct pa_mc_data {
39 char *name;
40 u_int irq;
41
42 /* Virtual machine */
43 vm_instance_t *vm;
44
45 /* PCI device information */
46 struct vdevice dev;
47 struct pci_device *pci_dev;
48
49 /* SSRAM device */
50 struct vdevice ssram_dev;
51 char *ssram_name;
52 m_uint8_t ssram_data[0x20000];
53
54 /* PLX9054 */
55 char *plx_name;
56 vm_obj_t *plx_obj;
57
58 /* NetIO descriptor */
59 netio_desc_t *nio;
60
61 /* TX ring scanner task id */
62 ptask_id_t tx_tid;
63 };
64
65 /* Log a PA-MC-8TE1 message */
66 #define PA_MC_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
67
68 /*
69 * dev_ssram_access
70 */
71 static void *dev_ssram_access(cpu_gen_t *cpu,struct vdevice *dev,
72 m_uint32_t offset,u_int op_size,u_int op_type,
73 m_uint64_t *data)
74 {
75 struct pa_mc_data *d = dev->priv_data;
76
77 if (op_type == MTS_READ)
78 *data = 0;
79
80 if ((offset >= SSRAM_START) && (offset < SSRAM_END))
81 return(&d->ssram_data[offset-SSRAM_START]);
82
83 #if DEBUG_ACCESS
84 if (op_type == MTS_READ) {
85 cpu_log(cpu,d->name,
86 "read access to offset = 0x%x, pc = 0x%llx (size=%u)\n",
87 offset,cpu_get_pc(cpu),op_size);
88 } else {
89 cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
90 "val = 0x%llx (size=%u)\n",
91 offset,cpu_get_pc(cpu),*data,op_size);
92 }
93 #endif
94
95 switch(offset) {
96 case 0xfff0c:
97 if (op_type == MTS_READ)
98 *data = 0xdeadbeef;
99 break;
100
101 case 0xfff10:
102 if (op_type == MTS_READ)
103 *data = 0xbeeffeed;
104 break;
105
106 case 0x08: /* max_dsx1 */
107 case 0x10: /* no_buf */
108 case 0x18: /* ev */
109 if (op_type == MTS_READ)
110 *data = 0x0ULL;
111 break;
112
113 case 0x00: /* tx packets */
114 if (op_type == MTS_READ)
115 *data = 0x0;
116 break;
117
118 case 0x04: /* rx packets */
119 if (op_type == MTS_READ)
120 *data = 0x0;
121 break;
122
123 case 0x0c: /* rx drops */
124 if (op_type == MTS_READ)
125 *data = 0;
126 break;
127 }
128
129 return NULL;
130 }
131
132 /* Callback when PLX9054 PCI-to-Local register is written */
133 static void plx9054_doorbell_callback(struct plx_data *plx_data,
134 struct pa_mc_data *pa_data,
135 m_uint32_t val)
136 {
137 printf("DOORBELL: 0x%x\n",val);
138
139 /* Trigger interrupt */
140 //vm_set_irq(pa_data->vm,pa_data->irq);
141 vm_set_irq(pa_data->vm,3);
142 }
143
144 /*
145 * pa_mc8te1_access()
146 */
147 static void *pa_mc8te1_access(cpu_gen_t *cpu,struct vdevice *dev,
148 m_uint32_t offset,u_int op_size,u_int op_type,
149 m_uint64_t *data)
150 {
151 struct pa_mc_data *d = dev->priv_data;
152
153 if (op_type == MTS_READ)
154 *data = 0;
155
156 #if DEBUG_ACCESS
157 if (op_type == MTS_READ) {
158 cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx\n",
159 offset,cpu_get_pc(cpu));
160 } else {
161 cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
162 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
163 }
164 #endif
165
166 switch(offset) {
167
168 #if DEBUG_UNKNOWN
169 default:
170 if (op_type == MTS_READ) {
171 cpu_log(cpu,d->name,
172 "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
173 offset,cpu_get_pc(cpu),op_size);
174 } else {
175 cpu_log(cpu,d->name,
176 "write to unknown addr 0x%x, value=0x%llx, "
177 "pc=0x%llx (size=%u)\n",
178 offset,*data,cpu_get_pc(cpu),op_size);
179 }
180 #endif
181 }
182
183 return NULL;
184 }
185
186 /*
187 * pci_pos_read()
188 */
189 static m_uint32_t pci_pos_read(cpu_gen_t *cpu,struct pci_device *dev,int reg)
190 {
191 struct pa_mc_data *d = dev->priv_data;
192
193 #if DEBUG_ACCESS
194 PA_MC_LOG(d,"read PCI register 0x%x\n",reg);
195 #endif
196
197 switch(reg) {
198 case PCI_REG_BAR0:
199 return(d->dev.phys_addr);
200 default:
201 return(0);
202 }
203 }
204
205 /*
206 * pci_pos_write()
207 */
208 static void pci_pos_write(cpu_gen_t *cpu,struct pci_device *dev,
209 int reg,m_uint32_t value)
210 {
211 struct pa_mc_data *d = dev->priv_data;
212
213 #if DEBUG_ACCESS
214 PA_MC_LOG(d,"write 0x%x to PCI register 0x%x\n",value,reg);
215 #endif
216
217 switch(reg) {
218 case PCI_REG_BAR0:
219 //vm_map_device(cpu->vm,&d->dev,(m_uint64_t)value);
220 PA_MC_LOG(d,"registers are mapped at 0x%x\n",value);
221 break;
222 }
223 }
224
225 /*
226 * dev_c7200_pa_mc8te1_init()
227 *
228 * Add a PA-MC-8TE1 port adapter into specified slot.
229 */
230 int dev_c7200_pa_mc8te1_init(vm_instance_t *vm,struct cisco_card *card)
231 {
232 struct pa_mc_data *d;
233 u_int slot = card->slot_id;
234
235 /* Allocate the private data structure for PA-MC-8TE1 chip */
236 if (!(d = malloc(sizeof(*d)))) {
237 vm_error(vm,"%s: out of memory\n",card->dev_name);
238 return(-1);
239 }
240
241 memset(d,0,sizeof(*d));
242 d->name = card->dev_name;
243 d->vm = vm;
244 d->irq = c7200_net_irq_for_slot_port(slot,0);
245
246 /* Set the PCI bus */
247 card->pci_bus = vm->slots_pci_bus[slot];
248
249 /* Set the EEPROM */
250 cisco_card_set_eeprom(vm,card,cisco_eeprom_find_pa("PA-MC-8TE1"));
251 c7200_set_slot_eeprom(VM_C7200(vm),slot,&card->eeprom);
252
253 /* Create the PM7380 */
254 d->pci_dev = pci_dev_add(card->pci_bus,card->dev_name,
255 0x11f8, 0x7380,
256 0,0,d->irq,d,
257 NULL,pci_pos_read,pci_pos_write);
258
259 /* Initialize SSRAM device */
260 d->ssram_name = dyn_sprintf("%s_ssram",card->dev_name);
261 dev_init(&d->ssram_dev);
262 d->ssram_dev.name = d->ssram_name;
263 d->ssram_dev.priv_data = d;
264 d->ssram_dev.handler = dev_ssram_access;
265
266 /* Create the PLX9054 */
267 d->plx_name = dyn_sprintf("%s_plx",card->dev_name);
268 d->plx_obj = dev_plx9054_init(vm,d->plx_name,
269 card->pci_bus,1,
270 &d->ssram_dev,NULL);
271
272 /* Set callback function for PLX9054 PCI-To-Local doorbell */
273 dev_plx_set_pci2loc_doorbell_cbk(d->plx_obj->data,
274 (dev_plx_doorbell_cbk)
275 plx9054_doorbell_callback,
276 d);
277
278 /* Store device info into the router structure */
279 card->drv_info = d;
280 return(0);
281 }
282
283 /* Remove a PA-POS-OC3 from the specified slot */
284 int dev_c7200_pa_mc8te1_shutdown(vm_instance_t *vm,struct cisco_card *card)
285 {
286 struct pa_mc_data *d = card->drv_info;
287
288 /* Remove the PA EEPROM */
289 cisco_card_unset_eeprom(card);
290 c7200_set_slot_eeprom(VM_C7200(vm),card->slot_id,NULL);
291
292 /* Remove the PCI device */
293 pci_dev_remove(d->pci_dev);
294
295 /* Remove the PLX9054 chip */
296 vm_object_remove(vm,d->plx_obj);
297
298 /* Remove the device from the CPU address space */
299 //vm_unbind_device(vm,&d->dev);
300 vm_unbind_device(vm,&d->ssram_dev);
301
302 cpu_group_rebuild_mts(vm->cpu_group);
303
304 /* Free the device structure itself */
305 free(d);
306 return(0);
307 }
308
309 /* Bind a Network IO descriptor to a specific port */
310 int dev_c7200_pa_mc8te1_set_nio(vm_instance_t *vm,struct cisco_card *card,
311 u_int port_id,netio_desc_t *nio)
312 {
313 struct pa_mc_data *d = card->drv_info;
314
315 if (!d || (port_id > 0))
316 return(-1);
317
318 if (d->nio != NULL)
319 return(-1);
320
321 d->nio = nio;
322 //d->tx_tid = ptask_add((ptask_callback)dev_pos_oc3_handle_txring,d,NULL);
323 //netio_rxl_add(nio,(netio_rx_handler_t)dev_pos_oc3_handle_rxring,d,NULL);
324 return(0);
325 }
326
327 /* Bind a Network IO descriptor to a specific port */
328 int dev_c7200_pa_mc8te1_unset_nio(vm_instance_t *vm,struct cisco_card *card,
329 u_int port_id)
330 {
331 struct pa_mc_data *d = card->drv_info;
332
333 if (!d || (port_id > 0))
334 return(-1);
335
336 if (d->nio) {
337 ptask_remove(d->tx_tid);
338 netio_rxl_remove(d->nio);
339 d->nio = NULL;
340 }
341 return(0);
342 }
343
344 /* PA-MC-8TE1 driver */
345 struct cisco_card_driver dev_c7200_pa_mc8te1_driver = {
346 "PA-MC-8TE1", 0, 0,
347 dev_c7200_pa_mc8te1_init,
348 dev_c7200_pa_mc8te1_shutdown,
349 NULL,
350 dev_c7200_pa_mc8te1_set_nio,
351 dev_c7200_pa_mc8te1_unset_nio,
352 NULL,
353 };

  ViewVC Help
Powered by ViewVC 1.1.26