/[dynamips]/trunk/dev_c7200_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

Diff of /trunk/dev_c7200_mpfpga.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.6-RC4/dev_c7200_mpfpga.c revision 5 by dpavlin, Sat Oct 6 16:08:03 2007 UTC upstream/dynamips-0.2.7-RC2/dev_c7200_mpfpga.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco 7200 (Predator) simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2005-2007 Christophe Fillot (cf@utc.fr)
4   *   *
5   * Cisco C7200 (Predator) Midplane FPGA.   * Cisco c7200 Midplane FPGA.
6   */   */
7    
8  #include <stdio.h>  #include <stdio.h>
9  #include <stdlib.h>  #include <stdlib.h>
10  #include <string.h>  #include <string.h>
11    
12  #include "mips64.h"  #include "cpu.h"
13    #include "vm.h"
14  #include "dynamips.h"  #include "dynamips.h"
15  #include "memory.h"  #include "memory.h"
16  #include "device.h"  #include "device.h"
17  #include "nmc93c46.h"  #include "nmc93cX6.h"
18  #include "dev_c7200.h"  #include "dev_c7200.h"
19    
20  #define DEBUG_UNKNOWN  1  #define DEBUG_UNKNOWN  1
21  #define DEBUG_ACCESS   0  #define DEBUG_ACCESS   0
22  #define DEBUG_OIR      0  #define DEBUG_NET_IRQ  0
23    #define DEBUG_OIR      1
24    
25  /*  /*
26   * Definitions for Port Adapter Status.   * Definitions for Port Adapter Status.
# Line 86  Line 88 
88  #define BAY6_EEPROM_DOUT_BIT     22  #define BAY6_EEPROM_DOUT_BIT     22
89    
90  /* PA Bay EEPROM definitions */  /* PA Bay EEPROM definitions */
91  static const struct nmc93c46_eeprom_def eeprom_bay_def[C7200_MAX_PA_BAYS] = {  static const struct nmc93cX6_eeprom_def eeprom_bay_def[C7200_MAX_PA_BAYS] = {
92     /* Bay 0 */     /* Bay 0 */
93     { BAY0_EEPROM_CLOCK_BIT , BAY0_EEPROM_SELECT_BIT,     { BAY0_EEPROM_CLOCK_BIT , BAY0_EEPROM_SELECT_BIT,
94       BAY0_EEPROM_DIN_BIT   , BAY0_EEPROM_DOUT_BIT,       BAY0_EEPROM_DIN_BIT   , BAY0_EEPROM_DOUT_BIT,
# Line 124  static const struct nmc93c46_eeprom_def Line 126  static const struct nmc93c46_eeprom_def
126  };  };
127    
128  /* EEPROM group #1 (Bays 0, 1, 3, 4) */  /* EEPROM group #1 (Bays 0, 1, 3, 4) */
129  static const struct nmc93c46_group eeprom_bays_g1 = {  static const struct nmc93cX6_group eeprom_bays_g1 = {
130     4, 0, "PA Bays (Group #1) EEPROM", FALSE,     EEPROM_TYPE_NMC93C46, 4, 0, "PA Bays (Group #1) EEPROM", FALSE,
131    
132     { &eeprom_bay_def[0], &eeprom_bay_def[1],     { &eeprom_bay_def[0], &eeprom_bay_def[1],
133       &eeprom_bay_def[3], &eeprom_bay_def[4],       &eeprom_bay_def[3], &eeprom_bay_def[4],
# Line 133  static const struct nmc93c46_group eepro Line 135  static const struct nmc93c46_group eepro
135  };  };
136    
137  /* EEPROM group #2 (Bays 2, 5, 6) */  /* EEPROM group #2 (Bays 2, 5, 6) */
138  static const struct nmc93c46_group eeprom_bays_g2 = {  static const struct nmc93cX6_group eeprom_bays_g2 = {
139     3, 0, "PA Bays (Group #2) EEPROM", FALSE,     EEPROM_TYPE_NMC93C46, 3, 0, "PA Bays (Group #2) EEPROM", FALSE,
140    
141     { &eeprom_bay_def[2], &eeprom_bay_def[5], &eeprom_bay_def[6] },     { &eeprom_bay_def[2], &eeprom_bay_def[5], &eeprom_bay_def[6] },
142  };  };
143    
144    /* Network IRQ distribution */
145    struct net_irq_distrib  {
146       u_int reg;
147       u_int offset;
148    };
149    
150    static struct net_irq_distrib net_irq_dist[C7200_MAX_PA_BAYS] = {
151       { 0,  0 },  /* Slot 0: reg 0x10, 0x000000XX */
152       { 0,  8 },  /* Slot 1: reg 0x10, 0x0000XX00 */
153       { 1,  8 },  /* Slot 2: reg 0x18, 0x0000XX00 */
154       { 0, 24 },  /* Slot 3: reg 0x10, 0xXX000000 */
155       { 0, 16 },  /* Slot 4: reg 0x10, 0x00XX0000 */
156       { 1, 24 },  /* Slot 5: reg 0x18, 0xXX000000 */
157       { 1, 16 },  /* Slot 6: reg 0x18, 0x00XX0000 */
158    };
159    
160  /* Midplane FPGA private data */  /* Midplane FPGA private data */
161  struct mpfpga_data {  struct c7200_mpfpga_data {
162     vm_obj_t vm_obj;     vm_obj_t vm_obj;
163     struct vdevice dev;     struct vdevice dev;
164    
165     c7200_t *router;     c7200_t *router;
166     m_uint32_t pa_status_reg;     m_uint32_t pa_status_reg;
167     m_uint32_t pa_ctrl_reg;     m_uint32_t pa_ctrl_reg;
168    
169       m_uint32_t net_irq_status[2];
170       m_uint32_t net_irq_mask[2];
171  };  };
172    
173    /* Update network interrupt status */
174    static inline void dev_c7200_mpfpga_net_update_irq(struct c7200_mpfpga_data *d)
175    {
176       int status;
177    
178       status = (d->net_irq_status[0] & d->net_irq_mask[0]) ||
179          (d->net_irq_status[1] & d->net_irq_mask[1]);
180      
181       if (status) {
182          vm_set_irq(d->router->vm,C7200_NETIO_IRQ);
183       } else {
184          vm_clear_irq(d->router->vm,C7200_NETIO_IRQ);
185       }
186    }
187    
188    /* Trigger a Network IRQ for the specified slot/port */
189    void dev_c7200_mpfpga_net_set_irq(struct c7200_mpfpga_data *d,
190                                      u_int slot,u_int port)
191    {
192       struct net_irq_distrib *irq_dist;
193    
194    #if DEBUG_NET_IRQ
195       vm_log(d->router->vm,"MP_FPGA","setting NetIRQ for slot %u port %u\n",
196              slot,port);
197    #endif
198       irq_dist = &net_irq_dist[slot];
199       d->net_irq_status[irq_dist->reg] |= 1 << (irq_dist->offset + port);
200       dev_c7200_mpfpga_net_update_irq(d);
201    }
202    
203    /* Clear a Network IRQ for the specified slot/port */
204    void dev_c7200_mpfpga_net_clear_irq(struct c7200_mpfpga_data *d,
205                                        u_int slot,u_int port)
206    {
207       struct net_irq_distrib *irq_dist;
208    
209    #if DEBUG_NET_IRQ
210       vm_log(d->router->vm,"MP_FPGA","clearing NetIRQ for slot %u port %u\n",
211              slot,port);
212    #endif
213       irq_dist = &net_irq_dist[slot];
214       d->net_irq_status[irq_dist->reg] &= ~(1 << (irq_dist->offset + port));
215       dev_c7200_mpfpga_net_update_irq(d);
216    }
217    
218  /* Update Port Adapter Status */  /* Update Port Adapter Status */
219  static void pa_update_status_reg(struct mpfpga_data *d)  static void pa_update_status_reg(struct c7200_mpfpga_data *d)
220  {  {
221     m_uint32_t res = 0;     m_uint32_t res = 0;
222    
223     /* PA Power. Bay 0 is always powered */     /* PA Power. Bay 0 is always powered */
224     res |= PCI_BAY0_5V_OK | PCI_BAY0_3V_OK;     res |= PCI_BAY0_5V_OK | PCI_BAY0_3V_OK;
225      
226     /* We fake power on bays defined by the final user */     /* We fake power on bays defined by the final user */
227     if (c7200_pa_check_eeprom(d->router,1))     if (c7200_pa_check_eeprom(d->router,1))
228        res |= PCI_BAY1_5V_OK | PCI_BAY1_3V_OK;        res |= PCI_BAY1_5V_OK | PCI_BAY1_3V_OK;
# Line 182  static void pa_update_status_reg(struct Line 248  static void pa_update_status_reg(struct
248  /*  /*
249   * dev_mpfpga_access()   * dev_mpfpga_access()
250   */   */
251  void *dev_c7200_mpfpga_access(cpu_mips_t *cpu,struct vdevice *dev,  void *dev_c7200_mpfpga_access(cpu_gen_t *cpu,struct vdevice *dev,
252                                m_uint32_t offset,u_int op_size,u_int op_type,                                m_uint32_t offset,u_int op_size,u_int op_type,
253                                m_uint64_t *data)                                m_uint64_t *data)
254  {  {
255     struct mpfpga_data *d = dev->priv_data;     struct c7200_mpfpga_data *d = dev->priv_data;
256    
257     if (op_type == MTS_READ)     if (op_type == MTS_READ)
258        *data = 0x0;        *data = 0x0;
# Line 198  void *dev_c7200_mpfpga_access(cpu_mips_t Line 264  void *dev_c7200_mpfpga_access(cpu_mips_t
264  #if DEBUG_ACCESS  #if DEBUG_ACCESS
265     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
266        cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",        cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
267                offset,cpu->pc,op_size);                offset,cpu_get_pc(cpu),op_size);
268     } else {     } else {
269        cpu_log(cpu,"MP_FPGA",        cpu_log(cpu,"MP_FPGA",
270                "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",                "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
271                offset,cpu->pc,*data,op_size);                offset,cpu_get_pc(cpu),*data,op_size);
272     }     }
273  #endif  #endif
274    
275     switch(offset) {           switch(offset) {
276        case 0x10:  /* interrupt mask, should be done more efficiently */        /* Interrupt status for slots 0, 1, 3, 4 */
277          case 0x10:
278        case 0x11:        case 0x11:
279        case 0x12:        case 0x12:
280        case 0x13:        case 0x13:
281           if (op_type == MTS_READ) {           if (op_type == MTS_READ)
282              *data = 0xFFFFFFFF;              *data = d->net_irq_status[0];
             vm_clear_irq(d->router->vm,C7200_NETIO_IRQ);  
          }  
283           break;           break;
284    
285        case 0x18:  /* interrupt mask, should be done more efficiently */        /* Interrupt status for slots 2, 5, 6 */
286          case 0x18:
287        case 0x19:        case 0x19:
288        case 0x1a:        case 0x1a:
289          case 0x1b:
290             if (op_type == MTS_READ)
291                *data = d->net_irq_status[1];
292             break;
293    
294          /* Interrupt mask for slots 0, 1, 3, 4 */
295          case 0x20:
296           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
297              *data = 0xFFFFFFFF;              *data = d->net_irq_mask[0];
298              vm_clear_irq(d->router->vm,C7200_NETIO_IRQ);           } else {
299                d->net_irq_mask[0] = *data;
300                dev_c7200_mpfpga_net_update_irq(d);
301             }
302             break;
303    
304          /* Interrupt mask for slots 2, 5, 6 */
305          case 0x28:
306             if (op_type == MTS_READ) {
307                *data = d->net_irq_mask[1];
308             } else {
309                d->net_irq_mask[1] = *data;
310                dev_c7200_mpfpga_net_update_irq(d);
311           }           }
312           break;           break;
313    
# Line 239  void *dev_c7200_mpfpga_access(cpu_mips_t Line 324  void *dev_c7200_mpfpga_access(cpu_mips_t
324           if (op_type == MTS_READ)           if (op_type == MTS_READ)
325              *data = 0x66666600 & d->pa_status_reg;              *data = 0x66666600 & d->pa_status_reg;
326    
327           mips64_clear_irq(cpu,C7200_PA_MGMT_IRQ);           vm_clear_irq(d->router->vm,C7200_PA_MGMT_IRQ);
328           break;           break;
329    
330        case 0x48:  /* ??? (test) */        case 0x48:  /* ??? (test) */
# Line 258  void *dev_c7200_mpfpga_access(cpu_mips_t Line 343  void *dev_c7200_mpfpga_access(cpu_mips_t
343           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
344  #if DEBUG_OIR  #if DEBUG_OIR
345              cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx, val=0x%x\n",              cpu_log(cpu,"MP_FPGA","reading reg 0x%x at pc=0x%llx, val=0x%x\n",
346                      offset,cpu->pc,d->router->oir_status);                      offset,cpu_get_pc(cpu),d->router->oir_status);
347  #endif  #endif
348              *data = d->router->oir_status;              *data = d->router->oir_status;
349                vm_clear_irq(d->router->vm,C7200_OIR_IRQ);
350           } else {           } else {
351  #if DEBUG_OIR  #if DEBUG_OIR
352              cpu_log(cpu,"MP_FPGA","writing reg 0x%x at pc=0x%llx "              cpu_log(cpu,"MP_FPGA","writing reg 0x%x at pc=0x%llx "
353                      "(data=0x%llx)\n",offset,cpu->pc,*data);                      "(data=0x%llx)\n",offset,cpu_get_pc(cpu),*data);
354  #endif  #endif
355              d->router->oir_status &= ~(*data);              d->router->oir_status &= ~(*data);
356              vm_clear_irq(d->router->vm,C7200_OIR_IRQ);                                  vm_clear_irq(d->router->vm,C7200_OIR_IRQ);                    
# Line 278  void *dev_c7200_mpfpga_access(cpu_mips_t Line 364  void *dev_c7200_mpfpga_access(cpu_mips_t
364        case 0x78:        case 0x78:
365           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
366  #if DEBUG_OIR  #if DEBUG_OIR
367              cpu_log(cpu,"MP_FPGA","reading 0x78 at pc=0x%llx\n",cpu->pc);              cpu_log(cpu,"MP_FPGA","reading 0x78 at pc=0x%llx\n",
368                        cpu_get_pc(cpu));
369  #endif  #endif
370              *data = 0x00;              *data = 0x00;
371           } else {           } else {
372  #if DEBUG_OIR  #if DEBUG_OIR
373              cpu_log(cpu,"MP_FPGA","writing reg 0x78 at pc=0x%llx "              cpu_log(cpu,"MP_FPGA","writing reg 0x78 at pc=0x%llx "
374                    "(data=0x%llx)\n",cpu->pc,*data);                    "(data=0x%llx)\n",cpu_get_pc(cpu),*data);
375  #endif  #endif
376           }           }
377           break;           break;
# Line 308  void *dev_c7200_mpfpga_access(cpu_mips_t Line 395  void *dev_c7200_mpfpga_access(cpu_mips_t
395    
396        case 0x60:   /* EEPROM for PA in slots 0,1,3,4 */        case 0x60:   /* EEPROM for PA in slots 0,1,3,4 */
397           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
398              nmc93c46_write(&d->router->pa_eeprom_g1,*data);              nmc93cX6_write(&d->router->pa_eeprom_g1,*data);
399           else           else
400              *data = nmc93c46_read(&d->router->pa_eeprom_g1);              *data = nmc93cX6_read(&d->router->pa_eeprom_g1);
401           break;           break;
402    
403        case 0x68:   /* EEPROM for PA in slots 2,5,6 */        case 0x68:   /* EEPROM for PA in slots 2,5,6 */
404           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
405              nmc93c46_write(&d->router->pa_eeprom_g2,*data);              nmc93cX6_write(&d->router->pa_eeprom_g2,*data);
406           else           else
407              *data = nmc93c46_read(&d->router->pa_eeprom_g2);              *data = nmc93cX6_read(&d->router->pa_eeprom_g2);
408           break;           break;
409    
410        case 0x7b:  /* ??? */        case 0x7b:  /* ??? */
# Line 327  void *dev_c7200_mpfpga_access(cpu_mips_t Line 414  void *dev_c7200_mpfpga_access(cpu_mips_t
414        default:        default:
415           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
416              cpu_log(cpu,"MP_FPGA","read from addr 0x%x, pc=0x%llx\n",              cpu_log(cpu,"MP_FPGA","read from addr 0x%x, pc=0x%llx\n",
417                      offset,cpu->pc);                      offset,cpu_get_pc(cpu));
418           } else {           } else {
419              cpu_log(cpu,"MP_FPGA","write to addr 0x%x, value=0x%llx, "              cpu_log(cpu,"MP_FPGA","write to addr 0x%x, value=0x%llx, "
420                      "pc=0x%llx\n",offset,*data,cpu->pc);                      "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu));
421           }           }
422  #endif  #endif
423     }     }
# Line 356  static void init_eeprom_groups(c7200_t * Line 443  static void init_eeprom_groups(c7200_t *
443  }  }
444    
445  /* Shutdown the MP FPGA device */  /* Shutdown the MP FPGA device */
446  void dev_c7200_mpfpga_shutdown(vm_instance_t *vm,struct mpfpga_data *d)  static void
447    dev_c7200_mpfpga_shutdown(vm_instance_t *vm,struct c7200_mpfpga_data *d)
448  {  {
449     if (d != NULL) {     if (d != NULL) {
450        /* Remove the device */        /* Remove the device */
# Line 367  void dev_c7200_mpfpga_shutdown(vm_instan Line 455  void dev_c7200_mpfpga_shutdown(vm_instan
455     }     }
456  }  }
457    
458  /*  /* Create the c7200 Midplane FPGA */
  * dev_c7200_mpfpga_init()  
  */  
459  int dev_c7200_mpfpga_init(c7200_t *router,m_uint64_t paddr,m_uint32_t len)  int dev_c7200_mpfpga_init(c7200_t *router,m_uint64_t paddr,m_uint32_t len)
460  {    {  
461     struct mpfpga_data *d;     struct c7200_mpfpga_data *d;
462    
463     /* Allocate private data structure */     /* Allocate private data structure */
464     if (!(d = malloc(sizeof(*d)))) {     if (!(d = malloc(sizeof(*d)))) {

Legend:
Removed from v.5  
changed lines
  Added in v.8

  ViewVC Help
Powered by ViewVC 1.1.26