~ubuntu-branches/ubuntu/raring/qemu-kvm/raring

« back to all changes in this revision

Viewing changes to hw/pflash_cfi02.c

  • Committer: Serge Hallyn
  • Date: 2011-12-06 22:40:24 UTC
  • mfrom: (1.2.8)
  • Revision ID: serge.hallyn@ubuntu.com-20111206224024-x6bw4wnn65pgf55v
Tags: 1.0+noroms-0ubuntu1
* New upstream release
* Remaining changes from upstream:
  - removed all binary roms and tests/pi_10.com
* debian/qemu-kvm.links: qemu is now called qemu-system-i386, don't symlink
  it
* remove patches applied upstream:
  - debian/patches/vpc.patch
  - debian/patches/e1000-Dont-set-the-Capabilities-List-bit.patch
  - debian/patches/CVE-2011-4111.patch
* replace default-to-tcg.patch with simpler fallback-to-tcg.patch
* keep remaining patches:
  - larger_default_ram_size.patch
  - CVE-2011-2212-virtqueue-indirect-overflow.patch
  - qemuifup-fix-paths.patch
  - dont-try-to-hotplug-cpu.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "flash.h"
40
40
#include "qemu-timer.h"
41
41
#include "block.h"
 
42
#include "exec-memory.h"
42
43
 
43
44
//#define PFLASH_DEBUG
44
45
#ifdef PFLASH_DEBUG
69
70
    uint8_t cfi_len;
70
71
    uint8_t cfi_table[0x52];
71
72
    QEMUTimer *timer;
72
 
    ram_addr_t off;
73
 
    int fl_mem;
 
73
    /* The device replicates the flash memory across its memory space.  Emulate
 
74
     * that by having a container (.mem) filled with an array of aliases
 
75
     * (.mem_mappings) pointing to the flash memory (.orig_mem).
 
76
     */
 
77
    MemoryRegion mem;
 
78
    MemoryRegion *mem_mappings;    /* array; one per mapping */
 
79
    MemoryRegion orig_mem;
74
80
    int rom_mode;
75
81
    int read_counter; /* used for lazy switch-back to rom mode */
76
82
    void *storage;
77
83
};
78
84
 
 
85
/*
 
86
 * Set up replicated mappings of the same region.
 
87
 */
 
88
static void pflash_setup_mappings(pflash_t *pfl)
 
89
{
 
90
    unsigned i;
 
91
    target_phys_addr_t size = memory_region_size(&pfl->orig_mem);
 
92
 
 
93
    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
 
94
    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
 
95
    for (i = 0; i < pfl->mappings; ++i) {
 
96
        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias",
 
97
                                 &pfl->orig_mem, 0, size);
 
98
        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
 
99
    }
 
100
}
 
101
 
79
102
static void pflash_register_memory(pflash_t *pfl, int rom_mode)
80
103
{
81
 
    unsigned long phys_offset = pfl->fl_mem;
82
 
    int i;
83
 
 
84
 
    if (rom_mode)
85
 
        phys_offset |= pfl->off | IO_MEM_ROMD;
86
 
    pfl->rom_mode = rom_mode;
87
 
 
88
 
    for (i = 0; i < pfl->mappings; i++)
89
 
        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
90
 
                                     pfl->chip_len, phys_offset);
 
104
    memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
91
105
}
92
106
 
93
107
static void pflash_timer (void *opaque)
538
552
    pflash_write(pfl, addr, value, 4, 0);
539
553
}
540
554
 
541
 
static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
542
 
    &pflash_writeb_be,
543
 
    &pflash_writew_be,
544
 
    &pflash_writel_be,
545
 
};
546
 
 
547
 
static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
548
 
    &pflash_readb_be,
549
 
    &pflash_readw_be,
550
 
    &pflash_readl_be,
551
 
};
552
 
 
553
 
static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
554
 
    &pflash_writeb_le,
555
 
    &pflash_writew_le,
556
 
    &pflash_writel_le,
557
 
};
558
 
 
559
 
static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
560
 
    &pflash_readb_le,
561
 
    &pflash_readw_le,
562
 
    &pflash_readl_le,
 
555
static const MemoryRegionOps pflash_cfi02_ops_be = {
 
556
    .old_mmio = {
 
557
        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
 
558
        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
 
559
    },
 
560
    .endianness = DEVICE_NATIVE_ENDIAN,
 
561
};
 
562
 
 
563
static const MemoryRegionOps pflash_cfi02_ops_le = {
 
564
    .old_mmio = {
 
565
        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
 
566
        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
 
567
    },
 
568
    .endianness = DEVICE_NATIVE_ENDIAN,
563
569
};
564
570
 
565
571
/* Count trailing zeroes of a 32 bits quantity */
598
604
    return ret;
599
605
}
600
606
 
601
 
pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
 
607
pflash_t *pflash_cfi02_register(target_phys_addr_t base,
 
608
                                DeviceState *qdev, const char *name,
 
609
                                target_phys_addr_t size,
602
610
                                BlockDriverState *bs, uint32_t sector_len,
603
611
                                int nb_blocs, int nb_mappings, int width,
604
612
                                uint16_t id0, uint16_t id1,
617
625
        total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
618
626
        return NULL;
619
627
#endif
620
 
    pfl = qemu_mallocz(sizeof(pflash_t));
621
 
    /* FIXME: Allocate ram ourselves.  */
622
 
    pfl->storage = qemu_get_ram_ptr(off);
623
 
    if (be) {
624
 
        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
625
 
                                             pflash_write_ops_be,
626
 
                                             pfl, DEVICE_NATIVE_ENDIAN);
627
 
    } else {
628
 
        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
629
 
                                             pflash_write_ops_le,
630
 
                                             pfl, DEVICE_NATIVE_ENDIAN);
631
 
    }
632
 
    pfl->off = off;
 
628
    pfl = g_malloc0(sizeof(pflash_t));
 
629
    memory_region_init_rom_device(
 
630
        &pfl->orig_mem, be ? &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, pfl,
 
631
        qdev, name, size);
 
632
    pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
633
633
    pfl->base = base;
634
634
    pfl->chip_len = chip_len;
635
635
    pfl->mappings = nb_mappings;
636
 
    pflash_register_memory(pfl, 1);
637
636
    pfl->bs = bs;
638
637
    if (pfl->bs) {
639
638
        /* read the initial flash content */
640
639
        ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
641
640
        if (ret < 0) {
642
 
            cpu_unregister_io_memory(pfl->fl_mem);
643
 
            qemu_free(pfl);
 
641
            g_free(pfl);
644
642
            return NULL;
645
643
        }
 
644
        bdrv_attach_dev_nofail(pfl->bs, pfl);
646
645
    }
 
646
    pflash_setup_mappings(pfl);
 
647
    pfl->rom_mode = 1;
 
648
    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
647
649
#if 0 /* XXX: there should be a bit to set up read-only,
648
650
       *      the same way the hardware does (with WP pin).
649
651
       */