Commit 05ee37ebf630fa970feb362671a5aee22bcb529f

Authored by balrog
1 parent 7f1559c6

Gumstix 'connex' board support by Thorsten Zitterell.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3667 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -499,6 +499,7 @@ VL_OBJS+= ssd0323.o pl061.o
499 499 VL_OBJS+= arm-semi.o
500 500 VL_OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
501 501 VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o max111x.o max7310.o
  502 +VL_OBJS+= pflash_cfi01.o gumstix.o
502 503 VL_OBJS+= spitz.o ads7846.o ide.o serial.o nand.o ecc.o wm8750.o
503 504 VL_OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o omap_i2c.o
504 505 VL_OBJS+= palm.o tsc210x.o
... ...
hw/gumstix.c 0 → 100644
  1 +/*
  2 + * Gumstix Platforms
  3 + *
  4 + * Copyright (c) 2007 by Thorsten Zitterell <info@bitmux.org>
  5 + *
  6 + * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
  7 + *
  8 + * This code is licensed under the GNU GPL v2.
  9 + */
  10 +
  11 +#include "vl.h"
  12 +
  13 +static void connex_smc_irq(void *opaque, int line, int level)
  14 +{
  15 + /* Interrupt line of NIC is connected to GPIO line 36 */
  16 + struct pxa2xx_state_s *cpu = (struct pxa2xx_state_s *) opaque;
  17 + pxa2xx_gpio_set(cpu->gpio, 36, level);
  18 +}
  19 +
  20 +/* Board init. */
  21 +enum gumstix_model_e { connex };
  22 +
  23 +static void gumstix_common_init(int ram_size, int vga_ram_size,
  24 + DisplayState *ds, const char *kernel_filename,
  25 + const char *kernel_cmdline, const char *initrd_filename,
  26 + const char *cpu_model, enum gumstix_model_e model)
  27 +{
  28 + struct pxa2xx_state_s *cpu;
  29 +
  30 + uint32_t gumstix_rom = 0x02000000;
  31 + uint32_t gumstix_ram = 0x08000000;
  32 +
  33 + if (ram_size < (gumstix_ram + gumstix_rom + PXA2XX_INTERNAL_SIZE)) {
  34 + fprintf(stderr, "This platform requires %i bytes of memory\n",
  35 + gumstix_ram + gumstix_rom + PXA2XX_INTERNAL_SIZE);
  36 + exit(1);
  37 + }
  38 +
  39 + cpu = pxa255_init(gumstix_ram, ds);
  40 +
  41 + if (pflash_table[0] == NULL) {
  42 + fprintf(stderr, "A flash image must be given with the "
  43 + "'pflash' parameter\n");
  44 + exit(1);
  45 + }
  46 +
  47 + if (!pflash_register(0x00000000, gumstix_ram + PXA2XX_INTERNAL_SIZE,
  48 + pflash_table[0], 128 * 1024, 128, 2, 0, 0, 0, 0)) {
  49 + fprintf(stderr, "qemu: Error register flash memory.\n");
  50 + exit(1);
  51 + }
  52 +
  53 + cpu->env->regs[15] = 0x00000000;
  54 +
  55 + qemu_irq *irq = qemu_allocate_irqs(connex_smc_irq, cpu, 1);
  56 + smc91c111_init(&nd_table[0], 0x04000300, *irq);
  57 +}
  58 +
  59 +static void connex_init(int ram_size, int vga_ram_size,
  60 + const char *boot_device, DisplayState *ds,
  61 + const char **fd_filename, int snapshot,
  62 + const char *kernel_filename, const char *kernel_cmdline,
  63 + const char *initrd_filename, const char *cpu_model)
  64 +{
  65 + gumstix_common_init(ram_size, vga_ram_size, ds, kernel_filename,
  66 + kernel_cmdline, initrd_filename, cpu_model, connex);
  67 +}
  68 +
  69 +QEMUMachine connex_machine = {
  70 + "connex",
  71 + "Gumstix Connex (PXA255)",
  72 + connex_init,
  73 +};
