/[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.7-RC1/dev_c7200_mpfpga.c revision 7 by dpavlin, Sat Oct 6 16:23:47 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 router 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 Midplane FPGA.   * Cisco c7200 Midplane FPGA.
6   */   */
# Line 14  Line 14 
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_NET_IRQ  0
23  #define DEBUG_OIR      1  #define DEBUG_OIR      1
24    
25  /*  /*
# Line 87  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 125  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 134  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    
# Line 187  void *dev_c7200_mpfpga_access(cpu_gen_t Line 252  void *dev_c7200_mpfpga_access(cpu_gen_t
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 207  void *dev_c7200_mpfpga_access(cpu_gen_t Line 272  void *dev_c7200_mpfpga_access(cpu_gen_t
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 311  void *dev_c7200_mpfpga_access(cpu_gen_t Line 395  void *dev_c7200_mpfpga_access(cpu_gen_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 359  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 370  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.7  
changed lines
  Added in v.8

  ViewVC Help
Powered by ViewVC 1.1.26