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);
|