Annotation of qemu/hw/integratorcp.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * ARM Integrator CP System emulation.
                      3:  *
                      4:  * Copyright (c) 2005 CodeSourcery, LLC.
                      5:  * Written by Paul Brook
                      6:  *
                      7:  * This code is licenced under the GPL
                      8:  */
                      9: 
                     10: #include <vl.h>
                     11: 
                     12: #define KERNEL_ARGS_ADDR 0x100
                     13: #define KERNEL_LOAD_ADDR 0x00010000
                     14: #define INITRD_LOAD_ADDR 0x00800000
                     15: 
                     16: /* Stub functions for hardware that doesn't exist.  */
                     17: void pic_set_irq(int irq, int level)
                     18: {
                     19:     cpu_abort (cpu_single_env, "pic_set_irq");
                     20: }
                     21: 
                     22: void pic_info(void)
                     23: {
                     24: }
                     25: 
                     26: void irq_info(void)
                     27: {
                     28: }
                     29: 
                     30: void vga_update_display(void)
                     31: {
                     32: }
                     33: 
                     34: void vga_screen_dump(const char *filename)
                     35: {
                     36: }
                     37: 
                     38: void vga_invalidate_display(void)
                     39: {
                     40: }
                     41: 
                     42: void DMA_run (void)
                     43: {
                     44: }
                     45: 
                     46: typedef struct {
                     47:     uint32_t flash_offset;
                     48:     uint32_t cm_osc;
                     49:     uint32_t cm_ctrl;
                     50:     uint32_t cm_lock;
                     51:     uint32_t cm_auxosc;
                     52:     uint32_t cm_sdram;
                     53:     uint32_t cm_init;
                     54:     uint32_t cm_flags;
                     55:     uint32_t cm_nvflags;
                     56:     uint32_t int_level;
                     57:     uint32_t irq_enabled;
                     58:     uint32_t fiq_enabled;
                     59: } integratorcm_state;
                     60: 
                     61: static uint8_t integrator_spd[128] = {
                     62:    128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
                     63:    0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
                     64: };
                     65: 
                     66: static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
                     67: {
                     68:     integratorcm_state *s = (integratorcm_state *)opaque;
                     69:     offset -= 0x10000000;
                     70:     if (offset >= 0x100 && offset < 0x200) {
                     71:         /* CM_SPD */
                     72:         if (offset >= 0x180)
                     73:             return 0;
                     74:         return integrator_spd[offset >> 2];
                     75:     }
                     76:     switch (offset >> 2) {
                     77:     case 0: /* CM_ID */
                     78:         return 0x411a3001;
                     79:     case 1: /* CM_PROC */
                     80:         return 0;
                     81:     case 2: /* CM_OSC */
                     82:         return s->cm_osc;
                     83:     case 3: /* CM_CTRL */
                     84:         return s->cm_ctrl;
                     85:     case 4: /* CM_STAT */
                     86:         return 0x00100000;
                     87:     case 5: /* CM_LOCK */
                     88:         if (s->cm_lock == 0xa05f) {
                     89:             return 0x1a05f;
                     90:         } else {
                     91:             return s->cm_lock;
                     92:         }
                     93:     case 6: /* CM_LMBUSCNT */
                     94:         /* ??? High frequency timer.  */
                     95:         cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT");
                     96:     case 7: /* CM_AUXOSC */
                     97:         return s->cm_auxosc;
                     98:     case 8: /* CM_SDRAM */
                     99:         return s->cm_sdram;
                    100:     case 9: /* CM_INIT */
                    101:         return s->cm_init;
                    102:     case 10: /* CM_REFCT */
                    103:         /* ??? High frequency timer.  */
                    104:         cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT");
                    105:     case 12: /* CM_FLAGS */
                    106:         return s->cm_flags;
                    107:     case 14: /* CM_NVFLAGS */
                    108:         return s->cm_nvflags;
                    109:     case 16: /* CM_IRQ_STAT */
                    110:         return s->int_level & s->irq_enabled;
                    111:     case 17: /* CM_IRQ_RSTAT */
                    112:         return s->int_level;
                    113:     case 18: /* CM_IRQ_ENSET */
                    114:         return s->irq_enabled;
                    115:     case 20: /* CM_SOFT_INTSET */
                    116:         return s->int_level & 1;
                    117:     case 24: /* CM_FIQ_STAT */
                    118:         return s->int_level & s->fiq_enabled;
                    119:     case 25: /* CM_FIQ_RSTAT */
                    120:         return s->int_level;
                    121:     case 26: /* CM_FIQ_ENSET */
                    122:         return s->fiq_enabled;
                    123:     case 32: /* CM_VOLTAGE_CTL0 */
                    124:     case 33: /* CM_VOLTAGE_CTL1 */
                    125:     case 34: /* CM_VOLTAGE_CTL2 */
                    126:     case 35: /* CM_VOLTAGE_CTL3 */
                    127:         /* ??? Voltage control unimplemented.  */
                    128:         return 0;
                    129:     default:
                    130:         cpu_abort (cpu_single_env,
                    131:             "integratorcm_read: Unimplemented offset 0x%x\n", offset);
                    132:         return 0;
                    133:     }
                    134: }
                    135: 
                    136: static void integratorcm_do_remap(integratorcm_state *s, int flash)
                    137: {
                    138:     if (flash) {
                    139:         cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
                    140:     } else {
                    141:         cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
                    142:     }
                    143:     //??? tlb_flush (cpu_single_env, 1);
                    144: }
                    145: 
                    146: static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
                    147: {
                    148:     if (value & 8) {
                    149:         cpu_abort(cpu_single_env, "Board reset\n");
                    150:     }
                    151:     if ((s->cm_init ^ value) & 4) {
                    152:         integratorcm_do_remap(s, (value & 4) == 0);
                    153:     }
                    154:     if ((s->cm_init ^ value) & 1) {
                    155:         printf("Green LED %s\n", (value & 1) ? "on" : "off");
                    156:     }
                    157:     s->cm_init = (s->cm_init & ~ 5) | (value ^ 5);
                    158: }
                    159: 
                    160: static void integratorcm_update(integratorcm_state *s)
                    161: {
                    162:     /* ??? The CPU irq/fiq is raised when either the core module or base PIC
                    163:        are active.  */
                    164:     if (s->int_level & (s->irq_enabled | s->fiq_enabled))
                    165:         cpu_abort(cpu_single_env, "Core module interrupt\n");
                    166: }
                    167: 
                    168: static void integratorcm_write(void *opaque, target_phys_addr_t offset,
                    169:                                uint32_t value)
                    170: {
                    171:     integratorcm_state *s = (integratorcm_state *)opaque;
                    172:     offset -= 0x10000000;
                    173:     switch (offset >> 2) {
                    174:     case 2: /* CM_OSC */
                    175:         if (s->cm_lock == 0xa05f)
                    176:             s->cm_osc = value;
                    177:         break;
                    178:     case 3: /* CM_CTRL */
                    179:         integratorcm_set_ctrl(s, value);
                    180:         break;
                    181:     case 5: /* CM_LOCK */
                    182:         s->cm_lock = value & 0xffff;
                    183:         break;
                    184:     case 7: /* CM_AUXOSC */
                    185:         if (s->cm_lock == 0xa05f)
                    186:             s->cm_auxosc = value;
                    187:         break;
                    188:     case 8: /* CM_SDRAM */
                    189:         s->cm_sdram = value;
                    190:         break;
                    191:     case 9: /* CM_INIT */
                    192:         /* ??? This can change the memory bus frequency.  */
                    193:         s->cm_init = value;
                    194:         break;
                    195:     case 12: /* CM_FLAGSS */
                    196:         s->cm_flags |= value;
                    197:         break;
                    198:     case 13: /* CM_FLAGSC */
                    199:         s->cm_flags &= ~value;
                    200:         break;
                    201:     case 14: /* CM_NVFLAGSS */
                    202:         s->cm_nvflags |= value;
                    203:         break;
                    204:     case 15: /* CM_NVFLAGSS */
                    205:         s->cm_nvflags &= ~value;
                    206:         break;
                    207:     case 18: /* CM_IRQ_ENSET */
                    208:         s->irq_enabled |= value;
                    209:         integratorcm_update(s);
                    210:         break;
                    211:     case 19: /* CM_IRQ_ENCLR */
                    212:         s->irq_enabled &= ~value;
                    213:         integratorcm_update(s);
                    214:         break;
                    215:     case 20: /* CM_SOFT_INTSET */
                    216:         s->int_level |= (value & 1);
                    217:         integratorcm_update(s);
                    218:         break;
                    219:     case 21: /* CM_SOFT_INTCLR */
                    220:         s->int_level &= ~(value & 1);
                    221:         integratorcm_update(s);
                    222:         break;
                    223:     case 26: /* CM_FIQ_ENSET */
                    224:         s->fiq_enabled |= value;
                    225:         integratorcm_update(s);
                    226:         break;
                    227:     case 27: /* CM_FIQ_ENCLR */
                    228:         s->fiq_enabled &= ~value;
                    229:         integratorcm_update(s);
                    230:         break;
                    231:     case 32: /* CM_VOLTAGE_CTL0 */
                    232:     case 33: /* CM_VOLTAGE_CTL1 */
                    233:     case 34: /* CM_VOLTAGE_CTL2 */
                    234:     case 35: /* CM_VOLTAGE_CTL3 */
                    235:         /* ??? Voltage control unimplemented.  */
                    236:         break;
                    237:     default:
                    238:         cpu_abort (cpu_single_env,
                    239:             "integratorcm_write: Unimplemented offset 0x%x\n", offset);
                    240:         break;
                    241:     }
                    242: }
                    243: 
                    244: /* Integrator/CM control registers.  */
                    245: 
                    246: static CPUReadMemoryFunc *integratorcm_readfn[] = {
                    247:    integratorcm_read,
                    248:    integratorcm_read,
                    249:    integratorcm_read
                    250: };
                    251: 
                    252: static CPUWriteMemoryFunc *integratorcm_writefn[] = {
                    253:    integratorcm_write,
                    254:    integratorcm_write,
                    255:    integratorcm_write
                    256: };
                    257: 
                    258: static void integratorcm_init(int memsz, uint32_t flash_offset)
                    259: {
                    260:     int iomemtype;
                    261:     integratorcm_state *s;
                    262: 
                    263:     s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
                    264:     s->cm_osc = 0x01000048;
                    265:     /* ??? What should the high bits of this value be?  */
                    266:     s->cm_auxosc = 0x0007feff;
                    267:     s->cm_sdram = 0x00011122;
                    268:     if (memsz >= 256) {
                    269:         integrator_spd[31] = 64;
                    270:         s->cm_sdram |= 0x10;
                    271:     } else if (memsz >= 128) {
                    272:         integrator_spd[31] = 32;
                    273:         s->cm_sdram |= 0x0c;
                    274:     } else if (memsz >= 64) {
                    275:         integrator_spd[31] = 16;
                    276:         s->cm_sdram |= 0x08;
                    277:     } else if (memsz >= 32) {
                    278:         integrator_spd[31] = 4;
                    279:         s->cm_sdram |= 0x04;
                    280:     } else {
                    281:         integrator_spd[31] = 2;
                    282:     }
                    283:     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
                    284:     s->cm_init = 0x00000112;
                    285:     s->flash_offset = flash_offset;
                    286: 
                    287:     iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
                    288:                                        integratorcm_writefn, s);
                    289:     cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype);
                    290:     integratorcm_do_remap(s, 1);
                    291:     /* ??? Save/restore.  */
                    292: }
                    293: 
                    294: /* Integrator/CP hardware emulation.  */
                    295: /* Primary interrupt controller.  */
                    296: 
                    297: typedef struct icp_pic_state
                    298: {
                    299:   uint32_t base;
                    300:   uint32_t level;
                    301:   uint32_t irq_enabled;
                    302:   uint32_t fiq_enabled;
                    303:   void *parent;
                    304:   /* -1 if parent is a cpu, otherwise IRQ number on parent PIC.  */
                    305:   int parent_irq;
                    306: } icp_pic_state;
                    307: 
                    308: static void icp_pic_update(icp_pic_state *s)
                    309: {
                    310:     CPUState *env;
                    311:     if (s->parent_irq != -1) {
                    312:         uint32_t flags;
                    313: 
                    314:         flags = (s->level & s->irq_enabled);
                    315:         pic_set_irq_new(s->parent, s->parent_irq,
                    316:                         flags != 0);
                    317:         return;
                    318:     }
                    319:     /* Raise CPU interrupt.  */
                    320:     env = (CPUState *)s->parent;
                    321:     if (s->level & s->fiq_enabled) {
                    322:         cpu_interrupt (env, CPU_INTERRUPT_FIQ);
                    323:     } else {
                    324:         cpu_reset_interrupt (env, CPU_INTERRUPT_FIQ);
                    325:     }
                    326:     if (s->level & s->irq_enabled) {
                    327:       cpu_interrupt (env, CPU_INTERRUPT_HARD);
                    328:     } else {
                    329:       cpu_reset_interrupt (env, CPU_INTERRUPT_HARD);
                    330:     }
                    331: }
                    332: 
                    333: void pic_set_irq_new(void *opaque, int irq, int level)
                    334: {
                    335:     icp_pic_state *s = (icp_pic_state *)opaque;
                    336:     if (level)
                    337:         s->level |= 1 << irq;
                    338:     else
                    339:         s->level &= ~(1 << irq);
                    340:     icp_pic_update(s);
                    341: }
                    342: 
                    343: static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
                    344: {
                    345:     icp_pic_state *s = (icp_pic_state *)opaque;
                    346: 
                    347:     offset -= s->base;
                    348:     switch (offset >> 2) {
                    349:     case 0: /* IRQ_STATUS */
                    350:         return s->level & s->irq_enabled;
                    351:     case 1: /* IRQ_RAWSTAT */
                    352:         return s->level;
                    353:     case 2: /* IRQ_ENABLESET */
                    354:         return s->irq_enabled;
                    355:     case 4: /* INT_SOFTSET */
                    356:         return s->level & 1;
                    357:     case 8: /* FRQ_STATUS */
                    358:         return s->level & s->fiq_enabled;
                    359:     case 9: /* FRQ_RAWSTAT */
                    360:         return s->level;
                    361:     case 10: /* FRQ_ENABLESET */
                    362:         return s->fiq_enabled;
                    363:     case 3: /* IRQ_ENABLECLR */
                    364:     case 5: /* INT_SOFTCLR */
                    365:     case 11: /* FRQ_ENABLECLR */
                    366:     default:
                    367:         printf ("icp_pic_read: Bad register offset 0x%x\n", offset);
                    368:         return 0;
                    369:     }
                    370: }
                    371: 
                    372: static void icp_pic_write(void *opaque, target_phys_addr_t offset,
                    373:                           uint32_t value)
                    374: {
                    375:     icp_pic_state *s = (icp_pic_state *)opaque;
                    376:     offset -= s->base;
                    377: 
                    378:     switch (offset >> 2) {
                    379:     case 2: /* IRQ_ENABLESET */
                    380:         s->irq_enabled |= value;
                    381:         break;
                    382:     case 3: /* IRQ_ENABLECLR */
                    383:         s->irq_enabled &= ~value;
                    384:         break;
                    385:     case 4: /* INT_SOFTSET */
                    386:         if (value & 1)
                    387:             pic_set_irq_new(s, 0, 1);
                    388:         break;
                    389:     case 5: /* INT_SOFTCLR */
                    390:         if (value & 1)
                    391:             pic_set_irq_new(s, 0, 0);
                    392:         break;
                    393:     case 10: /* FRQ_ENABLESET */
                    394:         s->fiq_enabled |= value;
                    395:         break;
                    396:     case 11: /* FRQ_ENABLECLR */
                    397:         s->fiq_enabled &= ~value;
                    398:         break;
                    399:     case 0: /* IRQ_STATUS */
                    400:     case 1: /* IRQ_RAWSTAT */
                    401:     case 8: /* FRQ_STATUS */
                    402:     case 9: /* FRQ_RAWSTAT */
                    403:     default:
                    404:         printf ("icp_pic_write: Bad register offset 0x%x\n", offset);
                    405:         return;
                    406:     }
                    407:     icp_pic_update(s);
                    408: }
                    409: 
                    410: static CPUReadMemoryFunc *icp_pic_readfn[] = {
                    411:    icp_pic_read,
                    412:    icp_pic_read,
                    413:    icp_pic_read
                    414: };
                    415: 
                    416: static CPUWriteMemoryFunc *icp_pic_writefn[] = {
                    417:    icp_pic_write,
                    418:    icp_pic_write,
                    419:    icp_pic_write
                    420: };
                    421: 
                    422: static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
                    423:                                    int parent_irq)
                    424: {
                    425:     icp_pic_state *s;
                    426:     int iomemtype;
                    427: 
                    428:     s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
                    429:     if (!s)
                    430:         return NULL;
                    431: 
                    432:     s->base = base;
                    433:     s->parent = parent;
                    434:     s->parent_irq = parent_irq;
                    435:     iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
                    436:                                        icp_pic_writefn, s);
                    437:     cpu_register_physical_memory(base, 0x007fffff, iomemtype);
                    438:     /* ??? Save/restore.  */
                    439:     return s;
                    440: }
                    441: 
                    442: /* Timers.  */
                    443: 
                    444: /* System bus clock speed (40MHz) for timer 0.  Not sure about this value.  */
                    445: #define ICP_BUS_FREQ 40000000
                    446: 
                    447: typedef struct {
                    448:     int64_t next_time;
                    449:     int64_t expires[3];
                    450:     int64_t loaded[3];
                    451:     QEMUTimer *timer;
                    452:     icp_pic_state *pic;
                    453:     uint32_t base;
                    454:     uint32_t control[3];
                    455:     uint32_t count[3];
                    456:     uint32_t limit[3];
                    457:     int freq[3];
                    458:     int int_level[3];
                    459: } icp_pit_state;
                    460: 
                    461: /* Calculate the new expiry time of the given timer.  */
                    462: 
                    463: static void icp_pit_reload(icp_pit_state *s, int n)
                    464: {
                    465:     int64_t delay;
                    466: 
                    467:     s->loaded[n] = s->expires[n];
                    468:     delay = muldiv64(s->count[n], ticks_per_sec, s->freq[n]);
                    469:     if (delay == 0)
                    470:         delay = 1;
                    471:     s->expires[n] += delay;
                    472: }
                    473: 
                    474: /* Check all active timers, and schedule the next timer interrupt.  */
                    475: 
                    476: static void icp_pit_update(icp_pit_state *s, int64_t now)
                    477: {
                    478:     int n;
                    479:     int64_t next;
                    480: 
                    481:     next = now;
                    482:     for (n = 0; n < 3; n++) {
                    483:         /* Ignore disabled timers.  */
                    484:         if ((s->control[n] & 0x80) == 0)
                    485:             continue;
                    486:         /* Ignore expired one-shot timers.  */
                    487:         if (s->count[n] == 0 && s->control[n] & 1)
                    488:             continue;
                    489:         if (s->expires[n] - now <= 0) {
                    490:             /* Timer has expired.  */
                    491:             s->int_level[n] = 1;
                    492:             if (s->control[n] & 1) {
                    493:                 /* One-shot.  */
                    494:                 s->count[n] = 0;
                    495:             } else {
                    496:                 if ((s->control[n] & 0x40) == 0) {
                    497:                     /* Free running.  */
                    498:                     if (s->control[n] & 2)
                    499:                         s->count[n] = 0xffffffff;
                    500:                     else
                    501:                         s->count[n] = 0xffff;
                    502:                 } else {
                    503:                       /* Periodic.  */
                    504:                       s->count[n] = s->limit[n];
                    505:                 }
                    506:             }
                    507:         }
                    508:         while (s->expires[n] - now <= 0) {
                    509:             icp_pit_reload(s, n);
                    510:         }
                    511:     }
                    512:     /* Update interrupts.  */
                    513:     for (n = 0; n < 3; n++) {
                    514:         if (s->int_level[n] && (s->control[n] & 0x20)) {
                    515:             pic_set_irq_new(s->pic, 5 + n, 1);
                    516:         } else {
                    517:             pic_set_irq_new(s->pic, 5 + n, 0);
                    518:         }
                    519:         if (next - s->expires[n] < 0)
                    520:             next = s->expires[n];
                    521:     }
                    522:     /* Schedule the next timer interrupt.  */
                    523:     if (next == now) {
                    524:         qemu_del_timer(s->timer);
                    525:         s->next_time = 0;
                    526:     } else if (next != s->next_time) {
                    527:         qemu_mod_timer(s->timer, next);
                    528:         s->next_time = next;
                    529:     }
                    530: }
                    531: 
                    532: /* Return the current value of the timer.  */
                    533: static uint32_t icp_pit_getcount(icp_pit_state *s, int n, int64_t now)
                    534: {
                    535:     int64_t elapsed;
                    536:     int64_t period;
                    537: 
                    538:     if (s->count[n] == 0)
                    539:         return 0;
                    540:     if ((s->control[n] & 0x80) == 0)
                    541:         return s->count[n];
                    542:     elapsed = now - s->loaded[n];
                    543:     period = s->expires[n] - s->loaded[n];
                    544:     /* If the timer should have expired then return 0.  This can happen
                    545:        when the host timer signal doesnt occur immediately.  It's better to
                    546:        have a timer appear to sit at zero for a while than have it wrap
                    547:        around before the guest interrupt is raised.  */
                    548:     /* ??? Could we trigger the interrupt here?  */
                    549:     if (elapsed > period)
                    550:         return 0;
                    551:     /* We need to calculate count * elapsed / period without overfowing.
                    552:        Scale both elapsed and period so they fit in a 32-bit int.  */
                    553:     while (period != (int32_t)period) {
                    554:         period >>= 1;
                    555:         elapsed >>= 1;
                    556:     }
                    557:     return ((uint64_t)s->count[n] * (uint64_t)(int32_t)elapsed)
                    558:             / (int32_t)period;
                    559: }
                    560: 
                    561: static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
                    562: {
                    563:     int n;
                    564:     icp_pit_state *s = (icp_pit_state *)opaque;
                    565: 
                    566:     offset -= s->base;
                    567:     n = offset >> 8;
                    568:     if (n > 2)
                    569:         cpu_abort (cpu_single_env, "icp_pit_read: Bad timer %x\n", offset);
                    570:     switch ((offset & 0xff) >> 2) {
                    571:     case 0: /* TimerLoad */
                    572:     case 6: /* TimerBGLoad */
                    573:         return s->limit[n];
                    574:     case 1: /* TimerValue */
                    575:         return icp_pit_getcount(s, n, qemu_get_clock(vm_clock));
                    576:     case 2: /* TimerControl */
                    577:         return s->control[n];
                    578:     case 4: /* TimerRIS */
                    579:         return s->int_level[n];
                    580:     case 5: /* TimerMIS */
                    581:         if ((s->control[n] & 0x20) == 0)
                    582:             return 0;
                    583:         return s->int_level[n];
                    584:     default:
                    585:         cpu_abort (cpu_single_env, "icp_pit_read: Bad offset %x\n", offset);
                    586:         return 0;
                    587:     }
                    588: }
                    589: 
                    590: static void icp_pit_write(void *opaque, target_phys_addr_t offset,
                    591:                           uint32_t value)
                    592: {
                    593:     icp_pit_state *s = (icp_pit_state *)opaque;
                    594:     int n;
                    595:     int64_t now;
                    596: 
                    597:     now = qemu_get_clock(vm_clock);
                    598:     offset -= s->base;
                    599:     n = offset >> 8;
                    600:     if (n > 2)
                    601:         cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
                    602: 
                    603:     switch ((offset & 0xff) >> 2) {
                    604:     case 0: /* TimerLoad */
                    605:         s->limit[n] = value;
                    606:         s->count[n] = value;
                    607:         s->expires[n] = now;
                    608:         icp_pit_reload(s, n);
                    609:         break;
                    610:     case 1: /* TimerValue */
                    611:         /* ??? Linux seems to want to write to this readonly register.
                    612:            Ignore it.  */
                    613:         break;
                    614:     case 2: /* TimerControl */
                    615:         if (s->control[n] & 0x80) {
                    616:             /* Pause the timer if it is running.  This may cause some
                    617:                inaccuracy dure to rounding, but avoids a whole lot of other
                    618:                messyness.  */
                    619:             s->count[n] = icp_pit_getcount(s, n, now);
                    620:         }
                    621:         s->control[n] = value;
                    622:         if (n == 0)
                    623:             s->freq[n] = ICP_BUS_FREQ;
                    624:         else
                    625:             s->freq[n] = 1000000;
                    626:         /* ??? Need to recalculate expiry time after changing divisor.  */
                    627:         switch ((value >> 2) & 3) {
                    628:         case 1: s->freq[n] >>= 4; break;
                    629:         case 2: s->freq[n] >>= 8; break;
                    630:         }
                    631:         if (s->control[n] & 0x80) {
                    632:             /* Restart the timer if still enabled.  */
                    633:             s->expires[n] = now;
                    634:             icp_pit_reload(s, n);
                    635:         }
                    636:         break;
                    637:     case 3: /* TimerIntClr */
                    638:         s->int_level[n] = 0;
                    639:         break;
                    640:     case 6: /* TimerBGLoad */
                    641:         s->limit[n] = value;
                    642:         break;
                    643:     default:
                    644:         cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
                    645:     }
                    646:     icp_pit_update(s, now);
                    647: }
                    648: 
                    649: static void icp_pit_tick(void *opaque)
                    650: {
                    651:     int64_t now;
                    652: 
                    653:     now = qemu_get_clock(vm_clock);
                    654:     icp_pit_update((icp_pit_state *)opaque, now);
                    655: }
                    656: 
                    657: static CPUReadMemoryFunc *icp_pit_readfn[] = {
                    658:    icp_pit_read,
                    659:    icp_pit_read,
                    660:    icp_pit_read
                    661: };
                    662: 
                    663: static CPUWriteMemoryFunc *icp_pit_writefn[] = {
                    664:    icp_pit_write,
                    665:    icp_pit_write,
                    666:    icp_pit_write
                    667: };
                    668: 
                    669: static void icp_pit_init(uint32_t base, icp_pic_state *pic)
                    670: {
                    671:     int iomemtype;
                    672:     icp_pit_state *s;
                    673:     int n;
                    674: 
                    675:     s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
                    676:     s->base = base;
                    677:     s->pic = pic;
                    678:     s->freq[0] = ICP_BUS_FREQ;
                    679:     s->freq[1] = 1000000;
                    680:     s->freq[2] = 1000000;
                    681:     for (n = 0; n < 3; n++) {
                    682:         s->control[n] = 0x20;
                    683:         s->count[n] = 0xffffffff;
                    684:     }
                    685: 
                    686:     iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
                    687:                                        icp_pit_writefn, s);
                    688:     cpu_register_physical_memory(base, 0x007fffff, iomemtype);
                    689:     s->timer = qemu_new_timer(vm_clock, icp_pit_tick, s);
                    690:     /* ??? Save/restore.  */
                    691: }
                    692: 
                    693: /* ARM PrimeCell PL011 UART */
                    694: 
                    695: typedef struct {
                    696:     uint32_t base;
                    697:     uint32_t readbuff;
                    698:     uint32_t flags;
                    699:     uint32_t lcr;
                    700:     uint32_t cr;
                    701:     uint32_t dmacr;
                    702:     uint32_t int_enabled;
                    703:     uint32_t int_level;
                    704:     uint32_t read_fifo[16];
                    705:     uint32_t ilpr;
                    706:     uint32_t ibrd;
                    707:     uint32_t fbrd;
                    708:     uint32_t ifl;
                    709:     int read_pos;
                    710:     int read_count;
                    711:     int read_trigger;
                    712:     CharDriverState *chr;
                    713:     icp_pic_state *pic;
                    714:     int irq;
                    715: } pl011_state;
                    716: 
                    717: #define PL011_INT_TX 0x20
                    718: #define PL011_INT_RX 0x10
                    719: 
                    720: #define PL011_FLAG_TXFE 0x80
                    721: #define PL011_FLAG_RXFF 0x40
                    722: #define PL011_FLAG_TXFF 0x20
                    723: #define PL011_FLAG_RXFE 0x10
                    724: 
                    725: static const unsigned char pl011_id[] =
                    726: { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
                    727: 
                    728: static void pl011_update(pl011_state *s)
                    729: {
                    730:     uint32_t flags;
                    731:     
                    732:     flags = s->int_level & s->int_enabled;
                    733:     pic_set_irq_new(s->pic, s->irq, flags != 0);
                    734: }
                    735: 
                    736: static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
                    737: {
                    738:     pl011_state *s = (pl011_state *)opaque;
                    739:     uint32_t c;
                    740: 
                    741:     offset -= s->base;
                    742:     if (offset >= 0xfe0 && offset < 0x1000) {
                    743:         return pl011_id[(offset - 0xfe0) >> 2];
                    744:     }
                    745:     switch (offset >> 2) {
                    746:     case 0: /* UARTDR */
                    747:         s->flags &= ~PL011_FLAG_RXFF;
                    748:         c = s->read_fifo[s->read_pos];
                    749:         if (s->read_count > 0) {
                    750:             s->read_count--;
                    751:             if (++s->read_pos == 16)
                    752:                 s->read_pos = 0;
                    753:         }
                    754:         if (s->read_count == 0) {
                    755:             s->flags |= PL011_FLAG_RXFE;
                    756:         }
                    757:         if (s->read_count == s->read_trigger - 1)
                    758:             s->int_level &= ~ PL011_INT_RX;
                    759:         pl011_update(s);
                    760:         return c;
                    761:     case 1: /* UARTCR */
                    762:         return 0;
                    763:     case 6: /* UARTFR */
                    764:         return s->flags;
                    765:     case 8: /* UARTILPR */
                    766:         return s->ilpr;
                    767:     case 9: /* UARTIBRD */
                    768:         return s->ibrd;
                    769:     case 10: /* UARTFBRD */
                    770:         return s->fbrd;
                    771:     case 11: /* UARTLCR_H */
                    772:         return s->lcr;
                    773:     case 12: /* UARTCR */
                    774:         return s->cr;
                    775:     case 13: /* UARTIFLS */
                    776:         return s->ifl;
                    777:     case 14: /* UARTIMSC */
                    778:         return s->int_enabled;
                    779:     case 15: /* UARTRIS */
                    780:         return s->int_level;
                    781:     case 16: /* UARTMIS */
                    782:         return s->int_level & s->int_enabled;
                    783:     case 18: /* UARTDMACR */
                    784:         return s->dmacr;
                    785:     default:
                    786:         cpu_abort (cpu_single_env, "pl011_read: Bad offset %x\n", offset);
                    787:         return 0;
                    788:     }
                    789: }
                    790: 
                    791: static void pl011_set_read_trigger(pl011_state *s)
                    792: {
                    793: #if 0
                    794:     /* The docs say the RX interrupt is triggered when the FIFO exceeds
                    795:        the threshold.  However linux only reads the FIFO in response to an
                    796:        interrupt.  Triggering the interrupt when the FIFO is non-empty seems
                    797:        to make things work.  */
                    798:     if (s->lcr & 0x10)
                    799:         s->read_trigger = (s->ifl >> 1) & 0x1c;
                    800:     else
                    801: #endif
                    802:         s->read_trigger = 1;
                    803: }
                    804: 
                    805: static void pl011_write(void *opaque, target_phys_addr_t offset,
                    806:                           uint32_t value)
                    807: {
                    808:     pl011_state *s = (pl011_state *)opaque;
                    809:     unsigned char ch;
                    810: 
                    811:     offset -= s->base;
                    812:     switch (offset >> 2) {
                    813:     case 0: /* UARTDR */
                    814:         /* ??? Check if transmitter is enabled.  */
                    815:         ch = value;
                    816:         if (s->chr)
                    817:             qemu_chr_write(s->chr, &ch, 1);
                    818:         s->int_level |= PL011_INT_TX;
                    819:         pl011_update(s);
                    820:         break;
                    821:     case 1: /* UARTCR */
                    822:         s->cr = value;
                    823:         break;
                    824:     case 8: /* UARTUARTILPR */
                    825:         s->ilpr = value;
                    826:         break;
                    827:     case 9: /* UARTIBRD */
                    828:         s->ibrd = value;
                    829:         break;
                    830:     case 10: /* UARTFBRD */
                    831:         s->fbrd = value;
                    832:         break;
                    833:     case 11: /* UARTLCR_H */
                    834:         s->lcr = value;
                    835:         pl011_set_read_trigger(s);
                    836:         break;
                    837:     case 12: /* UARTCR */
                    838:         /* ??? Need to implement the enable and loopback bits.  */
                    839:         s->cr = value;
                    840:         break;
                    841:     case 13: /* UARTIFS */
                    842:         s->ifl = value;
                    843:         pl011_set_read_trigger(s);
                    844:         break;
                    845:     case 14: /* UARTIMSC */
                    846:         s->int_enabled = value;
                    847:         pl011_update(s);
                    848:         break;
                    849:     case 17: /* UARTICR */
                    850:         s->int_level &= ~value;
                    851:         pl011_update(s);
                    852:         break;
                    853:     case 18: /* UARTDMACR */
                    854:         s->dmacr = value;
                    855:         if (value & 3)
                    856:             cpu_abort(cpu_single_env, "PL011: DMA not implemented\n");
                    857:         break;
                    858:     default:
                    859:         cpu_abort (cpu_single_env, "pl011_write: Bad offset %x\n", offset);
                    860:     }
                    861: }
                    862: 
                    863: static int pl011_can_recieve(void *opaque)
                    864: {
                    865:     pl011_state *s = (pl011_state *)opaque;
                    866: 
                    867:     if (s->lcr & 0x10)
                    868:         return s->read_count < 16;
                    869:     else
                    870:         return s->read_count < 1;
                    871: }
                    872: 
                    873: static void pl011_recieve(void *opaque, const uint8_t *buf, int size)
                    874: {
                    875:     pl011_state *s = (pl011_state *)opaque;
                    876:     int slot;
                    877: 
                    878:     slot = s->read_pos + s->read_count;
                    879:     if (slot >= 16)
                    880:         slot -= 16;
                    881:     s->read_fifo[slot] = *buf;
                    882:     s->read_count++;
                    883:     s->flags &= ~PL011_FLAG_RXFE;
                    884:     if (s->cr & 0x10 || s->read_count == 16) {
                    885:         s->flags |= PL011_FLAG_RXFF;
                    886:     }
                    887:     if (s->read_count == s->read_trigger) {
                    888:         s->int_level |= PL011_INT_RX;
                    889:         pl011_update(s);
                    890:     }
                    891: }
                    892: 
                    893: static void pl011_event(void *opaque, int event)
                    894: {
                    895:     /* ??? Should probably implement break.  */
                    896: }
                    897: 
                    898: static CPUReadMemoryFunc *pl011_readfn[] = {
                    899:    pl011_read,
                    900:    pl011_read,
                    901:    pl011_read
                    902: };
                    903: 
                    904: static CPUWriteMemoryFunc *pl011_writefn[] = {
                    905:    pl011_write,
                    906:    pl011_write,
                    907:    pl011_write
                    908: };
                    909: 
                    910: static void pl011_init(uint32_t base, icp_pic_state *pic, int irq,
                    911:                        CharDriverState *chr)
                    912: {
                    913:     int iomemtype;
                    914:     pl011_state *s;
                    915: 
                    916:     s = (pl011_state *)qemu_mallocz(sizeof(pl011_state));
                    917:     iomemtype = cpu_register_io_memory(0, pl011_readfn,
                    918:                                        pl011_writefn, s);
                    919:     cpu_register_physical_memory(base, 0x007fffff, iomemtype);
                    920:     s->base = base;
                    921:     s->pic = pic;
                    922:     s->irq = irq;
                    923:     s->chr = chr;
                    924:     s->read_trigger = 1;
                    925:     s->ifl = 0x12;
                    926:     s->cr = 0x300;
                    927:     s->flags = 0x90;
                    928:     if (chr){ 
                    929:         qemu_chr_add_read_handler(chr, pl011_can_recieve, pl011_recieve, s);
                    930:         qemu_chr_add_event_handler(chr, pl011_event);
                    931:     }
                    932:     /* ??? Save/restore.  */
                    933: }
                    934: 
                    935: /* CP control registers.  */
                    936: typedef struct {
                    937:     uint32_t base;
                    938: } icp_control_state;
                    939: 
                    940: static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
                    941: {
                    942:     icp_control_state *s = (icp_control_state *)opaque;
                    943:     offset -= s->base;
                    944:     switch (offset >> 2) {
                    945:     case 0: /* CP_IDFIELD */
                    946:         return 0x41034003;
                    947:     case 1: /* CP_FLASHPROG */
                    948:         return 0;
                    949:     case 2: /* CP_INTREG */
                    950:         return 0;
                    951:     case 3: /* CP_DECODE */
                    952:         return 0x11;
                    953:     default:
                    954:         cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n", offset);
                    955:         return 0;
                    956:     }
                    957: }
                    958: 
                    959: static void icp_control_write(void *opaque, target_phys_addr_t offset,
                    960:                           uint32_t value)
                    961: {
                    962:     icp_control_state *s = (icp_control_state *)opaque;
                    963:     offset -= s->base;
                    964:     switch (offset >> 2) {
                    965:     case 1: /* CP_FLASHPROG */
                    966:     case 2: /* CP_INTREG */
                    967:     case 3: /* CP_DECODE */
                    968:         /* Nothing interesting implemented yet.  */
                    969:         break;
                    970:     default:
                    971:         cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n", offset);
                    972:     }
                    973: }
                    974: static CPUReadMemoryFunc *icp_control_readfn[] = {
                    975:    icp_control_read,
                    976:    icp_control_read,
                    977:    icp_control_read
                    978: };
                    979: 
                    980: static CPUWriteMemoryFunc *icp_control_writefn[] = {
                    981:    icp_control_write,
                    982:    icp_control_write,
                    983:    icp_control_write
                    984: };
                    985: 
                    986: static void icp_control_init(uint32_t base)
                    987: {
                    988:     int iomemtype;
                    989:     icp_control_state *s;
                    990: 
                    991:     s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
                    992:     iomemtype = cpu_register_io_memory(0, icp_control_readfn,
                    993:                                        icp_control_writefn, s);
                    994:     cpu_register_physical_memory(base, 0x007fffff, iomemtype);
                    995:     s->base = base;
                    996:     /* ??? Save/restore.  */
                    997: }
                    998: 
                    999: 
                   1000: /* Keyboard/Mouse Interface.  */
                   1001: 
                   1002: typedef struct {
                   1003:     void *dev;
                   1004:     uint32_t base;
                   1005:     uint32_t cr;
                   1006:     uint32_t clk;
                   1007:     uint32_t last;
                   1008:     icp_pic_state *pic;
                   1009:     int pending;
                   1010:     int irq;
                   1011:     int is_mouse;
                   1012: } icp_kmi_state;
                   1013: 
                   1014: static void icp_kmi_update(void *opaque, int level)
                   1015: {
                   1016:     icp_kmi_state *s = (icp_kmi_state *)opaque;
                   1017:     int raise;
                   1018: 
                   1019:     s->pending = level;
                   1020:     raise = (s->pending && (s->cr & 0x10) != 0)
                   1021:             || (s->cr & 0x08) != 0;
                   1022:     pic_set_irq_new(s->pic, s->irq, raise);
                   1023: }
                   1024: 
                   1025: static uint32_t icp_kmi_read(void *opaque, target_phys_addr_t offset)
                   1026: {
                   1027:     icp_kmi_state *s = (icp_kmi_state *)opaque;
                   1028:     offset -= s->base;
                   1029:     if (offset >= 0xfe0 && offset < 0x1000)
                   1030:         return 0;
                   1031: 
                   1032:     switch (offset >> 2) {
                   1033:     case 0: /* KMICR */
                   1034:         return s->cr;
                   1035:     case 1: /* KMISTAT */
                   1036:         /* KMIC and KMID bits not implemented.  */
                   1037:         if (s->pending) {
                   1038:             return 0x10;
                   1039:         } else {
                   1040:             return 0;
                   1041:         }
                   1042:     case 2: /* KMIDATA */
                   1043:         if (s->pending)
                   1044:             s->last = ps2_read_data(s->dev);
                   1045:         return s->last;
                   1046:     case 3: /* KMICLKDIV */
                   1047:         return s->clk;
                   1048:     case 4: /* KMIIR */
                   1049:         return s->pending | 2;
                   1050:     default:
                   1051:         cpu_abort (cpu_single_env, "icp_kmi_read: Bad offset %x\n", offset);
                   1052:         return 0;
                   1053:     }
                   1054: }
                   1055: 
                   1056: static void icp_kmi_write(void *opaque, target_phys_addr_t offset,
                   1057:                           uint32_t value)
                   1058: {
                   1059:     icp_kmi_state *s = (icp_kmi_state *)opaque;
                   1060:     offset -= s->base;
                   1061:     switch (offset >> 2) {
                   1062:     case 0: /* KMICR */
                   1063:         s->cr = value;
                   1064:         icp_kmi_update(s, s->pending);
                   1065:         /* ??? Need to implement the enable/disable bit.  */
                   1066:         break;
                   1067:     case 2: /* KMIDATA */
                   1068:         /* ??? This should toggle the TX interrupt line.  */
                   1069:         /* ??? This means kbd/mouse can block each other.  */
                   1070:         if (s->is_mouse) {
                   1071:             ps2_write_mouse(s->dev, value);
                   1072:         } else {
                   1073:             ps2_write_keyboard(s->dev, value);
                   1074:         }
                   1075:         break;
                   1076:     case 3: /* KMICLKDIV */
                   1077:         s->clk = value;
                   1078:         return;
                   1079:     default:
                   1080:         cpu_abort (cpu_single_env, "icp_kmi_write: Bad offset %x\n", offset);
                   1081:     }
                   1082: }
                   1083: static CPUReadMemoryFunc *icp_kmi_readfn[] = {
                   1084:    icp_kmi_read,
                   1085:    icp_kmi_read,
                   1086:    icp_kmi_read
                   1087: };
                   1088: 
                   1089: static CPUWriteMemoryFunc *icp_kmi_writefn[] = {
                   1090:    icp_kmi_write,
                   1091:    icp_kmi_write,
                   1092:    icp_kmi_write
                   1093: };
                   1094: 
                   1095: static void icp_kmi_init(uint32_t base, icp_pic_state * pic, int irq,
                   1096:                          int is_mouse)
                   1097: {
                   1098:     int iomemtype;
                   1099:     icp_kmi_state *s;
                   1100: 
                   1101:     s = (icp_kmi_state *)qemu_mallocz(sizeof(icp_kmi_state));
                   1102:     iomemtype = cpu_register_io_memory(0, icp_kmi_readfn,
                   1103:                                        icp_kmi_writefn, s);
                   1104:     cpu_register_physical_memory(base, 0x007fffff, iomemtype);
                   1105:     s->base = base;
                   1106:     s->pic = pic;
                   1107:     s->irq = irq;
                   1108:     s->is_mouse = is_mouse;
                   1109:     if (is_mouse)
                   1110:         s->dev = ps2_mouse_init(icp_kmi_update, s);
                   1111:     else
                   1112:         s->dev = ps2_kbd_init(icp_kmi_update, s);
                   1113:     /* ??? Save/restore.  */
                   1114: }
                   1115: 
                   1116: /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
                   1117: static uint32_t bootloader[] = {
                   1118:   0xe3a00000, /* mov     r0, #0 */
                   1119:   0xe3a01013, /* mov     r1, #0x13 */
                   1120:   0xe3811c01, /* orr     r1, r1, #0x100 */
                   1121:   0xe59f2000, /* ldr     r2, [pc, #0] */
                   1122:   0xe59ff000, /* ldr     pc, [pc, #0] */
                   1123:   0, /* Address of kernel args.  Set by integratorcp_init.  */
                   1124:   0  /* Kernel entry point.  Set by integratorcp_init.  */
                   1125: };
                   1126: 
                   1127: static void set_kernel_args(uint32_t ram_size, int initrd_size,
                   1128:                             const char *kernel_cmdline)
                   1129: {
                   1130:     uint32_t *p;
                   1131: 
                   1132:     p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
                   1133:     /* ATAG_CORE */
                   1134:     *(p++) = 5;
                   1135:     *(p++) = 0x54410001;
                   1136:     *(p++) = 1;
                   1137:     *(p++) = 0x1000;
                   1138:     *(p++) = 0;
                   1139:     /* ATAG_MEM */
                   1140:     *(p++) = 4;
                   1141:     *(p++) = 0x54410002;
                   1142:     *(p++) = ram_size;
                   1143:     *(p++) = 0;
                   1144:     if (initrd_size) {
                   1145:         /* ATAG_INITRD2 */
                   1146:         *(p++) = 4;
                   1147:         *(p++) = 0x54420005;
                   1148:         *(p++) = INITRD_LOAD_ADDR;
                   1149:         *(p++) = initrd_size;
                   1150:     }
                   1151:     if (kernel_cmdline && *kernel_cmdline) {
                   1152:         /* ATAG_CMDLINE */
                   1153:         int cmdline_size;
                   1154: 
                   1155:         cmdline_size = strlen(kernel_cmdline);
                   1156:         memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
                   1157:         cmdline_size = (cmdline_size >> 2) + 1;
                   1158:         *(p++) = cmdline_size + 2;
                   1159:         *(p++) = 0x54410009;
                   1160:         p += cmdline_size;
                   1161:     }
                   1162:     /* ATAG_END */
                   1163:     *(p++) = 0;
                   1164:     *(p++) = 0;
                   1165: }
                   1166: 
                   1167: /* Board init.  */
                   1168: 
                   1169: static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
                   1170:                      DisplayState *ds, const char **fd_filename, int snapshot,
                   1171:                      const char *kernel_filename, const char *kernel_cmdline,
                   1172:                      const char *initrd_filename)
                   1173: {
                   1174:     CPUState *env;
                   1175:     uint32_t bios_offset;
                   1176:     icp_pic_state *pic;
                   1177:     int kernel_size;
                   1178:     int initrd_size;
                   1179: 
                   1180:     env = cpu_init();
                   1181:     bios_offset = ram_size + vga_ram_size;
                   1182:     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
                   1183:     /* ??? RAM shoud repeat to fill physical memory space.  */
                   1184:     /* SDRAM at address zero*/
                   1185:     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
                   1186:     /* And again at address 0x80000000 */
                   1187:     cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
                   1188: 
                   1189:     integratorcm_init(ram_size >> 20, bios_offset);
                   1190:     pic = icp_pic_init(0x14000000, env, -1);
                   1191:     icp_pic_init(0xca000000, pic, 26);
                   1192:     icp_pit_init(0x13000000, pic);
                   1193:     pl011_init(0x16000000, pic, 1, serial_hds[0]);
                   1194:     pl011_init(0x17000000, pic, 2, serial_hds[1]);
                   1195:     icp_control_init(0xcb000000);
                   1196:     icp_kmi_init(0x18000000, pic, 3, 0);
                   1197:     icp_kmi_init(0x19000000, pic, 4, 1);
                   1198:     if (nd_table[0].vlan)
                   1199:         smc91c111_init(&nd_table[0], 0xc8000000, pic, 27);
                   1200: 
                   1201:     /* Load the kernel.  */
                   1202:     if (!kernel_filename) {
                   1203:         fprintf(stderr, "Kernel image must be specified\n");
                   1204:         exit(1);
                   1205:     }
                   1206:     kernel_size = load_image(kernel_filename,
                   1207:                              phys_ram_base + KERNEL_LOAD_ADDR);
                   1208:     if (kernel_size < 0) {
                   1209:         fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
                   1210:         exit(1);
                   1211:     }
                   1212:     if (initrd_filename) {
                   1213:         initrd_size = load_image(initrd_filename,
                   1214:                                  phys_ram_base + INITRD_LOAD_ADDR);
                   1215:         if (initrd_size < 0) {
                   1216:             fprintf(stderr, "qemu: could not load initrd '%s'\n",
                   1217:                     initrd_filename);
                   1218:             exit(1);
                   1219:         }
                   1220:     } else {
                   1221:         initrd_size = 0;
                   1222:     }
                   1223:     bootloader[5] = KERNEL_ARGS_ADDR;
                   1224:     bootloader[6] = KERNEL_LOAD_ADDR;
                   1225:     memcpy(phys_ram_base, bootloader, sizeof(bootloader));
                   1226:     set_kernel_args(ram_size, initrd_size, kernel_cmdline);
                   1227: }
                   1228: 
                   1229: QEMUMachine integratorcp_machine = {
                   1230:     "integratorcp",
                   1231:     "ARM Integrator/CP",
                   1232:     integratorcp_init,
                   1233: };

unix.superglobalmegacorp.com

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