symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/spitz.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * PXA270-based Clamshell PDA platforms.
       
     3  *
       
     4  * Copyright (c) 2006 Openedhand Ltd.
       
     5  * Written by Andrzej Zaborowski <balrog@zabor.org>
       
     6  *
       
     7  * This code is licensed under the GNU GPL v2.
       
     8  */
       
     9 
       
    10 #include "hw.h"
       
    11 #include "pxa.h"
       
    12 #include "arm-misc.h"
       
    13 #include "sysemu.h"
       
    14 #include "pcmcia.h"
       
    15 #include "i2c.h"
       
    16 #include "flash.h"
       
    17 #include "qemu-timer.h"
       
    18 #include "devices.h"
       
    19 #include "sharpsl.h"
       
    20 #include "console.h"
       
    21 #include "gui.h"
       
    22 #include "block.h"
       
    23 #include "audio/audio.h"
       
    24 #include "boards.h"
       
    25 
       
    26 #undef REG_FMT
       
    27 #if TARGET_PHYS_ADDR_BITS == 32
       
    28 #define REG_FMT			"0x%02x"
       
    29 #else
       
    30 #define REG_FMT			"0x%02lx"
       
    31 #endif
       
    32 
       
    33 /* Spitz Flash */
       
    34 #define FLASH_BASE		0x0c000000
       
    35 #define FLASH_ECCLPLB		0x00	/* Line parity 7 - 0 bit */
       
    36 #define FLASH_ECCLPUB		0x04	/* Line parity 15 - 8 bit */
       
    37 #define FLASH_ECCCP		0x08	/* Column parity 5 - 0 bit */
       
    38 #define FLASH_ECCCNTR		0x0c	/* ECC byte counter */
       
    39 #define FLASH_ECCCLRR		0x10	/* Clear ECC */
       
    40 #define FLASH_FLASHIO		0x14	/* Flash I/O */
       
    41 #define FLASH_FLASHCTL		0x18	/* Flash Control */
       
    42 
       
    43 #define FLASHCTL_CE0		(1 << 0)
       
    44 #define FLASHCTL_CLE		(1 << 1)
       
    45 #define FLASHCTL_ALE		(1 << 2)
       
    46 #define FLASHCTL_WP		(1 << 3)
       
    47 #define FLASHCTL_CE1		(1 << 4)
       
    48 #define FLASHCTL_RYBY		(1 << 5)
       
    49 #define FLASHCTL_NCE		(FLASHCTL_CE0 | FLASHCTL_CE1)
       
    50 
       
    51 struct sl_nand_s {
       
    52     struct nand_flash_s *nand;
       
    53     uint8_t ctl;
       
    54     struct ecc_state_s ecc;
       
    55 };
       
    56 
       
    57 static uint32_t sl_readb(void *opaque, target_phys_addr_t addr)
       
    58 {
       
    59     struct sl_nand_s *s = (struct sl_nand_s *) opaque;
       
    60     int ryby;
       
    61 
       
    62     switch (addr) {
       
    63 #define BSHR(byte, from, to)	((s->ecc.lp[byte] >> (from - to)) & (1 << to))
       
    64     case FLASH_ECCLPLB:
       
    65         return BSHR(0, 4, 0) | BSHR(0, 5, 2) | BSHR(0, 6, 4) | BSHR(0, 7, 6) |
       
    66                 BSHR(1, 4, 1) | BSHR(1, 5, 3) | BSHR(1, 6, 5) | BSHR(1, 7, 7);
       
    67 
       
    68 #define BSHL(byte, from, to)	((s->ecc.lp[byte] << (to - from)) & (1 << to))
       
    69     case FLASH_ECCLPUB:
       
    70         return BSHL(0, 0, 0) | BSHL(0, 1, 2) | BSHL(0, 2, 4) | BSHL(0, 3, 6) |
       
    71                 BSHL(1, 0, 1) | BSHL(1, 1, 3) | BSHL(1, 2, 5) | BSHL(1, 3, 7);
       
    72 
       
    73     case FLASH_ECCCP:
       
    74         return s->ecc.cp;
       
    75 
       
    76     case FLASH_ECCCNTR:
       
    77         return s->ecc.count & 0xff;
       
    78 
       
    79     case FLASH_FLASHCTL:
       
    80         nand_getpins(s->nand, &ryby);
       
    81         if (ryby)
       
    82             return s->ctl | FLASHCTL_RYBY;
       
    83         else
       
    84             return s->ctl;
       
    85 
       
    86     case FLASH_FLASHIO:
       
    87         return ecc_digest(&s->ecc, nand_getio(s->nand));
       
    88 
       
    89     default:
       
    90         zaurus_printf("Bad register offset " REG_FMT "\n", addr);
       
    91     }
       
    92     return 0;
       
    93 }
       
    94 
       
    95 static uint32_t sl_readl(void *opaque, target_phys_addr_t addr)
       
    96 {
       
    97     struct sl_nand_s *s = (struct sl_nand_s *) opaque;
       
    98 
       
    99     if (addr == FLASH_FLASHIO)
       
   100         return ecc_digest(&s->ecc, nand_getio(s->nand)) |
       
   101                 (ecc_digest(&s->ecc, nand_getio(s->nand)) << 16);
       
   102 
       
   103     return sl_readb(opaque, addr);
       
   104 }
       
   105 
       
   106 static void sl_writeb(void *opaque, target_phys_addr_t addr,
       
   107                 uint32_t value)
       
   108 {
       
   109     struct sl_nand_s *s = (struct sl_nand_s *) opaque;
       
   110 
       
   111     switch (addr) {
       
   112     case FLASH_ECCCLRR:
       
   113         /* Value is ignored.  */
       
   114         ecc_reset(&s->ecc);
       
   115         break;
       
   116 
       
   117     case FLASH_FLASHCTL:
       
   118         s->ctl = value & 0xff & ~FLASHCTL_RYBY;
       
   119         nand_setpins(s->nand,
       
   120                         s->ctl & FLASHCTL_CLE,
       
   121                         s->ctl & FLASHCTL_ALE,
       
   122                         s->ctl & FLASHCTL_NCE,
       
   123                         s->ctl & FLASHCTL_WP,
       
   124                         0);
       
   125         break;
       
   126 
       
   127     case FLASH_FLASHIO:
       
   128         nand_setio(s->nand, ecc_digest(&s->ecc, value & 0xff));
       
   129         break;
       
   130 
       
   131     default:
       
   132         zaurus_printf("Bad register offset " REG_FMT "\n", addr);
       
   133     }
       
   134 }
       
   135 
       
   136 static void sl_save(QEMUFile *f, void *opaque)
       
   137 {
       
   138     struct sl_nand_s *s = (struct sl_nand_s *) opaque;
       
   139 
       
   140     qemu_put_8s(f, &s->ctl);
       
   141     ecc_put(f, &s->ecc);
       
   142 }
       
   143 
       
   144 static int sl_load(QEMUFile *f, void *opaque, int version_id)
       
   145 {
       
   146     struct sl_nand_s *s = (struct sl_nand_s *) opaque;
       
   147 
       
   148     qemu_get_8s(f, &s->ctl);
       
   149     ecc_get(f, &s->ecc);
       
   150 
       
   151     return 0;
       
   152 }
       
   153 
       
   154 enum {
       
   155     FLASH_128M,
       
   156     FLASH_1024M,
       
   157 };
       
   158 
       
   159 static void sl_flash_register(struct pxa2xx_state_s *cpu, int size)
       
   160 {
       
   161     int iomemtype;
       
   162     struct sl_nand_s *s;
       
   163     CPUReadMemoryFunc *sl_readfn[] = {
       
   164         sl_readb,
       
   165         sl_readb,
       
   166         sl_readl,
       
   167     };
       
   168     CPUWriteMemoryFunc *sl_writefn[] = {
       
   169         sl_writeb,
       
   170         sl_writeb,
       
   171         sl_writeb,
       
   172     };
       
   173 
       
   174     s = (struct sl_nand_s *) qemu_mallocz(sizeof(struct sl_nand_s));
       
   175     s->ctl = 0;
       
   176     if (size == FLASH_128M)
       
   177         s->nand = nand_init(NAND_MFR_SAMSUNG, 0x73);
       
   178     else if (size == FLASH_1024M)
       
   179         s->nand = nand_init(NAND_MFR_SAMSUNG, 0xf1);
       
   180 
       
   181     iomemtype = cpu_register_io_memory(0, sl_readfn,
       
   182                     sl_writefn, s);
       
   183     cpu_register_physical_memory(FLASH_BASE, 0x40, iomemtype);
       
   184 
       
   185     register_savevm("sl_flash", 0, 0, sl_save, sl_load, s);
       
   186 }
       
   187 
       
   188 /* Spitz Keyboard */
       
   189 
       
   190 #define SPITZ_KEY_STROBE_NUM	11
       
   191 #define SPITZ_KEY_SENSE_NUM	7
       
   192 
       
   193 static const int spitz_gpio_key_sense[SPITZ_KEY_SENSE_NUM] = {
       
   194     12, 17, 91, 34, 36, 38, 39
       
   195 };
       
   196 
       
   197 static const int spitz_gpio_key_strobe[SPITZ_KEY_STROBE_NUM] = {
       
   198     88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114
       
   199 };
       
   200 
       
   201 /* Eighth additional row maps the special keys */
       
   202 static int spitz_keymap[SPITZ_KEY_SENSE_NUM + 1][SPITZ_KEY_STROBE_NUM] = {
       
   203     { 0x1d, 0x02, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x3f, 0x40 },
       
   204     {  -1 , 0x03, 0x05, 0x13, 0x15, 0x09, 0x17, 0x18, 0x19, 0x41, 0x42 },
       
   205     { 0x0f, 0x10, 0x12, 0x14, 0x22, 0x16, 0x24, 0x25,  -1 ,  -1 ,  -1  },
       
   206     { 0x3c, 0x11, 0x1f, 0x21, 0x2f, 0x23, 0x32, 0x26,  -1 , 0x36,  -1  },
       
   207     { 0x3b, 0x1e, 0x20, 0x2e, 0x30, 0x31, 0x34,  -1 , 0x1c, 0x2a,  -1  },
       
   208     { 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33,  -1 , 0x48,  -1 ,  -1 , 0x38 },
       
   209     { 0x37, 0x3d,  -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d,  -1 ,  -1  },
       
   210     { 0x52, 0x43, 0x01, 0x47, 0x49,  -1 ,  -1 ,  -1 ,  -1 ,  -1 ,  -1  },
       
   211 };
       
   212 
       
   213 #define SPITZ_GPIO_AK_INT	13	/* Remote control */
       
   214 #define SPITZ_GPIO_SYNC		16	/* Sync button */
       
   215 #define SPITZ_GPIO_ON_KEY	95	/* Power button */
       
   216 #define SPITZ_GPIO_SWA		97	/* Lid */
       
   217 #define SPITZ_GPIO_SWB		96	/* Tablet mode */
       
   218 
       
   219 /* The special buttons are mapped to unused keys */
       
   220 static const int spitz_gpiomap[5] = {
       
   221     SPITZ_GPIO_AK_INT, SPITZ_GPIO_SYNC, SPITZ_GPIO_ON_KEY,
       
   222     SPITZ_GPIO_SWA, SPITZ_GPIO_SWB,
       
   223 };
       
   224 static int spitz_gpio_invert[5] = { 0, 0, 0, 0, 0, };
       
   225 
       
   226 struct spitz_keyboard_s {
       
   227     qemu_irq sense[SPITZ_KEY_SENSE_NUM];
       
   228     qemu_irq *strobe;
       
   229     qemu_irq gpiomap[5];
       
   230     int keymap[0x80];
       
   231     uint16_t keyrow[SPITZ_KEY_SENSE_NUM];
       
   232     uint16_t strobe_state;
       
   233     uint16_t sense_state;
       
   234 
       
   235     uint16_t pre_map[0x100];
       
   236     uint16_t modifiers;
       
   237     uint16_t imodifiers;
       
   238     uint8_t fifo[16];
       
   239     int fifopos, fifolen;
       
   240     QEMUTimer *kbdtimer;
       
   241 };
       
   242 
       
   243 static void spitz_keyboard_sense_update(struct spitz_keyboard_s *s)
       
   244 {
       
   245     int i;
       
   246     uint16_t strobe, sense = 0;
       
   247     for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++) {
       
   248         strobe = s->keyrow[i] & s->strobe_state;
       
   249         if (strobe) {
       
   250             sense |= 1 << i;
       
   251             if (!(s->sense_state & (1 << i)))
       
   252                 qemu_irq_raise(s->sense[i]);
       
   253         } else if (s->sense_state & (1 << i))
       
   254             qemu_irq_lower(s->sense[i]);
       
   255     }
       
   256 
       
   257     s->sense_state = sense;
       
   258 }
       
   259 
       
   260 static void spitz_keyboard_strobe(void *opaque, int line, int level)
       
   261 {
       
   262     struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
       
   263 
       
   264     if (level)
       
   265         s->strobe_state |= 1 << line;
       
   266     else
       
   267         s->strobe_state &= ~(1 << line);
       
   268     spitz_keyboard_sense_update(s);
       
   269 }
       
   270 
       
   271 static void spitz_keyboard_keydown(struct spitz_keyboard_s *s, int keycode)
       
   272 {
       
   273     int spitz_keycode = s->keymap[keycode & 0x7f];
       
   274     if (spitz_keycode == -1)
       
   275         return;
       
   276 
       
   277     /* Handle the additional keys */
       
   278     if ((spitz_keycode >> 4) == SPITZ_KEY_SENSE_NUM) {
       
   279         qemu_set_irq(s->gpiomap[spitz_keycode & 0xf], (keycode < 0x80) ^
       
   280                         spitz_gpio_invert[spitz_keycode & 0xf]);
       
   281         return;
       
   282     }
       
   283 
       
   284     if (keycode & 0x80)
       
   285         s->keyrow[spitz_keycode >> 4] &= ~(1 << (spitz_keycode & 0xf));
       
   286     else
       
   287         s->keyrow[spitz_keycode >> 4] |= 1 << (spitz_keycode & 0xf);
       
   288 
       
   289     spitz_keyboard_sense_update(s);
       
   290 }
       
   291 
       
   292 #define SHIFT	(1 << 7)
       
   293 #define CTRL	(1 << 8)
       
   294 #define FN	(1 << 9)
       
   295 
       
   296 #define QUEUE_KEY(c)	s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
       
   297 
       
   298 static void spitz_keyboard_handler(void *opaque, int keycode)
       
   299 {
       
   300     struct spitz_keyboard_s * const s = opaque;
       
   301     uint16_t code;
       
   302     int mapcode;
       
   303     switch (keycode) {
       
   304     case 0x2a:	/* Left Shift */
       
   305         s->modifiers |= 1;
       
   306         break;
       
   307     case 0xaa:
       
   308         s->modifiers &= ~1;
       
   309         break;
       
   310     case 0x36:	/* Right Shift */
       
   311         s->modifiers |= 2;
       
   312         break;
       
   313     case 0xb6:
       
   314         s->modifiers &= ~2;
       
   315         break;
       
   316     case 0x1d:	/* Control */
       
   317         s->modifiers |= 4;
       
   318         break;
       
   319     case 0x9d:
       
   320         s->modifiers &= ~4;
       
   321         break;
       
   322     case 0x38:	/* Alt */
       
   323         s->modifiers |= 8;
       
   324         break;
       
   325     case 0xb8:
       
   326         s->modifiers &= ~8;
       
   327         break;
       
   328     }
       
   329 
       
   330     code = s->pre_map[mapcode = ((s->modifiers & 3) ?
       
   331             (keycode | SHIFT) :
       
   332             (keycode & ~SHIFT))];
       
   333 
       
   334     if (code != mapcode) {
       
   335 #if 0
       
   336         if ((code & SHIFT) && !(s->modifiers & 1))
       
   337             QUEUE_KEY(0x2a | (keycode & 0x80));
       
   338         if ((code & CTRL ) && !(s->modifiers & 4))
       
   339             QUEUE_KEY(0x1d | (keycode & 0x80));
       
   340         if ((code & FN   ) && !(s->modifiers & 8))
       
   341             QUEUE_KEY(0x38 | (keycode & 0x80));
       
   342         if ((code & FN   ) && (s->modifiers & 1))
       
   343             QUEUE_KEY(0x2a | (~keycode & 0x80));
       
   344         if ((code & FN   ) && (s->modifiers & 2))
       
   345             QUEUE_KEY(0x36 | (~keycode & 0x80));
       
   346 #else
       
   347         if (keycode & 0x80) {
       
   348             if ((s->imodifiers & 1   ) && !(s->modifiers & 1))
       
   349                 QUEUE_KEY(0x2a | 0x80);
       
   350             if ((s->imodifiers & 4   ) && !(s->modifiers & 4))
       
   351                 QUEUE_KEY(0x1d | 0x80);
       
   352             if ((s->imodifiers & 8   ) && !(s->modifiers & 8))
       
   353                 QUEUE_KEY(0x38 | 0x80);
       
   354             if ((s->imodifiers & 0x10) && (s->modifiers & 1))
       
   355                 QUEUE_KEY(0x2a);
       
   356             if ((s->imodifiers & 0x20) && (s->modifiers & 2))
       
   357                 QUEUE_KEY(0x36);
       
   358             s->imodifiers = 0;
       
   359         } else {
       
   360             if ((code & SHIFT) && !((s->modifiers | s->imodifiers) & 1)) {
       
   361                 QUEUE_KEY(0x2a);
       
   362                 s->imodifiers |= 1;
       
   363             }
       
   364             if ((code & CTRL ) && !((s->modifiers | s->imodifiers) & 4)) {
       
   365                 QUEUE_KEY(0x1d);
       
   366                 s->imodifiers |= 4;
       
   367             }
       
   368             if ((code & FN   ) && !((s->modifiers | s->imodifiers) & 8)) {
       
   369                 QUEUE_KEY(0x38);
       
   370                 s->imodifiers |= 8;
       
   371             }
       
   372             if ((code & FN   ) && (s->modifiers & 1) &&
       
   373                             !(s->imodifiers & 0x10)) {
       
   374                 QUEUE_KEY(0x2a | 0x80);
       
   375                 s->imodifiers |= 0x10;
       
   376             }
       
   377             if ((code & FN   ) && (s->modifiers & 2) &&
       
   378                             !(s->imodifiers & 0x20)) {
       
   379                 QUEUE_KEY(0x36 | 0x80);
       
   380                 s->imodifiers |= 0x20;
       
   381             }
       
   382         }
       
   383 #endif
       
   384     }
       
   385 
       
   386     QUEUE_KEY((code & 0x7f) | (keycode & 0x80));
       
   387 }
       
   388 
       
   389 static void spitz_keyboard_tick(void *opaque)
       
   390 {
       
   391     struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
       
   392 
       
   393     if (s->fifolen) {
       
   394         spitz_keyboard_keydown(s, s->fifo[s->fifopos ++]);
       
   395         s->fifolen --;
       
   396         if (s->fifopos >= 16)
       
   397             s->fifopos = 0;
       
   398     }
       
   399 
       
   400     qemu_mod_timer(s->kbdtimer, qemu_get_clock(vm_clock) + ticks_per_sec / 32);
       
   401 }
       
   402 
       
   403 static void spitz_keyboard_pre_map(struct spitz_keyboard_s *s)
       
   404 {
       
   405     int i;
       
   406     for (i = 0; i < 0x100; i ++)
       
   407         s->pre_map[i] = i;
       
   408     s->pre_map[0x02 | SHIFT	] = 0x02 | SHIFT;	/* exclam */
       
   409     s->pre_map[0x28 | SHIFT	] = 0x03 | SHIFT;	/* quotedbl */
       
   410     s->pre_map[0x04 | SHIFT	] = 0x04 | SHIFT;	/* numbersign */
       
   411     s->pre_map[0x05 | SHIFT	] = 0x05 | SHIFT;	/* dollar */
       
   412     s->pre_map[0x06 | SHIFT	] = 0x06 | SHIFT;	/* percent */
       
   413     s->pre_map[0x08 | SHIFT	] = 0x07 | SHIFT;	/* ampersand */
       
   414     s->pre_map[0x28		] = 0x08 | SHIFT;	/* apostrophe */
       
   415     s->pre_map[0x0a | SHIFT	] = 0x09 | SHIFT;	/* parenleft */
       
   416     s->pre_map[0x0b | SHIFT	] = 0x0a | SHIFT;	/* parenright */
       
   417     s->pre_map[0x29 | SHIFT	] = 0x0b | SHIFT;	/* asciitilde */
       
   418     s->pre_map[0x03 | SHIFT	] = 0x0c | SHIFT;	/* at */
       
   419     s->pre_map[0xd3		] = 0x0e | FN;		/* Delete */
       
   420     s->pre_map[0x3a		] = 0x0f | FN;		/* Caps_Lock */
       
   421     s->pre_map[0x07 | SHIFT	] = 0x11 | FN;		/* asciicircum */
       
   422     s->pre_map[0x0d		] = 0x12 | FN;		/* equal */
       
   423     s->pre_map[0x0d | SHIFT	] = 0x13 | FN;		/* plus */
       
   424     s->pre_map[0x1a		] = 0x14 | FN;		/* bracketleft */
       
   425     s->pre_map[0x1b		] = 0x15 | FN;		/* bracketright */
       
   426     s->pre_map[0x1a | SHIFT	] = 0x16 | FN;		/* braceleft */
       
   427     s->pre_map[0x1b | SHIFT	] = 0x17 | FN;		/* braceright */
       
   428     s->pre_map[0x27		] = 0x22 | FN;		/* semicolon */
       
   429     s->pre_map[0x27 | SHIFT	] = 0x23 | FN;		/* colon */
       
   430     s->pre_map[0x09 | SHIFT	] = 0x24 | FN;		/* asterisk */
       
   431     s->pre_map[0x2b		] = 0x25 | FN;		/* backslash */
       
   432     s->pre_map[0x2b | SHIFT	] = 0x26 | FN;		/* bar */
       
   433     s->pre_map[0x0c | SHIFT	] = 0x30 | FN;		/* underscore */
       
   434     s->pre_map[0x33 | SHIFT	] = 0x33 | FN;		/* less */
       
   435     s->pre_map[0x35		] = 0x33 | SHIFT;	/* slash */
       
   436     s->pre_map[0x34 | SHIFT	] = 0x34 | FN;		/* greater */
       
   437     s->pre_map[0x35 | SHIFT	] = 0x34 | SHIFT;	/* question */
       
   438     s->pre_map[0x49		] = 0x48 | FN;		/* Page_Up */
       
   439     s->pre_map[0x51		] = 0x50 | FN;		/* Page_Down */
       
   440 
       
   441     s->modifiers = 0;
       
   442     s->imodifiers = 0;
       
   443     s->fifopos = 0;
       
   444     s->fifolen = 0;
       
   445     s->kbdtimer = qemu_new_timer(vm_clock, spitz_keyboard_tick, s);
       
   446     spitz_keyboard_tick(s);
       
   447 }
       
   448 
       
   449 #undef SHIFT
       
   450 #undef CTRL
       
   451 #undef FN
       
   452 
       
   453 static void spitz_keyboard_save(QEMUFile *f, void *opaque)
       
   454 {
       
   455     struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
       
   456     int i;
       
   457 
       
   458     qemu_put_be16s(f, &s->sense_state);
       
   459     qemu_put_be16s(f, &s->strobe_state);
       
   460     for (i = 0; i < 5; i ++)
       
   461         qemu_put_byte(f, spitz_gpio_invert[i]);
       
   462 }
       
   463 
       
   464 static int spitz_keyboard_load(QEMUFile *f, void *opaque, int version_id)
       
   465 {
       
   466     struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
       
   467     int i;
       
   468 
       
   469     qemu_get_be16s(f, &s->sense_state);
       
   470     qemu_get_be16s(f, &s->strobe_state);
       
   471     for (i = 0; i < 5; i ++)
       
   472         spitz_gpio_invert[i] = qemu_get_byte(f);
       
   473 
       
   474     /* Release all pressed keys */
       
   475     memset(s->keyrow, 0, sizeof(s->keyrow));
       
   476     spitz_keyboard_sense_update(s);
       
   477     s->modifiers = 0;
       
   478     s->imodifiers = 0;
       
   479     s->fifopos = 0;
       
   480     s->fifolen = 0;
       
   481 
       
   482     return 0;
       
   483 }
       
   484 
       
   485 static void spitz_keyboard_register(struct pxa2xx_state_s *cpu)
       
   486 {
       
   487     int i, j;
       
   488     struct spitz_keyboard_s *s;
       
   489 
       
   490     s = (struct spitz_keyboard_s *)
       
   491             qemu_mallocz(sizeof(struct spitz_keyboard_s));
       
   492     memset(s, 0, sizeof(struct spitz_keyboard_s));
       
   493 
       
   494     for (i = 0; i < 0x80; i ++)
       
   495         s->keymap[i] = -1;
       
   496     for (i = 0; i < SPITZ_KEY_SENSE_NUM + 1; i ++)
       
   497         for (j = 0; j < SPITZ_KEY_STROBE_NUM; j ++)
       
   498             if (spitz_keymap[i][j] != -1)
       
   499                 s->keymap[spitz_keymap[i][j]] = (i << 4) | j;
       
   500 
       
   501     for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++)
       
   502         s->sense[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpio_key_sense[i]];
       
   503 
       
   504     for (i = 0; i < 5; i ++)
       
   505         s->gpiomap[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpiomap[i]];
       
   506 
       
   507     s->strobe = qemu_allocate_irqs(spitz_keyboard_strobe, s,
       
   508                     SPITZ_KEY_STROBE_NUM);
       
   509     for (i = 0; i < SPITZ_KEY_STROBE_NUM; i ++)
       
   510         pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
       
   511 
       
   512     spitz_keyboard_pre_map(s);
       
   513     gui_register_dev_key_callback(spitz_keyboard_handler, s);
       
   514 
       
   515     register_savevm("spitz_keyboard", 0, 0,
       
   516                     spitz_keyboard_save, spitz_keyboard_load, s);
       
   517 }
       
   518 
       
   519 /* LCD backlight controller */
       
   520 
       
   521 #define LCDTG_RESCTL	0x00
       
   522 #define LCDTG_PHACTRL	0x01
       
   523 #define LCDTG_DUTYCTRL	0x02
       
   524 #define LCDTG_POWERREG0	0x03
       
   525 #define LCDTG_POWERREG1	0x04
       
   526 #define LCDTG_GPOR3	0x05
       
   527 #define LCDTG_PICTRL	0x06
       
   528 #define LCDTG_POLCTRL	0x07
       
   529 
       
   530 static int bl_intensity, bl_power;
       
   531 
       
   532 static void spitz_bl_update(struct pxa2xx_state_s *s)
       
   533 {
       
   534     if (bl_power && bl_intensity)
       
   535         zaurus_printf("LCD Backlight now at %i/63\n", bl_intensity);
       
   536     else
       
   537         zaurus_printf("LCD Backlight now off\n");
       
   538 }
       
   539 
       
   540 static inline void spitz_bl_bit5(void *opaque, int line, int level)
       
   541 {
       
   542     int prev = bl_intensity;
       
   543 
       
   544     if (level)
       
   545         bl_intensity &= ~0x20;
       
   546     else
       
   547         bl_intensity |= 0x20;
       
   548 
       
   549     if (bl_power && prev != bl_intensity)
       
   550         spitz_bl_update((struct pxa2xx_state_s *) opaque);
       
   551 }
       
   552 
       
   553 static inline void spitz_bl_power(void *opaque, int line, int level)
       
   554 {
       
   555     bl_power = !!level;
       
   556     spitz_bl_update((struct pxa2xx_state_s *) opaque);
       
   557 }
       
   558 
       
   559 static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd)
       
   560 {
       
   561     int addr, value;
       
   562     addr = cmd >> 5;
       
   563     value = cmd & 0x1f;
       
   564 
       
   565     switch (addr) {
       
   566     case LCDTG_RESCTL:
       
   567         if (value)
       
   568             zaurus_printf("LCD in QVGA mode\n");
       
   569         else
       
   570             zaurus_printf("LCD in VGA mode\n");
       
   571         break;
       
   572 
       
   573     case LCDTG_DUTYCTRL:
       
   574         bl_intensity &= ~0x1f;
       
   575         bl_intensity |= value;
       
   576         if (bl_power)
       
   577             spitz_bl_update((struct pxa2xx_state_s *) opaque);
       
   578         break;
       
   579 
       
   580     case LCDTG_POWERREG0:
       
   581         /* Set common voltage to M62332FP */
       
   582         break;
       
   583     }
       
   584 }
       
   585 
       
   586 /* SSP devices */
       
   587 
       
   588 #define CORGI_SSP_PORT		2
       
   589 
       
   590 #define SPITZ_GPIO_LCDCON_CS	53
       
   591 #define SPITZ_GPIO_ADS7846_CS	14
       
   592 #define SPITZ_GPIO_MAX1111_CS	20
       
   593 #define SPITZ_GPIO_TP_INT	11
       
   594 
       
   595 static int lcd_en, ads_en, max_en;
       
   596 static struct max111x_s *max1111;
       
   597 static struct ads7846_state_s *ads7846;
       
   598 
       
   599 /* "Demux" the signal based on current chipselect */
       
   600 static uint32_t corgi_ssp_read(void *opaque)
       
   601 {
       
   602     if (lcd_en)
       
   603         return 0;
       
   604     if (ads_en)
       
   605         return ads7846_read(ads7846);
       
   606     if (max_en)
       
   607         return max111x_read(max1111);
       
   608     return 0;
       
   609 }
       
   610 
       
   611 static void corgi_ssp_write(void *opaque, uint32_t value)
       
   612 {
       
   613     if (lcd_en)
       
   614         spitz_lcdtg_dac_put(opaque, value);
       
   615     if (ads_en)
       
   616         ads7846_write(ads7846, value);
       
   617     if (max_en)
       
   618         max111x_write(max1111, value);
       
   619 }
       
   620 
       
   621 static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
       
   622 {
       
   623     switch (line) {
       
   624     case 0:
       
   625         lcd_en = !level;
       
   626         break;
       
   627     case 1:
       
   628         ads_en = !level;
       
   629         break;
       
   630     case 2:
       
   631         max_en = !level;
       
   632         break;
       
   633     }
       
   634 }
       
   635 
       
   636 #define MAX1111_BATT_VOLT	1
       
   637 #define MAX1111_BATT_TEMP	2
       
   638 #define MAX1111_ACIN_VOLT	3
       
   639 
       
   640 #define SPITZ_BATTERY_TEMP	0xe0	/* About 2.9V */
       
   641 #define SPITZ_BATTERY_VOLT	0xd0	/* About 4.0V */
       
   642 #define SPITZ_CHARGEON_ACIN	0x80	/* About 5.0V */
       
   643 
       
   644 static void spitz_adc_temp_on(void *opaque, int line, int level)
       
   645 {
       
   646     if (!max1111)
       
   647         return;
       
   648 
       
   649     if (level)
       
   650         max111x_set_input(max1111, MAX1111_BATT_TEMP, SPITZ_BATTERY_TEMP);
       
   651     else
       
   652         max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
       
   653 }
       
   654 
       
   655 static void spitz_ssp_save(QEMUFile *f, void *opaque)
       
   656 {
       
   657     qemu_put_be32(f, lcd_en);
       
   658     qemu_put_be32(f, ads_en);
       
   659     qemu_put_be32(f, max_en);
       
   660     qemu_put_be32(f, bl_intensity);
       
   661     qemu_put_be32(f, bl_power);
       
   662 }
       
   663 
       
   664 static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id)
       
   665 {
       
   666     lcd_en = qemu_get_be32(f);
       
   667     ads_en = qemu_get_be32(f);
       
   668     max_en = qemu_get_be32(f);
       
   669     bl_intensity = qemu_get_be32(f);
       
   670     bl_power = qemu_get_be32(f);
       
   671 
       
   672     return 0;
       
   673 }
       
   674 
       
   675 static void spitz_ssp_attach(struct pxa2xx_state_s *cpu)
       
   676 {
       
   677     qemu_irq *chipselects;
       
   678 
       
   679     lcd_en = ads_en = max_en = 0;
       
   680 
       
   681     ads7846 = ads7846_init(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_TP_INT]);
       
   682 
       
   683     max1111 = max1111_init(0);
       
   684     max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT);
       
   685     max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
       
   686     max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN);
       
   687 
       
   688     pxa2xx_ssp_attach(cpu->ssp[CORGI_SSP_PORT - 1], corgi_ssp_read,
       
   689                     corgi_ssp_write, cpu);
       
   690 
       
   691     chipselects = qemu_allocate_irqs(corgi_ssp_gpio_cs, cpu, 3);
       
   692     pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_LCDCON_CS,  chipselects[0]);
       
   693     pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ADS7846_CS, chipselects[1]);
       
   694     pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_MAX1111_CS, chipselects[2]);
       
   695 
       
   696     bl_intensity = 0x20;
       
   697     bl_power = 0;
       
   698 
       
   699     register_savevm("spitz_ssp", 0, 0, spitz_ssp_save, spitz_ssp_load, cpu);
       
   700 }
       
   701 
       
   702 /* CF Microdrive */
       
   703 
       
   704 static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu, int slot)
       
   705 {
       
   706     struct pcmcia_card_s *md;
       
   707     int index;
       
   708     BlockDriverState *bs;
       
   709 
       
   710     index = drive_get_index(IF_IDE, 0, 0);
       
   711     if (index == -1)
       
   712         return;
       
   713     bs = drives_table[index].bdrv;
       
   714     if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
       
   715         md = dscm1xxxx_init(bs);
       
   716         pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
       
   717     }
       
   718 }
       
   719 
       
   720 /* Wm8750 and Max7310 on I2C */
       
   721 
       
   722 #define AKITA_MAX_ADDR	0x18
       
   723 #define SPITZ_WM_ADDRL	0x1b
       
   724 #define SPITZ_WM_ADDRH	0x1a
       
   725 
       
   726 #define SPITZ_GPIO_WM	5
       
   727 
       
   728 #ifdef HAS_AUDIO
       
   729 static void spitz_wm8750_addr(void *opaque, int line, int level)
       
   730 {
       
   731     i2c_slave *wm = (i2c_slave *) opaque;
       
   732     if (level)
       
   733         i2c_set_slave_address(wm, SPITZ_WM_ADDRH);
       
   734     else
       
   735         i2c_set_slave_address(wm, SPITZ_WM_ADDRL);
       
   736 }
       
   737 #endif
       
   738 
       
   739 static void spitz_i2c_setup(struct pxa2xx_state_s *cpu)
       
   740 {
       
   741     /* Attach the CPU on one end of our I2C bus.  */
       
   742     i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
       
   743 
       
   744 #ifdef HAS_AUDIO
       
   745     AudioState *audio;
       
   746     i2c_slave *wm;
       
   747 
       
   748     audio = AUD_init();
       
   749     if (!audio)
       
   750         return;
       
   751     /* Attach a WM8750 to the bus */
       
   752     wm = wm8750_init(bus, audio);
       
   753 
       
   754     spitz_wm8750_addr(wm, 0, 0);
       
   755     pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_WM,
       
   756                     qemu_allocate_irqs(spitz_wm8750_addr, wm, 1)[0]);
       
   757     /* .. and to the sound interface.  */
       
   758     cpu->i2s->opaque = wm;
       
   759     cpu->i2s->codec_out = wm8750_dac_dat;
       
   760     cpu->i2s->codec_in = wm8750_adc_dat;
       
   761     wm8750_data_req_set(wm, cpu->i2s->data_req, cpu->i2s);
       
   762 #endif
       
   763 }
       
   764 
       
   765 static void spitz_akita_i2c_setup(struct pxa2xx_state_s *cpu)
       
   766 {
       
   767     /* Attach a Max7310 to Akita I2C bus.  */
       
   768     i2c_set_slave_address(max7310_init(pxa2xx_i2c_bus(cpu->i2c[0])),
       
   769                     AKITA_MAX_ADDR);
       
   770 }
       
   771 
       
   772 /* Other peripherals */
       
   773 
       
   774 static void spitz_out_switch(void *opaque, int line, int level)
       
   775 {
       
   776     switch (line) {
       
   777     case 0:
       
   778         zaurus_printf("Charging %s.\n", level ? "off" : "on");
       
   779         break;
       
   780     case 1:
       
   781         zaurus_printf("Discharging %s.\n", level ? "on" : "off");
       
   782         break;
       
   783     case 2:
       
   784         zaurus_printf("Green LED %s.\n", level ? "on" : "off");
       
   785         break;
       
   786     case 3:
       
   787         zaurus_printf("Orange LED %s.\n", level ? "on" : "off");
       
   788         break;
       
   789     case 4:
       
   790         spitz_bl_bit5(opaque, line, level);
       
   791         break;
       
   792     case 5:
       
   793         spitz_bl_power(opaque, line, level);
       
   794         break;
       
   795     case 6:
       
   796         spitz_adc_temp_on(opaque, line, level);
       
   797         break;
       
   798     }
       
   799 }
       
   800 
       
   801 #define SPITZ_SCP_LED_GREEN		1
       
   802 #define SPITZ_SCP_JK_B			2
       
   803 #define SPITZ_SCP_CHRG_ON		3
       
   804 #define SPITZ_SCP_MUTE_L		4
       
   805 #define SPITZ_SCP_MUTE_R		5
       
   806 #define SPITZ_SCP_CF_POWER		6
       
   807 #define SPITZ_SCP_LED_ORANGE		7
       
   808 #define SPITZ_SCP_JK_A			8
       
   809 #define SPITZ_SCP_ADC_TEMP_ON		9
       
   810 #define SPITZ_SCP2_IR_ON		1
       
   811 #define SPITZ_SCP2_AKIN_PULLUP		2
       
   812 #define SPITZ_SCP2_BACKLIGHT_CONT	7
       
   813 #define SPITZ_SCP2_BACKLIGHT_ON		8
       
   814 #define SPITZ_SCP2_MIC_BIAS		9
       
   815 
       
   816 static void spitz_scoop_gpio_setup(struct pxa2xx_state_s *cpu,
       
   817                 struct scoop_info_s *scp0, struct scoop_info_s *scp1)
       
   818 {
       
   819     qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8);
       
   820 
       
   821     scoop_gpio_out_set(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
       
   822     scoop_gpio_out_set(scp0, SPITZ_SCP_JK_B, outsignals[1]);
       
   823     scoop_gpio_out_set(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
       
   824     scoop_gpio_out_set(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
       
   825 
       
   826     if (scp1) {
       
   827         scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
       
   828         scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
       
   829     }
       
   830 
       
   831     scoop_gpio_out_set(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
       
   832 }
       
   833 
       
   834 #define SPITZ_GPIO_HSYNC		22
       
   835 #define SPITZ_GPIO_SD_DETECT		9
       
   836 #define SPITZ_GPIO_SD_WP		81
       
   837 #define SPITZ_GPIO_ON_RESET		89
       
   838 #define SPITZ_GPIO_BAT_COVER		90
       
   839 #define SPITZ_GPIO_CF1_IRQ		105
       
   840 #define SPITZ_GPIO_CF1_CD		94
       
   841 #define SPITZ_GPIO_CF2_IRQ		106
       
   842 #define SPITZ_GPIO_CF2_CD		93
       
   843 
       
   844 static int spitz_hsync;
       
   845 
       
   846 static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
       
   847 {
       
   848     struct pxa2xx_state_s *cpu = (struct pxa2xx_state_s *) opaque;
       
   849     qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_HSYNC], spitz_hsync);
       
   850     spitz_hsync ^= 1;
       
   851 }
       
   852 
       
   853 static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots)
       
   854 {
       
   855     qemu_irq lcd_hsync;
       
   856     /*
       
   857      * Bad hack: We toggle the LCD hsync GPIO on every GPIO status
       
   858      * read to satisfy broken guests that poll-wait for hsync.
       
   859      * Simulating a real hsync event would be less practical and
       
   860      * wouldn't guarantee that a guest ever exits the loop.
       
   861      */
       
   862     spitz_hsync = 0;
       
   863     lcd_hsync = qemu_allocate_irqs(spitz_lcd_hsync_handler, cpu, 1)[0];
       
   864     pxa2xx_gpio_read_notifier(cpu->gpio, lcd_hsync);
       
   865     pxa2xx_lcd_vsync_notifier(cpu->lcd, lcd_hsync);
       
   866 
       
   867     /* MMC/SD host */
       
   868     pxa2xx_mmci_handlers(cpu->mmc,
       
   869                     pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SD_WP],
       
   870                     pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SD_DETECT]);
       
   871 
       
   872     /* Battery lock always closed */
       
   873     qemu_irq_raise(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_BAT_COVER]);
       
   874 
       
   875     /* Handle reset */
       
   876     pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ON_RESET, cpu->reset);
       
   877 
       
   878     /* PCMCIA signals: card's IRQ and Card-Detect */
       
   879     if (slots >= 1)
       
   880         pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
       
   881                         pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF1_IRQ],
       
   882                         pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF1_CD]);
       
   883     if (slots >= 2)
       
   884         pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
       
   885                         pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF2_IRQ],
       
   886                         pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF2_CD]);
       
   887 
       
   888     /* Initialise the screen rotation related signals */
       
   889     spitz_gpio_invert[3] = 0;	/* Always open */
       
   890     if (graphic_rotate) {	/* Tablet mode */
       
   891         spitz_gpio_invert[4] = 0;
       
   892     } else {			/* Portrait mode */
       
   893         spitz_gpio_invert[4] = 1;
       
   894     }
       
   895     qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SWA],
       
   896                     spitz_gpio_invert[3]);
       
   897     qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SWB],
       
   898                     spitz_gpio_invert[4]);
       
   899 }
       
   900 
       
   901 /* Board init.  */
       
   902 enum spitz_model_e { spitz, akita, borzoi, terrier };
       
   903 
       
   904 #define SPITZ_RAM	0x04000000
       
   905 #define SPITZ_ROM	0x00800000
       
   906 
       
   907 static struct arm_boot_info spitz_binfo = {
       
   908     .loader_start = PXA2XX_SDRAM_BASE,
       
   909     .ram_size = 0x04000000,
       
   910 };
       
   911 
       
   912 static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size,
       
   913                 DisplayState *ds, const char *kernel_filename,
       
   914                 const char *kernel_cmdline, const char *initrd_filename,
       
   915                 const char *cpu_model, enum spitz_model_e model, int arm_id)
       
   916 {
       
   917     struct pxa2xx_state_s *cpu;
       
   918     struct scoop_info_s *scp0, *scp1 = NULL;
       
   919 
       
   920     if (!cpu_model)
       
   921         cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
       
   922 
       
   923     /* Setup CPU & memory */
       
   924     if (ram_size < SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE) {
       
   925         fprintf(stderr, "This platform requires %i bytes of memory\n",
       
   926                         SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE);
       
   927         exit(1);
       
   928     }
       
   929     cpu = pxa270_init(spitz_binfo.ram_size, ds, cpu_model);
       
   930 
       
   931     sl_flash_register(cpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
       
   932 
       
   933     cpu_register_physical_memory(0, SPITZ_ROM,
       
   934                     qemu_ram_alloc(SPITZ_ROM) | IO_MEM_ROM);
       
   935 
       
   936     /* Setup peripherals */
       
   937     spitz_keyboard_register(cpu);
       
   938 
       
   939     spitz_ssp_attach(cpu);
       
   940 
       
   941     scp0 = scoop_init(cpu, 0, 0x10800000);
       
   942     if (model != akita) {
       
   943 	    scp1 = scoop_init(cpu, 1, 0x08800040);
       
   944     }
       
   945 
       
   946     spitz_scoop_gpio_setup(cpu, scp0, scp1);
       
   947 
       
   948     spitz_gpio_setup(cpu, (model == akita) ? 1 : 2);
       
   949 
       
   950     spitz_i2c_setup(cpu);
       
   951 
       
   952     if (model == akita)
       
   953         spitz_akita_i2c_setup(cpu);
       
   954 
       
   955     if (model == terrier)
       
   956         /* A 6.0 GB microdrive is permanently sitting in CF slot 1.  */
       
   957         spitz_microdrive_attach(cpu, 1);
       
   958     else if (model != akita)
       
   959         /* A 4.0 GB microdrive is permanently sitting in CF slot 0.  */
       
   960         spitz_microdrive_attach(cpu, 0);
       
   961 
       
   962     /* Setup initial (reset) machine state */
       
   963     cpu->env->regs[15] = spitz_binfo.loader_start;
       
   964 
       
   965     spitz_binfo.kernel_filename = kernel_filename;
       
   966     spitz_binfo.kernel_cmdline = kernel_cmdline;
       
   967     spitz_binfo.initrd_filename = initrd_filename;
       
   968     spitz_binfo.board_id = arm_id;
       
   969     arm_load_kernel(cpu->env, &spitz_binfo);
       
   970     sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_SDRAM_BASE);
       
   971 }
       
   972 
       
   973 static void spitz_init(ram_addr_t ram_size, int vga_ram_size,
       
   974                 const char *boot_device, DisplayState *ds,
       
   975                 const char *kernel_filename, const char *kernel_cmdline,
       
   976                 const char *initrd_filename, const char *cpu_model)
       
   977 {
       
   978     spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
       
   979                 kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9);
       
   980 }
       
   981 
       
   982 static void borzoi_init(ram_addr_t ram_size, int vga_ram_size,
       
   983                 const char *boot_device, DisplayState *ds,
       
   984                 const char *kernel_filename, const char *kernel_cmdline,
       
   985                 const char *initrd_filename, const char *cpu_model)
       
   986 {
       
   987     spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
       
   988                 kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f);
       
   989 }
       
   990 
       
   991 static void akita_init(ram_addr_t ram_size, int vga_ram_size,
       
   992                 const char *boot_device, DisplayState *ds,
       
   993                 const char *kernel_filename, const char *kernel_cmdline,
       
   994                 const char *initrd_filename, const char *cpu_model)
       
   995 {
       
   996     spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
       
   997                 kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8);
       
   998 }
       
   999 
       
  1000 static void terrier_init(ram_addr_t ram_size, int vga_ram_size,
       
  1001                 const char *boot_device, DisplayState *ds,
       
  1002                 const char *kernel_filename, const char *kernel_cmdline,
       
  1003                 const char *initrd_filename, const char *cpu_model)
       
  1004 {
       
  1005     spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
       
  1006                 kernel_cmdline, initrd_filename, cpu_model, terrier, 0x33f);
       
  1007 }
       
  1008 
       
  1009 QEMUMachine akitapda_machine = {
       
  1010     .name = "akita",
       
  1011     .desc = "Akita PDA (PXA270)",
       
  1012     .init = akita_init,
       
  1013     .ram_require = SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED,
       
  1014 };
       
  1015 
       
  1016 QEMUMachine spitzpda_machine = {
       
  1017     .name = "spitz",
       
  1018     .desc = "Spitz PDA (PXA270)",
       
  1019     .init = spitz_init,
       
  1020     .ram_require = SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED,
       
  1021 };
       
  1022 
       
  1023 QEMUMachine borzoipda_machine = {
       
  1024     .name = "borzoi",
       
  1025     .desc = "Borzoi PDA (PXA270)",
       
  1026     .init = borzoi_init,
       
  1027     .ram_require = SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED,
       
  1028 };
       
  1029 
       
  1030 QEMUMachine terrierpda_machine = {
       
  1031     .name = "terrier",
       
  1032     .desc = "Terrier PDA (PXA270)",
       
  1033     .init = terrier_init,
       
  1034     .ram_require = SPITZ_RAM + SPITZ_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED,
       
  1035 };