Revision d0a9b5bc memory.c

b/memory.c
125 125
    target_phys_addr_t offset_in_region;
126 126
    AddrRange addr;
127 127
    uint8_t dirty_log_mask;
128
    bool readable;
128 129
};
129 130

  
130 131
/* Flattened global view of current active memory hierarchy.  Kept in sorted
......
164 165
{
165 166
    return a->mr == b->mr
166 167
        && addrrange_equal(a->addr, b->addr)
167
        && a->offset_in_region == b->offset_in_region;
168
        && a->offset_in_region == b->offset_in_region
169
        && a->readable == b->readable;
168 170
}
169 171

  
170 172
static void flatview_init(FlatView *view)
......
200 202
    return addrrange_end(r1->addr) == r2->addr.start
201 203
        && r1->mr == r2->mr
202 204
        && r1->offset_in_region + r1->addr.size == r2->offset_in_region
203
        && r1->dirty_log_mask == r2->dirty_log_mask;
205
        && r1->dirty_log_mask == r2->dirty_log_mask
206
        && r1->readable == r2->readable;
204 207
}
205 208

  
206 209
/* Attempt to simplify a view by merging ajacent ranges */
......
241 244
        region_offset = 0;
242 245
    }
243 246

  
247
    if (!fr->readable) {
248
        phys_offset &= TARGET_PAGE_MASK;
249
    }
250

  
244 251
    cpu_register_physical_memory_log(fr->addr.start,
245 252
                                     fr->addr.size,
246 253
                                     phys_offset,
......
462 469
            fr.offset_in_region = offset_in_region;
463 470
            fr.addr = addrrange_make(base, now);
464 471
            fr.dirty_log_mask = mr->dirty_log_mask;
472
            fr.readable = mr->readable;
465 473
            flatview_insert(view, i, &fr);
466 474
            ++i;
467 475
            base += now;
......
480 488
        fr.offset_in_region = offset_in_region;
481 489
        fr.addr = addrrange_make(base, remain);
482 490
        fr.dirty_log_mask = mr->dirty_log_mask;
491
        fr.readable = mr->readable;
483 492
        flatview_insert(view, i, &fr);
484 493
    }
485 494
}
......
680 689
    cpu_unregister_io_memory(mr->ram_addr);
681 690
}
682 691

  
692
static void memory_region_destructor_rom_device(MemoryRegion *mr)
693
{
694
    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
695
    cpu_unregister_io_memory(mr->ram_addr & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
696
}
697

  
683 698
void memory_region_init(MemoryRegion *mr,
684 699
                        const char *name,
685 700
                        uint64_t size)
......
690 705
    mr->addr = 0;
691 706
    mr->offset = 0;
692 707
    mr->terminates = false;
708
    mr->readable = true;
693 709
    mr->destructor = memory_region_destructor_none;
694 710
    mr->priority = 0;
695 711
    mr->may_overlap = false;
......
910 926
    mr->alias_offset = offset;
911 927
}
912 928

  
929
void memory_region_init_rom_device(MemoryRegion *mr,
930
                                   const MemoryRegionOps *ops,
931
                                   DeviceState *dev,
932
                                   const char *name,
933
                                   uint64_t size)
934
{
935
    memory_region_init(mr, name, size);
936
    mr->terminates = true;
937
    mr->destructor = memory_region_destructor_rom_device;
938
    mr->ram_addr = qemu_ram_alloc(dev, name, size);
939
    mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,
940
                                           memory_region_write_thunk,
941
                                           mr,
942
                                           mr->ops->endianness);
943
    mr->ram_addr |= IO_MEM_ROMD;
944
    mr->backend_registered = true;
945
}
946

  
913 947
void memory_region_destroy(MemoryRegion *mr)
914 948
{
915 949
    assert(QTAILQ_EMPTY(&mr->subregions));
......
967 1001
    /* FIXME */
968 1002
}
969 1003

  
1004
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
1005
{
1006
    if (mr->readable != readable) {
1007
        mr->readable = readable;
1008
        memory_region_update_topology();
1009
    }
1010
}
1011

  
970 1012
void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
971 1013
                               target_phys_addr_t size, unsigned client)
972 1014
{

Also available in: Unified diff