Annotation of qemu/hw/sun4u.c, revision 1.1.1.14

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

unix.superglobalmegacorp.com

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