/[dynamips]/upstream/dynamips-0.2.7-RC1/dev_c7200_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-RC1/dev_c7200_iofpga.c

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

upstream/dynamips-0.2.6-RC1/dev_c7200_iofpga.c revision 2 by dpavlin, Sat Oct 6 16:03:58 2007 UTC upstream/dynamips-0.2.7-RC1/dev_c7200_iofpga.c revision 7 by dpavlin, Sat Oct 6 16:23:47 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,2006 Christophe Fillot (cf@utc.fr)
4   *   *
5   * Cisco C7200 (Predator) I/O FPGA:   * Cisco 7200 I/O FPGA:
6   *   - Simulates a NMC93C46 Serial EEPROM as CPU and Midplane EEPROM.   *   - Simulates a NMC93C46 Serial EEPROM as CPU and Midplane EEPROM.
7   *   - Simulates a DALLAS DS1620 for Temperature Sensors.   *   - Simulates a DALLAS DS1620 for Temperature Sensors.
8   *   - Simulates voltage sensors.   *   - Simulates voltage sensors.
9   *   - Simulates console and AUX ports.   *   - Simulates console and AUX ports (SCN2681).
10   */   */
11    
12  #include <stdio.h>  #include <stdio.h>
# Line 20  Line 20 
20  #include <pthread.h>  #include <pthread.h>
21    
22  #include "ptask.h"  #include "ptask.h"
23  #include "mips64.h"  #include "cpu.h"
24    #include "vm.h"
25  #include "dynamips.h"  #include "dynamips.h"
26  #include "memory.h"  #include "memory.h"
27  #include "device.h"  #include "device.h"
# Line 123  struct iofpga_data { Line 124  struct iofpga_data {
124    
125     /* Voltages */     /* Voltages */
126     u_int mux;     u_int mux;
127    
128       /* NPE-G2 environmental part */
129       m_uint32_t envm_r0,envm_r1,envm_r2;
130  };  };
131    
132  #define IOFPGA_LOCK(d)   pthread_mutex_lock(&(d)->lock)  #define IOFPGA_LOCK(d)   pthread_mutex_lock(&(d)->lock)
133  #define IOFPGA_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)  #define IOFPGA_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)
134    
 /* Empty EEPROM */  
 static const m_uint16_t eeprom_empty_data[16] = {  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
 };  
   
