]> git.proxmox.com Git - mirror_qemu.git/blame - hw/mips_mipssim.c
Set boot sequence from command line (Dan Kenigsberg).
[mirror_qemu.git] / hw / mips_mipssim.c
CommitLineData
f0fc6f8f
TS
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#include "vl.h"
8
9#ifdef TARGET_WORDS_BIGENDIAN
10#define BIOS_FILENAME "mips_bios.bin"
11#else
12#define BIOS_FILENAME "mipsel_bios.bin"
13#endif
14
15#ifdef TARGET_MIPS64
16#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
17#else
18#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
19#endif
20
21#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
22
23static void load_kernel (CPUState *env)
24{
25 int64_t entry, kernel_low, kernel_high;
26 long kernel_size;
27 long initrd_size;
28 ram_addr_t initrd_offset;
29
30 kernel_size = load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
31 &entry, &kernel_low, &kernel_high);
32 if (kernel_size >= 0) {
33 if ((entry & ~0x7fffffffULL) == 0x80000000)
34 entry = (int32_t)entry;
35 env->PC[env->current_tc] = entry;
36 } else {
37 fprintf(stderr, "qemu: could not load kernel '%s'\n",
38 env->kernel_filename);
39 exit(1);
40 }
41
42 /* load initrd */
43 initrd_size = 0;
44 initrd_offset = 0;
45 if (env->initrd_filename) {
46 initrd_size = get_image_size (env->initrd_filename);
47 if (initrd_size > 0) {
48 initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
49 if (initrd_offset + initrd_size > env->ram_size) {
50 fprintf(stderr,
51 "qemu: memory too small for initial ram disk '%s'\n",
52 env->initrd_filename);
53 exit(1);
54 }
55 initrd_size = load_image(env->initrd_filename,
56 phys_ram_base + initrd_offset);
57 }
58 if (initrd_size == (target_ulong) -1) {
59 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
60 env->initrd_filename);
61 exit(1);
62 }
63 }
64}
65
66static void main_cpu_reset(void *opaque)
67{
68 CPUState *env = opaque;
69 cpu_reset(env);
70 cpu_mips_register(env, NULL);
71
72 if (env->kernel_filename)
73 load_kernel (env);
74}
75
76static void
6ac0e82d 77mips_mipssim_init (int ram_size, int vga_ram_size, const char *boot_device,
f0fc6f8f
TS
78 DisplayState *ds, const char **fd_filename, int snapshot,
79 const char *kernel_filename, const char *kernel_cmdline,
80 const char *initrd_filename, const char *cpu_model)
81{
82 char buf[1024];
83 unsigned long bios_offset;
84 CPUState *env;
b5334159 85 int bios_size;
f0fc6f8f
TS
86 mips_def_t *def;
87
88 /* Init CPUs. */
89 if (cpu_model == NULL) {
90#ifdef TARGET_MIPS64
91 cpu_model = "5Kf";
92#else
93 cpu_model = "24Kf";
94#endif
95 }
96 if (mips_find_by_name(cpu_model, &def) != 0)
97 def = NULL;
98 env = cpu_init();
99 cpu_mips_register(env, def);
100 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
101 qemu_register_reset(main_cpu_reset, env);
102
103 /* Allocate RAM. */
104 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
105
f0fc6f8f 106 /* Load a BIOS / boot exception handler image. */
b5334159 107 bios_offset = ram_size + vga_ram_size;
f0fc6f8f
TS
108 if (bios_name == NULL)
109 bios_name = BIOS_FILENAME;
110 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
b5334159
TS
111 bios_size = load_image(buf, phys_ram_base + bios_offset);
112 if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
f0fc6f8f
TS
113 /* Bail out if we have neither a kernel image nor boot vector code. */
114 fprintf(stderr,
115 "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
116 buf);
117 exit(1);
118 } else {
b5334159 119 /* Map the BIOS / boot exception handler. */
f0fc6f8f 120 cpu_register_physical_memory(0x1fc00000LL,
b5334159
TS
121 bios_size, bios_offset | IO_MEM_ROM);
122 /* We have a boot vector start address. */
123 env->PC[env->current_tc] = (target_long)(int32_t)0xbfc00000;
f0fc6f8f
TS
124 }
125
126 if (kernel_filename) {
127 env->ram_size = ram_size;
128 env->kernel_filename = kernel_filename;
129 env->kernel_cmdline = kernel_cmdline;
130 env->initrd_filename = initrd_filename;
131 load_kernel(env);
132 }
133
134 /* Init CPU internal devices. */
135 cpu_mips_irq_init_cpu(env);
136 cpu_mips_clock_init(env);
137 cpu_mips_irqctrl_init();
138
139 /* Register 64 KB of ISA IO space at 0x1fd00000. */
140 isa_mmio_init(0x1fd00000, 0x00010000);
141
142 /* A single 16450 sits at offset 0x3f8. It is attached to
143 MIPS CPU INT2, which is interrupt 4. */
144 if (serial_hds[0])
145 serial_init(0x3f8, env->irq[4], serial_hds[0]);
146
147 if (nd_table[0].vlan) {
148 if (nd_table[0].model == NULL
149 || strcmp(nd_table[0].model, "mipsnet") == 0) {
150 /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
151 mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
152 } else if (strcmp(nd_table[0].model, "?") == 0) {
153 fprintf(stderr, "qemu: Supported NICs: mipsnet\n");
154 exit (1);
155 } else {
156 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
157 exit (1);
158 }
159 }
160}
161
162QEMUMachine mips_mipssim_machine = {
163 "mipssim",
164 "MIPS MIPSsim platform",
165 mips_mipssim_init,
166};