/[dynamips]/upstream/dynamips-0.2.7-RC2/dev_c2691_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 /upstream/dynamips-0.2.7-RC2/dev_c2691_iofpga.c

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

upstream/dynamips-0.2.6-RC3/dev_c2691_iofpga.c revision 4 by dpavlin, Sat Oct 6 16:06:49 2007 UTC upstream/dynamips-0.2.7-RC2/dev_c2691_iofpga.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco 2691 simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4   */   */
5    
# Line 13  Line 13 
13  #include <pthread.h>  #include <pthread.h>
14    
15  #include "ptask.h"  #include "ptask.h"
16  #include "mips64.h"  #include "cpu.h"
17    #include "vm.h"
18  #include "dynamips.h"  #include "dynamips.h"
19  #include "memory.h"  #include "memory.h"
20  #include "device.h"  #include "device.h"
21  #include "dev_vtty.h"  #include "dev_vtty.h"
22  #include "nmc93c46.h"  #include "nmc93cX6.h"
23  #include "dev_c2691.h"  #include "dev_c2691.h"
24    
25  /* Debugging flags */  /* Debugging flags */
26  #define DEBUG_UNKNOWN   1  #define DEBUG_UNKNOWN   1
27  #define DEBUG_ACCESS    0  #define DEBUG_ACCESS    0
28    #define DEBUG_NET_IRQ   0
29    
30  /* Definitions for Mainboard EEPROM */  /* Definitions for Mainboard EEPROM */
31  #define EEPROM_MB_DOUT  3  #define EEPROM_MB_DOUT  3
# Line 37  Line 39 
39  #define EEPROM_NM_CLK   2  #define EEPROM_NM_CLK   2
40  #define EEPROM_NM_CS    4  #define EEPROM_NM_CS    4
41    
42  #define C2691_NET_IRQ_CLEARING_DELAY  16  /* Network IRQ distribution */
43    struct net_irq_distrib  {
44       u_int reg;
45       u_int offset;
46    };
47    
48    static struct net_irq_distrib net_irq_dist[C2691_MAX_NM_BAYS] = {
49       { 0,  0 },  /* Slot 0: reg 0x26, 0x000000XX */
50       { 1,  0 },  /* Slot 1: reg 0x28, 0x000000XX */
51    };
52    
53  /* IO FPGA structure */  /* IO FPGA structure */
54  struct iofpga_data {  struct c2691_iofpga_data {
55     vm_obj_t vm_obj;     vm_obj_t vm_obj;
56     struct vdevice dev;     struct vdevice dev;
57     c2691_t *router;     c2691_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;  
58    
59     /* Interrupt mask*/     /* Network IRQ status */
60       m_uint16_t net_irq_status[2];
61      
62       /* Interrupt mask */
63     m_uint16_t intr_mask;     m_uint16_t intr_mask;
64  };  };
65    
66  /* Mainboard EEPROM definition */  /* Mainboard EEPROM definition */
67  static const struct nmc93c46_eeprom_def eeprom_mb_def = {  static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
68     EEPROM_MB_CLK, EEPROM_MB_CS,     EEPROM_MB_CLK, EEPROM_MB_CS,
69     EEPROM_MB_DIN, EEPROM_MB_DOUT,     EEPROM_MB_DIN, EEPROM_MB_DOUT,
70  };  };
71    
72  /* Mainboard EEPROM */  /* Mainboard EEPROM */
73  static const struct nmc93c46_group eeprom_mb_group = {  static const struct nmc93cX6_group eeprom_mb_group = {
74     1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },     EEPROM_TYPE_NMC93C46, 1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
75  };  };
76    
77  /* NM EEPROM definition */  /* NM EEPROM definition */
78  static const struct nmc93c46_eeprom_def eeprom_nm_def = {  static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
79     EEPROM_NM_CLK, EEPROM_NM_CS,     EEPROM_NM_CLK, EEPROM_NM_CS,
80     EEPROM_NM_DIN, EEPROM_NM_DOUT,     EEPROM_NM_DIN, EEPROM_NM_DOUT,
81  };  };
82    
83  /* NM EEPROM */  /* NM EEPROM */
84  static const struct nmc93c46_group eeprom_nm_group = {  static const struct nmc93cX6_group eeprom_nm_group = {
85     1, 0, "NM EEPROM", 0, { &eeprom_nm_def },     EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
86  };  };
87    
88    /* Update network interrupt status */
89    static inline void dev_c2691_iofpga_net_update_irq(struct c2691_iofpga_data *d)
90    {
91       if ((d->net_irq_status[0] != 0xFFFF) || (d->net_irq_status[1] != 0xFFFF)) {
92          vm_set_irq(d->router->vm,C2691_NETIO_IRQ);
93       } else {
94          vm_clear_irq(d->router->vm,C2691_NETIO_IRQ);
95       }
96    }
97    
98    /* Trigger a Network IRQ for the specified slot/port */
99    void dev_c2691_iofpga_net_set_irq(struct c2691_iofpga_data *d,
100                                      u_int slot,u_int port)
101    {
102       struct net_irq_distrib *irq_dist;
103    
104    #if DEBUG_NET_IRQ
105       vm_log(d->router->vm,"IO_FPGA","setting NetIRQ for slot %u port %u\n",
106              slot,port);
107    #endif
108       irq_dist = &net_irq_dist[slot];
109       d->net_irq_status[irq_dist->reg] &= ~(1 << (irq_dist->offset + port));
110       dev_c2691_iofpga_net_update_irq(d);
111    }
112    
113    /* Clear a Network IRQ for the specified slot/port */
114    void dev_c2691_iofpga_net_clear_irq(struct c2691_iofpga_data *d,
115                                        u_int slot,u_int port)
116    {
117       struct net_irq_distrib *irq_dist;
118    
119    #if DEBUG_NET_IRQ
120       vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
121              slot,port);
122    #endif
123       irq_dist = &net_irq_dist[slot];
124       d->net_irq_status[irq_dist->reg] |= (1 << (irq_dist->offset + port));
125       dev_c2691_iofpga_net_update_irq(d);
126    }
127    
128  /*  /*
129   * dev_c2691_iofpga_access()   * dev_c2691_iofpga_access()
130   */   */
131  static void *  static void *
132  dev_c2691_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,  dev_c2691_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
133                          m_uint32_t offset,u_int op_size,u_int op_type,                          m_uint32_t offset,u_int op_size,u_int op_type,
134                          m_uint64_t *data)                          m_uint64_t *data)
135  {  {
136     struct iofpga_data *d = dev->priv_data;     struct c2691_iofpga_data *d = dev->priv_data;
137    
138     if (op_type == MTS_READ)     if (op_type == MTS_READ)
139        *data = 0x0;        *data = 0x0;
# Line 97  dev_c2691_iofpga_access(cpu_mips_t *cpu, Line 141  dev_c2691_iofpga_access(cpu_mips_t *cpu,
141  #if DEBUG_ACCESS  #if DEBUG_ACCESS
142     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
143        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",
144                offset,cpu->pc,op_size);                offset,cpu_get_pc(cpu),op_size);
145     } else {     } else {
146        cpu_log(cpu,"IO_FPGA",        cpu_log(cpu,"IO_FPGA",
147                "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",
148                offset,cpu->pc,*data,op_size);                offset,cpu_get_pc(cpu),*data,op_size);
149     }     }
150  #endif  #endif
151    
152     switch(offset) {     switch(offset) {
153        /*        /*
154         * Platform type ?         * Platform type ?
155         * (other values than 0 cause crashes or lot of errors).         * 0x04 and 0x05 seem to work.
156         */         */
157        case 0x36:        case 0x36:
158            if (op_type == MTS_READ)            if (op_type == MTS_READ)
159               *data = 0x0000;               *data = 0x04 << 5;
160            break;            break;
161    
162        /* Mainboard EEPROM */        /* Mainboard EEPROM */
163        case 0x0e:        case 0x0e:
164           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
165              nmc93c46_write(&d->router->mb_eeprom_group,(u_int)(*data));              nmc93cX6_write(&d->router->mb_eeprom_group,(u_int)(*data));
166           else           else
167              *data = nmc93c46_read(&d->router->mb_eeprom_group);              *data = nmc93cX6_read(&d->router->mb_eeprom_group);
168           break;           break;
169    
170        case 0x12:        case 0x12:
# Line 156  dev_c2691_iofpga_access(cpu_mips_t *cpu, Line 200  dev_c2691_iofpga_access(cpu_mips_t *cpu,
200        /* NM Slot 1 EEPROM */        /* NM Slot 1 EEPROM */
201        case 0x44:        case 0x44:
202           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
203              nmc93c46_write(&d->router->nm_eeprom_group,(u_int)(*data));              nmc93cX6_write(&d->router->nm_eeprom_group,(u_int)(*data));
204           else           else
205              *data = nmc93c46_read(&d->router->nm_eeprom_group);              *data = nmc93cX6_read(&d->router->nm_eeprom_group);
206           break;           break;
207    
208        /* AIM EEPROM #0 */        /* AIM EEPROM #0 */
# Line 207  dev_c2691_iofpga_access(cpu_mips_t *cpu, Line 251  dev_c2691_iofpga_access(cpu_mips_t *cpu,
251         * Other bits unknown.         * Other bits unknown.
252         */         */
253        case 0x26:        case 0x26:
254           if (op_type == MTS_READ) {           if (op_type == MTS_READ)
255              *data = 0xFFFE;              *data = d->net_irq_status[0];
             vm_clear_irq(d->router->vm,C2691_NETIO_IRQ);  
          }  
256           break;           break;
257    
258        /*        /*
# Line 220  dev_c2691_iofpga_access(cpu_mips_t *cpu, Line 262  dev_c2691_iofpga_access(cpu_mips_t *cpu,
262         * Other bits unknown.         * Other bits unknown.
263         */         */
264        case 0x28:        case 0x28:
265           if (op_type == MTS_READ) {           if (op_type == MTS_READ)
266              *data = 0xFFFE;              *data = d->net_irq_status[1];
             vm_clear_irq(d->router->vm,C2691_NETIO_IRQ);  
          }  
267           break;           break;
268    
269        case 0x2c:        case 0x2c:
# Line 277  dev_c2691_iofpga_access(cpu_mips_t *cpu, Line 317  dev_c2691_iofpga_access(cpu_mips_t *cpu,
317           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
318              cpu_log(cpu,"IO_FPGA",              cpu_log(cpu,"IO_FPGA",
319                      "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",                      "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
320                      offset,cpu->pc,op_size);                      offset,cpu_get_pc(cpu),op_size);
321           } else {           } else {
322              cpu_log(cpu,"IO_FPGA",              cpu_log(cpu,"IO_FPGA",
323                      "write to unknown addr 0x%x, value=0x%llx, "                      "write to unknown addr 0x%x, value=0x%llx, "
324                      "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                      "pc=0x%llx (size=%u)\n",
325                        offset,*data,cpu_get_pc(cpu),op_size);
326           }           }
327  #endif  #endif
328     }     }
# Line 304  void c2691_init_eeprom_groups(c2691_t *r Line 345  void c2691_init_eeprom_groups(c2691_t *r
345  }  }
346    
347  /* Shutdown the IO FPGA device */  /* Shutdown the IO FPGA device */
348  void dev_c2691_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)  static void
349    dev_c2691_iofpga_shutdown(vm_instance_t *vm,struct c2691_iofpga_data *d)
350  {  {
351     if (d != NULL) {     if (d != NULL) {
352        /* Remove the device */        /* Remove the device */
# Line 321  void dev_c2691_iofpga_shutdown(vm_instan Line 363  void dev_c2691_iofpga_shutdown(vm_instan
363  int dev_c2691_iofpga_init(c2691_t *router,m_uint64_t paddr,m_uint32_t len)  int dev_c2691_iofpga_init(c2691_t *router,m_uint64_t paddr,m_uint32_t len)
364  {  {
365     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
366     struct iofpga_data *d;     struct c2691_iofpga_data *d;
367    
368     /* Allocate private data structure */     /* Allocate private data structure */
369     if (!(d = malloc(sizeof(*d)))) {     if (!(d = malloc(sizeof(*d)))) {
# Line 331  int dev_c2691_iofpga_init(c2691_t *route Line 373  int dev_c2691_iofpga_init(c2691_t *route
373    
374     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
375     d->router = router;     d->router = router;
376       d->net_irq_status[0] = 0xFFFF;
377       d->net_irq_status[1] = 0xFFFF;
378    
379     vm_object_init(&d->vm_obj);     vm_object_init(&d->vm_obj);
380     d->vm_obj.name = "io_fpga";     d->vm_obj.name = "io_fpga";

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

  ViewVC Help
Powered by ViewVC 1.1.26