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

Annotation of /trunk/dev_pa_mc8te1.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: 8848 byte(s)
make working copy

1 dpavlin 4 /*
2 dpavlin 7 * Cisco router simulation platform.
3 dpavlin 4 * 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 dpavlin 7 #include "cpu.h"
17     #include "vm.h"
18 dpavlin 4 #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 dpavlin 8 u_int irq;
41 dpavlin 4
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 dpavlin 8 char *plx_name;
56 dpavlin 4 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 dpavlin 7 static void *dev_ssram_access(cpu_gen_t *cpu,struct vdevice *dev,
72 dpavlin 4 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 dpavlin 7 offset,cpu_get_pc(cpu),op_size);
88 dpavlin 4 } else {
89     cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
90 dpavlin 7 "val = 0x%llx (size=%u)\n",
91     offset,cpu_get_pc(cpu),*data,op_size);
92 dpavlin 4 }
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 dpavlin 8 //vm_set_irq(pa_data->vm,pa_data->irq);
141 dpavlin 4 vm_set_irq(pa_data->vm,3);
142     }
143    
144     /*
145     * pa_mc8te1_access()
146     */
147 dpavlin 7 static void *pa_mc8te1_access(cpu_gen_t *cpu,struct vdevice *dev,
148 dpavlin 4 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 dpavlin 7 offset,cpu_get_pc(cpu));
160 dpavlin 4 } else {
161     cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
162 dpavlin 7 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
163 dpavlin 4 }
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 dpavlin 7 offset,cpu_get_pc(cpu),op_size);
174 dpavlin 4 } else {
175     cpu_log(cpu,d->name,
176     "write to unknown addr 0x%x, value=0x%llx, "
177 dpavlin 7 "pc=0x%llx (size=%u)\n",
178     offset,*data,cpu_get_pc(cpu),op_size);
179 dpavlin 4 }
180     #endif
181     }
182    
183     return NULL;
184     }
185    
186     /*
187     * pci_pos_read()
188     */
189 dpavlin 7 static m_uint32_t pci_pos_read(cpu_gen_t *cpu,struct pci_device *dev,int reg)
190 dpavlin 4 {
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 dpavlin 7 static void pci_pos_write(cpu_gen_t *cpu,struct pci_device *dev,
209 dpavlin 4 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 dpavlin 11 int dev_c7200_pa_mc8te1_init(vm_instance_t *vm,struct cisco_card *card)
231 dpavlin 4 {
232     struct pa_mc_data *d;
233 dpavlin 11 u_int slot = card->slot_id;
234 dpavlin 4
235     /* Allocate the private data structure for PA-MC-8TE1 chip */
236     if (!(d = malloc(sizeof(*d)))) {
237 dpavlin 11 vm_error(vm,"%s: out of memory\n",card->dev_name);
238 dpavlin 4 return(-1);
239     }
240    
241     memset(d,0,sizeof(*d));
242 dpavlin 11 d->name = card->dev_name;
243     d->vm = vm;
244     d->irq = c7200_net_irq_for_slot_port(slot,0);
245 dpavlin 4
246 dpavlin 11 /* Set the PCI bus */
247     card->pci_bus = vm->slots_pci_bus[slot];
248    
249 dpavlin 4 /* Set the EEPROM */
250 dpavlin 11 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 dpavlin 4
253     /* Create the PM7380 */
254 dpavlin 11 d->pci_dev = pci_dev_add(card->pci_bus,card->dev_name,
255 dpavlin 4 0x11f8, 0x7380,
256 dpavlin 8 0,0,d->irq,d,
257 dpavlin 4 NULL,pci_pos_read,pci_pos_write);
258    
259     /* Initialize SSRAM device */
260 dpavlin 11 d->ssram_name = dyn_sprintf("%s_ssram",card->dev_name);
261 dpavlin 4 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 dpavlin 11 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 dpavlin 4 &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 dpavlin 11 card->drv_info = d;
280     return(0);
281 dpavlin 4 }
282    
283     /* Remove a PA-POS-OC3 from the specified slot */
284 dpavlin 11 int dev_c7200_pa_mc8te1_shutdown(vm_instance_t *vm,struct cisco_card *card)
285 dpavlin 4 {
286 dpavlin 11 struct pa_mc_data *d = card->drv_info;
287 dpavlin 4
288     /* Remove the PA EEPROM */
289 dpavlin 11 cisco_card_unset_eeprom(card);
290     c7200_set_slot_eeprom(VM_C7200(vm),card->slot_id,NULL);
291 dpavlin 4
292     /* Remove the PCI device */
293     pci_dev_remove(d->pci_dev);
294    
295     /* Remove the PLX9054 chip */
296 dpavlin 11 vm_object_remove(vm,d->plx_obj);
297 dpavlin 4
298     /* Remove the device from the CPU address space */
299 dpavlin 11 //vm_unbind_device(vm,&d->dev);
300     vm_unbind_device(vm,&d->ssram_dev);
301 dpavlin 4
302 dpavlin 11 cpu_group_rebuild_mts(vm->cpu_group);
303 dpavlin 4
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 dpavlin 11 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 dpavlin 4 {
313 dpavlin 11 struct pa_mc_data *d = card->drv_info;
314 dpavlin 4
315 dpavlin 11 if (!d || (port_id > 0))
316 dpavlin 4 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 dpavlin 11 int dev_c7200_pa_mc8te1_unset_nio(vm_instance_t *vm,struct cisco_card *card,
329     u_int port_id)
330 dpavlin 4 {
331 dpavlin 11 struct pa_mc_data *d = card->drv_info;
332 dpavlin 4
333 dpavlin 11 if (!d || (port_id > 0))
334 dpavlin 4 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 dpavlin 11 struct cisco_card_driver dev_c7200_pa_mc8te1_driver = {
346     "PA-MC-8TE1", 0, 0,
347 dpavlin 4 dev_c7200_pa_mc8te1_init,
348     dev_c7200_pa_mc8te1_shutdown,
349 dpavlin 11 NULL,
350 dpavlin 4 dev_c7200_pa_mc8te1_set_nio,
351     dev_c7200_pa_mc8te1_unset_nio,
352     NULL,
353     };

  ViewVC Help
Powered by ViewVC 1.1.26