/[dynamips]/trunk/dev_msfc1_mpfpga.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_msfc1_mpfpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations)
Sat Oct 6 16:29:14 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7/dev_msfc1_mpfpga.c
File MIME type: text/plain
File size: 4611 byte(s)
dynamips-0.2.7

1 dpavlin 8 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2007 Christophe Fillot (cf@utc.fr)
4     *
5     * MSFC1 Midplane FPGA.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11    
12     #include "cpu.h"
13     #include "vm.h"
14     #include "dynamips.h"
15     #include "memory.h"
16     #include "device.h"
17     #include "nmc93cX6.h"
18     #include "dev_msfc1.h"
19    
20     #define DEBUG_UNKNOWN 1
21     #define DEBUG_ACCESS 1
22     #define DEBUG_NET_IRQ 1
23    
24     /* Midplane FPGA private data */
25     struct msfc1_mpfpga_data {
26     vm_obj_t vm_obj;
27     struct vdevice dev;
28    
29     msfc1_t *router;
30     m_uint32_t irq_status;
31     m_uint32_t intr_enable;
32     };
33    
34     /* Update network interrupt status */
35     static inline void dev_msfc1_mpfpga_net_update_irq(struct msfc1_mpfpga_data *d)
36     {
37     if (d->irq_status) {
38     vm_set_irq(d->router->vm,MSFC1_NETIO_IRQ);
39     } else {
40     vm_clear_irq(d->router->vm,MSFC1_NETIO_IRQ);
41     }
42     }
43    
44     /* Trigger a Network IRQ for the specified slot/port */
45     void dev_msfc1_mpfpga_net_set_irq(struct msfc1_mpfpga_data *d,
46     u_int slot,u_int port)
47     {
48     #if DEBUG_NET_IRQ
49     vm_log(d->router->vm,"MP_FPGA","setting NetIRQ for slot %u port %u\n",
50     slot,port);
51     #endif
52     //d->net_irq_status[irq_dist->reg] |= 1 << (irq_dist->offset + port);
53     dev_msfc1_mpfpga_net_update_irq(d);
54     }
55    
56     /* Clear a Network IRQ for the specified slot/port */
57     void dev_msfc1_mpfpga_net_clear_irq(struct msfc1_mpfpga_data *d,
58     u_int slot,u_int port)
59     {
60     #if DEBUG_NET_IRQ
61     vm_log(d->router->vm,"MP_FPGA","clearing NetIRQ for slot %u port %u\n",
62     slot,port);
63     #endif
64     //d->net_irq_status[irq_dist->reg] &= ~(1 << (irq_dist->offset + port));
65     dev_msfc1_mpfpga_net_update_irq(d);
66     }
67    
68     /*
69     * dev_msfc1_access()
70     */
71     void *dev_msfc1_mpfpga_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 msfc1_mpfpga_data *d = dev->priv_data;
76    
77     if (op_type == MTS_READ)
78     *data = 0x0;
79    
80     #if DEBUG_ACCESS
81     if (op_type == MTS_READ) {
82     cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
83     offset,cpu_get_pc(cpu),op_size);
84     } else {
85     cpu_log(cpu,"MP_FPGA",
86     "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
87     offset,cpu_get_pc(cpu),*data,op_size);
88     }
89     #endif
90    
91     switch(offset) {
92     /*
93     * Revision + Slot: just tell we're in slot 1 (and chip rev 2)
94     * Other bits are unknown.
95     */
96     case 0x00:
97     if (op_type == MTS_READ)
98     *data = 0x12;
99     break;
100    
101     /* Interrupt Control ("sh msfc") - unknown */
102     case 0x08:
103     if (op_type == MTS_READ)
104     *data = 0x1c;
105     break;
106    
107     /* Interrupt Enable ("sh msfc") */
108     case 0x10:
109     if (op_type == MTS_READ)
110     *data = d->intr_enable;
111     else
112     d->intr_enable = *data;
113     break;
114    
115     /* Read when a Network Interrupt is triggered */
116     case 0x18:
117     case 0x1b:
118     if (op_type == MTS_READ)
119     *data = d->irq_status;
120     break;
121    
122     #if DEBUG_UNKNOWN
123     default:
124     if (op_type == MTS_READ) {
125     cpu_log(cpu,"MP_FPGA","read from addr 0x%x, pc=0x%llx\n",
126     offset,cpu_get_pc(cpu));
127     } else {
128     cpu_log(cpu,"MP_FPGA","write to addr 0x%x, value=0x%llx, "
129     "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu));
130     }
131     #endif
132     }
133    
134     return NULL;
135     }
136    
137     /* Shutdown the MP FPGA device */
138     static void
139     dev_msfc1_mpfpga_shutdown(vm_instance_t *vm,struct msfc1_mpfpga_data *d)
140     {
141     if (d != NULL) {
142     /* Remove the device */
143     dev_remove(vm,&d->dev);
144    
145     /* Free the structure itself */
146     free(d);
147     }
148     }
149    
150     /*
151     * dev_msfc1_mpfpga_init()
152     */
153     int dev_msfc1_mpfpga_init(msfc1_t *router,m_uint64_t paddr,m_uint32_t len)
154     {
155     struct msfc1_mpfpga_data *d;
156    
157     /* Allocate private data structure */
158     if (!(d = malloc(sizeof(*d)))) {
159     fprintf(stderr,"MP_FPGA: out of memory\n");
160     return(-1);
161     }
162    
163     memset(d,0,sizeof(*d));
164     d->router = router;
165    
166     vm_object_init(&d->vm_obj);
167     d->vm_obj.name = "mp_fpga";
168     d->vm_obj.data = d;
169     d->vm_obj.shutdown = (vm_shutdown_t)dev_msfc1_mpfpga_shutdown;
170    
171     /* Set device properties */
172     dev_init(&d->dev);
173     d->dev.name = "mp_fpga";
174     d->dev.phys_addr = paddr;
175     d->dev.phys_len = len;
176     d->dev.handler = dev_msfc1_mpfpga_access;
177     d->dev.priv_data = d;
178    
179     /* Map this device to the VM */
180     vm_bind_device(router->vm,&d->dev);
181     vm_object_add(router->vm,&d->vm_obj);
182     return(0);
183     }

  ViewVC Help
Powered by ViewVC 1.1.26