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

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