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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 21699 byte(s)
make working copy

1 dpavlin 11 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2007 Christophe Fillot (cf@utc.fr)
4     *
5     * Generic C6k-SUP1 routines and definitions (EEPROM,...).
6     *
7     * This is not a working platform! I only added it to play.
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include <unistd.h>
14     #include <sys/types.h>
15     #include <assert.h>
16    
17     #include "cpu.h"
18     #include "vm.h"
19     #include "dynamips.h"
20     #include "memory.h"
21     #include "device.h"
22     #include "pci_io.h"
23     #include "dev_gt.h"
24     #include "cisco_eeprom.h"
25     #include "dev_rom.h"
26     #include "dev_am79c971.h"
27     #include "dev_i8254x.h"
28     #include "dev_c6sup1.h"
29     #include "dev_c6sup1_mpfpga.h"
30     #include "dev_vtty.h"
31     #include "registry.h"
32     #include "net.h"
33    
34     /* ====================================================================== */
35     /* EOBC - Ethernet Out of Band Channel */
36     /* ====================================================================== */
37     static int dev_c6sup1_eobc_init(vm_instance_t *vm,struct cisco_card *card)
38     {
39     struct am79c971_data *data;
40    
41     /* Create the AMD 79c970 chip */
42     data = dev_am79c971_init(vm,card->dev_name,AM79C971_TYPE_100BASE_TX,
43     vm->pci_bus[0],6,
44     3/*c6sup1_net_irq_for_slot_port(0,0)*/);
45     if (!data) return(-1);
46    
47     /* Store device info into the router structure */
48     card->drv_info = data;
49     return(0);
50     }
51    
52     /* Remove EOBC */
53     static int dev_c6sup1_eobc_shutdown(vm_instance_t *vm,struct cisco_card *card)
54     {
55     struct am79c971_data *data = card->drv_info;
56     dev_am79c971_remove(data);
57     return(0);
58     }
59    
60     /* Bind a Network IO descriptor */
61     static int dev_c6sup1_eobc_set_nio(vm_instance_t *vm,struct cisco_card *card,
62     u_int port_id,netio_desc_t *nio)
63     {
64     struct am79c971_data *d = card->drv_info;
65    
66     if (!d || (port_id != 0))
67     return(-1);
68    
69     return(dev_am79c971_set_nio(d,nio));
70     }
71    
72     /* Unbind a Network IO descriptor */
73     static int dev_c6sup1_eobc_unset_nio(vm_instance_t *vm,
74     struct cisco_card *card,
75     u_int port_id)
76     {
77     struct am79c971_data *d = card->drv_info;
78    
79     if (!d || (port_id != 0))
80     return(-1);
81    
82     dev_am79c971_unset_nio(d);
83     return(0);
84     }
85    
86     /* EOBC driver */
87     struct cisco_card_driver dev_c6sup1_eobc = {
88     "C6SUP1_EOBC", 0, 0,
89     dev_c6sup1_eobc_init,
90     dev_c6sup1_eobc_shutdown,
91     NULL,
92     dev_c6sup1_eobc_set_nio,
93     dev_c6sup1_eobc_unset_nio,
94     NULL,
95     };
96    
97     /* ====================================================================== */
98     /* IBC - InBand Channel */
99     /* ====================================================================== */
100     static int dev_c6sup1_ibc_init(vm_instance_t *vm,struct cisco_card *card)
101     {
102     struct i8254x_data *data;
103    
104     /* Create the Intel Wiseman/Livengood chip */
105     data = dev_i8254x_init(vm,card->dev_name,0,vm->pci_bus[0],7,
106     2/*c6sup1_net_irq_for_slot_port(1,0)*/);
107     if (!data) return(-1);
108    
109     /* Store device info into the router structure */
110     card->drv_info = data;
111     return(0);
112     }
113    
114     /* Remove EOBC */
115     static int dev_c6sup1_ibc_shutdown(vm_instance_t *vm,struct cisco_card *card)
116     {
117     struct i8254x_data *data = card->drv_info;
118     dev_i8254x_remove(data);
119     return(0);
120     }
121    
122     /* Bind a Network IO descriptor */
123     static int dev_c6sup1_ibc_set_nio(vm_instance_t *vm,struct cisco_card *card,
124     u_int port_id,netio_desc_t *nio)
125     {
126     struct i8254x_data *d = card->drv_info;
127    
128     if (!d || (port_id != 0))
129     return(-1);
130    
131     return(dev_i8254x_set_nio(d,nio));
132     }
133    
134     /* Unbind a Network IO descriptor */
135     static int dev_c6sup1_ibc_unset_nio(vm_instance_t *vm,
136     struct cisco_card *card,
137     u_int port_id)
138     {
139     struct i8254x_data *d = card->drv_info;
140    
141     if (!d || (port_id != 0))
142     return(-1);
143    
144     dev_i8254x_unset_nio(d);
145     return(0);
146     }
147    
148     /* IBC driver */
149     struct cisco_card_driver dev_c6sup1_ibc = {
150     "C6SUP1_IBC", 0, 0,
151     dev_c6sup1_ibc_init,
152     dev_c6sup1_ibc_shutdown,
153     NULL,
154     dev_c6sup1_ibc_set_nio,
155     dev_c6sup1_ibc_unset_nio,
156     NULL,
157     };
158    
159     /* ======================================================================== */
160     /* Port Adapter Drivers */
161     /* ======================================================================== */
162     static struct cisco_card_driver *pa_drivers[] = {
163     &dev_c6sup1_eobc,
164     &dev_c6sup1_ibc,
165     NULL,
166     };
167    
168     /* ======================================================================== */
169     /* C6SUP1 router instances */
170     /* ======================================================================== */
171    
172     /* Initialize default parameters for a SUP1 */
173     static void c6sup1_init_defaults(c6sup1_t *router);
174    
175     /* Directly extract the configuration from the NVRAM device */
176     static ssize_t c6sup1_nvram_extract_config(vm_instance_t *vm,u_char **buffer)
177     {
178     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
179     m_uint32_t start,end,nvlen,clen;
180     m_uint16_t magic1,magic2;
181     struct vdevice *nvram_dev;
182     m_uint64_t nvram_addr;
183     off_t nvram_size;
184     int fd;
185    
186     if ((nvram_dev = dev_get_by_name(vm,"nvram")))
187     dev_sync(nvram_dev);
188    
189     fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size);
190    
191     if (fd == -1)
192     return(-1);
193    
194     nvram_addr = C6SUP1_NVRAM_ADDR;
195     ios_ptr = base_ptr + vm->nvram_rom_space;
196     end_ptr = base_ptr + nvram_size;
197    
198     if ((ios_ptr + 0x30) >= end_ptr) {
199     vm_error(vm,"NVRAM file too small\n");
200     return(-1);
201     }
202    
203     magic1 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06));
204     magic2 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08));
205    
206     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {
207     vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n",
208     magic1,magic2);
209     return(-1);
210     }
211    
212     start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1;
213     end = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x14));
214     nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));
215     clen = end - start;
216    
217     if ((clen + 1) != nvlen) {
218     vm_error(vm,"invalid configuration size (0x%x)\n",nvlen);
219     return(-1);
220     }
221    
222     if (!(*buffer = malloc(clen+1))) {
223     vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen);
224     return(-1);
225     }
226    
227     cfg_ptr = base_ptr + (start - nvram_addr);
228    
229     if ((start < nvram_addr) || ((cfg_ptr + clen) > end_ptr)) {
230     vm_error(vm,"NVRAM file too small\n");
231     return(-1);
232     }
233    
234     memcpy(*buffer,cfg_ptr,clen);
235     (*buffer)[clen] = 0;
236     return(clen);
237     }
238    
239     /* Directly push the IOS configuration to the NVRAM device */
240     static int c6sup1_nvram_push_config(vm_instance_t *vm,
241     u_char *buffer,size_t len)
242     {
243     u_char *base_ptr,*ios_ptr,*cfg_ptr;
244     m_uint32_t cfg_addr,cfg_offset;
245     m_uint32_t nvram_addr,cklen;
246     m_uint16_t cksum;
247     int fd;
248    
249     fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr);
250    
251     if (fd == -1)
252     return(-1);
253    
254     cfg_offset = 0x2c;
255     ios_ptr = base_ptr + vm->nvram_rom_space;
256     cfg_ptr = ios_ptr + cfg_offset;
257    
258     nvram_addr = C6SUP1_NVRAM_ADDR;
259     cfg_addr = nvram_addr + vm->nvram_rom_space + cfg_offset;
260    
261     /* Write IOS tag, uncompressed config... */
262     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5);
263     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD);
264     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001);
265     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000);
266     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0000);
267    
268     /* Store file contents to NVRAM */
269     memcpy(cfg_ptr,buffer,len);
270    
271     /* Write config addresses + size */
272     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(cfg_addr);
273     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(cfg_addr + len);
274     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len);
275    
276     /* Compute the checksum */
277     cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);
278     cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);
279     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);
280    
281     vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024);
282     return(0);
283     }
284    
285     /* Get slot/port corresponding to specified network IRQ */
286     static inline void
287     c6sup1_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port)
288     {
289     *slot = irq - C6SUP1_NETIO_IRQ_BASE;
290     *port = 0;
291     }
292    
293     /* Get network IRQ for specified slot/port */
294     u_int c6sup1_net_irq_for_slot_port(u_int slot,u_int port)
295     {
296     u_int irq;
297    
298     irq = C6SUP1_NETIO_IRQ_BASE + slot;
299     return(irq);
300     }
301    
302     /* Free specific hardware resources used by a SUP1 */
303     static void c6sup1_free_hw_ressources(c6sup1_t *router)
304     {
305     /* Shutdown all Port Adapters */
306     vm_slot_shutdown_all(router->vm);
307     }
308    
309     /* Create a new router instance */
310     static int c6sup1_create_instance(vm_instance_t *vm)
311     {
312     c6sup1_t *router;
313    
314     if (!(router = malloc(sizeof(*router)))) {
315     fprintf(stderr,"C6SUP1 '%s': Unable to create new instance!\n",vm->name);
316     return(-1);
317     }
318    
319     memset(router,0,sizeof(*router));
320     router->vm = vm;
321     vm->hw_data = router;
322     vm->elf_machine_id = C6SUP1_ELF_MACHINE_ID;
323    
324     c6sup1_init_defaults(router);
325     return(0);
326     }
327    
328     /* Free resources used by a router instance */
329     static int c6sup1_delete_instance(vm_instance_t *vm)
330     {
331     c6sup1_t *router = VM_C6SUP1(vm);
332     int i;
333    
334     /* Stop all CPUs */
335     if (vm->cpu_group != NULL) {
336     vm_stop(vm);
337    
338     if (cpu_group_sync_state(vm->cpu_group) == -1) {
339     vm_error(vm,"unable to sync with system CPUs.\n");
340     return(FALSE);
341     }
342     }
343    
344     /* Remove NIO bindings */
345     for(i=0;i<C6SUP1_MAX_PA_BAYS;i++)
346     vm_slot_remove_all_nio_bindings(vm,i);
347    
348     /* Free specific HW resources */
349     c6sup1_free_hw_ressources(router);
350    
351     /* Free all resources used by VM */
352     vm_free(vm);
353    
354     /* Free the router structure */
355     free(router);
356     return(TRUE);
357     }
358    
359     /* Create the main PCI bus for a GT64010 based system */
360     static int c6sup1_init_gt64010(c6sup1_t *router)
361     {
362     vm_instance_t *vm = router->vm;
363    
364     if (!(vm->pci_bus[0] = pci_bus_create("PCI Bus 0",0))) {
365     vm_error(vm,"unable to create PCI data.\n");
366     return(-1);
367     }
368    
369     return(dev_gt64010_init(vm,"gt64010",C6SUP1_GT64K_ADDR,0x1000,
370     C6SUP1_GT64K_IRQ));
371     }
372    
373     /* Initialize a SUP1 board */
374     static int c6sup1_init_hw(c6sup1_t *router)
375     {
376     vm_instance_t *vm = router->vm;
377    
378     /* Set the processor type: R5000 */
379     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R5000);
380    
381     /* Initialize the Galileo GT-64010 PCI controller */
382     if (c6sup1_init_gt64010(router) == -1)
383     return(-1);
384    
385     /* Create PCI bus 1 */
386     vm->pci_bus_pool[24] = pci_bus_create("PCI Bus 1",-1);
387     dev_dec21154_init(vm->pci_bus[0],1,vm->pci_bus_pool[24]);
388    
389     /* PCI IO space */
390     if (!(vm->pci_io_space = pci_io_data_init(vm,C6SUP1_PCI_IO_ADDR)))
391     return(-1);
392    
393     /* AGRAM ? */
394     dev_ram_init(vm,"agram",FALSE,FALSE,NULL,FALSE,0x1EA00000,0x40000);
395    
396     /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */
397     dev_clpd6729_init(vm,vm->pci_bus[0],5,vm->pci_io_space,0x402,0x403);
398    
399     return(0);
400     }
401    
402     /* Show SUP1 hardware info */
403     void c6sup1_show_hardware(c6sup1_t *router)
404     {
405     vm_instance_t *vm = router->vm;
406    
407     printf("C6SUP1 instance '%s' (id %d):\n",vm->name,vm->instance_id);
408    
409     printf(" VM Status : %d\n",vm->status);
410     printf(" RAM size : %u Mb\n",vm->ram_size);
411     printf(" IOMEM size : %u Mb\n",vm->iomem_size);
412     printf(" NVRAM size : %u Kb\n",vm->nvram_size);
413     printf(" IOS image : %s\n\n",vm->ios_image);
414    
415     if (vm->debug_level > 0) {
416     dev_show_list(vm);
417     pci_dev_show_list(vm->pci_bus[0]);
418     pci_dev_show_list(vm->pci_bus[1]);
419     printf("\n");
420     }
421     }
422    
423     /* Initialize default parameters for a SUP1 */
424     static void c6sup1_init_defaults(c6sup1_t *router)
425     {
426     vm_instance_t *vm = router->vm;
427     n_eth_addr_t *m;
428     m_uint16_t pid;
429    
430     /* Set platform slots characteristics */
431     vm->nr_slots = C6SUP1_MAX_PA_BAYS;
432     vm->slots_type = CISCO_CARD_TYPE_PA;
433     vm->slots_drivers = pa_drivers;
434    
435     pid = (m_uint16_t)getpid();
436    
437     /* Generate a chassis MAC address based on the instance ID */
438     m = &router->mac_addr;
439     m->eth_addr_byte[0] = vm_get_mac_addr_msb(vm);
440     m->eth_addr_byte[1] = vm->instance_id & 0xFF;
441     m->eth_addr_byte[2] = pid >> 8;
442     m->eth_addr_byte[3] = pid & 0xFF;
443     m->eth_addr_byte[4] = 0x00;
444     m->eth_addr_byte[5] = 0x00;
445    
446     /* Default slot: 1 */
447     router->sup_slot = 1;
448    
449     c6sup1_init_eeprom_groups(router);
450    
451     /* Create EOBC and IBC interfaces */
452     vm_slot_add_binding(vm,"C6SUP1_EOBC",0,0);
453     vm_slot_add_binding(vm,"C6SUP1_IBC",1,0);
454    
455     vm->ram_mmap = C6SUP1_DEFAULT_RAM_MMAP;
456     vm->ram_size = C6SUP1_DEFAULT_RAM_SIZE;
457     vm->rom_size = C6SUP1_DEFAULT_ROM_SIZE;
458     vm->nvram_size = C6SUP1_DEFAULT_NVRAM_SIZE;
459     vm->iomem_size = 0;
460     vm->conf_reg_setup = C6SUP1_DEFAULT_CONF_REG;
461     vm->clock_divisor = C6SUP1_DEFAULT_CLOCK_DIV;
462     vm->nvram_rom_space = C6SUP1_NVRAM_ROM_RES_SIZE;
463     }
464    
465     /* Run the checklist */
466     static int c6sup1_checklist(c6sup1_t *router)
467     {
468     struct vm_instance *vm = router->vm;
469     int res = 0;
470    
471     res += vm_object_check(vm,"ram");
472     res += vm_object_check(vm,"rom");
473     res += vm_object_check(vm,"nvram");
474     res += vm_object_check(vm,"zero");
475    
476     if (res < 0)
477     vm_error(vm,"incomplete initialization (no memory?)\n");
478    
479     return(res);
480     }
481    
482     /* Initialize Port Adapters */
483     static int c6sup1_init_platform_pa(c6sup1_t *router)
484     {
485     return(vm_slot_init_all(router->vm));
486     }
487    
488     /* Initialize the SUP1 Platform */
489     static int c6sup1_init_platform(c6sup1_t *router)
490     {
491     struct vm_instance *vm = router->vm;
492     cpu_mips_t *cpu0;
493     cpu_gen_t *gen0;
494     vm_obj_t *obj;
495    
496     /* Copy config register setup into "active" config register */
497     vm->conf_reg = vm->conf_reg_setup;
498    
499     /* Create Console and AUX ports */
500     vm_init_vtty(vm);
501    
502     /* Create a CPU group */
503     vm->cpu_group = cpu_group_create("System CPU");
504    
505     /* Initialize the virtual MIPS processor */
506     if (!(gen0 = cpu_create(vm,CPU_TYPE_MIPS64,0))) {
507     vm_error(vm,"unable to create CPU0!\n");
508     return(-1);
509     }
510    
511     cpu0 = CPU_MIPS64(gen0);
512    
513     /* Add this CPU to the system CPU group */
514     cpu_group_add(vm->cpu_group,gen0);
515     vm->boot_cpu = gen0;
516    
517     /* Initialize the IRQ routing vectors */
518     vm->set_irq = mips64_vm_set_irq;
519     vm->clear_irq = mips64_vm_clear_irq;
520    
521     /* Mark the Network IO interrupt as high priority */
522     cpu0->irq_idle_preempt[C6SUP1_NETIO_IRQ] = TRUE;
523     cpu0->irq_idle_preempt[C6SUP1_GT64K_IRQ] = TRUE;
524    
525     /* Copy some parameters from VM to CPU0 (idle PC, ...) */
526     cpu0->idle_pc = vm->idle_pc;
527    
528     if (vm->timer_irq_check_itv)
529     cpu0->timer_irq_check_itv = vm->timer_irq_check_itv;
530    
531     /*
532     * On the SUP1, bit 33 of physical addresses is used to bypass L2 cache.
533     * We clear it systematically.
534     */
535     cpu0->addr_bus_mask = C6SUP1_ADDR_BUS_MASK;
536    
537     /* Remote emulator control */
538     dev_remote_control_init(vm,0x16000000,0x1000);
539    
540     /* Bootflash (8 Mb) */
541     dev_bootflash_init(vm,"bootflash","c7200-bootflash-8mb",
542     C6SUP1_BOOTFLASH_ADDR);
543    
544     /* NVRAM and calendar */
545     dev_nvram_init(vm,"nvram",C6SUP1_NVRAM_ADDR,
546     vm->nvram_size*1024,&vm->conf_reg);
547    
548     /* Bit-bucket zone */
549     dev_zero_init(vm,"zero",C6SUP1_BITBUCKET_ADDR,0xc00000);
550    
551     /* Initialize the NPE board */
552     if (c6sup1_init_hw(router) == -1)
553     return(-1);
554    
555     /* Initialize RAM */
556     vm_ram_init(vm,0x00000000ULL);
557    
558     /* Initialize ROM */
559     if (!vm->rom_filename) {
560     /* use embedded ROM */
561     dev_rom_init(vm,"rom",C6SUP1_ROM_ADDR,vm->rom_size*1048576,
562     mips64_microcode,mips64_microcode_len);
563     } else {
564     /* use alternate ROM */
565     dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
566     C6SUP1_ROM_ADDR,vm->rom_size*1048576);
567     }
568    
569     /* Byte swapping */
570     dev_bswap_init(vm,"mem_bswap",C6SUP1_BSWAP_ADDR,1024*1048576,0x00000000ULL);
571    
572     /* PCI IO space */
573     if (!(vm->pci_io_space = pci_io_data_init(vm,C6SUP1_PCI_IO_ADDR)))
574     return(-1);
575    
576     /* Initialize the Port Adapters */
577     if (c6sup1_init_platform_pa(router) == -1)
578     return(-1);
579    
580     /* Verify the check list */
581     if (c6sup1_checklist(router) == -1)
582     return(-1);
583    
584     /* Midplane FPGA */
585     if (dev_c6sup1_mpfpga_init(router,C6SUP1_MPFPGA_ADDR,0x40000) == -1)
586     return(-1);
587    
588     if (!(obj = vm_object_find(router->vm,"mp_fpga")))
589     return(-1);
590    
591     router->mpfpga_data = obj->data;
592    
593     /* IO FPGA */
594     if (dev_c6sup1_iofpga_init(router,C6SUP1_IOFPGA_ADDR,0x1000) == -1)
595     return(-1);
596    
597     /* Show device list */
598     c6sup1_show_hardware(router);
599     return(0);
600     }
601    
602     /* Boot the IOS image */
603     static int c6sup1_boot_ios(c6sup1_t *router)
604     {
605     vm_instance_t *vm = router->vm;
606     cpu_mips_t *cpu;
607    
608     if (!vm->boot_cpu)
609     return(-1);
610    
611     /* Suspend CPU activity since we will restart directly from ROM */
612     vm_suspend(vm);
613    
614     /* Check that CPU activity is really suspended */
615     if (cpu_group_sync_state(vm->cpu_group) == -1) {
616     vm_error(vm,"unable to sync with system CPUs.\n");
617     return(-1);
618     }
619    
620     /* Reset the boot CPU */
621     cpu = CPU_MIPS64(vm->boot_cpu);
622     mips64_reset(cpu);
623    
624     /* Load IOS image */
625     if (mips64_load_elf_image(cpu,vm->ios_image,
626     (vm->ghost_status == VM_GHOST_RAM_USE),
627     &vm->ios_entry_point) < 0)
628     {
629     vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
630     return(-1);
631     }
632    
633     /* Launch the simulation */
634     printf("\nC6SUP1 '%s': starting simulation (CPU0 PC=0x%llx), "
635     "JIT %sabled.\n",
636     vm->name,cpu->pc,vm->jit_use ? "en":"dis");
637    
638     vm_log(vm,"C6SUP1_BOOT",
639     "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n",
640     cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");
641    
642     /* Start main CPU */
643     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
644     vm->status = VM_STATUS_RUNNING;
645     cpu_start(vm->boot_cpu);
646     } else {
647     vm->status = VM_STATUS_SHUTDOWN;
648     }
649     return(0);
650     }
651    
652     /* Set an IRQ */
653     static void c6sup1_set_irq(vm_instance_t *vm,u_int irq)
654     {
655     c6sup1_t *router = VM_C6SUP1(vm);
656     cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
657     u_int slot,port;
658    
659     switch(irq) {
660     case 0 ... 7:
661     mips64_set_irq(cpu0,irq);
662    
663     if (cpu0->irq_idle_preempt[irq])
664     cpu_idle_break_wait(cpu0->gen);
665     break;
666    
667     case C6SUP1_NETIO_IRQ_BASE ... C6SUP1_NETIO_IRQ_END:
668     c6sup1_net_irq_get_slot_port(irq,&slot,&port);
669     //dev_c6sup1_mpfpga_net_set_irq(router->mpfpga_data,slot,port);
670     break;
671     }
672     }
673    
674     /* Clear an IRQ */
675     static void c6sup1_clear_irq(vm_instance_t *vm,u_int irq)
676     {
677     c6sup1_t *router = VM_C6SUP1(vm);
678     cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
679     u_int slot,port;
680    
681     switch(irq) {
682     case 0 ... 7:
683     mips64_clear_irq(cpu0,irq);
684     break;
685    
686     case C6SUP1_NETIO_IRQ_BASE ... C6SUP1_NETIO_IRQ_END:
687     c6sup1_net_irq_get_slot_port(irq,&slot,&port);
688     //dev_c6sup1_mpfpga_net_clear_irq(router->mpfpga_data,slot,port);
689     break;
690     }
691     }
692    
693     /* Initialize a SUP1 instance */
694     static int c6sup1_init_instance(vm_instance_t *vm)
695     {
696     c6sup1_t *router = VM_C6SUP1(vm);
697     m_uint32_t rom_entry_point;
698     cpu_mips_t *cpu0;
699    
700     /* Initialize the SUP1 platform */
701     if (c6sup1_init_platform(router) == -1) {
702     vm_error(vm,"unable to initialize the platform hardware.\n");
703     return(-1);
704     }
705    
706     /* IRQ routing */
707     vm->set_irq = c6sup1_set_irq;
708     vm->clear_irq = c6sup1_clear_irq;
709    
710     /* Load IOS configuration file */
711     if (vm->ios_config != NULL) {
712     vm_nvram_push_config(vm,vm->ios_config);
713     vm->conf_reg &= ~0x40;
714     }
715    
716     /* Load ROM (ELF image or embedded) */
717     cpu0 = CPU_MIPS64(vm->boot_cpu);
718     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;
719    
720     if ((vm->rom_filename != NULL) &&
721     (mips64_load_elf_image(cpu0,vm->rom_filename,0,&rom_entry_point) < 0))
722     {
723     vm_error(vm,"unable to load alternate ROM '%s', "
724     "fallback to embedded ROM.\n\n",vm->rom_filename);
725     vm->rom_filename = NULL;
726     }
727    
728     /* Load symbol file */
729     if (vm->sym_filename) {
730     mips64_sym_load_file(cpu0,vm->sym_filename);
731     cpu0->sym_trace = 1;
732     }
733    
734     return(c6sup1_boot_ios(router));
735     }
736    
737     /* Stop a SUP1 instance */
738     static int c6sup1_stop_instance(vm_instance_t *vm)
739     {
740     printf("\nC6SUP1 '%s': stopping simulation.\n",vm->name);
741     vm_log(vm,"C6SUP1_STOP","stopping simulation.\n");
742    
743     /* Stop all CPUs */
744     if (vm->cpu_group != NULL) {
745     vm_stop(vm);
746    
747     if (cpu_group_sync_state(vm->cpu_group) == -1) {
748     vm_error(vm,"unable to sync with system CPUs.\n");
749     return(-1);
750     }
751     }
752    
753     /* Free resources that were used during execution to emulate hardware */
754     c6sup1_free_hw_ressources(VM_C6SUP1(vm));
755     vm_hardware_shutdown(vm);
756     return(0);
757     }
758    
759     /* Get MAC address MSB */
760     static u_int c6sup1_get_mac_addr_msb(void)
761     {
762     return(0xD0);
763     }
764    
765     /* Show specific CLI options */
766     static void c6sup1_cli_show_options(vm_instance_t *vm)
767     {
768     printf(" -s <pa_nio> : Bind a Network IO interface to a "
769     "Port Adapter\n");
770     }
771    
772     /* Platform definition */
773     static vm_platform_t c6sup1_platform = {
774     "c6sup1", "C6SUP1", "C6SUP1",
775     c6sup1_create_instance,
776     c6sup1_delete_instance,
777     c6sup1_init_instance,
778     c6sup1_stop_instance,
779     c6sup1_nvram_extract_config,
780     c6sup1_nvram_push_config,
781     c6sup1_get_mac_addr_msb,
782     NULL,
783     NULL,
784     c6sup1_cli_show_options,
785     NULL,
786     };
787    
788     /* Register the C6-SUP1 platform */
789     int c6sup1_platform_register(void)
790     {
791     return(vm_platform_register(&c6sup1_platform));
792     }

  ViewVC Help
Powered by ViewVC 1.1.26