/[dynamips]/trunk/dev_c6msfc1_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_c6msfc1_mpfpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 4663 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_c6msfc1.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 c6msfc1_mpfpga_data {
26 vm_obj_t vm_obj;
27 struct vdevice dev;
28
29 c6msfc1_t *router;
30 m_uint32_t irq_status;
31 m_uint32_t intr_enable;
32 };
33
34 /* Update network interrupt status */
35 static inline
36 void dev_c6msfc1_mpfpga_net_update_irq(struct c6msfc1_mpfpga_data *d)
37 {
38 if (d->irq_status) {
39 vm_set_irq(d->router->vm,C6MSFC1_NETIO_IRQ);
40 } else {
41 vm_clear_irq(d->router->vm,C6MSFC1_NETIO_IRQ);
42 }
43 }
44
45 /* Trigger a Network IRQ for the specified slot/port */
46 void dev_c6msfc1_mpfpga_net_set_irq(struct c6msfc1_mpfpga_data *d,
47 u_int slot,u_int port)
48 {
49 #if DEBUG_NET_IRQ
50 vm_log(d->router->vm,"MP_FPGA","setting NetIRQ for slot %u port %u\n",
51 slot,port);
52 #endif
53 d->irq_status |= 1 << slot;
54 dev_c6msfc1_mpfpga_net_update_irq(d);
55 }
56
57 /* Clear a Network IRQ for the specified slot/port */
58 void dev_c6msfc1_mpfpga_net_clear_irq(struct c6msfc1_mpfpga_data *d,
59 u_int slot,u_int port)
60 {
61 #if DEBUG_NET_IRQ
62 vm_log(d->router->vm,"MP_FPGA","clearing NetIRQ for slot %u port %u\n",
63 slot,port);
64 #endif
65 d->irq_status &= ~(1 << slot);
66 dev_c6msfc1_mpfpga_net_update_irq(d);
67 }
68
69 /*
70 * dev_c6msfc1_access()
71 */
72 void *dev_c6msfc1_mpfpga_access(cpu_gen_t *cpu,struct vdevice *dev,
73 m_uint32_t offset,u_int op_size,u_int op_type,
74 m_uint64_t *data)
75 {
76 struct c6msfc1_mpfpga_data *d = dev->priv_data;
77
78 if (op_type == MTS_READ)
79 *data = 0x0;
80
81 #if DEBUG_ACCESS
82 if (op_type == MTS_READ) {
83 cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
84 offset,cpu_get_pc(cpu),op_size);
85 } else {
86 cpu_log(cpu,"MP_FPGA",
87 "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
88 offset,cpu_get_pc(cpu),*data,op_size);
89 }
90 #endif
91
92 switch(offset) {
93 /*
94 * Revision + Slot: just tell we're in slot 1 (and chip rev 2)
95 * Other bits are unknown.
96 */
97 case 0x00:
98 if (op_type == MTS_READ)
99 *data = 0x12;
100 break;
101
102 /* Interrupt Control ("sh msfc") - unknown */
103 case 0x08:
104 if (op_type == MTS_READ)
105 *data = 0x1c;
106 break;
107
108 /* Interrupt Enable ("sh msfc") */
109 case 0x10:
110 if (op_type == MTS_READ)
111 *data = d->intr_enable;
112 else
113 d->intr_enable = *data;
114 break;
115
116 /*
117 * Read when a Network Interrupt is triggered.
118 * Bit 0: EOBC
119 * Bit 1: IBC
120 */
121 case 0x18:
122 case 0x1b:
123 if (op_type == MTS_READ)
124 *data = d->irq_status;
125 break;
126
127 #if DEBUG_UNKNOWN
128 default:
129 if (op_type == MTS_READ) {
130 cpu_log(cpu,"MP_FPGA","read from unknown addr 0x%x, pc=0x%llx\n",
131 offset,cpu_get_pc(cpu));
132 } else {
133 cpu_log(cpu,"MP_FPGA","write to unknown addr 0x%x, value=0x%llx, "
134 "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu));
135 }
136 #endif
137 }
138
139 return NULL;
140 }
141
142 /* Shutdown the MP FPGA device */
143 static void
144 dev_c6msfc1_mpfpga_shutdown(vm_instance_t *vm,struct c6msfc1_mpfpga_data *d)
145 {
146 if (d != NULL) {
147 /* Remove the device */
148 dev_remove(vm,&d->dev);
149
150 /* Free the structure itself */
151 free(d);
152 }
153 }
154
155 /*
156 * dev_c6msfc1_mpfpga_init()
157 */
158 int dev_c6msfc1_mpfpga_init(c6msfc1_t *router,m_uint64_t paddr,m_uint32_t len)
159 {
160 struct c6msfc1_mpfpga_data *d;
161
162 /* Allocate private data structure */
163 if (!(d = malloc(sizeof(*d)))) {
164 fprintf(stderr,"MP_FPGA: out of memory\n");
165 return(-1);
166 }
167
168 memset(d,0,sizeof(*d));
169 d->router = router;
170
171 vm_object_init(&d->vm_obj);
172 d->vm_obj.name = "mp_fpga";
173 d->vm_obj.data = d;
174 d->vm_obj.shutdown = (vm_shutdown_t)dev_c6msfc1_mpfpga_shutdown;
175
176 /* Set device properties */
177 dev_init(&d->dev);
178 d->dev.name = "mp_fpga";
179 d->dev.phys_addr = paddr;
180 d->dev.phys_len = len;
181 d->dev.handler = dev_c6msfc1_mpfpga_access;
182 d->dev.priv_data = d;
183
184 /* Map this device to the VM */
185 vm_bind_device(router->vm,&d->dev);
186 vm_object_add(router->vm,&d->vm_obj);
187 return(0);
188 }

  ViewVC Help
Powered by ViewVC 1.1.26