/[dynamips]/upstream/dynamips-0.2.6-RC3/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

Annotation of /upstream/dynamips-0.2.6-RC3/dev_c7200_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Sat Oct 6 16:03:58 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC1/dev_c7200_iofpga.c
File MIME type: text/plain
File size: 18654 byte(s)
import dynamips-0.2.6-RC1

1 dpavlin 1 /*
2     * Cisco 7200 (Predator) simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
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_ACCESS 0
35     #define DEBUG_LED 0
36     #define DEBUG_IO_CTL 0
37     #define DEBUG_ENVM 0
38    
39     /* DUART RX/TX status (SRA/SRB) */
40     #define DUART_RX_READY 0x01
41     #define DUART_TX_READY 0x04
42    
43     /* DUART RX/TX Interrupt Status/Mask */
44     #define DUART_TXRDYA 0x01
45     #define DUART_RXRDYA 0x02
46     #define DUART_TXRDYB 0x10
47     #define DUART_RXRDYB 0x20
48    
49     /* Definitions for CPU and Midplane Serial EEPROMs */
50     #define DO2_DATA_OUT_MIDPLANE 7
51     #define DO1_DATA_OUT_CPU 6
52     #define CS2_CHIP_SEL_MIDPLANE 5
53     #define SK2_CLOCK_MIDPLANE 4
54     #define DI2_DATA_IN_MIDPLANE 3
55     #define CS1_CHIP_SEL_CPU 2
56     #define SK1_CLOCK_CPU 1
57     #define DI1_DATA_IN_CPU 0
58    
59     /* Definitions for PEM (NPE-B) Serial EEPROM */
60     #define DO1_DATA_OUT_PEM 3
61     #define DI1_DATA_IN_PEM 2
62     #define CS1_CHIP_SEL_PEM 1
63     #define SK1_CLOCK_PEM 0
64    
65     /* Pack the NVRAM */
66     #define NVRAM_PACKED 0x04
67    
68     /* 4 temperature sensors in a C7200 */
69     #define C7200_TEMP_SENSORS 4
70     #define C7200_DEFAULT_TEMP 22 /* default temperature: 22°C */
71    
72     /* Voltages */
73     #define C7200_A2D_SAMPLES 9
74    
75     /*
76     * A2D MUX Select definitions.
77     */
78     #define C7200_MUX_PS0 0x00 /* Power Supply 0 */
79     #define C7200_MUX_PS1 0x02 /* Power Supply 1 */
80     #define C7200_MUX_P3V 0x04 /* +3V */
81     #define C7200_MUX_P12V 0x08 /* +12V */
82     #define C7200_MUX_P5V 0x0a /* +5V */
83     #define C7200_MUX_N12V 0x0c /* -12V */
84    
85     /* Analog To Digital Converters samples */
86     #define C7200_A2D_PS0 1150
87     #define C7200_A2D_PS1 1150
88    
89     /* Voltage Samples */
90     #define C7200_A2D_P3V 1150
91     #define C7200_A2D_P12V 1150
92     #define C7200_A2D_P5V 1150
93     #define C7200_A2D_N12V 1150
94    
95     /* IO FPGA structure */
96     struct iofpga_data {
97     vm_obj_t vm_obj;
98     struct vdevice dev;
99     c7200_t *router;
100    
101     /* Lock test */
102     pthread_mutex_t lock;
103    
104     /* Periodic task to trigger dummy DUART IRQ */
105     ptask_id_t duart_irq_tid;
106    
107     /* DUART & Console Management */
108     u_int duart_isr,duart_imr,duart_irq_seq;
109    
110     /* IO control register */
111     u_int io_ctrl_reg;
112    
113     /* Temperature Control */
114     u_int temp_cfg_reg[C7200_TEMP_SENSORS];
115     u_int temp_deg_reg[C7200_TEMP_SENSORS];
116     u_int temp_clk_low;
117    
118     u_int temp_cmd;
119     u_int temp_cmd_pos;
120    
121     u_int temp_data;
122     u_int temp_data_pos;
123    
124     /* Voltages */
125     u_int mux;
126     };
127    
128     #define IOFPGA_LOCK(d) pthread_mutex_lock(&(d)->lock)
129     #define IOFPGA_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)
130    
131     /* Empty EEPROM */
132     static const m_uint16_t eeprom_empty_data[16] = {
133     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
134     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
135     };
136    
137     /* CPU EEPROM definition */
138     static const struct nmc93c46_eeprom_def eeprom_cpu_def = {
139     SK1_CLOCK_CPU, CS1_CHIP_SEL_CPU,
140     DI1_DATA_IN_CPU, DO1_DATA_OUT_CPU,
141     NULL, 0,
142     };
143    
144     /* Midplane EEPROM definition */
145     static const struct nmc93c46_eeprom_def eeprom_midplane_def = {
146     SK2_CLOCK_MIDPLANE, CS2_CHIP_SEL_MIDPLANE,
147     DI2_DATA_IN_MIDPLANE, DO2_DATA_OUT_MIDPLANE,
148     NULL, 0,
149     };
150    
151     /* PEM (NPE-B) EEPROM definition */
152     static const struct nmc93c46_eeprom_def eeprom_pem_def = {
153     SK1_CLOCK_PEM, CS1_CHIP_SEL_PEM, DI1_DATA_IN_PEM, DO1_DATA_OUT_PEM,
154     (m_uint16_t *)eeprom_empty_data, (sizeof(eeprom_empty_data) / 2),
155     };
156    
157     /* IOFPGA manages simultaneously CPU and Midplane EEPROM */
158     static const struct nmc93c46_group eeprom_cpu_midplane = {
159     2, 0, "CPU and Midplane EEPROM", 0,
160     { NULL, NULL, }, { { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0} },
161     };
162    
163     /*
164     * IOFPGA manages also PEM EEPROM (for NPE-B)
165     * PEM stands for "Power Entry Module":
166     * http://www.cisco.com/en/US/products/hw/routers/ps341/products_field_notice09186a00801cb26d.shtml
167     */
168     static const struct nmc93c46_group eeprom_pem_npeb = {
169     1, 0, "PEM (NPE-B) EEPROM", 0, { NULL }, { { 0, 0, 0, 0, 0} },
170     };
171    
172     /* Reset DS1620 */
173     static void temp_reset(struct iofpga_data *d)
174     {
175     d->temp_cmd_pos = 0;
176     d->temp_cmd = 0;
177    
178     d->temp_data_pos = 0;
179     d->temp_data = 0;
180     }
181    
182     /* Write the temperature control data */
183     static void temp_write_ctrl(struct iofpga_data *d,u_char val)
184     {
185     switch(val) {
186     case DS1620_RESET_ON:
187     temp_reset(d);
188     break;
189    
190     case DS1620_CLK_LOW:
191     d->temp_clk_low = 1;
192     break;
193    
194     case DS1620_CLK_HIGH:
195     d->temp_clk_low = 0;
196     break;
197     }
198     }
199    
200     /* Read a temperature control data */
201     static u_int temp_read_data(struct iofpga_data *d)
202     {
203     u_int i,data = 0;
204    
205     switch(d->temp_cmd) {
206     case DS1620_READ_CONFIG:
207     for(i=0;i<C7200_TEMP_SENSORS;i++)
208     data |= ((d->temp_cfg_reg[i] >> d->temp_data_pos) & 1) << i;
209    
210     d->temp_data_pos++;
211    
212     if (d->temp_data_pos == DS1620_CONFIG_READ_SIZE)
213     temp_reset(d);
214    
215     break;
216    
217     case DS1620_READ_TEMP:
218     for(i=0;i<C7200_TEMP_SENSORS;i++)
219     data |= ((d->temp_deg_reg[i] >> d->temp_data_pos) & 1) << i;
220    
221     d->temp_data_pos++;
222    
223     if (d->temp_data_pos == DS1620_DATA_READ_SIZE)
224     temp_reset(d);
225    
226     break;
227    
228     default:
229     vm_log(d->router->vm,"IO_FPGA","temp_sensors: CMD = 0x%x\n",
230     d->temp_cmd);
231     }
232    
233     return(data);
234     }
235    
236     /* Write the temperature data write register */
237     static void temp_write_data(struct iofpga_data *d,u_char val)
238     {
239     if (val == DS1620_ENABLE_READ) {
240     d->temp_data_pos = 0;
241     return;
242     }
243    
244     if (!d->temp_clk_low)
245     return;
246    
247     /* Write a command */
248     if (d->temp_cmd_pos < DS1620_WRITE_SIZE)
249     {
250     if (val == DS1620_DATA_HIGH)
251     d->temp_cmd |= 1 << d->temp_cmd_pos;
252    
253     d->temp_cmd_pos++;
254    
255     if (d->temp_cmd_pos == DS1620_WRITE_SIZE) {
256     switch(d->temp_cmd) {
257     case DS1620_START_CONVT:
258     //printf("temp_sensors: IOS enabled continuous monitoring.\n");
259     temp_reset(d);
260     break;
261     case DS1620_READ_CONFIG:
262     case DS1620_READ_TEMP:
263     break;
264     default:
265     vm_log(d->router->vm,"IO_FPGA",
266     "temp_sensors: IOS sent command 0x%x.\n",
267     d->temp_cmd);
268     }
269     }
270     }
271     else
272     {
273     if (val == DS1620_DATA_HIGH)
274     d->temp_data |= 1 << d->temp_data_pos;
275    
276     d->temp_data_pos++;
277     }
278     }
279    
280     /* Console port input */
281     static void tty_con_input(vtty_t *vtty)
282     {
283     struct iofpga_data *d = vtty->priv_data;
284    
285     IOFPGA_LOCK(d);
286     if (d->duart_imr & DUART_RXRDYA) {
287     d->duart_isr |= DUART_RXRDYA;
288     vm_set_irq(d->router->vm,C7200_DUART_IRQ);
289     }
290     IOFPGA_UNLOCK(d);
291     }
292    
293     /* AUX port input */
294     static void tty_aux_input(vtty_t *vtty)
295     {
296     struct iofpga_data *d = vtty->priv_data;
297    
298     IOFPGA_LOCK(d);
299     if (d->duart_imr & DUART_RXRDYB) {
300     d->duart_isr |= DUART_RXRDYB;
301     vm_set_irq(d->router->vm,C7200_DUART_IRQ);
302     }
303     IOFPGA_UNLOCK(d);
304     }
305    
306     /* IRQ trickery for Console and AUX ports */
307     static int tty_trigger_dummy_irq(struct iofpga_data *d,void *arg)
308     {
309     u_int mask;
310    
311     IOFPGA_LOCK(d);
312     d->duart_irq_seq++;
313    
314     if (d->duart_irq_seq == 2) {
315     mask = DUART_TXRDYA|DUART_TXRDYB;
316     if (d->duart_imr & mask) {
317     d->duart_isr |= DUART_TXRDYA|DUART_TXRDYB;
318     vm_set_irq(d->router->vm,C7200_DUART_IRQ);
319     }
320    
321     d->duart_irq_seq = 0;
322     }
323    
324     IOFPGA_UNLOCK(d);
325     return(0);
326     }
327    
328     /*
329     * dev_c7200_iofpga_access()
330     */
331     void *dev_c7200_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,
332     m_uint32_t offset,u_int op_size,u_int op_type,
333     m_uint64_t *data)
334     {
335     struct iofpga_data *d = dev->priv_data;
336     vm_instance_t *vm = d->router->vm;
337     u_char odata;
338    
339     if (op_type == MTS_READ)
340     *data = 0x0;
341    
342     #if DEBUG_ACCESS
343     if (op_type == MTS_READ) {
344     cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx\n",offset,cpu->pc);
345     } else {
346     cpu_log(cpu,"IO_FPGA","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",
347     offset,cpu->pc,*data);
348     }
349     #endif
350    
351     IOFPGA_LOCK(d);
352    
353     switch(offset) {
354     case 0x294:
355     /*
356     * Unknown, seen in 12.4(6)T, and seems to be read at each
357     * network interrupt.
358     */
359     if (op_type == MTS_READ)
360     *data = 0x0;
361     break;
362    
363     /* NPE-G1 test - unknown (value written: 0x01) */
364     case 0x338:
365     break;
366    
367     /* NPE-G1 test - has influence on slot 0 / flash / pcmcia ... */
368     case 0x390:
369     if (op_type == MTS_READ)
370     *data = 0x0FFF0000; //0xFFFF0000;
371     break;
372    
373     /* I/O control register */
374     case 0x204:
375     if (op_type == MTS_WRITE) {
376     #if DEBUG_IO_CTL
377     vm_log(vm,"IO_FPGA","setting value 0x%llx in io_ctrl_reg\n",*data);
378     #endif
379     d->io_ctrl_reg = *data;
380     }
381     else {
382     *data = d->io_ctrl_reg;
383     *data |= NVRAM_PACKED; /* Packed NVRAM */
384     }
385     break;
386    
387     /* CPU/Midplane EEPROMs */
388     case 0x21c:
389     if (op_type == MTS_WRITE)
390     nmc93c46_write(&d->router->sys_eeprom_g1,(u_int)(*data));
391     else
392     *data = nmc93c46_read(&d->router->sys_eeprom_g1);
393     break;
394    
395     /* PEM (NPE-B) EEPROM */
396     case 0x388:
397     if (op_type == MTS_WRITE)
398     nmc93c46_write(&d->router->sys_eeprom_g2,(u_int)(*data));
399     else
400     *data = nmc93c46_read(&d->router->sys_eeprom_g2);
401     break;
402    
403     /* Watchdog */
404     case 0x234:
405     break;
406    
407     /*
408     * FPGA release/presence ? Flash SIMM size:
409     * 0x0001: 2048K Flash (2 banks)
410     * 0x0504: 8192K Flash (2 banks)
411     * 0x0704: 16384K Flash (2 banks)
412     * 0x0904: 32768K Flash (2 banks)
413     * 0x0B04: 65536K Flash (2 banks)
414     * 0x2001: 1024K Flash (1 bank)
415     * 0x2504: 4096K Flash (1 bank)
416     * 0x2704: 8192K Flash (1 bank)
417     * 0x2904: 16384K Flash (1 bank)
418     * 0x2B04: 32768K Flash (1 bank)
419     *
420     * Number of Flash SIMM banks + size.
421     * Touching some lower bits causes problems with environmental monitor.
422     *
423     * It is displayed by command "sh bootflash: chips"
424     */
425     case 0x23c:
426     if (op_type == MTS_READ)
427     *data = 0x2704;
428     break;
429    
430     /* LEDs */
431     case 0x244:
432     #if DEBUG_LED
433     vm_log(vm,"IO_FPGA","LED register is now 0x%x (0x%x)\n",
434     *data,(~*data) & 0x0F);
435     #endif
436     break;
437    
438     /* ==== DUART SCN2681 (console/aux) ==== */
439     case 0x404: /* Mode Register A (MRA) */
440     break;
441    
442     case 0x40c: /* Status Register A (SRA) */
443     if (op_type == MTS_READ) {
444     odata = 0;
445    
446     if (vtty_is_char_avail(vm->vtty_con))
447     odata |= DUART_RX_READY;
448    
449     odata |= DUART_TX_READY;
450    
451     vm_clear_irq(vm,C7200_DUART_IRQ);
452     *data = odata;
453     }
454     break;
455    
456     case 0x414: /* Command Register A (CRA) */
457     /* Disable TX = High */
458     if ((op_type == MTS_WRITE) && (*data & 0x8)) {
459     vm->vtty_con->managed_flush = TRUE;
460     vtty_flush(vm->vtty_con);
461     }
462     break;
463    
464     case 0x41c: /* RX/TX Holding Register A (RHRA/THRA) */
465     if (op_type == MTS_WRITE) {
466     vtty_put_char(vm->vtty_con,(char)*data);
467     d->duart_isr &= ~DUART_TXRDYA;
468     } else {
469     *data = vtty_get_char(vm->vtty_con);
470     d->duart_isr &= ~DUART_RXRDYA;
471     }
472     break;
473    
474     case 0x424: /* WRITE: Aux Control Register (ACR) */
475     break;
476    
477     case 0x42c: /* Interrupt Status/Mask Register (ISR/IMR) */
478     if (op_type == MTS_WRITE) {
479     d->duart_imr = *data;
480     } else
481     *data = d->duart_isr;
482     break;
483    
484     case 0x434: /* Counter/Timer Upper Value (CTU) */
485     case 0x43c: /* Counter/Timer Lower Value (CTL) */
486     case 0x444: /* Mode Register B (MRB) */
487     break;
488    
489     case 0x44c: /* Status Register B (SRB) */
490     if (op_type == MTS_READ) {
491     odata = 0;
492    
493     if (vtty_is_char_avail(vm->vtty_aux))
494     odata |= DUART_RX_READY;
495    
496     odata |= DUART_TX_READY;
497    
498     //vm_clear_irq(vm,C7200_DUART_IRQ);
499     *data = odata;
500     }
501     break;
502    
503     case 0x454: /* Command Register B (CRB) */
504     /* Disable TX = High */
505     if ((op_type == MTS_WRITE) && (*data & 0x8)) {
506     vm->vtty_aux->managed_flush = TRUE;
507     vtty_flush(vm->vtty_aux);
508     }
509     break;
510    
511     case 0x45c: /* RX/TX Holding Register B (RHRB/THRB) */
512     if (op_type == MTS_WRITE) {
513     vtty_put_char(vm->vtty_aux,(char)*data);
514     d->duart_isr &= ~DUART_TXRDYA;
515     } else {
516     *data = vtty_get_char(vm->vtty_aux);
517     d->duart_isr &= ~DUART_RXRDYB;
518     }
519     break;
520    
521     case 0x46c: /* WRITE: Output Port Configuration Register (OPCR) */
522     case 0x474: /* READ: Start Counter Command; */
523     /* WRITE: Set Output Port Bits Command */
524     case 0x47c: /* WRITE: Reset Output Port Bits Command */
525     break;
526    
527     /* ==== DS 1620 (temp sensors) ==== */
528     case 0x20c: /* Temperature Control */
529     if (op_type == MTS_WRITE)
530     temp_write_ctrl(d,*data);
531     break;
532    
533     case 0x214: /* Temperature data write */
534     if (op_type == MTS_WRITE) {
535     temp_write_data(d,*data);
536     d->mux = *data;
537     }
538     break;
539    
540     case 0x22c: /* Temperature data read */
541     if (op_type == MTS_READ)
542     *data = temp_read_data(d);
543     break;
544    
545     /*
546     * NPE-G1 - Voltages + Power Supplies.
547     * I don't understand exactly how it works, it seems that the low
548     * part must be equal to the high part to have the better values.
549     */
550     case 0x254:
551     #if DEBUG_ENVM
552     vm_log(vm,"ENVM","access to envm a/d converter - mux = %u\n",d->mux);
553     #endif
554     if (op_type == MTS_READ)
555     *data = 0xFFFFFFFF;
556     break;
557    
558     case 0x257: /* ENVM A/D Converter */
559     #if DEBUG_ENVM
560     vm_log(vm,"ENVM","access to envm a/d converter - mux = %u\n",d->mux);
561     #endif
562     if (op_type == MTS_READ) {
563     switch(d->mux) {
564     case C7200_MUX_PS0:
565     *data = C7200_A2D_PS0;
566     break;
567    
568     case C7200_MUX_PS1:
569     *data = C7200_A2D_PS1;
570     break;
571    
572     case C7200_MUX_P3V:
573     *data = C7200_A2D_P3V;
574     break;
575    
576     case C7200_MUX_P12V:
577     *data = C7200_A2D_P12V;
578     break;
579    
580     case C7200_MUX_P5V:
581     *data = C7200_A2D_P5V;
582     break;
583    
584     case C7200_MUX_N12V:
585     *data = C7200_A2D_N12V;
586     break;
587    
588     default:
589     *data = 0;
590     }
591    
592     *data = *data / C7200_A2D_SAMPLES;
593     }
594     break;
595    
596     #if DEBUG_UNKNOWN
597     default:
598     if (op_type == MTS_READ) {
599     cpu_log(cpu,"IO_FPGA","read from addr 0x%x, pc=0x%llx (size=%u)\n",
600     offset,cpu->pc,op_size);
601     } else {
602     cpu_log(cpu,"IO_FPGA","write to addr 0x%x, value=0x%llx, "
603     "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);
604     }
605     #endif
606     }
607    
608     IOFPGA_UNLOCK(d);
609     return NULL;
610     }
611    
612     /* Initialize EEPROM groups */
613     void c7200_init_eeprom_groups(c7200_t *router)
614     {
615     struct nmc93c46_group *g;
616    
617     /* Copy EEPROM definitions */
618     memcpy(&router->cpu_eeprom,&eeprom_cpu_def,sizeof(eeprom_cpu_def));
619     memcpy(&router->mp_eeprom,&eeprom_midplane_def,sizeof(eeprom_midplane_def));
620     memcpy(&router->pem_eeprom,&eeprom_pem_def,sizeof(eeprom_pem_def));
621    
622     /* Initialize groups */
623     g = &router->sys_eeprom_g1;
624     memcpy(g,&eeprom_cpu_midplane,sizeof(eeprom_cpu_midplane));
625     g->def[0] = &router->cpu_eeprom;
626     g->def[1] = &router->mp_eeprom;
627    
628     g = &router->sys_eeprom_g2;
629     memcpy(g,&eeprom_pem_npeb,sizeof(eeprom_pem_npeb));
630     g->def[0] = &router->pem_eeprom;
631     }
632    
633     /* Shutdown the IO FPGA device */
634     void dev_c7200_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)
635     {
636     if (d != NULL) {
637     IOFPGA_LOCK(d);
638     vm->vtty_con->read_notifier = NULL;
639     vm->vtty_aux->read_notifier = NULL;
640     IOFPGA_UNLOCK(d);
641    
642     /* Remove the dummy IRQ periodic task */
643     ptask_remove(d->duart_irq_tid);
644    
645     /* Remove the device */
646     dev_remove(vm,&d->dev);
647    
648     /* Free the structure itself */
649     free(d);
650     }
651     }
652    
653     /*
654     * dev_c7200_iofpga_init()
655     */
656     int dev_c7200_iofpga_init(c7200_t *router,m_uint64_t paddr,m_uint32_t len)
657     {
658     vm_instance_t *vm = router->vm;
659     struct iofpga_data *d;
660     u_int i;
661    
662     /* Allocate private data structure */
663     if (!(d = malloc(sizeof(*d)))) {
664     fprintf(stderr,"IO_FPGA: out of memory\n");
665     return(-1);
666     }
667    
668     memset(d,0,sizeof(*d));
669    
670     pthread_mutex_init(&d->lock,NULL);
671     d->router = router;
672    
673     for(i=0;i<C7200_TEMP_SENSORS;i++) {
674     d->temp_cfg_reg[i] = DS1620_CONFIG_STATUS_CPU;
675     d->temp_deg_reg[i] = C7200_DEFAULT_TEMP * 2;
676     }
677    
678     vm_object_init(&d->vm_obj);
679     d->vm_obj.name = "io_fpga";
680     d->vm_obj.data = d;
681     d->vm_obj.shutdown = (vm_shutdown_t)dev_c7200_iofpga_shutdown;
682    
683     /* Set device properties */
684     dev_init(&d->dev);
685     d->dev.name = "io_fpga";
686     d->dev.phys_addr = paddr;
687     d->dev.phys_len = len;
688     d->dev.handler = dev_c7200_iofpga_access;
689     d->dev.priv_data = d;
690    
691     /* Set console and AUX port notifying functions */
692     vm->vtty_con->priv_data = d;
693     vm->vtty_aux->priv_data = d;
694     vm->vtty_con->read_notifier = tty_con_input;
695     vm->vtty_aux->read_notifier = tty_aux_input;
696    
697     /* Trigger periodically a dummy IRQ to flush buffers */
698     d->duart_irq_tid = ptask_add((ptask_callback)tty_trigger_dummy_irq,d,NULL);
699    
700     /* Map this device to the VM */
701     vm_bind_device(vm,&d->dev);
702     vm_object_add(vm,&d->vm_obj);
703     return(0);
704     }

  ViewVC Help
Powered by ViewVC 1.1.26