*
* This code is licensed under the GNU GPLv2.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
*/
/* TODO:
void framebuffer_update_display(
DisplayState *ds,
- a_target_phys_addr base,
+ MemoryRegion *address_space,
+ target_phys_addr_t base,
int cols, /* Width in pixels. */
int rows, /* Leight in pixels. */
int src_width, /* Length of source line, in bytes. */
int *first_row, /* Input and output. */
int *last_row /* Output only */)
{
- a_target_phys_addr src_len;
+ target_phys_addr_t src_len;
uint8_t *dest;
uint8_t *src;
uint8_t *src_base;
int first, last = 0;
int dirty;
int i;
- a_ram_addr addr;
- a_ram_addr pd;
- a_ram_addr pd2;
+ ram_addr_t addr;
+ MemoryRegionSection mem_section;
+ MemoryRegion *mem;
i = *first_row;
*first_row = -1;
src_len = src_width * rows;
- cpu_physical_sync_dirty_bitmap(base, base + src_len);
- pd = cpu_get_physical_page_desc(base);
- pd2 = cpu_get_physical_page_desc(base + src_len - 1);
- /* We should reall check that this is a continuous ram region.
- Instead we just check that the first and last pages are
- both ram, and the right distance apart. */
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM
- || (pd2 & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
- return;
- }
- pd = (pd & TARGET_PAGE_MASK) + (base & ~TARGET_PAGE_MASK);
- if (((pd + src_len - 1) & TARGET_PAGE_MASK) != (pd2 & TARGET_PAGE_MASK)) {
+ mem_section = memory_region_find(address_space, base, src_len);
+ if (mem_section.size != src_len || !memory_region_is_ram(mem_section.mr)) {
return;
}
+ mem = mem_section.mr;
+ assert(mem);
+ assert(mem_section.offset_within_address_space == base);
+ memory_region_sync_dirty_bitmap(mem);
src_base = cpu_physical_memory_map(base, &src_len, 0);
/* If we can't map the framebuffer then bail. We could try harder,
but it's not really worth it as dirty flag tracking will probably
dest = ds_get_data(ds);
if (dest_col_pitch < 0)
dest -= dest_col_pitch * (cols - 1);
+ if (dest_row_pitch < 0) {
+ dest -= dest_row_pitch * (rows - 1);
+ }
first = -1;
- addr = pd;
+ addr = mem_section.offset_within_region;
addr += i * src_width;
src += i * src_width;
dest += i * dest_row_pitch;
for (; i < rows; i++) {
- a_target_phys_addr dirty_offset;
- dirty = 0;
- dirty_offset = 0;
- while (addr + dirty_offset < TARGET_PAGE_ALIGN(addr + src_width)) {
- dirty |= cpu_physical_memory_get_dirty(addr + dirty_offset,
- VGA_DIRTY_FLAG);
- dirty_offset += TARGET_PAGE_SIZE;
- }
-
+ dirty = memory_region_get_dirty(mem, addr, addr + src_width,
+ DIRTY_MEMORY_VGA);
if (dirty || invalidate) {
fn(opaque, dest, src, cols, dest_col_pitch);
if (first == -1)
if (first < 0) {
return;
}
- cpu_physical_memory_reset_dirty(pd, pd + src_len, VGA_DIRTY_FLAG);
+ memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len,
+ DIRTY_MEMORY_VGA);
*first_row = first;
*last_row = last;
return;