/[dynamips]/trunk/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 /trunk/dev_c7200_iofpga.c

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

upstream/dynamips-0.2.5/dev_c7200_iofpga.c revision 1 by dpavlin, Sat Oct 6 16:01:44 2007 UTC trunk/dev_c7200_iofpga.c revision 12 by dpavlin, Sat Oct 6 16:45:40 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"
28  #include "dev_vtty.h"  #include "dev_vtty.h"
29  #include "nmc93c46.h"  #include "nmc93cX6.h"
30  #include "ds1620.h"  #include "ds1620.h"
31  #include "dev_c7200.h"  #include "dev_c7200.h"
32    
# 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 nmc93cX6_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 nmc93cX6_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 nmc93cX6_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 nmc93cX6_group eeprom_cpu_midplane = {
154     2, 0, "CPU and Midplane EEPROM", 0,     EEPROM_TYPE_NMC93C46, 2, 0,
155     { NULL, NULL, }, { { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0} },     EEPROM_DORD_NORMAL,
156       EEPROM_DOUT_HIGH,
157       EEPROM_DEBUG_DISABLED,
158       "CPU and Midplane EEPROM",
159       { &eeprom_cpu_def, &eeprom_midplane_def },
160  };  };
161    
162  /*  /*
# Line 165  static const struct nmc93c46_group eepro Line 164  static const struct nmc93c46_group eepro
164   * PEM stands for "Power Entry Module":   * PEM stands for "Power Entry Module":
165   * 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
166   */   */
167  static const struct nmc93c46_group eeprom_pem_npeb = {  static const struct nmc93cX6_group eeprom_pem_npeb = {
168     1, 0, "PEM (NPE-B) EEPROM", 0, { NULL }, { { 0, 0, 0, 0, 0} },     EEPROM_TYPE_NMC93C46, 1, 0,
169       EEPROM_DORD_NORMAL,
170       EEPROM_DOUT_HIGH,
171       EEPROM_DEBUG_DISABLED,
172       "PEM (NPE-B) EEPROM",
173       { &eeprom_pem_def },
174  };  };
175    
176  /* Reset DS1620 */  /* Reset DS1620 */
# Line 277  static void temp_write_data(struct iofpg Line 281  static void temp_write_data(struct iofpg
281     }     }
282  }  }
283    
284    /* NPE-G2 environmental monitor reading */
285    static m_uint32_t g2_envm_read(struct iofpga_data *d)
286    {
287       m_uint32_t val = 0;
288       m_uint32_t p1;
289    
290       p1 = ((d->envm_r2 & 0xFF) << 8) | d->envm_r0 >> 3;
291      
292       switch(p1) {
293          case 0x2a00:     /* CPU Die Temperature */
294             val = 0x3000;
295             break;
296          case 0x4c00:     /* +3.30V */
297             val = 0x2a9;
298             break;
299          case 0x4c01:     /* +1.50V */
300             val = 0x135;
301             break;
302          case 0x4c02:     /* +2.50V */
303             val = 0x204;
304             break;
305          case 0x4c03:     /* +1.80V */
306             val = 0x173;
307             break;
308          case 0x4c04:     /* +1.20V */
309             val = 0xF7;
310             break;
311          case 0x4c05:     /* VDD_CPU */
312             val = 0x108;
313             break;
314          case 0x4800:     /* VDD_MEM */
315             val = 0x204;
316             break;
317          case 0x4801:     /* VTT */
318             val = 0xF9;
319             break;
320          case 0x4802:     /* +3.45V */
321             val = 0x2c8;
322             break;
323          case 0x4803:     /* -11.95V*/
324             val = 0x260;
325             break;
326          case 0x4804:     /* ? */
327             val = 0x111;
328             break;
329          case 0x4805:     /* ? */
330             val = 0x111;
331             break;
332          case 0x4806:     /* +5.15V */
333             val = 0x3F8;
334             break;
335          case 0x4807:     /* +12.15V */
336             val = 0x33D;
337             break;
338    #if DEBUG_UNKNOWN
339          default:
340             vm_log(d->router->vm,"IO_FPGA","p1 = 0x%8.8x\n",p1);
341    #endif
342       }
343    
344       return(htonl(val));
345    }
346    
347  /* Console port input */  /* Console port input */
348  static void tty_con_input(vtty_t *vtty)  static void tty_con_input(vtty_t *vtty)
349  {  {
# Line 328  static int tty_trigger_dummy_irq(struct Line 395  static int tty_trigger_dummy_irq(struct
395  /*  /*
396   * dev_c7200_iofpga_access()   * dev_c7200_iofpga_access()
397   */   */
398  void *dev_c7200_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,  void *dev_c7200_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
399                                m_uint32_t offset,u_int op_size,u_int op_type,                                m_uint32_t offset,u_int op_size,u_int op_type,
400                                m_uint64_t *data)                                m_uint64_t *data)
401  {  {
# Line 341  void *dev_c7200_iofpga_access(cpu_mips_t Line 408  void *dev_c7200_iofpga_access(cpu_mips_t
408    
409  #if DEBUG_ACCESS  #if DEBUG_ACCESS
410     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
411        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",
412                  offset,cpu_get_pc(cpu));
413     } else {     } else {
414        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",
415                offset,cpu->pc,*data);                offset,cpu_get_pc(cpu),*data);
416     }     }
417  #endif  #endif
418    
# Line 364  void *dev_c7200_iofpga_access(cpu_mips_t Line 432  void *dev_c7200_iofpga_access(cpu_mips_t
432        case 0x338:        case 0x338:
433           break;           break;
434    
435        /* NPE-G1 test - has influence on slot 0 / flash / pcmcia ... */        /*
436           * NPE-G1/NPE-G2 - has influence on slot 0 / flash / pcmcia ...
437           * Bit 24: 1=I/O slot present
438           * Lower 16 bits: FPGA version (displayed by "sh c7200")
439           */
440        case 0x390:        case 0x390:
441           if (op_type == MTS_READ)           if (op_type == MTS_READ) {
442              *data = 0x0FFF0000; //0xFFFF0000;              *data = 0x0102;
443                
444                /* If we have an I/O slot, we use the I/O slot DUART */
445                if (vm_slot_check_eeprom(d->router->vm,0,0))
446                   *data |= 0x01000000;
447             }
448           break;           break;
449    
450        /* I/O control register */        /* I/O control register */
# Line 377  void *dev_c7200_iofpga_access(cpu_mips_t Line 454  void *dev_c7200_iofpga_access(cpu_mips_t
454              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);
455  #endif  #endif
456              d->io_ctrl_reg = *data;              d->io_ctrl_reg = *data;
457           }           } else {
          else {  
458              *data = d->io_ctrl_reg;              *data = d->io_ctrl_reg;
459              *data |= NVRAM_PACKED;              /* Packed NVRAM */              *data |= NVRAM_PACKED;              /* Packed NVRAM */
460           }           }
# Line 387  void *dev_c7200_iofpga_access(cpu_mips_t Line 463  void *dev_c7200_iofpga_access(cpu_mips_t
463        /* CPU/Midplane EEPROMs */        /* CPU/Midplane EEPROMs */
464        case 0x21c:        case 0x21c:
465           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
466              nmc93c46_write(&d->router->sys_eeprom_g1,(u_int)(*data));              nmc93cX6_write(&d->router->sys_eeprom_g1,(u_int)(*data));
467           else           else
468              *data = nmc93c46_read(&d->router->sys_eeprom_g1);              *data = nmc93cX6_read(&d->router->sys_eeprom_g1);
469           break;           break;
470    
471        /* PEM (NPE-B) EEPROM */        /* PEM (NPE-B) EEPROM */
472        case 0x388:        case 0x388:
473            if (op_type == MTS_WRITE)            if (op_type == MTS_WRITE)
474              nmc93c46_write(&d->router->sys_eeprom_g2,(u_int)(*data));              nmc93cX6_write(&d->router->sys_eeprom_g2,(u_int)(*data));
475           else           else
476              *data = nmc93c46_read(&d->router->sys_eeprom_g2);              *data = nmc93cX6_read(&d->router->sys_eeprom_g2);
477           break;           break;
478    
479        /* Watchdog */        /* Watchdog */
# Line 593  void *dev_c7200_iofpga_access(cpu_mips_t Line 669  void *dev_c7200_iofpga_access(cpu_mips_t
669           }           }
670           break;           break;
671    
672          /* NPE-G2 environmental monitor reading */
673          case 0x3c0:
674             if (op_type == MTS_READ)
675                *data = 0;
676             break;
677    
678          case 0x3c4:
679             if (op_type == MTS_WRITE)
680                d->envm_r0 = ntohl(*data);
681             break;
682    
683          case 0x3c8:
684             if (op_type == MTS_WRITE) {
685                d->envm_r1 = ntohl(*data);
686             } else {
687                *data = g2_envm_read(d);
688             }
689             break;
690    
691          case 0x3cc:
692             if (op_type == MTS_WRITE)
693                d->envm_r2 = ntohl(*data);
694             break;
695    
696          /* PCMCIA status ? */
697          case 0x3d6:
698             if (op_type == MTS_READ)
699                *data = 0x33;
700             break;
701    
702  #if DEBUG_UNKNOWN  #if DEBUG_UNKNOWN
703        default:        default:
704           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
705              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",
706                      offset,cpu->pc,op_size);                      offset,cpu_get_pc(cpu),op_size);
707           } else {           } else {
708              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, "
709                      "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                      "pc=0x%llx (size=%u)\n",
710                        offset,*data,cpu_get_pc(cpu),op_size);
711           }           }
712  #endif  #endif
713     }     }
# Line 609  void *dev_c7200_iofpga_access(cpu_mips_t Line 716  void *dev_c7200_iofpga_access(cpu_mips_t
716     return NULL;     return NULL;
717  }  }
718    
719  /* Initialize EEPROM groups */  /* Initialize system EEPROM groups */
720  void c7200_init_eeprom_groups(c7200_t *router)  void c7200_init_sys_eeprom_groups(c7200_t *router)
721  {  {
722     struct nmc93c46_group *g;     router->sys_eeprom_g1 = eeprom_cpu_midplane;
723         router->sys_eeprom_g2 = eeprom_pem_npeb;
724     /* Copy EEPROM definitions */  
725     memcpy(&router->cpu_eeprom,&eeprom_cpu_def,sizeof(eeprom_cpu_def));     router->sys_eeprom_g1.eeprom[0] = &router->cpu_eeprom;
726     memcpy(&router->mp_eeprom,&eeprom_midplane_def,sizeof(eeprom_midplane_def));     router->sys_eeprom_g1.eeprom[1] = &router->mp_eeprom;
727     memcpy(&router->pem_eeprom,&eeprom_pem_def,sizeof(eeprom_pem_def));  
728       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;    
729  }  }
730    
731  /* Shutdown the IO FPGA device */  /* Shutdown the IO FPGA device */
# Line 688  int dev_c7200_iofpga_init(c7200_t *route Line 786  int dev_c7200_iofpga_init(c7200_t *route
786     d->dev.handler   = dev_c7200_iofpga_access;     d->dev.handler   = dev_c7200_iofpga_access;
787     d->dev.priv_data = d;     d->dev.priv_data = d;
788    
789     /* Set console and AUX port notifying functions */     /* If we have an I/O slot, we use the I/O slot DUART */
790     vm->vtty_con->priv_data = d;     if (vm_slot_check_eeprom(vm,0,0)) {
791     vm->vtty_aux->priv_data = d;        vm_log(vm,"CONSOLE","console managed by I/O board\n");
792     vm->vtty_con->read_notifier = tty_con_input;  
793     vm->vtty_aux->read_notifier = tty_aux_input;        /* Set console and AUX port notifying functions */
794          vm->vtty_con->priv_data = d;
795     /* Trigger periodically a dummy IRQ to flush buffers */        vm->vtty_aux->priv_data = d;
796     d->duart_irq_tid = ptask_add((ptask_callback)tty_trigger_dummy_irq,d,NULL);        vm->vtty_con->read_notifier = tty_con_input;
797          vm->vtty_aux->read_notifier = tty_aux_input;
798    
799          /* Trigger periodically a dummy IRQ to flush buffers */
800          d->duart_irq_tid = ptask_add((ptask_callback)tty_trigger_dummy_irq,
801                                       d,NULL);
802       }
803    
804     /* Map this device to the VM */     /* Map this device to the VM */
805     vm_bind_device(vm,&d->dev);     vm_bind_device(vm,&d->dev);

Legend:
Removed from v.1  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26