Annotation of cf/dev_iofpga.c, revision 1.1

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:  */
        !           526: int dev_iofpga_init(cpu_group_t *cpu_group,m_uint64_t paddr,m_uint32_t len,
        !           527:                     char *npe,char *midplane,char *mac_addr)
        !           528: {  
        !           529:    struct c7200_eeprom *npe_eeprom,*mp_eeprom,*pem_eeprom;
        !           530:    struct iofpga_data *d;
        !           531:    struct vdevice *dev;
        !           532:    cpu_mips_t *cpu0;
        !           533:    u_int i;
        !           534: 
        !           535:    /* Device is managed by CPU0 */
        !           536:    cpu0 = cpu_group_find_id(cpu_group,0);
        !           537: 
        !           538:    /* Set the NPE EEPROM */
        !           539:    if (!(npe_eeprom = c7200_get_cpu_eeprom(npe))) {
        !           540:       fprintf(stderr,"C7200: unknown NPE \"%s\"!\n",npe);
        !           541:       return(-1);
        !           542:    }
        !           543:    
        !           544:    eeprom_cpu_def.data = npe_eeprom->data;
        !           545:    eeprom_cpu_def.data_len = npe_eeprom->len;
        !           546: 
        !           547:    /* Set the Midplane EEPROM */
        !           548:    if (!(mp_eeprom = c7200_get_midplane_eeprom(midplane))) {
        !           549:       fprintf(stderr,"C7200: unknown Midplane \"%s\"!\n",midplane);
        !           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 */
        !           557:    if ((pem_eeprom = c7200_get_pem_eeprom(npe)) != NULL) {
        !           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 */
        !           563:    if (mac_addr != NULL) {
        !           564:       dev_iofpga_set_mac_addr(mp_eeprom,mac_addr);
        !           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;
        !           577:    d->vtty_con = vtty_create("Console port",vtty_con_type,vtty_con_tcp_port);
        !           578:    d->vtty_aux = vtty_create("AUX port",vtty_aux_type,vtty_aux_tcp_port);
        !           579: 
        !           580:    for(i=0;i<C7200_TEMP_SENSORS;i++) {
        !           581:       d->temp_cfg_reg[i] = DS1620_CONFIG_STATUS_CPU;
        !           582:       d->temp_deg_reg[i] = C7200_DEFAULT_TEMP * 2;
        !           583:    }
        !           584: 
        !           585:    /* Create the device itself */
        !           586:    if (!(dev = dev_create("io_fpga"))) {
        !           587:       fprintf(stderr,"IO_FPGA: unable to create device.\n");
        !           588:       return(-1);
        !           589:    }
        !           590: 
        !           591:    dev->phys_addr = paddr;
        !           592:    dev->phys_len  = len;
        !           593:    dev->handler   = dev_iofpga_access;
        !           594:    dev->priv_data = d;
        !           595: 
        !           596:    /* Map this device to all CPU */
        !           597:    cpu_group_bind_device(cpu_group,dev);
        !           598: 
        !           599:    /* Create console threads */
        !           600:    if (vtty_con_type != VTTY_TYPE_NONE)
        !           601:       pthread_create(&d->duart_con_thread,NULL,(void *)tty_con_input,d);
        !           602:    
        !           603:    if (vtty_aux_type != VTTY_TYPE_NONE)
        !           604:       pthread_create(&d->duart_aux_thread,NULL,(void *)tty_aux_input,d);
        !           605: 
        !           606:    ptask_add((ptask_callback)tty_trigger_dummy_irq,d,NULL);
        !           607:    return(0);
        !           608: }

unix.superglobalmegacorp.com

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