Bug Summary

File:hw/sparc64/sun4u.c
Location:line 883, column 5
Description:Function call argument is an uninitialized value

Annotated Source Code

1/*
2 * QEMU Sun4u/Sun4v System Emulator
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "hw/hw.h"
25#include "hw/pci/pci.h"
26#include "hw/pci-host/apb.h"
27#include "hw/i386/pc.h"
28#include "hw/char/serial.h"
29#include "hw/timer/m48t59.h"
30#include "hw/block/fdc.h"
31#include "net/net.h"
32#include "qemu/timer.h"
33#include "sysemu/sysemu.h"
34#include "hw/boards.h"
35#include "hw/nvram/openbios_firmware_abi.h"
36#include "hw/nvram/fw_cfg.h"
37#include "hw/sysbus.h"
38#include "hw/ide.h"
39#include "hw/loader.h"
40#include "elf.h"
41#include "sysemu/blockdev.h"
42#include "exec/address-spaces.h"
43
44//#define DEBUG_IRQ
45//#define DEBUG_EBUS
46//#define DEBUG_TIMER
47
48#ifdef DEBUG_IRQ
49#define CPUIRQ_DPRINTF(fmt, ...) \
50 do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
51#else
52#define CPUIRQ_DPRINTF(fmt, ...)
53#endif
54
55#ifdef DEBUG_EBUS
56#define EBUS_DPRINTF(fmt, ...) \
57 do { printf("EBUS: " fmt , ## __VA_ARGS__); } while (0)
58#else
59#define EBUS_DPRINTF(fmt, ...)
60#endif
61
62#ifdef DEBUG_TIMER
63#define TIMER_DPRINTF(fmt, ...) \
64 do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
65#else
66#define TIMER_DPRINTF(fmt, ...)
67#endif
68
69#define KERNEL_LOAD_ADDR0x00404000 0x00404000
70#define CMDLINE_ADDR0x003ff000 0x003ff000
71#define PROM_SIZE_MAX(4 * 1024 * 1024) (4 * 1024 * 1024)
72#define PROM_VADDR0x000ffd00000ULL 0x000ffd00000ULL
73#define APB_SPECIAL_BASE0x1fe00000000ULL 0x1fe00000000ULL
74#define APB_MEM_BASE0x1ff00000000ULL 0x1ff00000000ULL
75#define APB_PCI_IO_BASE(0x1fe00000000ULL + 0x02000000ULL) (APB_SPECIAL_BASE0x1fe00000000ULL + 0x02000000ULL)
76#define PROM_FILENAME"openbios-sparc64" "openbios-sparc64"
77#define NVRAM_SIZE0x2000 0x2000
78#define MAX_IDE_BUS2 2
79#define BIOS_CFG_IOPORT0x510 0x510
80#define FW_CFG_SPARC64_WIDTH(0x8000 + 0x00) (FW_CFG_ARCH_LOCAL0x8000 + 0x00)
81#define FW_CFG_SPARC64_HEIGHT(0x8000 + 0x01) (FW_CFG_ARCH_LOCAL0x8000 + 0x01)
82#define FW_CFG_SPARC64_DEPTH(0x8000 + 0x02) (FW_CFG_ARCH_LOCAL0x8000 + 0x02)
83
84#define IVEC_MAX0x40 0x40
85
86#define TICK_MAX0x7fffffffffffffffULL 0x7fffffffffffffffULL
87
88struct hwdef {
89 const char * const default_cpu_model;
90 uint16_t machine_id;
91 uint64_t prom_addr;
92 uint64_t console_serial_base;
93};
94
95typedef struct EbusState {
96 PCIDevice pci_dev;
97 MemoryRegion bar0;
98 MemoryRegion bar1;
99} EbusState;
100
101int DMA_get_channel_mode (int nchan)
102{
103 return 0;
104}
105int DMA_read_memory (int nchan, void *buf, int pos, int size)
106{
107 return 0;
108}
109int DMA_write_memory (int nchan, void *buf, int pos, int size)
110{
111 return 0;
112}
113void DMA_hold_DREQ (int nchan) {}
114void DMA_release_DREQ (int nchan) {}
115void DMA_schedule(int nchan) {}
116
117void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
118{
119}
120
121void DMA_register_channel (int nchan,
122 DMA_transfer_handler transfer_handler,
123 void *opaque)
124{
125}
126
127static int fw_cfg_boot_set(void *opaque, const char *boot_device)
128{
129 fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE0x0c, boot_device[0]);
130 return 0;
131}
132
133static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
134 const char *arch, ram_addr_t RAM_size,
135 const char *boot_devices,
136 uint32_t kernel_image, uint32_t kernel_size,
137 const char *cmdline,
138 uint32_t initrd_image, uint32_t initrd_size,
139 uint32_t NVRAM_image,
140 int width, int height, int depth,
141 const uint8_t *macaddr)
142{
143 unsigned int i;
144 uint32_t start, end;
145 uint8_t image[0x1ff0];
146 struct OpenBIOS_nvpart_v1 *part_header;
147
148 memset(image, '\0', sizeof(image));
149
150 start = 0;
151
152 // OpenBIOS nvram variables
153 // Variable partition
154 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
155 part_header->signature = OPENBIOS_PART_SYSTEM0x70;
156 pstrcpy(part_header->name, sizeof(part_header->name), "system");
157
158 end = start + sizeof(struct OpenBIOS_nvpart_v1);
159 for (i = 0; i < nb_prom_envs; i++)
160 end = OpenBIOS_set_var(image, end, prom_envs[i]);
161
162 // End marker
163 image[end++] = '\0';
164
165 end = start + ((end - start + 15) & ~15);
166 OpenBIOS_finish_partition(part_header, end - start);
167
168 // free partition
169 start = end;
170 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
171 part_header->signature = OPENBIOS_PART_FREE0x7f;
172 pstrcpy(part_header->name, sizeof(part_header->name), "free");
173
174 end = 0x1fd0;
175 OpenBIOS_finish_partition(part_header, end - start);
176
177 Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80);
178
179 for (i = 0; i < sizeof(image); i++)
180 m48t59_write(nvram, i, image[i]);
181
182 return 0;
183}
184
185static uint64_t sun4u_load_kernel(const char *kernel_filename,
186 const char *initrd_filename,
187 ram_addr_t RAM_size, uint64_t *initrd_size,
188 uint64_t *initrd_addr, uint64_t *kernel_addr,
189 uint64_t *kernel_entry)
190{
191 int linux_boot;
192 unsigned int i;
193 long kernel_size;
194 uint8_t *ptr;
195 uint64_t kernel_top;
196
197 linux_boot = (kernel_filename != NULL((void*)0));
24
Assuming 'kernel_filename' is equal to null
198
199 kernel_size = 0;
200 if (linux_boot) {
25
Taking false branch
201 int bswap_needed;
202
203#ifdef BSWAP_NEEDED
204 bswap_needed = 1;
205#else
206 bswap_needed = 0;
207#endif
208 kernel_size = load_elf(kernel_filename, NULL((void*)0), NULL((void*)0), kernel_entry,
209 kernel_addr, &kernel_top, 1, ELF_MACHINE43, 0);
210 if (kernel_size < 0) {
211 *kernel_addr = KERNEL_LOAD_ADDR0x00404000;
212 *kernel_entry = KERNEL_LOAD_ADDR0x00404000;
213 kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR0x00404000,
214 RAM_size - KERNEL_LOAD_ADDR0x00404000, bswap_needed,
215 TARGET_PAGE_SIZE(1 << 13));
216 }
217 if (kernel_size < 0) {
218 kernel_size = load_image_targphys(kernel_filename,
219 KERNEL_LOAD_ADDR0x00404000,
220 RAM_size - KERNEL_LOAD_ADDR0x00404000);
221 }
222 if (kernel_size < 0) {
223 fprintf(stderrstderr, "qemu: could not load kernel '%s'\n",
224 kernel_filename);
225 exit(1);
226 }
227 /* load initrd above kernel */
228 *initrd_size = 0;
229 if (initrd_filename) {
230 *initrd_addr = TARGET_PAGE_ALIGN(kernel_top)(((kernel_top) + (1 << 13) - 1) & ~((1 << 13)
- 1))
;
231
232 *initrd_size = load_image_targphys(initrd_filename,
233 *initrd_addr,
234 RAM_size - *initrd_addr);
235 if ((int)*initrd_size < 0) {
236 fprintf(stderrstderr, "qemu: could not load initial ram disk '%s'\n",
237 initrd_filename);
238 exit(1);
239 }
240 }
241 if (*initrd_size > 0) {
242 for (i = 0; i < 64 * TARGET_PAGE_SIZE(1 << 13); i += TARGET_PAGE_SIZE(1 << 13)) {
243 ptr = rom_ptr(*kernel_addr + i);
244 if (ldl_p(ptr + 8)ldl_be_p(ptr + 8) == 0x48647253) { /* HdrS */
245 stl_p(ptr + 24, *initrd_addr + *kernel_addr)stl_be_p(ptr + 24, *initrd_addr + *kernel_addr);
246 stl_p(ptr + 28, *initrd_size)stl_be_p(ptr + 28, *initrd_size);
247 break;
248 }
249 }
250 }
251 }
252 return kernel_size;
253}
254
255void cpu_check_irqs(CPUSPARCState *env)
256{
257 CPUState *cs;
258 uint32_t pil = env->pil_in |
259 (env->softint & ~(SOFTINT_TIMER1 | SOFTINT_STIMER(1 << 16)));
260
261 /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
262 if (env->ivec_status & 0x20) {
263 return;
264 }
265 cs = CPU(sparc_env_get_cpu(env))((CPUState *)object_dynamic_cast_assert(((Object *)((sparc_env_get_cpu
(env)))), ("cpu"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 265, __func__))
;
266 /* check if TM or SM in SOFTINT are set
267 setting these also causes interrupt 14 */
268 if (env->softint & (SOFTINT_TIMER1 | SOFTINT_STIMER(1 << 16))) {
269 pil |= 1 << 14;
270 }
271
272 /* The bit corresponding to psrpil is (1<< psrpil), the next bit
273 is (2 << psrpil). */
274 if (pil < (2 << env->psrpil)){
275 if (cs->interrupt_request & CPU_INTERRUPT_HARD0x0002) {
276 CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
277 env->interrupt_index);
278 env->interrupt_index = 0;
279 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD0x0002);
280 }
281 return;
282 }
283
284 if (cpu_interrupts_enabled(env)) {
285
286 unsigned int i;
287
288 for (i = 15; i > env->psrpil; i--) {
289 if (pil & (1 << i)) {
290 int old_interrupt = env->interrupt_index;
291 int new_interrupt = TT_EXTINT0x40 | i;
292
293 if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt__builtin_expect(!!(env->tl > 0 && cpu_tsptr(env
)->tt > new_interrupt && ((cpu_tsptr(env)->tt
& 0x1f0) == 0x40)), 0)
294 && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))__builtin_expect(!!(env->tl > 0 && cpu_tsptr(env
)->tt > new_interrupt && ((cpu_tsptr(env)->tt
& 0x1f0) == 0x40)), 0)
) {
295 CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
296 "current %x >= pending %x\n",
297 env->tl, cpu_tsptr(env)->tt, new_interrupt);
298 } else if (old_interrupt != new_interrupt) {
299 env->interrupt_index = new_interrupt;
300 CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
301 old_interrupt, new_interrupt);
302 cpu_interrupt(cs, CPU_INTERRUPT_HARD0x0002);
303 }
304 break;
305 }
306 }
307 } else if (cs->interrupt_request & CPU_INTERRUPT_HARD0x0002) {
308 CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
309 "current interrupt %x\n",
310 pil, env->pil_in, env->softint, env->interrupt_index);
311 env->interrupt_index = 0;
312 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD0x0002);
313 }
314}
315
316static void cpu_kick_irq(SPARCCPU *cpu)
317{
318 CPUState *cs = CPU(cpu)((CPUState *)object_dynamic_cast_assert(((Object *)((cpu))), (
"cpu"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 318, __func__))
;
319 CPUSPARCState *env = &cpu->env;
320
321 cs->halted = 0;
322 cpu_check_irqs(env);
323 qemu_cpu_kick(cs);
324}
325
326static void cpu_set_ivec_irq(void *opaque, int irq, int level)
327{
328 SPARCCPU *cpu = opaque;
329 CPUSPARCState *env = &cpu->env;
330 CPUState *cs;
331
332 if (level) {
333 if (!(env->ivec_status & 0x20)) {
334 CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
335 cs = CPU(cpu)((CPUState *)object_dynamic_cast_assert(((Object *)((cpu))), (
"cpu"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 335, __func__))
;
336 cs->halted = 0;
337 env->interrupt_index = TT_IVEC0x60;
338 env->ivec_status |= 0x20;
339 env->ivec_data[0] = (0x1f << 6) | irq;
340 env->ivec_data[1] = 0;
341 env->ivec_data[2] = 0;
342 cpu_interrupt(cs, CPU_INTERRUPT_HARD0x0002);
343 }
344 } else {
345 if (env->ivec_status & 0x20) {
346 CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
347 cs = CPU(cpu)((CPUState *)object_dynamic_cast_assert(((Object *)((cpu))), (
"cpu"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 347, __func__))
;
348 env->ivec_status &= ~0x20;
349 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD0x0002);
350 }
351 }
352}
353
354typedef struct ResetData {
355 SPARCCPU *cpu;
356 uint64_t prom_addr;
357} ResetData;
358
359void cpu_put_timer(QEMUFile *f, CPUTimer *s)
360{
361 qemu_put_be32s(f, &s->frequency);
362 qemu_put_be32s(f, &s->disabled);
363 qemu_put_be64s(f, &s->disabled_mask);
364 qemu_put_sbe64s(f, &s->clock_offset);
365
366 timer_put(f, s->qtimer);
367}
368
369void cpu_get_timer(QEMUFile *f, CPUTimer *s)
370{
371 qemu_get_be32s(f, &s->frequency);
372 qemu_get_be32s(f, &s->disabled);
373 qemu_get_be64s(f, &s->disabled_mask);
374 qemu_get_sbe64s(f, &s->clock_offset);
375
376 timer_get(f, s->qtimer);
377}
378
379static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
380 QEMUBHFunc *cb, uint32_t frequency,
381 uint64_t disabled_mask)
382{
383 CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
384
385 timer->name = name;
386 timer->frequency = frequency;
387 timer->disabled_mask = disabled_mask;
388
389 timer->disabled = 1;
390 timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
391
392 timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
393
394 return timer;
395}
396
397static void cpu_timer_reset(CPUTimer *timer)
398{
399 timer->disabled = 1;
400 timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
401
402 timer_del(timer->qtimer);
403}
404
405static void main_cpu_reset(void *opaque)
406{
407 ResetData *s = (ResetData *)opaque;
408 CPUSPARCState *env = &s->cpu->env;
409 static unsigned int nr_resets;
410
411 cpu_reset(CPU(s->cpu)((CPUState *)object_dynamic_cast_assert(((Object *)((s->cpu
))), ("cpu"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 411, __func__))
);
412
413 cpu_timer_reset(env->tick);
414 cpu_timer_reset(env->stick);
415 cpu_timer_reset(env->hstick);
416
417 env->gregs[1] = 0; // Memory start
418 env->gregs[2] = ram_size; // Memory size
419 env->gregs[3] = 0; // Machine description XXX
420 if (nr_resets++ == 0) {
421 /* Power on reset */
422 env->pc = s->prom_addr + 0x20ULL;
423 } else {
424 env->pc = s->prom_addr + 0x40ULL;
425 }
426 env->npc = env->pc + 4;
427}
428
429static void tick_irq(void *opaque)
430{
431 SPARCCPU *cpu = opaque;
432 CPUSPARCState *env = &cpu->env;
433
434 CPUTimer* timer = env->tick;
435
436 if (timer->disabled) {
437 CPUIRQ_DPRINTF("tick_irq: softint disabled\n");
438 return;
439 } else {
440 CPUIRQ_DPRINTF("tick: fire\n");
441 }
442
443 env->softint |= SOFTINT_TIMER1;
444 cpu_kick_irq(cpu);
445}
446
447static void stick_irq(void *opaque)
448{
449 SPARCCPU *cpu = opaque;
450 CPUSPARCState *env = &cpu->env;
451
452 CPUTimer* timer = env->stick;
453
454 if (timer->disabled) {
455 CPUIRQ_DPRINTF("stick_irq: softint disabled\n");
456 return;
457 } else {
458 CPUIRQ_DPRINTF("stick: fire\n");
459 }
460
461 env->softint |= SOFTINT_STIMER(1 << 16);
462 cpu_kick_irq(cpu);
463}
464
465static void hstick_irq(void *opaque)
466{
467 SPARCCPU *cpu = opaque;
468 CPUSPARCState *env = &cpu->env;
469
470 CPUTimer* timer = env->hstick;
471
472 if (timer->disabled) {
473 CPUIRQ_DPRINTF("hstick_irq: softint disabled\n");
474 return;
475 } else {
476 CPUIRQ_DPRINTF("hstick: fire\n");
477 }
478
479 env->softint |= SOFTINT_STIMER(1 << 16);
480 cpu_kick_irq(cpu);
481}
482
483static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency)
484{
485 return muldiv64(cpu_ticks, get_ticks_per_sec(), frequency);
486}
487
488static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
489{
490 return muldiv64(timer_ticks, frequency, get_ticks_per_sec());
491}
492
493void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
494{
495 uint64_t real_count = count & ~timer->disabled_mask;
496 uint64_t disabled_bit = count & timer->disabled_mask;
497
498 int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
499 cpu_to_timer_ticks(real_count, timer->frequency);
500
501 TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
502 timer->name, real_count,
503 timer->disabled?"disabled":"enabled", timer);
504
505 timer->disabled = disabled_bit ? 1 : 0;
506 timer->clock_offset = vm_clock_offset;
507}
508
509uint64_t cpu_tick_get_count(CPUTimer *timer)
510{
511 uint64_t real_count = timer_to_cpu_ticks(
512 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
513 timer->frequency);
514
515 TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
516 timer->name, real_count,
517 timer->disabled?"disabled":"enabled", timer);
518
519 if (timer->disabled)
520 real_count |= timer->disabled_mask;
521
522 return real_count;
523}
524
525void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
526{
527 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
528
529 uint64_t real_limit = limit & ~timer->disabled_mask;
530 timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
531
532 int64_t expires = cpu_to_timer_ticks(real_limit, timer->frequency) +
533 timer->clock_offset;
534
535 if (expires < now) {
536 expires = now + 1;
537 }
538
539 TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p "
540 "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n",
541 timer->name, real_limit,
542 timer->disabled?"disabled":"enabled",
543 timer, limit,
544 timer_to_cpu_ticks(now - timer->clock_offset,
545 timer->frequency),
546 timer_to_cpu_ticks(expires - now, timer->frequency));
547
548 if (!real_limit) {
549 TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
550 timer->name);
551 timer_del(timer->qtimer);
552 } else if (timer->disabled) {
553 timer_del(timer->qtimer);
554 } else {
555 timer_mod(timer->qtimer, expires);
556 }
557}
558
559static void isa_irq_handler(void *opaque, int n, int level)
560{
561 static const int isa_irq_to_ivec[16] = {
562 [1] = 0x29, /* keyboard */
563 [4] = 0x2b, /* serial */
564 [6] = 0x27, /* floppy */
565 [7] = 0x22, /* parallel */
566 [12] = 0x2a, /* mouse */
567 };
568 qemu_irq *irqs = opaque;
569 int ivec;
570
571 assert(n < 16)((n < 16) ? (void) (0) : __assert_fail ("n < 16", "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 571, __PRETTY_FUNCTION__))
;
572 ivec = isa_irq_to_ivec[n];
573 EBUS_DPRINTF("Set ISA IRQ %d level %d -> ivec 0x%x\n", n, level, ivec);
574 if (ivec) {
575 qemu_set_irq(irqs[ivec], level);
576 }
577}
578
579/* EBUS (Eight bit bus) bridge */
580static ISABus *
581pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs)
582{
583 qemu_irq *isa_irq;
584 PCIDevice *pci_dev;
585 ISABus *isa_bus;
586
587 pci_dev = pci_create_simple(bus, devfn, "ebus");
588 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"))((ISABus *)object_dynamic_cast_assert(((Object *)((qdev_get_child_bus
(((DeviceState *)object_dynamic_cast_assert(((Object *)((pci_dev
))), ("device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 588, __func__)), "isa.0")))), ("ISA"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 588, __func__))
;
589 isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16);
590 isa_bus_irqs(isa_bus, isa_irq);
591 return isa_bus;
592}
593
594static int
595pci_ebus_init1(PCIDevice *pci_dev)
596{
597 EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev)( __extension__ ( { char __attribute__((unused)) offset_must_be_zero
[ -__builtin_offsetof(EbusState, pci_dev)]; ({ const typeof((
(EbusState *) 0)->pci_dev) *__mptr = (pci_dev); (EbusState
*) ((char *) __mptr - __builtin_offsetof(EbusState, pci_dev)
);});}))
;
598
599 isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev));
600
601 pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
602 pci_dev->config[0x05] = 0x00;
603 pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
604 pci_dev->config[0x07] = 0x03; // status = medium devsel
605 pci_dev->config[0x09] = 0x00; // programming i/f
606 pci_dev->config[0x0D] = 0x0a; // latency_timer
607
608 memory_region_init_alias(&s->bar0, OBJECT(s)((Object *)(s)), "bar0", get_system_io(),
609 0, 0x1000000);
610 pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY0x00, &s->bar0);
611 memory_region_init_alias(&s->bar1, OBJECT(s)((Object *)(s)), "bar1", get_system_io(),
612 0, 0x800000);
613 pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY0x00, &s->bar1);
614 return 0;
615}
616
617static void ebus_class_init(ObjectClass *klass, void *data)
618{
619 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass)((PCIDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("pci-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 619, __func__))
;
620
621 k->init = pci_ebus_init1;
622 k->vendor_id = PCI_VENDOR_ID_SUN0x108e;
623 k->device_id = PCI_DEVICE_ID_SUN_EBUS0x1000;
624 k->revision = 0x01;
625 k->class_id = PCI_CLASS_BRIDGE_OTHER0x0680;
626}
627
628static const TypeInfo ebus_info = {
629 .name = "ebus",
630 .parent = TYPE_PCI_DEVICE"pci-device",
631 .instance_size = sizeof(EbusState),
632 .class_init = ebus_class_init,
633};
634
635#define TYPE_OPENPROM"openprom" "openprom"
636#define OPENPROM(obj)((PROMState *)object_dynamic_cast_assert(((Object *)((obj))),
("openprom"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 636, __func__))
OBJECT_CHECK(PROMState, (obj), TYPE_OPENPROM)((PROMState *)object_dynamic_cast_assert(((Object *)((obj))),
("openprom"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 636, __func__))
637
638typedef struct PROMState {
639 SysBusDevice parent_obj;
640
641 MemoryRegion prom;
642} PROMState;
643
644static uint64_t translate_prom_address(void *opaque, uint64_t addr)
645{
646 hwaddr *base_addr = (hwaddr *)opaque;
647 return addr + *base_addr - PROM_VADDR0x000ffd00000ULL;
648}
649
650/* Boot PROM (OpenBIOS) */
651static void prom_init(hwaddr addr, const char *bios_name)
652{
653 DeviceState *dev;
654 SysBusDevice *s;
655 char *filename;
656 int ret;
657
658 dev = qdev_create(NULL((void*)0), TYPE_OPENPROM"openprom");
659 qdev_init_nofail(dev);
660 s = SYS_BUS_DEVICE(dev)((SysBusDevice *)object_dynamic_cast_assert(((Object *)((dev)
)), ("sys-bus-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 660, __func__))
;
661
662 sysbus_mmio_map(s, 0, addr);
663
664 /* load boot prom */
665 if (bios_name == NULL((void*)0)) {
666 bios_name = PROM_FILENAME"openbios-sparc64";
667 }
668 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS0, bios_name);
669 if (filename) {
670 ret = load_elf(filename, translate_prom_address, &addr,
671 NULL((void*)0), NULL((void*)0), NULL((void*)0), 1, ELF_MACHINE43, 0);
672 if (ret < 0 || ret > PROM_SIZE_MAX(4 * 1024 * 1024)) {
673 ret = load_image_targphys(filename, addr, PROM_SIZE_MAX(4 * 1024 * 1024));
674 }
675 g_free(filename);
676 } else {
677 ret = -1;
678 }
679 if (ret < 0 || ret > PROM_SIZE_MAX(4 * 1024 * 1024)) {
680 fprintf(stderrstderr, "qemu: could not load prom '%s'\n", bios_name);
681 exit(1);
682 }
683}
684
685static int prom_init1(SysBusDevice *dev)
686{
687 PROMState *s = OPENPROM(dev)((PROMState *)object_dynamic_cast_assert(((Object *)((dev))),
("openprom"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 687, __func__))
;
688
689 memory_region_init_ram(&s->prom, OBJECT(s)((Object *)(s)), "sun4u.prom", PROM_SIZE_MAX(4 * 1024 * 1024));
690 vmstate_register_ram_global(&s->prom);
691 memory_region_set_readonly(&s->prom, true1);
692 sysbus_init_mmio(dev, &s->prom);
693 return 0;
694}
695
696static Property prom_properties[] = {
697 {/* end of property list */},
698};
699
700static void prom_class_init(ObjectClass *klass, void *data)
701{
702 DeviceClass *dc = DEVICE_CLASS(klass)((DeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 702, __func__))
;
703 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass)((SysBusDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("sys-bus-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 703, __func__))
;
704
705 k->init = prom_init1;
706 dc->props = prom_properties;
707}
708
709static const TypeInfo prom_info = {
710 .name = TYPE_OPENPROM"openprom",
711 .parent = TYPE_SYS_BUS_DEVICE"sys-bus-device",
712 .instance_size = sizeof(PROMState),
713 .class_init = prom_class_init,
714};
715
716
717#define TYPE_SUN4U_MEMORY"memory" "memory"
718#define SUN4U_RAM(obj)((RamDevice *)object_dynamic_cast_assert(((Object *)((obj))),
("memory"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 718, __func__))
OBJECT_CHECK(RamDevice, (obj), TYPE_SUN4U_MEMORY)((RamDevice *)object_dynamic_cast_assert(((Object *)((obj))),
("memory"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 718, __func__))
719
720typedef struct RamDevice {
721 SysBusDevice parent_obj;
722
723 MemoryRegion ram;
724 uint64_t size;
725} RamDevice;
726
727/* System RAM */
728static int ram_init1(SysBusDevice *dev)
729{
730 RamDevice *d = SUN4U_RAM(dev)((RamDevice *)object_dynamic_cast_assert(((Object *)((dev))),
("memory"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 730, __func__))
;
731
732 memory_region_init_ram(&d->ram, OBJECT(d)((Object *)(d)), "sun4u.ram", d->size);
733 vmstate_register_ram_global(&d->ram);
734 sysbus_init_mmio(dev, &d->ram);
735 return 0;
736}
737
738static void ram_init(hwaddr addr, ram_addr_t RAM_size)
739{
740 DeviceState *dev;
741 SysBusDevice *s;
742 RamDevice *d;
743
744 /* allocate RAM */
745 dev = qdev_create(NULL((void*)0), TYPE_SUN4U_MEMORY"memory");
746 s = SYS_BUS_DEVICE(dev)((SysBusDevice *)object_dynamic_cast_assert(((Object *)((dev)
)), ("sys-bus-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 746, __func__))
;
747
748 d = SUN4U_RAM(dev)((RamDevice *)object_dynamic_cast_assert(((Object *)((dev))),
("memory"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 748, __func__))
;
749 d->size = RAM_size;
750 qdev_init_nofail(dev);
751
752 sysbus_mmio_map(s, 0, addr);
753}
754
755static Property ram_properties[] = {
756 DEFINE_PROP_UINT64("size", RamDevice, size, 0){ .name = ("size"), .info = &(qdev_prop_uint64), .offset =
__builtin_offsetof(RamDevice, size) + ((uint64_t*)0 - (typeof
(((RamDevice *)0)->size)*)0), .qtype = QTYPE_QINT, .defval
= (uint64_t)0, }
,
757 DEFINE_PROP_END_OF_LIST(){},
758};
759
760static void ram_class_init(ObjectClass *klass, void *data)
761{
762 DeviceClass *dc = DEVICE_CLASS(klass)((DeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 762, __func__))
;
763 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass)((SysBusDeviceClass *)object_class_dynamic_cast_assert(((ObjectClass
*)((klass))), ("sys-bus-device"), "/home/stefan/src/qemu/qemu.org/qemu/hw/sparc64/sun4u.c"
, 763, __func__))
;
764
765 k->init = ram_init1;
766 dc->props = ram_properties;
767}
768
769static const TypeInfo ram_info = {
770 .name = TYPE_SUN4U_MEMORY"memory",
771 .parent = TYPE_SYS_BUS_DEVICE"sys-bus-device",
772 .instance_size = sizeof(RamDevice),
773 .class_init = ram_class_init,
774};
775
776static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
777{
778 SPARCCPU *cpu;
779 CPUSPARCState *env;
780 ResetData *reset_info;
781
782 uint32_t tick_frequency = 100*1000000;
783 uint32_t stick_frequency = 100*1000000;
784 uint32_t hstick_frequency = 100*1000000;
785
786 if (cpu_model == NULL((void*)0)) {
787 cpu_model = hwdef->default_cpu_model;
788 }
789 cpu = cpu_sparc_init(cpu_model);
790 if (cpu == NULL((void*)0)) {
791 fprintf(stderrstderr, "Unable to find Sparc CPU definition\n");
792 exit(1);
793 }
794 env = &cpu->env;
795
796 env->tick = cpu_timer_create("tick", cpu, tick_irq,
797 tick_frequency, TICK_NPT_MASK0x8000000000000000ULL);
798
799 env->stick = cpu_timer_create("stick", cpu, stick_irq,
800 stick_frequency, TICK_INT_DIS0x8000000000000000ULL);
801
802 env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
803 hstick_frequency, TICK_INT_DIS0x8000000000000000ULL);
804
805 reset_info = g_malloc0(sizeof(ResetData));
806 reset_info->cpu = cpu;
807 reset_info->prom_addr = hwdef->prom_addr;
808 qemu_register_reset(main_cpu_reset, reset_info);
809
810 return cpu;
811}
812
813static void sun4uv_init(MemoryRegion *address_space_mem,
814 QEMUMachineInitArgs *args,
815 const struct hwdef *hwdef)
816{
817 SPARCCPU *cpu;
818 M48t59State *nvram;
819 unsigned int i;
820 uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
2
'kernel_addr' declared without an initial value
821 PCIBus *pci_bus, *pci_bus2, *pci_bus3;
822 ISABus *isa_bus;
823 qemu_irq *ivec_irqs, *pbm_irqs;
824 DriveInfo *hd[MAX_IDE_BUS2 * MAX_IDE_DEVS2];
825 DriveInfo *fd[MAX_FD2];
826 FWCfgState *fw_cfg;
827
828 /* init CPUs */
829 cpu = cpu_devinit(args->cpu_model, hwdef);
830
831 /* set up devices */
832 ram_init(0, args->ram_size);
833
834 prom_init(hwdef->prom_addr, bios_name);
835
836 ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX0x40);
837 pci_bus = pci_apb_init(APB_SPECIAL_BASE0x1fe00000000ULL, APB_MEM_BASE0x1ff00000000ULL, ivec_irqs, &pci_bus2,
838 &pci_bus3, &pbm_irqs);
839 pci_vga_init(pci_bus);
840
841 // XXX Should be pci_bus3
842 isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs);
843
844 i = 0;
845 if (hwdef->console_serial_base) {
3
Taking true branch
846 serial_mm_init(address_space_mem, hwdef->console_serial_base, 0,
847 NULL((void*)0), 115200, serial_hds[i], DEVICE_BIG_ENDIAN);
848 i++;
849 }
850 for(; i < MAX_SERIAL_PORTS4; i++) {
4
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
8
Loop condition is true. Entering loop body
10
Loop condition is false. Execution continues on line 856
851 if (serial_hds[i]) {
5
Taking false branch
7
Taking false branch
9
Taking false branch
852 serial_isa_init(isa_bus, i, serial_hds[i]);
853 }
854 }
855
856 for(i = 0; i < MAX_PARALLEL_PORTS3; i++) {
11
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
15
Loop condition is true. Entering loop body
17
Loop condition is false. Execution continues on line 862
857 if (parallel_hds[i]) {
12
Taking false branch
14
Taking false branch
16
Taking false branch
858 parallel_init(isa_bus, i, parallel_hds[i]);
859 }
860 }
861
862 for(i = 0; i < nb_nics; i++)
18
Assuming 'i' is >= 'nb_nics'
19
Loop condition is false. Execution continues on line 865
863 pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL((void*)0));
864
865 ide_drive_get(hd, MAX_IDE_BUS2);
866
867 pci_cmd646_ide_init(pci_bus, hd, 1);
868
869 isa_create_simple(isa_bus, "i8042");
870 for(i = 0; i < MAX_FD2; i++) {
20
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
22
Loop condition is false. Execution continues on line 873
871 fd[i] = drive_get(IF_FLOPPY, 0, i);
872 }
873 fdctrl_init_isa(isa_bus, fd);
874 nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE0x2000, 59);
875
876 initrd_size = 0;
877 initrd_addr = 0;
878 kernel_size = sun4u_load_kernel(args->kernel_filename,
23
Calling 'sun4u_load_kernel'
26
Returning from 'sun4u_load_kernel'
879 args->initrd_filename,
880 ram_size, &initrd_size, &initrd_addr,
881 &kernel_addr, &kernel_entry);
882
883 sun4u_NVRAM_set_params(nvram, NVRAM_SIZE0x2000, "Sun4u", args->ram_size,
27
Function call argument is an uninitialized value
884 args->boot_order,
885 kernel_addr, kernel_size,
886 args->kernel_cmdline,
887 initrd_addr, initrd_size,
888 /* XXX: need an option to load a NVRAM image */
889 0,
890 graphic_width, graphic_height, graphic_depth,
891 (uint8_t *)&nd_table[0].macaddr);
892
893 fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT0x510, BIOS_CFG_IOPORT0x510 + 1, 0, 0);
894 fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS0x0f, (uint16_t)max_cpus);
895 fw_cfg_add_i32(fw_cfg, FW_CFG_ID0x01, 1);
896 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE0x03, (uint64_t)ram_size);
897 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID0x06, hwdef->machine_id);
898 fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR0x07, kernel_entry);
899 fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE0x08, kernel_size);
900 if (args->kernel_cmdline) {
901 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE0x14,
902 strlen(args->kernel_cmdline) + 1);
903 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA0x15, args->kernel_cmdline);
904 } else {
905 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE0x14, 0);
906 }
907 fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR0x0a, initrd_addr);
908 fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE0x0b, initrd_size);
909 fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE0x0c, args->boot_order[0]);
910
911 fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH(0x8000 + 0x00), graphic_width);
912 fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT(0x8000 + 0x01), graphic_height);
913 fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH(0x8000 + 0x02), graphic_depth);
914
915 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
916}
917
918enum {
919 sun4u_id = 0,
920 sun4v_id = 64,
921 niagara_id,
922};
923
924static const struct hwdef hwdefs[] = {
925 /* Sun4u generic PC-like machine */
926 {
927 .default_cpu_model = "TI UltraSparc IIi",
928 .machine_id = sun4u_id,
929 .prom_addr = 0x1fff0000000ULL,
930 .console_serial_base = 0,
931 },
932 /* Sun4v generic PC-like machine */
933 {
934 .default_cpu_model = "Sun UltraSparc T1",
935 .machine_id = sun4v_id,
936 .prom_addr = 0x1fff0000000ULL,
937 .console_serial_base = 0,
938 },
939 /* Sun4v generic Niagara machine */
940 {
941 .default_cpu_model = "Sun UltraSparc T1",
942 .machine_id = niagara_id,
943 .prom_addr = 0xfff0000000ULL,
944 .console_serial_base = 0xfff0c2c000ULL,
945 },
946};
947
948/* Sun4u hardware initialisation */
949static void sun4u_init(QEMUMachineInitArgs *args)
950{
951 sun4uv_init(get_system_memory(), args, &hwdefs[0]);
952}
953
954/* Sun4v hardware initialisation */
955static void sun4v_init(QEMUMachineInitArgs *args)
956{
957 sun4uv_init(get_system_memory(), args, &hwdefs[1]);
958}
959
960/* Niagara hardware initialisation */
961static void niagara_init(QEMUMachineInitArgs *args)
962{
963 sun4uv_init(get_system_memory(), args, &hwdefs[2]);
1
Calling 'sun4uv_init'
964}
965
966static QEMUMachine sun4u_machine = {
967 .name = "sun4u",
968 .desc = "Sun4u platform",
969 .init = sun4u_init,
970 .max_cpus = 1, // XXX for now
971 .is_default = 1,
972 .default_boot_order = "c",
973};
974
975static QEMUMachine sun4v_machine = {
976 .name = "sun4v",
977 .desc = "Sun4v platform",
978 .init = sun4v_init,
979 .max_cpus = 1, // XXX for now
980 .default_boot_order = "c",
981};
982
983static QEMUMachine niagara_machine = {
984 .name = "Niagara",
985 .desc = "Sun4v platform, Niagara",
986 .init = niagara_init,
987 .max_cpus = 1, // XXX for now
988 .default_boot_order = "c",
989};
990
991static void sun4u_register_types(void)
992{
993 type_register_static(&ebus_info);
994 type_register_static(&prom_info);
995 type_register_static(&ram_info);
996}
997
998static void sun4u_machine_init(void)
999{
1000 qemu_register_machine(&sun4u_machine);
1001 qemu_register_machine(&sun4v_machine);
1002 qemu_register_machine(&niagara_machine);
1003}
1004
1005type_init(sun4u_register_types)static void __attribute__((constructor)) do_qemu_init_sun4u_register_types
(void) { register_module_init(sun4u_register_types, MODULE_INIT_QOM
); }
1006machine_init(sun4u_machine_init)static void __attribute__((constructor)) do_qemu_init_sun4u_machine_init
(void) { register_module_init(sun4u_machine_init, MODULE_INIT_MACHINE
); }
;