/[qemu]/qemu/hw/pc.c
ViewVC logotype

Diff of /qemu/hw/pc.c

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

revision 1.45 by bellard, Sun Nov 6 18:20:37 2005 UTC revision 1.46 by bellard, Mon Nov 21 23:34:32 2005 UTC
# Line 86  int cpu_get_pic_interrupt(CPUState *env) Line 86  int cpu_get_pic_interrupt(CPUState *env)
86    
87  static void pic_irq_request(void *opaque, int level)  static void pic_irq_request(void *opaque, int level)
88  {  {
89        CPUState *env = opaque;
90      if (level)      if (level)
91          cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);          cpu_interrupt(env, CPU_INTERRUPT_HARD);
92      else      else
93          cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);          cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
94  }  }
95    
96  /* PC cmos mappings */  /* PC cmos mappings */
# Line 287  static uint32_t speaker_ioport_read(void Line 288  static uint32_t speaker_ioport_read(void
288        (dummy_refresh_clock << 4);        (dummy_refresh_clock << 4);
289  }  }
290    
291    void ioport_set_a20(int enable)
292    {
293        /* XXX: send to all CPUs ? */
294        cpu_x86_set_a20(first_cpu, enable);
295    }
296    
297    int ioport_get_a20(void)
298    {
299        return ((first_cpu->a20_mask >> 20) & 1);
300    }
301    
302  static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)  static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
303  {  {
304      cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);      ioport_set_a20((val >> 1) & 1);
305      /* XXX: bit 0 is fast reset */      /* XXX: bit 0 is fast reset */
306  }  }
307    
308  static uint32_t ioport92_read(void *opaque, uint32_t addr)  static uint32_t ioport92_read(void *opaque, uint32_t addr)
309  {  {
310      return ((cpu_single_env->a20_mask >> 20) & 1) << 1;      return ioport_get_a20() << 1;
311  }  }
312    
313  /***********************************************************/  /***********************************************************/
# Line 391  int load_kernel(const char *filename, ui Line 403  int load_kernel(const char *filename, ui
403      return -1;      return -1;
404  }  }
405    
406    static void main_cpu_reset(void *opaque)
407    {
408        CPUState *env = opaque;
409        cpu_reset(env);
410    }
411    
412    /*************************************************/
413    
414    static void putb(uint8_t **pp, int val)
415    {
416        uint8_t *q;
417        q = *pp;
418        *q++ = val;
419        *pp = q;
420    }
421    
422    static void putstr(uint8_t **pp, const char *str)
423    {
424        uint8_t *q;
425        q = *pp;
426        while (*str)
427            *q++ = *str++;
428        *pp = q;
429    }
430    
431    static void putle16(uint8_t **pp, int val)
432    {
433        uint8_t *q;
434        q = *pp;
435        *q++ = val;
436        *q++ = val >> 8;
437        *pp = q;
438    }
439    
440    static void putle32(uint8_t **pp, int val)
441    {
442        uint8_t *q;
443        q = *pp;
444        *q++ = val;
445        *q++ = val >> 8;
446        *q++ = val >> 16;
447        *q++ = val >> 24;
448        *pp = q;
449    }
450    
451    static int mpf_checksum(const uint8_t *data, int len)
452    {
453        int sum, i;
454        sum = 0;
455        for(i = 0; i < len; i++)
456            sum += data[i];
457        return sum & 0xff;
458    }
459    
460    /* Build the Multi Processor table in the BIOS. Same values as Bochs. */
461    static void bios_add_mptable(uint8_t *bios_data)
462    {
463        uint8_t *mp_config_table, *q, *float_pointer_struct;
464        int ioapic_id, offset, i, len;
465        
466        if (smp_cpus <= 1)
467            return;
468    
469        mp_config_table = bios_data + 0xcc00;
470        q = mp_config_table;
471        putstr(&q, "PCMP"); /* "PCMP signature */
472        putle16(&q, 0); /* table length (patched later) */
473        putb(&q, 4); /* spec rev */
474        putb(&q, 0); /* checksum (patched later) */
475        putstr(&q, "QEMUCPU "); /* OEM id */
476        putstr(&q, "0.1         "); /* vendor id */
477        putle32(&q, 0); /* OEM table ptr */
478        putle16(&q, 0); /* OEM table size */
479        putle16(&q, 20); /* entry count */
480        putle32(&q, 0xfee00000); /* local APIC addr */
481        putle16(&q, 0); /* ext table length */
482        putb(&q, 0); /* ext table checksum */
483        putb(&q, 0); /* reserved */
484        
485        for(i = 0; i < smp_cpus; i++) {
486            putb(&q, 0); /* entry type = processor */
487            putb(&q, i); /* APIC id */
488            putb(&q, 0x11); /* local APIC version number */
489            if (i == 0)
490                putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
491            else
492                putb(&q, 1); /* cpu flags: enabled */
493            putb(&q, 0); /* cpu signature */
494            putb(&q, 6);
495            putb(&q, 0);
496            putb(&q, 0);
497            putle16(&q, 0x201); /* feature flags */
498            putle16(&q, 0);
499    
500            putle16(&q, 0); /* reserved */
501            putle16(&q, 0);
502            putle16(&q, 0);
503            putle16(&q, 0);
504        }
505    
506        /* isa bus */
507        putb(&q, 1); /* entry type = bus */
508        putb(&q, 0); /* bus ID */
509        putstr(&q, "ISA   ");
510        
511        /* ioapic */
512        ioapic_id = smp_cpus;
513        putb(&q, 2); /* entry type = I/O APIC */
514        putb(&q, ioapic_id); /* apic ID */
515        putb(&q, 0x11); /* I/O APIC version number */
516        putb(&q, 1); /* enable */
517        putle32(&q, 0xfec00000); /* I/O APIC addr */
518    
519        /* irqs */
520        for(i = 0; i < 16; i++) {
521            putb(&q, 3); /* entry type = I/O interrupt */
522            putb(&q, 0); /* interrupt type = vectored interrupt */
523            putb(&q, 0); /* flags: po=0, el=0 */
524            putb(&q, 0);
525            putb(&q, 0); /* source bus ID = ISA */
526            putb(&q, i); /* source bus IRQ */
527            putb(&q, ioapic_id); /* dest I/O APIC ID */
528            putb(&q, i); /* dest I/O APIC interrupt in */
529        }
530        /* patch length */
531        len = q - mp_config_table;
532        mp_config_table[4] = len;
533        mp_config_table[5] = len >> 8;
534    
535        mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
536    
537        /* align to 16 */
538        offset = q - bios_data;
539        offset = (offset + 15) & ~15;
540        float_pointer_struct = bios_data + offset;
541        
542        /* floating pointer structure */
543        q = float_pointer_struct;
544        putstr(&q, "_MP_");
545        /* pointer to MP config table */
546        putle32(&q, mp_config_table - bios_data + 0x000f0000);
547    
548        putb(&q, 1); /* length in 16 byte units */
549        putb(&q, 4); /* MP spec revision */
550        putb(&q, 0); /* checksum (patched later) */
551        putb(&q, 0); /* MP feature byte 1 */
552    
553        putb(&q, 0);
554        putb(&q, 0);
555        putb(&q, 0);
556        putb(&q, 0);
557        float_pointer_struct[10] =
558            -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
559    }
560    
561    
562  static const int ide_iobase[2] = { 0x1f0, 0x170 };  static const int ide_iobase[2] = { 0x1f0, 0x170 };
563  static const int ide_iobase2[2] = { 0x3f6, 0x376 };  static const int ide_iobase2[2] = { 0x3f6, 0x376 };
564  static const int ide_irq[2] = { 14, 15 };  static const int ide_irq[2] = { 14, 15 };
# Line 418  static void pc_init1(int ram_size, int v Line 586  static void pc_init1(int ram_size, int v
586      unsigned long bios_offset, vga_bios_offset;      unsigned long bios_offset, vga_bios_offset;
587      int bios_size, isa_bios_size;      int bios_size, isa_bios_size;
588      PCIBus *pci_bus;      PCIBus *pci_bus;
589        CPUState *env;
590    
591      linux_boot = (kernel_filename != NULL);      linux_boot = (kernel_filename != NULL);
592    
593        /* init CPUs */
594        for(i = 0; i < smp_cpus; i++) {
595            env = cpu_init();
596            if (i != 0)
597                env->cpu_halted = 1;
598            if (smp_cpus > 1) {
599                /* XXX: enable it in all cases */
600                env->cpuid_features |= CPUID_APIC;
601            }
602            register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
603            qemu_register_reset(main_cpu_reset, env);
604            if (pci_enabled) {
605                apic_init(env);
606            }
607        }
608    
609      /* allocate RAM */      /* allocate RAM */
610      cpu_register_physical_memory(0, ram_size, 0);      cpu_register_physical_memory(0, ram_size, 0);
611    
# Line 441  static void pc_init1(int ram_size, int v Line 626  static void pc_init1(int ram_size, int v
626          fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);          fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
627          exit(1);          exit(1);
628      }      }
629        if (bios_size == 65536) {
630            bios_add_mptable(phys_ram_base + bios_offset);
631        }
632    
633      /* VGA BIOS load */      /* VGA BIOS load */
634      if (cirrus_vga_enabled) {      if (cirrus_vga_enabled) {
# Line 559  static void pc_init1(int ram_size, int v Line 747  static void pc_init1(int ram_size, int v
747      register_ioport_write(0x92, 1, 1, ioport92_write, NULL);      register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
748    
749      if (pci_enabled) {      if (pci_enabled) {
         apic_init(cpu_single_env);  
750          ioapic = ioapic_init();          ioapic = ioapic_init();
751      }      }
752      isa_pic = pic_init(pic_irq_request, cpu_single_env);      isa_pic = pic_init(pic_irq_request, first_cpu);
753      pit = pit_init(0x40, 0);      pit = pit_init(0x40, 0);
754      if (pci_enabled) {      if (pci_enabled) {
755          pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);          pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);

Legend:
Removed from v.1.45  
changed lines
  Added in v.1.46

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26