/[dynamips]/upstream/dynamips-0.2.7-RC2/dev_c2600_iofpga.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 /upstream/dynamips-0.2.7-RC2/dev_c2600_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 6774 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <termios.h>
12 #include <fcntl.h>
13 #include <pthread.h>
14
15 #include "ptask.h"
16 #include "cpu.h"
17 #include "vm.h"
18 #include "dynamips.h"
19 #include "memory.h"
20 #include "device.h"
21 #include "dev_vtty.h"
22 #include "nmc93cX6.h"
23 #include "dev_c2600.h"
24
25 /* Debugging flags */
26 #define DEBUG_UNKNOWN 1
27 #define DEBUG_ACCESS 0
28 #define DEBUG_NET_IRQ 0
29
30 /* Definitions for Mainboard EEPROM */
31 #define EEPROM_MB_DOUT 3
32 #define EEPROM_MB_DIN 2
33 #define EEPROM_MB_CLK 1
34 #define EEPROM_MB_CS 0
35
36 /* Definitions for Network Modules EEPROM */
37 #define EEPROM_NM_DOUT 7
38 #define EEPROM_NM_DIN 6
39 #define EEPROM_NM_CLK 2
40 #define EEPROM_NM_CS 4
41
42 #define C2691_NET_IRQ_CLEARING_DELAY 16
43
44 /* Network IRQ distribution */
45 static u_int net_irq_dist[C2600_MAX_NM_BAYS] = {
46 4, /* reg 0x08, bits 4-5 */
47 0, /* reg 0x08, bits 0-3 */
48 };
49
50 /* IO FPGA structure */
51 struct c2600_iofpga_data {
52 vm_obj_t vm_obj;
53 struct vdevice dev;
54 c2600_t *router;
55
56 /* Network Interrupt status */
57 m_uint8_t net_irq_status;
58
59 /* Interrupt mask */
60 m_uint16_t intr_mask;
61 };
62
63 /* Mainboard EEPROM definition */
64 static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
65 EEPROM_MB_CLK, EEPROM_MB_CS,
66 EEPROM_MB_DIN, EEPROM_MB_DOUT,
67 };
68
69 /* Mainboard EEPROM */
70 static const struct nmc93cX6_group eeprom_mb_group = {
71 EEPROM_TYPE_NMC93C46, 1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
72 };
73
74 /* NM EEPROM definition */
75 static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
76 EEPROM_NM_CLK, EEPROM_NM_CS,
77 EEPROM_NM_DIN, EEPROM_NM_DOUT,
78 };
79
80 /* NM EEPROM */
81 static const struct nmc93cX6_group eeprom_nm_group = {
82 EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
83 };
84
85 /* Update network interrupt status */
86 static inline void dev_c2600_iofpga_net_update_irq(struct c2600_iofpga_data *d)
87 {
88 if (d->net_irq_status) {
89 vm_set_irq(d->router->vm,C2600_NETIO_IRQ);
90 } else {
91 vm_clear_irq(d->router->vm,C2600_NETIO_IRQ);
92 }
93 }
94
95 /* Trigger a Network IRQ for the specified slot/port */
96 void dev_c2600_iofpga_net_set_irq(struct c2600_iofpga_data *d,
97 u_int slot,u_int port)
98 {
99 #if DEBUG_NET_IRQ
100 vm_log(d->router->vm,"IO_FPGA","setting NetIRQ for slot %u port %u\n",
101 slot,port);
102 #endif
103 d->net_irq_status |= 1 << (net_irq_dist[slot] + port);
104 dev_c2600_iofpga_net_update_irq(d);
105 }
106
107 /* Clear a Network IRQ for the specified slot/port */
108 void dev_c2600_iofpga_net_clear_irq(struct c2600_iofpga_data *d,
109 u_int slot,u_int port)
110 {
111 #if DEBUG_NET_IRQ
112 vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
113 slot,port);
114 #endif
115 d->net_irq_status &= ~(1 << (net_irq_dist[slot] + port));
116 dev_c2600_iofpga_net_update_irq(d);
117 }
118
119 /*
120 * dev_c2600_iofpga_access()
121 */
122 static void *
123 dev_c2600_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
124 m_uint32_t offset,u_int op_size,u_int op_type,
125 m_uint64_t *data)
126 {
127 struct c2600_iofpga_data *d = dev->priv_data;
128
129 if (op_type == MTS_READ)
130 *data = 0x0;
131
132 #if DEBUG_ACCESS
133 if (op_type == MTS_READ) {
134 cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
135 offset,cpu_get_pc(cpu),op_size);
136 } else {
137 cpu_log(cpu,"IO_FPGA",
138 "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
139 offset,cpu_get_pc(cpu),*data,op_size);
140 }
141 #endif
142
143 switch(offset) {
144 case 0x04:
145 if (op_type == MTS_READ)
146 *data = 0x00;
147 break;
148
149 /*
150 * Network Interrupt.
151 *
152 * Bit 0-3: slot 1.
153 * Bit 4: slot 0 (MB), port 0
154 * Bit 5: slot 0 (MB), port 1
155 * Other: AIM ? (error messages displayed)
156 */
157 case 0x08:
158 if (op_type == MTS_READ)
159 *data = d->net_irq_status;
160 break;
161
162 case 0x10:
163 case 0x14:
164 if (op_type == MTS_READ)
165 *data = 0xFFFFFFFF;
166 break;
167
168 /*
169 * Flash Related: 0x1y
170 *
171 * Bit 1: card present in slot 0 / WIC 0.
172 * Bit 2: card present in slot 0 / WIC 1.
173 *
174 * Other bits unknown.
175 */
176 #if 1
177 case 0x0c:
178 if (op_type == MTS_READ)
179 *data = 0x10; //0x10;
180 break;
181 #endif
182
183 /* NM EEPROM */
184 case 0x1c:
185 if (op_type == MTS_WRITE)
186 nmc93cX6_write(&d->router->nm_eeprom_group,(u_int)(*data));
187 else
188 *data = nmc93cX6_read(&d->router->nm_eeprom_group);
189 break;
190
191 #if DEBUG_UNKNOWN
192 default:
193 if (op_type == MTS_READ) {
194 cpu_log(cpu,"IO_FPGA",
195 "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
196 offset,cpu_get_pc(cpu),op_size);
197 } else {
198 cpu_log(cpu,"IO_FPGA",
199 "write to unknown addr 0x%x, value=0x%llx, "
200 "pc=0x%llx (size=%u)\n",
201 offset,*data,cpu_get_pc(cpu),op_size);
202 }
203 #endif
204 }
205
206 return NULL;
207 }
208
209 /* Initialize EEPROM groups */
210 void c2600_init_eeprom_groups(c2600_t *router)
211 {
212 /* Initialize Mainboard EEPROM */
213 router->mb_eeprom_group = eeprom_mb_group;
214 router->mb_eeprom_group.eeprom[0] = &router->mb_eeprom;
215 router->mb_eeprom.data = NULL;
216 router->mb_eeprom.len = 0;
217
218 /* EEPROM for NM slot 1 */
219 router->nm_eeprom_group = eeprom_nm_group;
220 router->nm_eeprom_group.eeprom[0] = &router->nm_bay[1].eeprom;
221 }
222
223 /* Shutdown the IO FPGA device */
224 static void
225 dev_c2600_iofpga_shutdown(vm_instance_t *vm,struct c2600_iofpga_data *d)
226 {
227 if (d != NULL) {
228 /* Remove the device */
229 dev_remove(vm,&d->dev);
230
231 /* Free the structure itself */
232 free(d);
233 }
234 }
235
236 /*
237 * dev_c2600_iofpga_init()
238 */
239 int dev_c2600_iofpga_init(c2600_t *router,m_uint64_t paddr,m_uint32_t len)
240 {
241 vm_instance_t *vm = router->vm;
242 struct c2600_iofpga_data *d;
243
244 /* Allocate private data structure */
245 if (!(d = malloc(sizeof(*d)))) {
246 fprintf(stderr,"IO_FPGA: out of memory\n");
247 return(-1);
248 }
249
250 memset(d,0,sizeof(*d));
251 d->router = router;
252
253 vm_object_init(&d->vm_obj);
254 d->vm_obj.name = "io_fpga";
255 d->vm_obj.data = d;
256 d->vm_obj.shutdown = (vm_shutdown_t)dev_c2600_iofpga_shutdown;
257
258 /* Set device properties */
259 dev_init(&d->dev);
260 d->dev.name = "io_fpga";
261 d->dev.phys_addr = paddr;
262 d->dev.phys_len = len;
263 d->dev.priv_data = d;
264 d->dev.handler = dev_c2600_iofpga_access;
265
266 /* Map this device to the VM */
267 vm_bind_device(router->vm,&d->dev);
268 vm_object_add(vm,&d->vm_obj);
269 return(0);
270 }

  ViewVC Help
Powered by ViewVC 1.1.26