Annotation of cf/dev_iofpga.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Cisco 7200 (Predator) simulation platform.
                      3:  * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
                      4:  *
                      5:  * Cisco C7200 (Predator) I/O FPGA:
                      6:  *   - Simulates a NMC93C46 Serial EEPROM as CPU and Midplane EEPROM.
                      7:  *   - Simulates a DALLAS DS1620 for Temperature Sensors.
                      8:  *   - Simulates voltage sensors.
                      9:  *   - Simulates console and AUX ports.
                     10:  */
                     11: 
                     12: #include <stdio.h>
                     13: #include <stdlib.h>
                     14: #include <string.h>
                     15: #include <unistd.h>
                     16: #include <sys/types.h>
                     17: 
                     18: #include <termios.h>
                     19: #include <fcntl.h>
                     20: #include <pthread.h>
                     21: 
                     22: #include "ptask.h"
                     23: #include "mips64.h"
                     24: #include "dynamips.h"
                     25: #include "memory.h"
                     26: #include "device.h"
                     27: #include "dev_vtty.h"
                     28: #include "nmc93c46.h"
                     29: #include "ds1620.h"
                     30: #include "dev_c7200.h"
                     31: 
                     32: /* Debugging flags */
                     33: #define DEBUG_UNKNOWN  1
                     34: #define DEBUG_LED      0
                     35: #define DEBUG_IO_CTL   0
                     36: #define DEBUG_ENVM     0
                     37: 
                     38: /* DUART RX/TX status (SRA/SRB) */
                     39: #define DUART_RX_READY  0x01
                     40: #define DUART_TX_READY  0x04
                     41: 
                     42: /* DUART RX/TX Interrupt Status/Mask */
                     43: #define DUART_TXRDYA  0x01
                     44: #define DUART_RXRDYA  0x02
                     45: #define DUART_TXRDYB  0x10
                     46: #define DUART_RXRDYB  0x20
                     47: 
                     48: /* Definitions for CPU and Midplane Serial EEPROMs */
                     49: #define DO2_DATA_OUT_MIDPLANE   7
                     50: #define DO1_DATA_OUT_CPU        6
                     51: #define CS2_CHIP_SEL_MIDPLANE   5
                     52: #define SK2_CLOCK_MIDPLANE      4
                     53: #define DI2_DATA_IN_MIDPLANE    3
                     54: #define CS1_CHIP_SEL_CPU        2
                     55: #define SK1_CLOCK_CPU           1
                     56: #define DI1_DATA_IN_CPU                 0
                     57: 
                     58: /* Definitions for PEM (NPE-B) Serial EEPROM */
                     59: #define DO1_DATA_OUT_PEM   3
                     60: #define DI1_DATA_IN_PEM    2
                     61: #define CS1_CHIP_SEL_PEM   1
                     62: #define SK1_CLOCK_PEM      0
                     63: 
                     64: /* Pack the NVRAM */
                     65: #define NVRAM_PACKED   0x04
                     66: 
                     67: /* 4 temperature sensors in a C7200 */
                     68: #define C7200_TEMP_SENSORS  4
                     69: #define C7200_DEFAULT_TEMP  22    /* default temperature: 22�C */
                     70: 
                     71: /* Voltages */
                     72: #define C7200_A2D_SAMPLES   9
                     73: 
                     74: /*
                     75:  * A2D MUX Select definitions.
                     76:  */
                     77: #define C7200_MUX_PS0     0x00   /* Power Supply 0 */
                     78: #define C7200_MUX_PS1     0x02   /* Power Supply 1 */
                     79: #define C7200_MUX_P3V     0x04   /* +3V */
                     80: #define C7200_MUX_P12V    0x08   /* +12V */
                     81: #define C7200_MUX_P5V     0x0a   /* +5V */
                     82: #define C7200_MUX_N12V    0x0c   /* -12V */
                     83: 
                     84: /* Analog To Digital Converters samples */
                     85: #define C7200_A2D_PS0     1150
                     86: #define C7200_A2D_PS1     1150
                     87: 
                     88: /* Voltage Samples */
                     89: #define C7200_A2D_P3V     1150
                     90: #define C7200_A2D_P12V    1150
                     91: #define C7200_A2D_P5V     1150
                     92: #define C7200_A2D_N12V    1150
                     93: 
                     94: /* IO FPGA structure */
                     95: struct iofpga_data {
                     96:    u_int io_ctrl_reg;
                     97: 
                     98:    /* Managing CPU */
                     99:    cpu_mips_t *mgr_cpu;
                    100: 
                    101:    /* DUART & Console Management */
                    102:    u_int duart_interrupt;
                    103:    pthread_t duart_con_thread;
                    104:    pthread_t duart_aux_thread;
                    105: 
                    106:    /* Virtual TTY for Console and AUX ports */
                    107:    vtty_t *vtty_con,*vtty_aux;
                    108: 
                    109:    /* Temperature Control */
                    110:    u_int temp_cfg_reg[C7200_TEMP_SENSORS];
                    111:    u_int temp_deg_reg[C7200_TEMP_SENSORS];
                    112:    u_int temp_clk_low;
                    113: 
                    114:    u_int temp_cmd;
                    115:    u_int temp_cmd_pos;
                    116: 
                    117:    u_int temp_data;
                    118:    u_int temp_data_pos;
                    119: 
                    120:    /* Voltages */
                    121:    u_int mux;
                    122: };
                    123: 
                    124: /* Empty EEPROM */
                    125: static unsigned short eeprom_empty_data[16] = {
                    126:    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 
                    127:    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 
                    128: };
                    129: 
                    130: /* CPU EEPROM definition */
                    131: static struct nmc93c46_group_def eeprom_cpu_def = {
                    132:    SK1_CLOCK_CPU, CS1_CHIP_SEL_CPU, 
                    133:    DI1_DATA_IN_CPU, DO1_DATA_OUT_CPU,
                    134:    NULL, 0,
                    135: };
                    136: 
                    137: /* Midplane EEPROM definition */
                    138: static struct nmc93c46_group_def eeprom_midplane_def = {
                    139:    SK2_CLOCK_MIDPLANE, CS2_CHIP_SEL_MIDPLANE, 
                    140:    DI2_DATA_IN_MIDPLANE, DO2_DATA_OUT_MIDPLANE,
                    141:    NULL, 0,
                    142: };
                    143: 
                    144: /* PEM (NPE-B) EEPROM definition */
                    145: static struct nmc93c46_group_def eeprom_pem_def = {
                    146:    SK1_CLOCK_PEM, CS1_CHIP_SEL_PEM, DI1_DATA_IN_PEM, DO1_DATA_OUT_PEM,
                    147:    eeprom_empty_data, (sizeof(eeprom_empty_data) / 2),
                    148: };
                    149: 
                    150: /* IOFPGA manages simultaneously CPU and Midplane EEPROM */
                    151: static struct nmc93c46_eeprom eeprom_cpu_midplane = {
                    152:    2, 0, "CPU and Midplane EEPROM", 0, 
                    153:    { &eeprom_cpu_def, &eeprom_midplane_def },
                    154:    { { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0} },
                    155: };
                    156: 
                    157: /* 
                    158:  * IOFPGA manages also PEM EEPROM (for NPE-B)
                    159:  * PEM stands for "Power Entry Module":
                    160:  * http://www.cisco.com/en/US/products/hw/routers/ps341/products_field_notice09186a00801cb26d.shtml
                    161:  */
                    162: static struct nmc93c46_eeprom eeprom_pem_npeb = {
                    163:    1, 0, "PEM (NPE-B) EEPROM", 0, { &eeprom_pem_def }, { { 0, 0, 0, 0, 0} },
                    164: };
                    165: 
                    166: /* Reset DS1620 */
                    167: static void temp_reset(struct iofpga_data *d)
                    168: {
                    169:    d->temp_cmd_pos = 0;
                    170:    d->temp_cmd = 0;
                    171: 
                    172:    d->temp_data_pos = 0;
                    173:    d->temp_data = 0;
                    174: }
                    175: 
                    176: /* Write the temperature control data */
                    177: static void temp_write_ctrl(struct iofpga_data *d,u_char val)
                    178: {
                    179:    switch(val) {
                    180:       case DS1620_RESET_ON:
                    181:          temp_reset(d);
                    182:          break;
                    183: 
                    184:       case DS1620_CLK_LOW:
                    185:          d->temp_clk_low = 1;
                    186:          break;
                    187: 
                    188:       case DS1620_CLK_HIGH:
                    189:          d->temp_clk_low = 0;
                    190:          break;
                    191:    }
                    192: }
                    193: 
                    194: /* Read a temperature control data */
                    195: static u_int temp_read_data(struct iofpga_data *d)
                    196: {
                    197:    u_int i,data = 0;
                    198: 
                    199:    switch(d->temp_cmd) {
                    200:       case DS1620_READ_CONFIG:
                    201:          for(i=0;i<C7200_TEMP_SENSORS;i++)
                    202:             data |= ((d->temp_cfg_reg[i] >> d->temp_data_pos) & 1) << i;
                    203: 
                    204:          d->temp_data_pos++;
                    205: 
                    206:          if (d->temp_data_pos == DS1620_CONFIG_READ_SIZE)
                    207:             temp_reset(d);
                    208: 
                    209:          break;
                    210: 
                    211:       case DS1620_READ_TEMP:
                    212:          for(i=0;i<C7200_TEMP_SENSORS;i++)
                    213:             data |= ((d->temp_deg_reg[i] >> d->temp_data_pos) & 1) << i;
                    214: 
                    215:          d->temp_data_pos++;
                    216: 
                    217:          if (d->temp_data_pos == DS1620_DATA_READ_SIZE)
                    218:             temp_reset(d);
                    219: 
                    220:          break;
                    221: 
                    222:       default:
                    223:          m_log("IO_FPGA","temp_sensors: CMD = 0x%x\n",d->temp_cmd);
                    224:    }
                    225: 
                    226:    return(data);
                    227: }
                    228: 
                    229: /* Write the temperature data write register */
                    230: static void temp_write_data(struct iofpga_data *d,u_char val)
                    231: {
                    232:    if (val == DS1620_ENABLE_READ) {
                    233:       d->temp_data_pos = 0;
                    234:       return;
                    235:    }
                    236: 
                    237:    if (!d->temp_clk_low)
                    238:       return;
                    239: 
                    240:    /* Write a command */
                    241:    if (d->temp_cmd_pos < DS1620_WRITE_SIZE)
                    242:    {
                    243:       if (val == DS1620_DATA_HIGH)
                    244:          d->temp_cmd |= 1 << d->temp_cmd_pos;
                    245: 
                    246:       d->temp_cmd_pos++;
                    247:    
                    248:       if (d->temp_cmd_pos == DS1620_WRITE_SIZE) {
                    249:          switch(d->temp_cmd) {
                    250:             case DS1620_START_CONVT:
                    251:                //printf("temp_sensors: IOS enabled continuous monitoring.\n");
                    252:                temp_reset(d);
                    253:                break;
                    254:             case DS1620_READ_CONFIG:
                    255:             case DS1620_READ_TEMP:
                    256:                break;
                    257:             default:
                    258:                m_log("IO_FPGA","temp_sensors: IOS sent command 0x%x.\n",
                    259:                      d->temp_cmd);
                    260:          }
                    261:       }
                    262:    }
                    263:    else
                    264:    {
                    265:       if (val == DS1620_DATA_HIGH)
                    266:          d->temp_data |= 1 << d->temp_data_pos;
                    267: 
                    268:       d->temp_data_pos++;
                    269:    }
                    270: }
                    271: 
                    272: /* Console port input thread */
                    273: static void *tty_con_input(struct iofpga_data *d)
                    274: {
                    275:    while(1) {
                    276:       if (!vtty_read_and_store(d->vtty_con)) {
                    277:          if (d->duart_interrupt & DUART_RXRDYA)
                    278:             mips64_set_irq(d->mgr_cpu,C7200_DUART_IRQ);
                    279:       }
                    280:    }
                    281: 
                    282:    return NULL;
                    283: }
                    284: 
                    285: /* AUX port input thread */
                    286: static void *tty_aux_input(struct iofpga_data *d)
                    287: {
                    288:    while(1) {
                    289:       if (!vtty_read_and_store(d->vtty_aux)) {
                    290:          if (d->duart_interrupt & DUART_RXRDYB)
                    291:             mips64_set_irq(d->mgr_cpu,C7200_DUART_IRQ);
                    292:       }
                    293:    }
                    294: 
                    295:    return NULL;
                    296: }
                    297: 
                    298: /* IRQ trickery for Console and AUX ports */
                    299: static int tty_trigger_dummy_irq(struct iofpga_data *d,void *arg)
                    300: {
                    301:    if (d->duart_interrupt & (DUART_TXRDYA|DUART_TXRDYB))
                    302:       mips64_set_irq(d->mgr_cpu,C7200_DUART_IRQ);
                    303:    return(0);
                    304: }
                    305: 
                    306: /*
                    307:  * dev_iofpga_access()
                    308:  */
                    309: void *dev_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,
                    310:                         u_int op_size,u_int op_type,m_uint64_t *data)
                    311: {
                    312:    struct iofpga_data *d = dev->priv_data;
                    313:    u_char odata;
                    314: 
                    315:    if (op_type == MTS_READ)
                    316:       *data = 0;
                    317: 
                    318:    switch(offset) {
                    319:       /* I/O control register */
                    320:       case 0x204:
                    321:          if (op_type == MTS_WRITE) {
                    322: #if DEBUG_IO_CTL
                    323:             m_log("IO_FPGA: setting value 0x%llx in IO control register\n",
                    324:                   *data);
                    325: #endif
                    326:             d->io_ctrl_reg = *data;
                    327:          }
                    328:          else {
                    329:             *data = d->io_ctrl_reg;
                    330:             *data |= NVRAM_PACKED;              /* Packed NVRAM */
                    331:          }
                    332:          break;
                    333: 
                    334:       /* CPU/Midplane EEPROMs */
                    335:       case 0x21c:
                    336:          if (op_type == MTS_WRITE)
                    337:             nmc93c46_write(&eeprom_cpu_midplane,(u_int)(*data));
                    338:          else
                    339:             *data = nmc93c46_read(&eeprom_cpu_midplane);
                    340:          break;
                    341: 
                    342:       /* PEM (NPE-B) EEPROM */
                    343:       case 0x388:
                    344:           if (op_type == MTS_WRITE)
                    345:             nmc93c46_write(&eeprom_pem_npeb,(u_int)(*data));
                    346:          else
                    347:             *data = nmc93c46_read(&eeprom_pem_npeb);
                    348:          break;
                    349: 
                    350:       /* Watchdog */
                    351:       case 0x234:
                    352:          break;
                    353: 
                    354:       /* 
                    355:        * FPGA release/presence ? Flash SIMM size:
                    356:        *   0x0001: 2048K Flash (2 banks)
                    357:        *   0x0504: 8192K Flash (2 banks)
                    358:        *   0x0704: 16384K Flash (2 banks)
                    359:        *   0x2001: 1024K Flash (1 bank)
                    360:        *   0x2504: 4096K Flash (1 bank)
                    361:        *   0x2704: 8192K Flash (1 bank)
                    362:        *
                    363:        *   Number of Flash SIMM banks + size.
                    364:        *   Touching some lower bits causes problems with environmental monitor.
                    365:        *
                    366:        * It is displayed by command "sh bootflash: chips"
                    367:        */
                    368:       case 0x23c:
                    369:          if (op_type == MTS_READ)
                    370:             *data = 0x00002704;
                    371:          break;
                    372: 
                    373:       /* LEDs */
                    374:       case 0x244:
                    375: #if DEBUG_LED
                    376:          m_log("IO_FPGA","LED register is now 0x%x (0x%x)\n",
                    377:                *data,(~*data) & 0x0F);
                    378: #endif
                    379:          break;
                    380: 
                    381:       /* ==== DUART SCN2681 (console/aux) ==== */
                    382:       case 0x40c:   /* Status Register A (SRA) */
                    383:          if (op_type == MTS_READ) {
                    384:             odata = 0;
                    385: 
                    386:             if (vtty_is_char_avail(d->vtty_con))
                    387:                odata |= DUART_RX_READY;
                    388: 
                    389:             odata |= DUART_TX_READY;
                    390:          
                    391:             mips64_clear_irq(d->mgr_cpu,C7200_DUART_IRQ);
                    392:             *data = odata;
                    393:          }
                    394:          break;
                    395: 
                    396:       case 0x414:   /* Command Register A (CRA) */
                    397:          break;
                    398: 
                    399:       case 0x41c:   /* RX/TX Holding Register A (RHRA/THRA) */
                    400:          if (op_type == MTS_WRITE) {
                    401:             vtty_put_char(d->vtty_con,(char)*data);
                    402:          } else {
                    403:             *data = vtty_get_char(d->vtty_con);
                    404:          }
                    405:          break;
                    406: 
                    407:       case 0x42c:   /* Interrupt Status/Mask Register (ISR/IMR) */
                    408:          if (op_type == MTS_WRITE) {
                    409:             d->duart_interrupt = *data;
                    410:          } else
                    411:             *data = d->duart_interrupt;
                    412:          break;         
                    413: 
                    414:       case 0x44c:   /* Status Register B (SRB) */
                    415:          if (op_type == MTS_READ) {
                    416:             odata = 0;
                    417: 
                    418:             if (vtty_is_char_avail(d->vtty_aux))
                    419:                odata |= DUART_RX_READY;
                    420: 
                    421:             odata |= DUART_TX_READY;
                    422:          
                    423:             //mips64_clear_irq(d->mgr_cpu,C7200_DUART_IRQ);
                    424:             *data = odata;
                    425:          }
                    426:          break;
                    427: 
                    428:       case 0x454:   /* Command Register B (CRB) */
                    429:          break;
                    430: 
                    431:       case 0x45c:   /* RX/TX Holding Register B (RHRB/THRB) */
                    432:          if (op_type == MTS_WRITE) {
                    433:             vtty_put_char(d->vtty_aux,(char)*data);
                    434:          } else {
                    435:             *data = vtty_get_char(d->vtty_aux);
                    436:          }
                    437:          break;
                    438: 
                    439:       /* ==== DS 1620 (temp sensors) ==== */
                    440:       case 0x20c:   /* Temperature Control */
                    441:          if (op_type == MTS_WRITE)
                    442:             temp_write_ctrl(d,*data);
                    443:          break;
                    444: 
                    445:       case 0x214:   /* Temperature data write */
                    446:          if (op_type == MTS_WRITE) {
                    447:             temp_write_data(d,*data);
                    448:             d->mux = *data;
                    449:          }
                    450:          break;
                    451: 
                    452:       case 0x22c:   /* Temperature data read */
                    453:          *data = temp_read_data(d);
                    454:          break;
                    455: 
                    456:       case 0x257:   /* ENVM A/D Converter */
                    457: #if DEBUG_ENVM
                    458:          m_log("ENVM","access to envm a/d converter - mux = %u\n",d->mux);
                    459: #endif
                    460:          if (op_type == MTS_READ) {
                    461:             switch(d->mux) {
                    462:                case C7200_MUX_PS0:
                    463:                   *data = C7200_A2D_PS0;
                    464:                   break;
                    465: 
                    466:                case C7200_MUX_PS1:
                    467:                   *data = C7200_A2D_PS1;
                    468:                   break;
                    469: 
                    470:                case C7200_MUX_P3V:
                    471:                   *data = C7200_A2D_P3V;
                    472:                   break;
                    473: 
                    474:                case C7200_MUX_P12V:
                    475:                   *data = C7200_A2D_P12V;
                    476:                   break;
                    477: 
                    478:                case C7200_MUX_P5V:
                    479:                   *data = C7200_A2D_P5V;
                    480:                   break;
                    481: 
                    482:                case C7200_MUX_N12V:
                    483:                   *data = C7200_A2D_N12V;
                    484:                   break;
                    485:                   
                    486:                default:
                    487:                   *data = 0;
                    488:             }
                    489: 
                    490:             *data = *data / C7200_A2D_SAMPLES;
                    491:          }
                    492:          break;
                    493: 
                    494: #if DEBUG_UNKNOWN
                    495:       default:
                    496:          if (op_type == MTS_WRITE)
                    497:             m_log("IO_FPGA","read from addr 0x%x\n",offset);
                    498:          else
                    499:             m_log("IO_FPGA","write to addr 0x%x, value=0x%llx\n",offset,*data);
                    500: #endif
                    501:    }
                    502: 
                    503:    return NULL;
                    504: }
                    505: 
                    506: /*
                    507:  * Set the base MAC address of the system.
                    508:  */
                    509: static int dev_iofpga_set_mac_addr(struct c7200_eeprom *mp_eeprom,
                    510:                                    char *mac_addr)
                    511: {
                    512:    m_eth_addr_t addr;
                    513: 
                    514:    if (parse_mac_addr(&addr,mac_addr) == -1) {
                    515:       fprintf(stderr,"IO_FPGA: unable to parse MAC address '%s'\n",mac_addr);
                    516:       return(-1);
                    517:    }
                    518:    
                    519:    c7200_set_mac_addr(mp_eeprom,&addr);
                    520:    return(0);
                    521: }
                    522: 
                    523: /*
                    524:  * dev_iofpga_init()
                    525:  */