135  /* CPU EEPROM definition */  /* CPU EEPROM definition */
136  static const struct nmc93c46_eeprom_def eeprom_cpu_def = {  static const struct nmc93c46_eeprom_def eeprom_cpu_def = {
137     SK1_CLOCK_CPU, CS1_CHIP_SEL_CPU,     SK1_CLOCK_CPU, CS1_CHIP_SEL_CPU,
138     DI1_DATA_IN_CPU, DO1_DATA_OUT_CPU,     DI1_DATA_IN_CPU, DO1_DATA_OUT_CPU,
    NULL, 0,  
139  };  };
140    
141  /* Midplane EEPROM definition */  /* Midplane EEPROM definition */
142  static const struct nmc93c46_eeprom_def eeprom_midplane_def = {  static const struct nmc93c46_eeprom_def eeprom_midplane_def = {
143     SK2_CLOCK_MIDPLANE, CS2_CHIP_SEL_MIDPLANE,     SK2_CLOCK_MIDPLANE, CS2_CHIP_SEL_MIDPLANE,
144     DI2_DATA_IN_MIDPLANE, DO2_DATA_OUT_MIDPLANE,     DI2_DATA_IN_MIDPLANE, DO2_DATA_OUT_MIDPLANE,
    NULL, 0,  
145  };  };
146    
147  /* PEM (NPE-B) EEPROM definition */  /* PEM (NPE-B) EEPROM definition */
148  static const struct nmc93c46_eeprom_def eeprom_pem_def = {  static const struct nmc93c46_eeprom_def eeprom_pem_def = {
149     SK1_CLOCK_PEM, CS1_CHIP_SEL_PEM, DI1_DATA_IN_PEM, DO1_DATA_OUT_PEM,     SK1_CLOCK_PEM, CS1_CHIP_SEL_PEM, DI1_DATA_IN_PEM, DO1_DATA_OUT_PEM,
    (m_uint16_t *)eeprom_empty_data, (sizeof(eeprom_empty_data) / 2),  
150  };  };
151    
152  /* IOFPGA manages simultaneously CPU and Midplane EEPROM */  /* IOFPGA manages simultaneously CPU and Midplane EEPROM */
153  static const struct nmc93c46_group eeprom_cpu_midplane = {  static const struct nmc93c46_group eeprom_cpu_midplane = {
154     2, 0, "CPU and Midplane EEPROM", 0,     2, 0, "CPU and Midplane EEPROM", 0,
155     { NULL, NULL, }, { { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0} },     { &eeprom_cpu_def, &eeprom_midplane_def },
156  };  };
157    
158  /*  /*
# Line 166  static const struct nmc93c46_group eepro Line 161  static const struct nmc93c46_group eepro
161   * http://www.cisco.com/en/US/products/hw/routers/ps341/products_field_notice09186a00801cb26d.shtml   * http://www.cisco.com/en/US/products/hw/routers/ps341/products_field_notice09186a00801cb26d.shtml
162   */   */
163  static const struct nmc93c46_group eeprom_pem_npeb = {  static const struct nmc93c46_group eeprom_pem_npeb = {
164     1, 0, "PEM (NPE-B) EEPROM", 0, { NULL }, { { 0, 0, 0, 0, 0} },     1, 0, "PEM (NPE-B) EEPROM", 0, { &eeprom_pem_def },
165  };  };
166    
167  /* Reset DS1620 */  /* Reset DS1620 */
# Line 277  static void temp_write_data(struct iofpg Line 272  static void temp_write_data(struct iofpg
272     }     }
273  }  }
274    
275    /* NPE-G2 environmental monitor reading */
276    static m_uint32_t g2_envm_read(struct iofpga_data *d)
277    {
278       m_uint32_t val = 0;
279       m_uint32_t p1;
280    
281       p1 = ((d->envm_r2 & 0xFF) << 8) | d->envm_r0 >> 3;
282      
283       switch(p1) {
284          case 0x2a00:     /* CPU Die Temperature */
285             val = 0x3000;
286             break;
287          case 0x4c00:     /* +3.30V */
288             val = 0x2a9;
289             break;
290          case 0x4c01:     /* +1.50V */
291             val = 0x135;
292             break;
293          case 0x4c02:     /* +2.50V */
294             val = 0x204;
295             break;
296          case 0x4c03:     /* +1.80V */
297             val = 0x173;
298             break;
299          case 0x4c04:     /* +1.20V */
300             val = 0xF7;
301             break;
302          case 0x4c05:     /* VDD_CPU */
303             val = 0x108;
304             break;
305          case 0x4800:     /* VDD_MEM */
306             val = 0x204;
307             break;
308          case 0x4801:     /* VTT */
309             val = 0xF9;
310             break;
311          case 0x4802:     /* +3.45V */
312             val = 0x2c8;
313             break;
314          case 0x4803:     /* -11.95V*/
315             val = 0x260;
316             break;
317          case 0x4804:     /* ? */
318             val = 0x111;
319             break;
320          case 0x4805:     /* ? */
321             val = 0x111;
322             break;
323          case 0x4806:     /* +5.15V */
324             val = 0x3F8;
325             break;
326          case 0x4807:     /* +12.15V */
327             val = 0x33D;
328             break;
329    #if DEBUG_UNKNOWN
330          default:
331             vm_log(d->router->vm,"IO_FPGA","p1 = 0x%8.8x\n",p1);
332    #endif
333       }
334    
335       return(htonl(val));
336    }
337    
338  /* Console port input */  /* Console port input */
339  static void tty_con_input(vtty_t *vtty)  static void tty_con_input(vtty_t *vtty)
340  {  {
# Line 328  static int tty_trigger_dummy_irq(struct Line 386  static int tty_trigger_dummy_irq(struct
386  /*  /*
387   * dev_c7200_iofpga_access()   * dev_c7200_iofpga_access()
388   */   */
389  void *dev_c7200_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,  void *dev_c7200_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
390                                m_uint32_t offset,u_int op_size,u_int op_type,                                m_uint32_t offset,u_int op_size,u_int op_type,
391                                m_uint64_t *data)                                m_uint64_t *data)
392  {  {
# Line 341  void *dev_c7200_iofpga_access(cpu_mips_t Line 399  void *dev_c7200_iofpga_access(cpu_mips_t
399    
400  #if DEBUG_ACCESS  #if DEBUG_ACCESS
401     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
402        cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx\n",offset,cpu->pc);        cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx\n",
403                  offset,cpu_get_pc(cpu));
404     } else {     } else {
405        cpu_log(cpu,"IO_FPGA","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",        cpu_log(cpu,"IO_FPGA","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",
406                offset,cpu->pc,*data);                offset,cpu_get_pc(cpu),*data);
407     }     }
408  #endif  #endif
409    
# Line 364  void *dev_c7200_iofpga_access(cpu_mips_t Line 423  void *dev_c7200_iofpga_access(cpu_mips_t
423        case 0x338:        case 0x338:
424           break;           break;
425    
426        /* NPE-G1 test - has influence on slot 0 / flash / pcmcia ... */        /*
427           * NPE-G1/NPE-G2 - has influence on slot 0 / flash / pcmcia ...
428           * Bit 24: 1=I/O slot present
429           * Lower 16 bits: FPGA version (displayed by "sh c7200")
430           */
431        case 0x390:        case 0x390:
432           if (op_type == MTS_READ)           if (op_type == MTS_READ) {
433              *data = 0x0FFF0000; //0xFFFF0000;              *data = 0x0102;
434                
435                /* If we have an I/O slot, we use the I/O slot DUART */
436                if (c7200_pa_check_eeprom(d->router,0))
437                   *data |= 0x01000000;
438             }
439           break;           break;
440    
441        /* I/O control register */        /* I/O control register */
# Line 377  void *dev_c7200_iofpga_access(cpu_mips_t Line 445  void *dev_c7200_iofpga_access(cpu_mips_t
445              vm_log(vm,"IO_FPGA","setting value 0x%llx in io_ctrl_reg\n",*data);              vm_log(vm,"IO_FPGA","setting value 0x%llx in io_ctrl_reg\n",*data);
446  #endif  #endif
447              d->io_ctrl_reg = *data;              d->io_ctrl_reg = *data;
448           }           } else {
          else {  
449              *data = d->io_ctrl_reg;              *data = d->io_ctrl_reg;
450              *data |= NVRAM_PACKED;              /* Packed NVRAM */              *data |= NVRAM_PACKED;              /* Packed NVRAM */
451           }           }
# Line 593  void *dev_c7200_iofpga_access(cpu_mips_t Line 660  void *dev_c7200_iofpga_access(cpu_mips_t
660           }           }
661           break;           break;
662    
663          /* NPE-G2 environmental monitor reading */
664          case 0x3c0:
665             if (op_type == MTS_READ)
666                *data = 0;
667             break;
668    
669          case 0x3c4:
670             if (op_type == MTS_WRITE)
671                d->envm_r0 = ntohl(*data);
672             break;
673    
674          case 0x3c8:
675             if (op_type == MTS_WRITE) {
676                d->envm_r1 = ntohl(*data);
677             } else {
678                *data = g2_envm_read(d);
679             }
680             break;
681    
682          case 0x3cc:
683             if (op_type == MTS_WRITE)
684                d->envm_r2 = ntohl(*data);
685             break;
686    
687          /* PCMCIA status ? */
688          case 0x3d6:
689             if (op_type == MTS_READ)
690                *data = 0x33;
691             break;
692    
693  #if DEBUG_UNKNOWN  #if DEBUG_UNKNOWN
694        default:        default:
695           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
696              cpu_log(cpu,"IO_FPGA","read from addr 0x%x, pc=0x%llx (size=%u)\n",              cpu_log(cpu,"IO_FPGA","read from addr 0x%x, pc=0x%llx (size=%u)\n",
697                      offset,cpu->pc,op_size);                      offset,cpu_get_pc(cpu),op_size);
698           } else {           } else {
699              cpu_log(cpu,"IO_FPGA","write to addr 0x%x, value=0x%llx, "              cpu_log(cpu,"IO_FPGA","write to addr 0x%x, value=0x%llx, "
700                      "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                      "pc=0x%llx (size=%u)\n",
701                        offset,*data,cpu_get_pc(cpu),op_size);
702           }           }
703  #endif  #endif
704     }     }
# Line 612  void *dev_c7200_iofpga_access(cpu_mips_t Line 710  void *dev_c7200_iofpga_access(cpu_mips_t
710  /* Initialize EEPROM groups */  /* Initialize EEPROM groups */
711  void c7200_init_eeprom_groups(c7200_t *router)  void c7200_init_eeprom_groups(c7200_t *router)
712  {  {
713     struct nmc93c46_group *g;     router->sys_eeprom_g1 = eeprom_cpu_midplane;
714         router->sys_eeprom_g2 = eeprom_pem_npeb;
715     /* Copy EEPROM definitions */  
716     memcpy(&router->cpu_eeprom,&eeprom_cpu_def,sizeof(eeprom_cpu_def));     router->sys_eeprom_g1.eeprom[0] = &router->cpu_eeprom;
717     memcpy(&router->mp_eeprom,&eeprom_midplane_def,sizeof(eeprom_midplane_def));     router->sys_eeprom_g1.eeprom[1] = &router->mp_eeprom;
718     memcpy(&router->pem_eeprom,&eeprom_pem_def,sizeof(eeprom_pem_def));  
719       router->sys_eeprom_g2.eeprom[0] = &router->pem_eeprom;
    /* Initialize groups */  
    g = &router->sys_eeprom_g1;  
    memcpy(g,&eeprom_cpu_midplane,sizeof(eeprom_cpu_midplane));  
    g->def[0] = &router->cpu_eeprom;  
    g->def[1] = &router->mp_eeprom;  
   
    g = &router->sys_eeprom_g2;  
    memcpy(g,&eeprom_pem_npeb,sizeof(eeprom_pem_npeb));  
    g->def[0] = &router->pem_eeprom;    
720  }  }
721    
722  /* Shutdown the IO FPGA device */  /* Shutdown the IO FPGA device */
# Line 688  int dev_c7200_iofpga_init(c7200_t *route Line 777  int dev_c7200_iofpga_init(c7200_t *route
777     d->dev.handler   = dev_c7200_iofpga_access;     d->dev.handler   = dev_c7200_iofpga_access;
778     d->dev.priv_data = d;     d->dev.priv_data = d;
779    
780     /* Set console and AUX port notifying functions */     /* If we have an I/O slot, we use the I/O slot DUART */
781     vm->vtty_con->priv_data = d;     if (c7200_pa_check_eeprom(d->router,0)) {
782     vm->vtty_aux->priv_data = d;        vm_log(vm,"CONSOLE","console managed by I/O board\n");
783     vm->vtty_con->read_notifier = tty_con_input;  
784     vm->vtty_aux->read_notifier = tty_aux_input;        /* Set console and AUX port notifying functions */
785          vm->vtty_con->priv_data = d;
786     /* Trigger periodically a dummy IRQ to flush buffers */        vm->vtty_aux->priv_data = d;
787     d->duart_irq_tid = ptask_add((ptask_callback)tty_trigger_dummy_irq,d,NULL);        vm->vtty_con->read_notifier = tty_con_input;
788          vm->vtty_aux->read_notifier = tty_aux_input;
789    
790          /* Trigger periodically a dummy IRQ to flush buffers */
791          d->duart_irq_tid = ptask_add((ptask_callback)tty_trigger_dummy_irq,
792                                       d,NULL);
793       }
794    
795     /* Map this device to the VM */     /* Map this device to the VM */
796     vm_bind_device(vm,&d->dev);     vm_bind_device(vm,&d->dev);

Legend:
Removed from v.2  
changed lines
  Added in v.7

  ViewVC Help
Powered by ViewVC 1.1.26