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

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