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

Contents of /trunk/dev_msfc1_mpfpga.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
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