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