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

Diff of /trunk/dev_c3725_iofpga.c

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

upstream/dynamips-0.2.6-RC5/dev_c3725_iofpga.c revision 6 by dpavlin, Sat Oct 6 16:09:07 2007 UTC upstream/dynamips-0.2.7-RC2/dev_c3725_iofpga.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 15  Line 15 
15  #include <pthread.h>  #include <pthread.h>
16    
17  #include "ptask.h"  #include "ptask.h"
18  #include "mips64.h"  #include "cpu.h"
19    #include "vm.h"
20  #include "dynamips.h"  #include "dynamips.h"
21  #include "memory.h"  #include "memory.h"
22  #include "device.h"  #include "device.h"
23  #include "dev_vtty.h"  #include "dev_vtty.h"
24  #include "nmc93c46.h"  #include "nmc93cX6.h"
25  #include "dev_c3725.h"  #include "dev_c3725.h"
26    
27  /* Debugging flags */  /* Debugging flags */
28  #define DEBUG_UNKNOWN   1  #define DEBUG_UNKNOWN   1
29  #define DEBUG_ACCESS    0  #define DEBUG_ACCESS    0
30    #define DEBUG_NET_IRQ   0
31    
32  /* Definitions for Mainboard EEPROM */  /* Definitions for Mainboard EEPROM */
33  #define EEPROM_MB_DOUT  3  #define EEPROM_MB_DOUT  3
# Line 39  Line 41 
41  #define EEPROM_NM_CLK   2  #define EEPROM_NM_CLK   2
42  #define EEPROM_NM_CS    4  #define EEPROM_NM_CS    4
43    
44  #define C3725_NET_IRQ_CLEARING_DELAY  16  /* Network IRQ distribution */
45    struct net_irq_distrib  {
46       u_int reg;
47       u_int offset;
48    };
49    
50    static struct net_irq_distrib net_irq_dist[C3725_MAX_NM_BAYS] = {
51       { 0,  0 },  /* Slot 0: reg 0x26, 0x000000XX */
52       { 1,  0 },  /* Slot 1: reg 0x28, 0x000000XX */
53       { 1,  8 },  /* Slot 2: reg 0x28, 0x0000XX00 */
54    };
55    
56  /* IO FPGA structure */  /* IO FPGA structure */
57  struct iofpga_data {  struct c3725_iofpga_data {
58     vm_obj_t vm_obj;     vm_obj_t vm_obj;
59     struct vdevice dev;     struct vdevice dev;
60     c3725_t *router;     c3725_t *router;
     
    /*  
     * Used to introduce a "delay" before clearing the network interrupt  
     * on 3620/3640 platforms. Added due to a packet loss when using an  
     * Ethernet NM on these platforms.  
     *  
     * Anyway, we should rely on the device information with appropriate IRQ  
     * routing.  
     */  
    int net_irq_clearing_count;  
61    
62     /* Interrupt mask*/     /* Network IRQ status */
63       m_uint16_t net_irq_status[2];
64    
65       /* Interrupt mask */
66     m_uint16_t intr_mask;     m_uint16_t intr_mask;
67  };  };
68    
69  /* Mainboard EEPROM definition */  /* Mainboard EEPROM definition */
70  static const struct nmc93c46_eeprom_def eeprom_mb_def = {  static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
71     EEPROM_MB_CLK, EEPROM_MB_CS,     EEPROM_MB_CLK, EEPROM_MB_CS,
72     EEPROM_MB_DIN, EEPROM_MB_DOUT,     EEPROM_MB_DIN, EEPROM_MB_DOUT,
73  };  };
74    
75  /* Mainboard EEPROM */  /* Mainboard EEPROM */
76  static const struct nmc93c46_group eeprom_mb_group = {  static const struct nmc93cX6_group eeprom_mb_group = {
77     1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },     EEPROM_TYPE_NMC93C46, 1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
78  };  };
79    
80  /* NM EEPROM definition */  /* NM EEPROM definition */
81  static const struct nmc93c46_eeprom_def eeprom_nm_def = {  static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
82     EEPROM_NM_CLK, EEPROM_NM_CS,     EEPROM_NM_CLK, EEPROM_NM_CS,
83     EEPROM_NM_DIN, EEPROM_NM_DOUT,     EEPROM_NM_DIN, EEPROM_NM_DOUT,
84  };  };
85    
86  /* NM EEPROM */  /* NM EEPROM */
87  static const struct nmc93c46_group eeprom_nm_group = {  static const struct nmc93cX6_group eeprom_nm_group = {
88     1, 0, "NM EEPROM", 0, { &eeprom_nm_def },     EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
89  };  };
90    
91    /* Update network interrupt status */
92    static inline void dev_c3725_iofpga_net_update_irq(struct c3725_iofpga_data *d)
93    {
94       if ((d->net_irq_status[0] != 0xFFFF) || (d->net_irq_status[1] != 0xFFFF)) {
95          vm_set_irq(d->router->vm,C3725_NETIO_IRQ);
96       } else {
97          vm_clear_irq(d->router->vm,C3725_NETIO_IRQ);
98       }
99    }
100    
101    /* Trigger a Network IRQ for the specified slot/port */
102    void dev_c3725_iofpga_net_set_irq(struct c3725_iofpga_data *d,
103                                      u_int slot,u_int port)
104    {
105       struct net_irq_distrib *irq_dist;
106    
107    #if DEBUG_NET_IRQ
108       vm_log(d->router->vm,"IO_FPGA","setting NetIRQ for slot %u port %u\n",
109              slot,port);
110    #endif
111       irq_dist = &net_irq_dist[slot];
112       d->net_irq_status[irq_dist->reg] &= ~(1 << (irq_dist->offset + port));
113       dev_c3725_iofpga_net_update_irq(d);
114    }
115    
116    /* Clear a Network IRQ for the specified slot/port */
117    void dev_c3725_iofpga_net_clear_irq(struct c3725_iofpga_data *d,
118                                        u_int slot,u_int port)
119    {
120       struct net_irq_distrib *irq_dist;
121    
122    #if DEBUG_NET_IRQ
123       vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
124              slot,port);
125    #endif
126       irq_dist = &net_irq_dist[slot];
127       d->net_irq_status[irq_dist->reg] |= (1 << (irq_dist->offset + port));
128       dev_c3725_iofpga_net_update_irq(d);
129    }
130    
131  /*  /*
132   * dev_c3725_iofpga_access()   * dev_c3725_iofpga_access()
133   */   */
134  static void *  static void *
135  dev_c3725_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,  dev_c3725_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
136                          m_uint32_t offset,u_int op_size,u_int op_type,                          m_uint32_t offset,u_int op_size,u_int op_type,
137                          m_uint64_t *data)                          m_uint64_t *data)
138  {  {
139     struct iofpga_data *d = dev->priv_data;     struct c3725_iofpga_data *d = dev->priv_data;
140    
141     if (op_type == MTS_READ)     if (op_type == MTS_READ)
142        *data = 0x0;        *data = 0x0;
# Line 99  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 144  dev_c3725_iofpga_access(cpu_mips_t *cpu,
144  #if DEBUG_ACCESS  #if DEBUG_ACCESS
145     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
146        cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",        cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
147                offset,cpu->pc,op_size);                offset,cpu_get_pc(cpu),op_size);
148     } else {     } else {
149        cpu_log(cpu,"IO_FPGA",        cpu_log(cpu,"IO_FPGA",
150                "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",
151                offset,cpu->pc,*data,op_size);                offset,cpu_get_pc(cpu),*data,op_size);
152     }     }
153  #endif  #endif
154    
# Line 120  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 165  dev_c3725_iofpga_access(cpu_mips_t *cpu,
165        /* Mainboard EEPROM */        /* Mainboard EEPROM */
166        case 0x0e:        case 0x0e:
167           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
168              nmc93c46_write(&d->router->mb_eeprom_group,(u_int)(*data));              nmc93cX6_write(&d->router->mb_eeprom_group,(u_int)(*data));
169           else           else
170              *data = nmc93c46_read(&d->router->mb_eeprom_group);              *data = nmc93cX6_read(&d->router->mb_eeprom_group);
171           break;           break;
172    
173        case 0x12:        case 0x12:
# Line 158  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 203  dev_c3725_iofpga_access(cpu_mips_t *cpu,
203        /* NM Slot 1 EEPROM */        /* NM Slot 1 EEPROM */
204        case 0x44:        case 0x44:
205           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
206              nmc93c46_write(&d->router->nm_eeprom_group[0],(u_int)(*data));              nmc93cX6_write(&d->router->nm_eeprom_group[0],(u_int)(*data));
207           else           else
208              *data = nmc93c46_read(&d->router->nm_eeprom_group[0]);              *data = nmc93cX6_read(&d->router->nm_eeprom_group[0]);
209           break;           break;
210    
211        /* NM Slot 2 EEPROM */        /* NM Slot 2 EEPROM */
212        case 0x46:        case 0x46:
213           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
214              nmc93c46_write(&d->router->nm_eeprom_group[1],(u_int)(*data));              nmc93cX6_write(&d->router->nm_eeprom_group[1],(u_int)(*data));
215           else           else
216              *data = nmc93c46_read(&d->router->nm_eeprom_group[1]);              *data = nmc93cX6_read(&d->router->nm_eeprom_group[1]);
217           break;           break;
218    
219        /* AIM EEPROM #0 */        /* AIM EEPROM #0 */
# Line 222  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 267  dev_c3725_iofpga_access(cpu_mips_t *cpu,
267         */         */
268        case 0x26:        case 0x26:
269           if (op_type == MTS_READ)           if (op_type == MTS_READ)
270              *data = 0xFFFE;              *data = d->net_irq_status[0];
271           break;           break;
272    
273        /*        /*
# Line 233  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 278  dev_c3725_iofpga_access(cpu_mips_t *cpu,
278         * Other bits unknown.         * Other bits unknown.
279         */         */
280        case 0x28:        case 0x28:
281           if (op_type == MTS_READ) {           if (op_type == MTS_READ)
282              *data = 0xFFEE;              *data = d->net_irq_status[1];
   
             if (++d->net_irq_clearing_count == C3725_NET_IRQ_CLEARING_DELAY) {  
                vm_clear_irq(d->router->vm,C3725_NETIO_IRQ);  
                d->net_irq_clearing_count = 0;  
             }  
          }  
