Annotation of qemu/hw/alpha_dp264.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU Alpha DP264/CLIPPER hardware system emulator.
        !             3:  *
        !             4:  * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK
        !             5:  * variants because CLIPPER doesn't have an SMC669 SuperIO controler
        !             6:  * that we need to emulate as well.
        !             7:  */
        !             8: 
        !             9: #include "hw.h"
        !            10: #include "elf.h"
        !            11: #include "loader.h"
        !            12: #include "boards.h"
        !            13: #include "alpha_sys.h"
        !            14: #include "sysemu.h"
        !            15: #include "mc146818rtc.h"
        !            16: #include "ide.h"
        !            17: 
        !            18: #define MAX_IDE_BUS 2
        !            19: 
        !            20: static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
        !            21: {
        !            22:     if (((addr >> 41) & 3) == 2) {
        !            23:         addr &= 0xffffffffffull;
        !            24:     }
        !            25:     return addr;
        !            26: }
        !            27: 
        !            28: /* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
        !            29:     (0) The dev_irq_n lines into the cpu, which we totally ignore,
        !            30:     (1) The DRIR lines in the typhoon chipset,
        !            31:     (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
        !            32:     (3) The interrupt number assigned by the kernel.
        !            33:    The following function is concerned with (1) only.  */
        !            34: 
        !            35: static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
        !            36: {
        !            37:     int slot = d->devfn >> 3;
        !            38: 
        !            39:     assert(irq_num >= 0 && irq_num <= 3);
        !            40: 
        !            41:     return (slot + 1) * 4 + irq_num;
        !            42: }
        !            43: 
        !            44: static void clipper_init(ram_addr_t ram_size,
        !            45:                          const char *boot_device,
        !            46:                          const char *kernel_filename,
        !            47:                          const char *kernel_cmdline,
        !            48:                          const char *initrd_filename,
        !            49:                          const char *cpu_model)
        !            50: {
        !            51:     CPUState *cpus[4];
        !            52:     PCIBus *pci_bus;
        !            53:     qemu_irq rtc_irq;
        !            54:     long size, i;
        !            55:     const char *palcode_filename;
        !            56:     uint64_t palcode_entry, palcode_low, palcode_high;
        !            57:     uint64_t kernel_entry, kernel_low, kernel_high;
        !            58: 
        !            59:     /* Create up to 4 cpus.  */
        !            60:     memset(cpus, 0, sizeof(cpus));
        !            61:     for (i = 0; i < smp_cpus; ++i) {
        !            62:         cpus[i] = cpu_init(cpu_model ? cpu_model : "ev67");
        !            63:     }
        !            64: 
        !            65:     cpus[0]->trap_arg0 = ram_size;
        !            66:     cpus[0]->trap_arg1 = 0;
        !            67:     cpus[0]->trap_arg2 = smp_cpus;
        !            68: 
        !            69:     /* Init the chipset.  */
        !            70:     pci_bus = typhoon_init(ram_size, &rtc_irq, cpus, clipper_pci_map_irq);
        !            71: 
        !            72:     rtc_init(1980, rtc_irq);
        !            73:     pit_init(0x40, 0);
        !            74:     isa_create_simple("i8042");
        !            75: 
        !            76:     /* VGA setup.  Don't bother loading the bios.  */
        !            77:     alpha_pci_vga_setup(pci_bus);
        !            78: 
        !            79:     /* Serial code setup.  */
        !            80:     for (i = 0; i < MAX_SERIAL_PORTS; ++i) {
        !            81:         if (serial_hds[i]) {
        !            82:             serial_isa_init(i, serial_hds[i]);
        !            83:         }
        !            84:     }
        !            85: 
        !            86:     /* Network setup.  e1000 is good enough, failing Tulip support.  */
        !            87:     for (i = 0; i < nb_nics; i++) {
        !            88:         pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
        !            89:     }
        !            90: 
        !            91:     /* IDE disk setup.  */
        !            92:     {
        !            93:         DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
        !            94:         ide_drive_get(hd, MAX_IDE_BUS);
        !            95: 
        !            96:         pci_cmd646_ide_init(pci_bus, hd, 0);
        !            97:     }
        !            98: 
        !            99:     /* Load PALcode.  Given that this is not "real" cpu palcode,
        !           100:        but one explicitly written for the emulation, we might as
        !           101:        well load it directly from and ELF image.  */
        !           102:     palcode_filename = (bios_name ? bios_name : "palcode-clipper");
        !           103:     palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename);
        !           104:     if (palcode_filename == NULL) {
        !           105:         hw_error("no palcode provided\n");
        !           106:         exit(1);
        !           107:     }
        !           108:     size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
        !           109:                     NULL, &palcode_entry, &palcode_low, &palcode_high,
        !           110:                     0, EM_ALPHA, 0);
        !           111:     if (size < 0) {
        !           112:         hw_error("could not load palcode '%s'\n", palcode_filename);
        !           113:         exit(1);
        !           114:     }
        !           115: 
        !           116:     /* Start all cpus at the PALcode RESET entry point.  */
        !           117:     for (i = 0; i < smp_cpus; ++i) {
        !           118:         cpus[i]->pal_mode = 1;
        !           119:         cpus[i]->pc = palcode_entry;
        !           120:         cpus[i]->palbr = palcode_entry;
        !           121:     }
        !           122: 
        !           123:     /* Load a kernel.  */
        !           124:     if (kernel_filename) {
        !           125:         uint64_t param_offset;
        !           126: 
        !           127:         size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
        !           128:                         NULL, &kernel_entry, &kernel_low, &kernel_high,
        !           129:                         0, EM_ALPHA, 0);
        !           130:         if (size < 0) {
        !           131:             hw_error("could not load kernel '%s'\n", kernel_filename);
        !           132:             exit(1);
        !           133:         }
        !           134: 
        !           135:         cpus[0]->trap_arg1 = kernel_entry;
        !           136: 
        !           137:         param_offset = kernel_low - 0x6000;
        !           138: 
        !           139:         if (kernel_cmdline) {
        !           140:             pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
        !           141:         }
        !           142: 
        !           143:         if (initrd_filename) {
        !           144:             long initrd_base, initrd_size;
        !           145: 
        !           146:             initrd_size = get_image_size(initrd_filename);
        !           147:             if (initrd_size < 0) {
        !           148:                 hw_error("could not load initial ram disk '%s'\n",
        !           149:                          initrd_filename);
        !           150:                 exit(1);
        !           151:             }
        !           152: 
        !           153:             /* Put the initrd image as high in memory as possible.  */
        !           154:             initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
        !           155:             load_image_targphys(initrd_filename, initrd_base,
        !           156:                                 ram_size - initrd_base);
        !           157: 
        !           158:             stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL);
        !           159:             stq_phys(param_offset + 0x108, initrd_size);
        !           160:         }
        !           161:     }
        !           162: }
        !           163: 
        !           164: static QEMUMachine clipper_machine = {
        !           165:     .name = "clipper",
        !           166:     .desc = "Alpha DP264/CLIPPER",
        !           167:     .init = clipper_init,
        !           168:     .max_cpus = 4,
        !           169:     .is_default = 1,
        !           170: };
        !           171: 
        !           172: static void clipper_machine_init(void)
        !           173: {
        !           174:     qemu_register_machine(&clipper_machine);
        !           175: }
        !           176: 
        !           177: machine_init(clipper_machine_init);

unix.superglobalmegacorp.com

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