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

1.1     ! root        1: /*
        !             2:  * QEMU/mipssim emulation
        !             3:  *
        !             4:  * Emulates a very simple machine model similiar to the one use by the
        !             5:  * proprietary MIPS emulator.
        !             6:  * 
        !             7:  * Copyright (c) 2007 Thiemo Seufer
        !             8:  *
        !             9:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !            10:  * of this software and associated documentation files (the "Software"), to deal
        !            11:  * in the Software without restriction, including without limitation the rights
        !            12:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            13:  * copies of the Software, and to permit persons to whom the Software is
        !            14:  * furnished to do so, subject to the following conditions:
        !            15:  *
        !            16:  * The above copyright notice and this permission notice shall be included in
        !            17:  * all copies or substantial portions of the Software.
        !            18:  *
        !            19:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            20:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            21:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            22:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            23:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            24:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            25:  * THE SOFTWARE.
        !            26:  */
        !            27: #include "hw.h"
        !            28: #include "mips.h"
        !            29: #include "pc.h"
        !            30: #include "isa.h"
        !            31: #include "net.h"
        !            32: #include "sysemu.h"
        !            33: #include "boards.h"
        !            34: 
        !            35: #ifdef TARGET_WORDS_BIGENDIAN
        !            36: #define BIOS_FILENAME "mips_bios.bin"
        !            37: #else
        !            38: #define BIOS_FILENAME "mipsel_bios.bin"
        !            39: #endif
        !            40: 
        !            41: #ifdef TARGET_MIPS64
        !            42: #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
        !            43: #else
        !            44: #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
        !            45: #endif
        !            46: 
        !            47: #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
        !            48: 
        !            49: static struct _loaderparams {
        !            50:     int ram_size;
        !            51:     const char *kernel_filename;
        !            52:     const char *kernel_cmdline;
        !            53:     const char *initrd_filename;
        !            54: } loaderparams;
        !            55: 
        !            56: static void load_kernel (CPUState *env)
        !            57: {
        !            58:     int64_t entry, kernel_low, kernel_high;
        !            59:     long kernel_size;
        !            60:     long initrd_size;
        !            61:     ram_addr_t initrd_offset;
        !            62: 
        !            63:     kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
        !            64:                            &entry, &kernel_low, &kernel_high);
        !            65:     if (kernel_size >= 0) {
        !            66:         if ((entry & ~0x7fffffffULL) == 0x80000000)
        !            67:             entry = (int32_t)entry;
        !            68:         env->PC[env->current_tc] = entry;
        !            69:     } else {
        !            70:         fprintf(stderr, "qemu: could not load kernel '%s'\n",
        !            71:                 loaderparams.kernel_filename);
        !            72:         exit(1);
        !            73:     }
        !            74: 
        !            75:     /* load initrd */
        !            76:     initrd_size = 0;
        !            77:     initrd_offset = 0;
        !            78:     if (loaderparams.initrd_filename) {
        !            79:         initrd_size = get_image_size (loaderparams.initrd_filename);
        !            80:         if (initrd_size > 0) {
        !            81:             initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
        !            82:             if (initrd_offset + initrd_size > loaderparams.ram_size) {
        !            83:                 fprintf(stderr,
        !            84:                         "qemu: memory too small for initial ram disk '%s'\n",
        !            85:                         loaderparams.initrd_filename);
        !            86:                 exit(1);
        !            87:             }
        !            88:             initrd_size = load_image(loaderparams.initrd_filename,
        !            89:                                      phys_ram_base + initrd_offset);
        !            90:         }
        !            91:         if (initrd_size == (target_ulong) -1) {
        !            92:             fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
        !            93:                     loaderparams.initrd_filename);
        !            94:             exit(1);
        !            95:         }
        !            96:     }
        !            97: }
        !            98: 
        !            99: static void main_cpu_reset(void *opaque)
        !           100: {
        !           101:     CPUState *env = opaque;
        !           102:     cpu_reset(env);
        !           103: 
        !           104:     if (loaderparams.kernel_filename)
        !           105:         load_kernel (env);
        !           106: }
        !           107: 
        !           108: static void
        !           109: mips_mipssim_init (int ram_size, int vga_ram_size,
        !           110:                    const char *boot_device, DisplayState *ds,
        !           111:                    const char *kernel_filename, const char *kernel_cmdline,
        !           112:                    const char *initrd_filename, const char *cpu_model)
        !           113: {
        !           114:     char buf[1024];
        !           115:     unsigned long bios_offset;
        !           116:     CPUState *env;
        !           117:     int bios_size;
        !           118: 
        !           119:     /* Init CPUs. */
        !           120:     if (cpu_model == NULL) {
        !           121: #ifdef TARGET_MIPS64
        !           122:         cpu_model = "5Kf";
        !           123: #else
        !           124:         cpu_model = "24Kf";
        !           125: #endif
        !           126:     }
        !           127:     env = cpu_init(cpu_model);
        !           128:     if (!env) {
        !           129:         fprintf(stderr, "Unable to find CPU definition\n");
        !           130:         exit(1);
        !           131:     }
        !           132:     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
        !           133:     qemu_register_reset(main_cpu_reset, env);
        !           134: 
        !           135:     /* Allocate RAM. */
        !           136:     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
        !           137: 
        !           138:     /* Load a BIOS / boot exception handler image. */
        !           139:     bios_offset = ram_size + vga_ram_size;
        !           140:     if (bios_name == NULL)
        !           141:         bios_name = BIOS_FILENAME;
        !           142:     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
        !           143:     bios_size = load_image(buf, phys_ram_base + bios_offset);
        !           144:     if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
        !           145:         /* Bail out if we have neither a kernel image nor boot vector code. */
        !           146:         fprintf(stderr,
        !           147:                 "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
        !           148:                 buf);
        !           149:         exit(1);
        !           150:     } else {
        !           151:         /* Map the BIOS / boot exception handler. */
        !           152:         cpu_register_physical_memory(0x1fc00000LL,
        !           153:                                      bios_size, bios_offset | IO_MEM_ROM);
        !           154:         /* We have a boot vector start address. */
        !           155:         env->PC[env->current_tc] = (target_long)(int32_t)0xbfc00000;
        !           156:     }
        !           157: 
        !           158:     if (kernel_filename) {
        !           159:         loaderparams.ram_size = ram_size;
        !           160:         loaderparams.kernel_filename = kernel_filename;
        !           161:         loaderparams.kernel_cmdline = kernel_cmdline;
        !           162:         loaderparams.initrd_filename = initrd_filename;
        !           163:         load_kernel(env);
        !           164:     }
        !           165: 
        !           166:     /* Init CPU internal devices. */
        !           167:     cpu_mips_irq_init_cpu(env);
        !           168:     cpu_mips_clock_init(env);
        !           169:     cpu_mips_irqctrl_init();
        !           170: 
        !           171:     /* Register 64 KB of ISA IO space at 0x1fd00000. */
        !           172:     isa_mmio_init(0x1fd00000, 0x00010000);
        !           173: 
        !           174:     /* A single 16450 sits at offset 0x3f8. It is attached to
        !           175:        MIPS CPU INT2, which is interrupt 4. */
        !           176:     if (serial_hds[0])
        !           177:         serial_init(0x3f8, env->irq[4], serial_hds[0]);
        !           178: 
        !           179:     if (nd_table[0].vlan) {
        !           180:         if (nd_table[0].model == NULL
        !           181:             || strcmp(nd_table[0].model, "mipsnet") == 0) {
        !           182:             /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
        !           183:             mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
        !           184:         } else if (strcmp(nd_table[0].model, "?") == 0) {
        !           185:             fprintf(stderr, "qemu: Supported NICs: mipsnet\n");
        !           186:             exit (1);
        !           187:         } else {
        !           188:             fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
        !           189:             exit (1);
        !           190:         }
        !           191:     }
        !           192: }
        !           193: 
        !           194: QEMUMachine mips_mipssim_machine = {
        !           195:     "mipssim",
        !           196:     "MIPS MIPSsim platform",
        !           197:     mips_mipssim_init,
        !           198: };

unix.superglobalmegacorp.com

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