283           break;           break;
284    
285        case 0x2c:        case 0x2c:
# Line 294  dev_c3725_iofpga_access(cpu_mips_t *cpu, Line 333  dev_c3725_iofpga_access(cpu_mips_t *cpu,
333           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
334              cpu_log(cpu,"IO_FPGA",              cpu_log(cpu,"IO_FPGA",
335                      "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",                      "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
336                      offset,cpu->pc,op_size);                      offset,cpu_get_pc(cpu),op_size);
337           } else {           } else {
338              cpu_log(cpu,"IO_FPGA",              cpu_log(cpu,"IO_FPGA",
339                      "write to unknown addr 0x%x, value=0x%llx, "                      "write to unknown addr 0x%x, value=0x%llx, "
340                      "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                      "pc=0x%llx (size=%u)\n",
341                        offset,*data,cpu_get_pc(cpu),op_size);
342           }           }
343  #endif  #endif
344     }     }
# Line 325  void c3725_init_eeprom_groups(c3725_t *r Line 365  void c3725_init_eeprom_groups(c3725_t *r
365  }  }
366    
367  /* Shutdown the IO FPGA device */  /* Shutdown the IO FPGA device */
368  void dev_c3725_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)  static void
369    dev_c3725_iofpga_shutdown(vm_instance_t *vm,struct c3725_iofpga_data *d)
370  {  {
371     if (d != NULL) {     if (d != NULL) {
372        /* Remove the device */        /* Remove the device */
# Line 342  void dev_c3725_iofpga_shutdown(vm_instan Line 383  void dev_c3725_iofpga_shutdown(vm_instan
383  int dev_c3725_iofpga_init(c3725_t *router,m_uint64_t paddr,m_uint32_t len)  int dev_c3725_iofpga_init(c3725_t *router,m_uint64_t paddr,m_uint32_t len)
384  {  {
385     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
386     struct iofpga_data *d;     struct c3725_iofpga_data *d;
387    
388     /* Allocate private data structure */     /* Allocate private data structure */
389     if (!(d = malloc(sizeof(*d)))) {     if (!(d = malloc(sizeof(*d)))) {
# Line 352  int dev_c3725_iofpga_init(c3725_t *route Line 393  int dev_c3725_iofpga_init(c3725_t *route
393    
394     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
395     d->router = router;     d->router = router;
396       d->net_irq_status[0] = 0xFFFF;
397       d->net_irq_status[1] = 0xFFFF;
398    
399     vm_object_init(&d->vm_obj);     vm_object_init(&d->vm_obj);
400     d->vm_obj.name = "io_fpga";     d->vm_obj.name = "io_fpga";

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

  ViewVC Help
Powered by ViewVC 1.1.26