1.1.1.2 ! root      526: int dev_iofpga_init(c7200_t *router,m_uint64_t paddr,m_uint32_t len)
1.1       root      527: {  
                    528:    struct c7200_eeprom *npe_eeprom,*mp_eeprom,*pem_eeprom;
                    529:    struct iofpga_data *d;
                    530:    struct vdevice *dev;
                    531:    cpu_mips_t *cpu0;
                    532:    u_int i;
                    533: 
                    534:    /* Device is managed by CPU0 */
1.1.1.2 ! root      535:    cpu0 = cpu_group_find_id(router->cpu_group,0);
1.1       root      536: 
                    537:    /* Set the NPE EEPROM */
1.1.1.2 ! root      538:    if (!(npe_eeprom = c7200_get_cpu_eeprom(router->npe_type))) {
        !           539:       fprintf(stderr,"C7200: unknown NPE \"%s\"!\n",router->npe_type);
1.1       root      540:       return(-1);
                    541:    }
                    542:    
                    543:    eeprom_cpu_def.data = npe_eeprom->data;
                    544:    eeprom_cpu_def.data_len = npe_eeprom->len;
                    545: 
                    546:    /* Set the Midplane EEPROM */
1.1.1.2 ! root      547:    if (!(mp_eeprom = c7200_get_midplane_eeprom(router->midplane_type))) {
        !           548:       fprintf(stderr,"C7200: unknown Midplane \"%s\"!\n",
        !           549:               router->midplane_type);
1.1       root      550:       return(-1);
                    551:    }
                    552:    
                    553:    eeprom_midplane_def.data = mp_eeprom->data;
                    554:    eeprom_midplane_def.data_len = mp_eeprom->len;
                    555: 
                    556:    /* Set the PEM EEPROM for NPE-175/NPE-225 */
1.1.1.2 ! root      557:    if ((pem_eeprom = c7200_get_pem_eeprom(router->npe_type)) != NULL) {
1.1       root      558:       eeprom_pem_def.data = pem_eeprom->data;
                    559:       eeprom_pem_def.data_len = pem_eeprom->len;
                    560:    }
                    561: 
                    562:    /* Set the base MAC address */
1.1.1.2 ! root      563:    if (router->mac_addr != NULL) {
        !           564:       dev_iofpga_set_mac_addr(mp_eeprom,router->mac_addr);
1.1       root      565:    } else {
                    566:       printf("C7200: Warning, no MAC address set.\n");
                    567:    }
                    568: 
                    569:    /* Allocate private data structure */
                    570:    if (!(d = malloc(sizeof(*d)))) {
                    571:       fprintf(stderr,"IO_FPGA: out of memory\n");
                    572:       return(-1);
                    573:    }
                    574: 
                    575:    memset(d,0,sizeof(*d));
                    576:    d->mgr_cpu  = cpu0;
1.1.1.2 ! root      577:    d->vtty_con = vtty_create("Console port",
        !           578:                              router->vtty_con_type,router->vtty_con_tcp_port);
        !           579:    d->vtty_aux = vtty_create("AUX port",
        !           580:                              router->vtty_aux_type,router->vtty_aux_tcp_port);
1.1       root      581: 
                    582:    for(i=0;i<C7200_TEMP_SENSORS;i++) {
                    583:       d->temp_cfg_reg[i] = DS1620_CONFIG_STATUS_CPU;
                    584:       d->temp_deg_reg[i] = C7200_DEFAULT_TEMP * 2;
                    585:    }
                    586: 
                    587:    /* Create the device itself */
                    588:    if (!(dev = dev_create("io_fpga"))) {
                    589:       fprintf(stderr,"IO_FPGA: unable to create device.\n");
                    590:       return(-1);
                    591:    }
                    592: 
                    593:    dev->phys_addr = paddr;
                    594:    dev->phys_len  = len;
                    595:    dev->handler   = dev_iofpga_access;
                    596:    dev->priv_data = d;
                    597: 
                    598:    /* Map this device to all CPU */
1.1.1.2 ! root      599:    cpu_group_bind_device(router->cpu_group,dev);
1.1       root      600: 
                    601:    /* Create console threads */
1.1.1.2 ! root      602:    if (router->vtty_con_type != VTTY_TYPE_NONE)
1.1       root      603:       pthread_create(&d->duart_con_thread,NULL,(void *)tty_con_input,d);
                    604:    
1.1.1.2 ! root      605:    if (router->vtty_aux_type != VTTY_TYPE_NONE)
1.1       root      606:       pthread_create(&d->duart_aux_thread,NULL,(void *)tty_aux_input,d);
                    607: 
                    608:    ptask_add((ptask_callback)tty_trigger_dummy_irq,d,NULL);
                    609:    return(0);
                    610: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.