... ...
hw/pflash_cfi01.c 0 → 100644
  1 +/*
  2 + * CFI parallel flash with Intel command set emulation
  3 + *
  4 + * Copyright (c) 2006 Thorsten Zitterell
  5 + * Copyright (c) 2005 Jocelyn Mayer
  6 + *
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
  11 + *
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 + */
  21 +
  22 +/*
  23 + * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
  24 + * Supported commands/modes are:
  25 + * - flash read
  26 + * - flash write
  27 + * - flash ID read
  28 + * - sector erase
  29 + * - CFI queries
  30 + *
  31 + * It does not support timings
  32 + * It does not support flash interleaving
  33 + * It does not implement software data protection as found in many real chips
  34 + * It does not implement erase suspend/resume commands
  35 + * It does not implement multiple sectors erase
  36 + *
  37 + * It does not implement much more ...
  38 + */
  39 +
  40 +#include "vl.h"
  41 +
  42 +#define PFLASH_BUG(fmt, args...) \
  43 +do { \
  44 + printf("PFLASH: Possible BUG - " fmt, ##args); \
  45 + exit(1); \
  46 +} while(0)
  47 +
  48 +/* #define PFLASH_DEBUG */
  49 +#ifdef PFLASH_DEBUG
  50 +#define DPRINTF(fmt, args...) \
  51 +do { \
  52 + printf("PFLASH: " fmt , ##args); \
  53 +} while (0)
  54 +#else
  55 +#define DPRINTF(fmt, args...) do { } while (0)
  56 +#endif
  57 +
  58 +struct pflash_t {
  59 + BlockDriverState *bs;
  60 + target_ulong base;
  61 + target_ulong sector_len;
  62 + target_ulong total_len;
  63 + int width;
  64 + int wcycle; /* if 0, the flash is read normally */
  65 + int bypass;
  66 + int ro;
  67 + uint8_t cmd;
  68 + uint8_t status;
  69 + uint16_t ident[4];
  70 + uint8_t cfi_len;
  71 + uint8_t cfi_table[0x52];
  72 + target_ulong counter;
  73 + QEMUTimer *timer;
  74 + ram_addr_t off;
  75 + int fl_mem;
  76 + void *storage;
  77 +};
  78 +
  79 +static void pflash_timer (void *opaque)
  80 +{
  81 + pflash_t *pfl = opaque;
  82 +
  83 + DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
  84 + /* Reset flash */
  85 + pfl->status ^= 0x80;
  86 + if (pfl->bypass) {
  87 + pfl->wcycle = 2;
  88 + } else {
  89 + cpu_register_physical_memory(pfl->base, pfl->total_len,
  90 + pfl->off | IO_MEM_ROMD | pfl->fl_mem);
  91 + pfl->wcycle = 0;
  92 + }
  93 + pfl->cmd = 0;
  94 +}
  95 +
  96 +static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width)
  97 +{
  98 + target_ulong boff;
  99 + uint32_t ret;
  100 + uint8_t *p;
  101 +
  102 + ret = -1;
  103 + offset -= pfl->base;
  104 + boff = offset & 0xFF; /* why this here ?? */
  105 +
  106 + if (pfl->width == 2)
  107 + boff = boff >> 1;
  108 + else if (pfl->width == 4)
  109 + boff = boff >> 2;
  110 +
  111 + DPRINTF("%s: reading offset %08x under cmd %02x\n",
  112 + __func__, boff, pfl->cmd);
  113 +
  114 + switch (pfl->cmd) {
  115 + case 0x00:
  116 + /* Flash area read */
  117 + p = pfl->storage;
  118 + switch (width) {
  119 + case 1:
  120 + ret = p[offset];
  121 + DPRINTF("%s: data offset %08x %02x\n", __func__, offset, ret);
  122 + break;
  123 + case 2:
  124 +#if defined(TARGET_WORDS_BIGENDIAN)
  125 + ret = p[offset] << 8;
  126 + ret |= p[offset + 1];
  127 +#else
  128 + ret = p[offset];
  129 + ret |= p[offset + 1] << 8;
  130 +#endif
  131 + DPRINTF("%s: data offset %08x %04x\n", __func__, offset, ret);
  132 + break;
  133 + case 4:
  134 +#if defined(TARGET_WORDS_BIGENDIAN)
  135 + ret = p[offset] << 24;
  136 + ret |= p[offset + 1] << 16;
  137 + ret |= p[offset + 2] << 8;
  138 + ret |= p[offset + 3];
  139 +#else
  140 + ret = p[offset];
  141 + ret |= p[offset + 1] << 8;
  142 + ret |= p[offset + 1] << 8;
  143 + ret |= p[offset + 2] << 16;
  144 + ret |= p[offset + 3] << 24;
  145 +#endif
  146 + DPRINTF("%s: data offset %08x %08x\n", __func__, offset, ret);
  147 + break;
  148 + default:
  149 + DPRINTF("BUG in %s\n", __func__);
  150 + }
  151 +
  152 + break;
  153 + case 0x20: /* Block erase */
  154 + case 0x50: /* Clear status register */
  155 + case 0x60: /* Block /un)lock */
  156 + case 0x70: /* Status Register */
  157 + case 0xe8: /* Write block */
  158 + /* Status register read */
  159 + ret = pfl->status;
  160 + DPRINTF("%s: status %x\n", __func__, ret);
  161 + break;
  162 + case 0x98: /* Query mode */
  163 + if (boff > pfl->cfi_len)
  164 + ret = 0;
  165 + else
  166 + ret = pfl->cfi_table[boff];
  167 + break;
  168 + default:
  169 + /* This should never happen : reset state & treat it as a read */
  170 + DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
  171 + pfl->wcycle = 0;
  172 + pfl->cmd = 0;
  173 + }
  174 + return ret;
  175 +}
  176 +
  177 +/* update flash content on disk */
  178 +static void pflash_update(pflash_t *pfl, int offset,
  179 + int size)
  180 +{
  181 + int offset_end;
  182 + if (pfl->bs) {
  183 + offset_end = offset + size;
  184 + /* round to sectors */
  185 + offset = offset >> 9;
  186 + offset_end = (offset_end + 511) >> 9;
  187 + bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
  188 + offset_end - offset);
  189 + }
  190 +}
  191 +
  192 +static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
  193 + int width)
  194 +{
  195 + target_ulong boff;
  196 + uint8_t *p;
  197 + uint8_t cmd;
  198 +
  199 + /* WARNING: when the memory area is in ROMD mode, the offset is a
  200 + ram offset, not a physical address */
  201 + cmd = value;
  202 +
  203 + if (pfl->wcycle == 0)
  204 + offset -= (target_ulong)(long)pfl->storage;
  205 + else
  206 + offset -= pfl->base;
  207 +
  208 + DPRINTF("%s: offset %08x %08x %d wcycle 0x%x\n",
  209 + __func__, offset, value, width, pfl->wcycle);
  210 +
  211 + /* Set the device in I/O access mode */
  212 + cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
  213 + boff = offset & (pfl->sector_len - 1);
  214 +
  215 + if (pfl->width == 2)
  216 + boff = boff >> 1;
  217 + else if (pfl->width == 4)
  218 + boff = boff >> 2;
  219 +
  220 + switch (pfl->wcycle) {
  221 + case 0:
  222 + /* read mode */
  223 + switch (cmd) {
  224 + case 0x00: /* ??? */
  225 + goto reset_flash;
  226 + case 0x20: /* Block erase */
  227 + p = pfl->storage;
  228 + offset &= ~(pfl->sector_len - 1);
  229 +
  230 + DPRINTF("%s: block erase at 0x%x bytes 0x%x\n", __func__,
  231 + offset, pfl->sector_len);
  232 +
  233 + memset(p + offset, 0xff, pfl->sector_len);
  234 + pflash_update(pfl, offset, pfl->sector_len);
  235 + pfl->status |= 0x80; /* Ready! */
  236 + break;
  237 + case 0x50: /* Clear status bits */
  238 + DPRINTF("%s: Clear status bits\n", __func__);
  239 + pfl->status = 0x0;
  240 + goto reset_flash;
  241 + case 0x60: /* Block (un)lock */
  242 + DPRINTF("%s: Block unlock\n", __func__);
  243 + break;
  244 + case 0x70: /* Status Register */
  245 + DPRINTF("%s: Read status register\n", __func__);
  246 + pfl->cmd = cmd;
  247 + return;
  248 + case 0x98: /* CFI query */
  249 + DPRINTF("%s: CFI query\n", __func__);
  250 + break;
  251 + case 0xe8: /* Write to buffer */
  252 + DPRINTF("%s: Write to buffer\n", __func__);
  253 + pfl->status |= 0x80; /* Ready! */
  254 + break;
  255 + case 0xff: /* Read array mode */
  256 + DPRINTF("%s: Read array mode\n", __func__);
  257 + goto reset_flash;
  258 + default:
  259 + goto error_flash;
  260 + }
  261 + pfl->wcycle++;
  262 + pfl->cmd = cmd;
  263 + return;
  264 + case 1:
  265 + switch (pfl->cmd) {
  266 + case 0x20: /* Block erase */
  267 + case 0x28:
  268 + if (cmd == 0xd0) { /* confirm */
  269 + pfl->wcycle = 1;
  270 + pfl->status |= 0x80;
  271 + } if (cmd == 0xff) { /* read array mode */
  272 + goto reset_flash;
  273 + } else
  274 + goto error_flash;
  275 +
  276 + break;
  277 + case 0xe8:
  278 + DPRINTF("%s: block write of 0x%x bytes\n", __func__, cmd);
  279 + pfl->counter = cmd;
  280 + pfl->wcycle++;
  281 + break;
  282 + case 0x60:
  283 + if (cmd == 0xd0) {
  284 + pfl->wcycle = 0;
  285 + pfl->status |= 0x80;
  286 + } else if (cmd == 0x01) {
  287 + pfl->wcycle = 0;
  288 + pfl->status |= 0x80;
  289 + } else if (cmd == 0xff) {
  290 + goto reset_flash;
  291 + } else {
  292 + DPRINTF("%s: Unknown (un)locking command\n", __func__);
  293 + goto reset_flash;
  294 + }
  295 + break;
  296 + case 0x98:
  297 + if (cmd == 0xff) {
  298 + goto reset_flash;
  299 + } else {
  300 + DPRINTF("%s: leaving query mode\n", __func__);
  301 + }
  302 + break;
  303 + default:
  304 + goto error_flash;
  305 + }
  306 + return;
  307 + case 2:
  308 + switch (pfl->cmd) {
  309 + case 0xe8: /* Block write */
  310 + p = pfl->storage;
  311 + DPRINTF("%s: block write offset 0x%x value 0x%x counter 0x%x\n",
  312 + __func__, offset, value, pfl->counter);
  313 + switch (width) {
  314 + case 1:
  315 + p[offset] = value;
  316 + pflash_update(pfl, offset, 1);
  317 + break;
  318 + case 2:
  319 +#if defined(TARGET_WORDS_BIGENDIAN)
  320 + p[offset] = value >> 8;
  321 + p[offset + 1] = value;
  322 +#else
  323 + p[offset] = value;
  324 + p[offset + 1] = value >> 8;
  325 +#endif
  326 + pflash_update(pfl, offset, 2);
  327 + break;
  328 + case 4:
  329 +#if defined(TARGET_WORDS_BIGENDIAN)
  330 + p[offset] = value >> 24;
  331 + p[offset + 1] = value >> 16;
  332 + p[offset + 2] = value >> 8;
  333 + p[offset + 3] = value;
  334 +#else
  335 + p[offset] = value;
  336 + p[offset + 1] = value >> 8;
  337 + p[offset + 2] = value >> 16;
  338 + p[offset + 3] = value >> 24;
  339 +#endif
  340 + pflash_update(pfl, offset, 4);
  341 + break;
  342 + }
  343 +
  344 + pfl->status |= 0x80;
  345 +
  346 + if (!pfl->counter) {
  347 + DPRINTF("%s: block write finished\n", __func__);
  348 + pfl->wcycle++;
  349 + }
  350 +
  351 + pfl->counter--;
  352 + break;
  353 + }
  354 + return;
  355 + case 3: /* Confirm mode */
  356 + switch (pfl->cmd) {
  357 + case 0xe8: /* Block write */
  358 + if (cmd == 0xd0) {
  359 + pfl->wcycle = 0;
  360 + pfl->status |= 0x80;
  361 + break;
  362 + } else {
  363 + DPRINTF("%s: unknown command for \"write block\"\n", __func__);
  364 + PFLASH_BUG("Write block confirm");
  365 + }
  366 + }
  367 + return;
  368 + default:
  369 + /* Should never happen */
  370 + DPRINTF("%s: invalid write state\n", __func__);
  371 + goto reset_flash;
  372 + }
  373 + return;
  374 +
  375 + error_flash:
  376 + printf("%s: Unimplemented flash cmd sequence "
  377 + "(offset 0x%x, wcycle 0x%x cmd 0x%x value 0x%x\n",
  378 + __func__, offset, pfl->wcycle, pfl->cmd, value);
  379 +
  380 + reset_flash:
  381 + cpu_register_physical_memory(pfl->base, pfl->total_len,
  382 + pfl->off | IO_MEM_ROMD | pfl->fl_mem);
  383 +
  384 + pfl->bypass = 0;
  385 + pfl->wcycle = 0;
  386 + pfl->cmd = 0;
  387 + return;
  388 +}
  389 +
  390 +
  391 +static uint32_t pflash_readb (void *opaque, target_phys_addr_t addr)
  392 +{
  393 + return pflash_read(opaque, addr, 1);
  394 +}
  395 +
  396 +static uint32_t pflash_readw (void *opaque, target_phys_addr_t addr)
  397 +{
  398 + pflash_t *pfl = opaque;
  399 +
  400 + return pflash_read(pfl, addr, 2);
  401 +}
  402 +
  403 +static uint32_t pflash_readl (void *opaque, target_phys_addr_t addr)
  404 +{
  405 + pflash_t *pfl = opaque;
  406 +
  407 + return pflash_read(pfl, addr, 4);
  408 +}
  409 +
  410 +static void pflash_writeb (void *opaque, target_phys_addr_t addr,
  411 + uint32_t value)
  412 +{
  413 + pflash_write(opaque, addr, value, 1);
  414 +}
  415 +
  416 +static void pflash_writew (void *opaque, target_phys_addr_t addr,
  417 + uint32_t value)
  418 +{
  419 + pflash_t *pfl = opaque;
  420 +
  421 + pflash_write(pfl, addr, value, 2);
  422 +}
  423 +
  424 +static void pflash_writel (void *opaque, target_phys_addr_t addr,
  425 + uint32_t value)
  426 +{
  427 + pflash_t *pfl = opaque;
  428 +
  429 + pflash_write(pfl, addr, value, 4);
  430 +}
  431 +
  432 +static CPUWriteMemoryFunc *pflash_write_ops[] = {
  433 + &pflash_writeb,
  434 + &pflash_writew,
  435 + &pflash_writel,
  436 +};
  437 +
  438 +static CPUReadMemoryFunc *pflash_read_ops[] = {
  439 + &pflash_readb,
  440 + &pflash_readw,
  441 + &pflash_readl,
  442 +};
  443 +
  444 +/* Count trailing zeroes of a 32 bits quantity */
  445 +static int ctz32 (uint32_t n)
  446 +{
  447 + int ret;
  448 +
  449 + ret = 0;
  450 + if (!(n & 0xFFFF)) {
  451 + ret += 16;
  452 + n = n >> 16;
  453 + }
  454 + if (!(n & 0xFF)) {
  455 + ret += 8;
  456 + n = n >> 8;
  457 + }
  458 + if (!(n & 0xF)) {
  459 + ret += 4;
  460 + n = n >> 4;
  461 + }
  462 + if (!(n & 0x3)) {
  463 + ret += 2;
  464 + n = n >> 2;
  465 + }
  466 + if (!(n & 0x1)) {
  467 + ret++;
  468 + n = n >> 1;
  469 + }
  470 +#if 0 /* This is not necessary as n is never 0 */
  471 + if (!n)
  472 + ret++;
  473 +#endif
  474 +
  475 + return ret;
  476 +}
  477 +
  478 +pflash_t *pflash_register (target_phys_addr_t base, ram_addr_t off,
  479 + BlockDriverState *bs,
  480 + target_ulong sector_len, int nb_blocs, int width,
  481 + uint16_t id0, uint16_t id1,
  482 + uint16_t id2, uint16_t id3)
  483 +{
  484 + pflash_t *pfl;
  485 + target_long total_len;
  486 +
  487 + total_len = sector_len * nb_blocs;
  488 +
  489 + /* XXX: to be fixed */
  490 + if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
  491 + total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
  492 + return NULL;
  493 +
  494 + pfl = qemu_mallocz(sizeof(pflash_t));
  495 +
  496 + if (pfl == NULL)
  497 + return NULL;
  498 + pfl->storage = phys_ram_base + off;
  499 + pfl->fl_mem = cpu_register_io_memory(0,
  500 + pflash_read_ops, pflash_write_ops, pfl);
  501 + pfl->off = off;
  502 + cpu_register_physical_memory(base, total_len,
  503 + off | pfl->fl_mem | IO_MEM_ROMD);
  504 +
  505 + pfl->bs = bs;
  506 + if (pfl->bs) {
  507 + /* read the initial flash content */
  508 + bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
  509 + }
  510 +#if 0 /* XXX: there should be a bit to set up read-only,
  511 + * the same way the hardware does (with WP pin).
  512 + */
  513 + pfl->ro = 1;
  514 +#else
  515 + pfl->ro = 0;
  516 +#endif
  517 + pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl);
  518 + pfl->base = base;
  519 + pfl->sector_len = sector_len;
  520 + pfl->total_len = total_len;
  521 + pfl->width = width;
  522 + pfl->wcycle = 0;
  523 + pfl->cmd = 0;
  524 + pfl->status = 0;
  525 + pfl->ident[0] = id0;
  526 + pfl->ident[1] = id1;
  527 + pfl->ident[2] = id2;
  528 + pfl->ident[3] = id3;
  529 + /* Hardcoded CFI table */
  530 + pfl->cfi_len = 0x52;
  531 + /* Standard "QRY" string */
  532 + pfl->cfi_table[0x10] = 'Q';
  533 + pfl->cfi_table[0x11] = 'R';
  534 + pfl->cfi_table[0x12] = 'Y';
  535 + /* Command set (Intel) */
  536 + pfl->cfi_table[0x13] = 0x01;
  537 + pfl->cfi_table[0x14] = 0x00;
  538 + /* Primary extended table address (none) */
  539 + pfl->cfi_table[0x15] = 0x31;
  540 + pfl->cfi_table[0x16] = 0x00;
  541 + /* Alternate command set (none) */
  542 + pfl->cfi_table[0x17] = 0x00;
  543 + pfl->cfi_table[0x18] = 0x00;
  544 + /* Alternate extended table (none) */
  545 + pfl->cfi_table[0x19] = 0x00;
  546 + pfl->cfi_table[0x1A] = 0x00;
  547 + /* Vcc min */
  548 + pfl->cfi_table[0x1B] = 0x45;
  549 + /* Vcc max */
  550 + pfl->cfi_table[0x1C] = 0x55;
  551 + /* Vpp min (no Vpp pin) */
  552 + pfl->cfi_table[0x1D] = 0x00;
  553 + /* Vpp max (no Vpp pin) */
  554 + pfl->cfi_table[0x1E] = 0x00;
  555 + /* Reserved */
  556 + pfl->cfi_table[0x1F] = 0x07;
  557 + /* Timeout for min size buffer write */
  558 + pfl->cfi_table[0x20] = 0x07;
  559 + /* Typical timeout for block erase */
  560 + pfl->cfi_table[0x21] = 0x0a;
  561 + /* Typical timeout for full chip erase (4096 ms) */
  562 + pfl->cfi_table[0x22] = 0x00;
  563 + /* Reserved */
  564 + pfl->cfi_table[0x23] = 0x04;
  565 + /* Max timeout for buffer write */
  566 + pfl->cfi_table[0x24] = 0x04;
  567 + /* Max timeout for block erase */
  568 + pfl->cfi_table[0x25] = 0x04;
  569 + /* Max timeout for chip erase */
  570 + pfl->cfi_table[0x26] = 0x00;
  571 + /* Device size */
  572 + pfl->cfi_table[0x27] = ctz32(total_len); // + 1;
  573 + /* Flash device interface (8 & 16 bits) */
  574 + pfl->cfi_table[0x28] = 0x02;
  575 + pfl->cfi_table[0x29] = 0x00;
  576 + /* Max number of bytes in multi-bytes write */
  577 + pfl->cfi_table[0x2A] = 0x04;
  578 + pfl->cfi_table[0x2B] = 0x00;
  579 + /* Number of erase block regions (uniform) */
  580 + pfl->cfi_table[0x2C] = 0x01;
  581 + /* Erase block region 1 */
  582 + pfl->cfi_table[0x2D] = nb_blocs - 1;
  583 + pfl->cfi_table[0x2E] = (nb_blocs - 1) >> 8;
  584 + pfl->cfi_table[0x2F] = sector_len >> 8;
  585 + pfl->cfi_table[0x30] = sector_len >> 16;
  586 +
  587 + /* Extended */
  588 + pfl->cfi_table[0x31] = 'P';
  589 + pfl->cfi_table[0x32] = 'R';
  590 + pfl->cfi_table[0x33] = 'I';
  591 +
  592 + pfl->cfi_table[0x34] = '1';
  593 + pfl->cfi_table[0x35] = '1';
  594 +
  595 + pfl->cfi_table[0x36] = 0x00;
  596 + pfl->cfi_table[0x37] = 0x00;
  597 + pfl->cfi_table[0x38] = 0x00;
  598 + pfl->cfi_table[0x39] = 0x00;
  599 +
  600 + pfl->cfi_table[0x3a] = 0x00;
  601 +
  602 + pfl->cfi_table[0x3b] = 0x00;
  603 + pfl->cfi_table[0x3c] = 0x00;
  604 +
  605 + return pfl;
  606 +}
