Revision 90260c6c exec.c

b/exec.c
97 97
    MemoryListener listener;
98 98
};
99 99

  
100
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
101
typedef struct subpage_t {
102
    MemoryRegion iomem;
103
    hwaddr base;
104
    uint16_t sub_section[TARGET_PAGE_SIZE];
105
} subpage_t;
106

  
100 107
static MemoryRegionSection *phys_sections;
101 108
static unsigned phys_sections_nb, phys_sections_nb_alloc;
102 109
static uint16_t phys_section_unassigned;
......
220 227
}
221 228

  
222 229
static MemoryRegionSection *address_space_lookup_region(AddressSpace *as,
223
                                                        hwaddr addr)
230
                                                        hwaddr addr,
231
                                                        bool resolve_subpage)
224 232
{
225
    return phys_page_find(as->dispatch, addr >> TARGET_PAGE_BITS);
233
    MemoryRegionSection *section;
234
    subpage_t *subpage;
235

  
236
    section = phys_page_find(as->dispatch, addr >> TARGET_PAGE_BITS);
237
    if (resolve_subpage && section->mr->subpage) {
238
        subpage = container_of(section->mr, subpage_t, iomem);
239
        section = &phys_sections[subpage->sub_section[SUBPAGE_IDX(addr)]];
240
    }
241
    return section;
226 242
}
227 243

  
228
MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
229
                                             hwaddr *xlat, hwaddr *plen,
230
                                             bool is_write)
244
static MemoryRegionSection *
245
address_space_translate_internal(AddressSpace *as, hwaddr addr, hwaddr *xlat,
246
                                 hwaddr *plen, bool resolve_subpage)
231 247
{
232 248
    MemoryRegionSection *section;
233 249
    Int128 diff;
234 250

  
235
    section = address_space_lookup_region(as, addr);
251
    section = address_space_lookup_region(as, addr, resolve_subpage);
236 252
    /* Compute offset within MemoryRegionSection */
237 253
    addr -= section->offset_within_address_space;
238 254

  
......
243 259
    *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
244 260
    return section;
245 261
}
262

  
263
MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
264
                                             hwaddr *xlat, hwaddr *plen,
265
                                             bool is_write)
266
{
267
    return address_space_translate_internal(as, addr, xlat, plen, true);
268
}
269

  
270
MemoryRegionSection *
271
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
272
                                  hwaddr *plen)
273
{
274
    return address_space_translate_internal(as, addr, xlat, plen, false);
275
}
246 276
#endif
247 277

  
248 278
void cpu_exec_init_all(void)
......
697 727

  
698 728
#if !defined(CONFIG_USER_ONLY)
699 729

  
700
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
701
typedef struct subpage_t {
702
    MemoryRegion iomem;
703
    hwaddr base;
704
    uint16_t sub_section[TARGET_PAGE_SIZE];
705
} subpage_t;
706

  
707 730
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
708 731
                             uint16_t section);
709 732
static subpage_t *subpage_init(hwaddr base);

Also available in: Unified diff