... ...
... ... @@ -7435,6 +7435,7 @@ void register_machines(void)
7435 7435 qemu_register_machine(&palmte_machine);
7436 7436 qemu_register_machine(&lm3s811evb_machine);
7437 7437 qemu_register_machine(&lm3s6965evb_machine);
  7438 + qemu_register_machine(&connex_machine);
7438 7439 #elif defined(TARGET_SH4)
7439 7440 qemu_register_machine(&shix_machine);
7440 7441 qemu_register_machine(&r2d_machine);
... ... @@ -8260,7 +8261,8 @@ int main(int argc, char **argv)
8260 8261 if (!linux_boot && net_boot == 0 &&
8261 8262 hd_filename[0] == '\0' &&
8262 8263 (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
8263   - fd_filename[0] == '\0')
  8264 + fd_filename[0] == '\0' &&
  8265 + pflash_filename[0] == '\0')
8264 8266 help(1);
8265 8267  
8266 8268 /* boot to floppy or the default cd if no hard disk defined yet */
... ...
... ... @@ -1254,6 +1254,9 @@ extern QEMUMachine spitzpda_machine;
1254 1254 extern QEMUMachine borzoipda_machine;
1255 1255 extern QEMUMachine terrierpda_machine;
1256 1256  
  1257 +/* gumstix.c */
  1258 +extern QEMUMachine connex_machine;
  1259 +
1257 1260 /* palm.c */
1258 1261 extern QEMUMachine palmte_machine;
1259 1262  
... ...