|
@@ -3047,26 +3047,8 @@ void cpu_flush_icache_range(hwaddr start, hwaddr len)
|
|
NULL, len, FLUSH_CACHE);
|
|
NULL, len, FLUSH_CACHE);
|
|
}
|
|
}
|
|
|
|
|
|
-typedef struct {
|
|
|
|
- MemoryRegion *mr;
|
|
|
|
- void *buffer;
|
|
|
|
- hwaddr addr;
|
|
|
|
- hwaddr len;
|
|
|
|
- bool in_use;
|
|
|
|
-} BounceBuffer;
|
|
|
|
-
|
|
|
|
-static BounceBuffer bounce;
|
|
|
|
-
|
|
|
|
-typedef struct MapClient {
|
|
|
|
- QEMUBH *bh;
|
|
|
|
- QLIST_ENTRY(MapClient) link;
|
|
|
|
-} MapClient;
|
|
|
|
-
|
|
|
|
-QemuMutex map_client_list_lock;
|
|
|
|
-static QLIST_HEAD(, MapClient) map_client_list
|
|
|
|
- = QLIST_HEAD_INITIALIZER(map_client_list);
|
|
|
|
-
|
|
|
|
-static void address_space_unregister_map_client_do(MapClient *client)
|
|
|
|
|
|
+static void
|
|
|
|
+address_space_unregister_map_client_do(AddressSpaceMapClient *client)
|
|
{
|
|
{
|
|
QLIST_REMOVE(client, link);
|
|
QLIST_REMOVE(client, link);
|
|
g_free(client);
|
|
g_free(client);
|
|
@@ -3074,10 +3056,10 @@ static void address_space_unregister_map_client_do(MapClient *client)
|
|
|
|
|
|
static void address_space_notify_map_clients_locked(AddressSpace *as)
|
|
static void address_space_notify_map_clients_locked(AddressSpace *as)
|
|
{
|
|
{
|
|
- MapClient *client;
|
|
|
|
|
|
+ AddressSpaceMapClient *client;
|
|
|
|
|
|
- while (!QLIST_EMPTY(&map_client_list)) {
|
|
|
|
- client = QLIST_FIRST(&map_client_list);
|
|
|
|
|
|
+ while (!QLIST_EMPTY(&as->map_client_list)) {
|
|
|
|
+ client = QLIST_FIRST(&as->map_client_list);
|
|
qemu_bh_schedule(client->bh);
|
|
qemu_bh_schedule(client->bh);
|
|
address_space_unregister_map_client_do(client);
|
|
address_space_unregister_map_client_do(client);
|
|
}
|
|
}
|
|
@@ -3085,14 +3067,14 @@ static void address_space_notify_map_clients_locked(AddressSpace *as)
|
|
|
|
|
|
void address_space_register_map_client(AddressSpace *as, QEMUBH *bh)
|
|
void address_space_register_map_client(AddressSpace *as, QEMUBH *bh)
|
|
{
|
|
{
|
|
- MapClient *client = g_malloc(sizeof(*client));
|
|
|
|
|
|
+ AddressSpaceMapClient *client = g_malloc(sizeof(*client));
|
|
|
|
|
|
- QEMU_LOCK_GUARD(&map_client_list_lock);
|
|
|
|
|
|
+ QEMU_LOCK_GUARD(&as->map_client_list_lock);
|
|
client->bh = bh;
|
|
client->bh = bh;
|
|
- QLIST_INSERT_HEAD(&map_client_list, client, link);
|
|
|
|
|
|
+ QLIST_INSERT_HEAD(&as->map_client_list, client, link);
|
|
/* Write map_client_list before reading in_use. */
|
|
/* Write map_client_list before reading in_use. */
|
|
smp_mb();
|
|
smp_mb();
|
|
- if (!qatomic_read(&bounce.in_use)) {
|
|
|
|
|
|
+ if (!qatomic_read(&as->bounce.in_use)) {
|
|
address_space_notify_map_clients_locked(as);
|
|
address_space_notify_map_clients_locked(as);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -3110,15 +3092,14 @@ void cpu_exec_init_all(void)
|
|
finalize_target_page_bits();
|
|
finalize_target_page_bits();
|
|
io_mem_init();
|
|
io_mem_init();
|
|
memory_map_init();
|
|
memory_map_init();
|
|
- qemu_mutex_init(&map_client_list_lock);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
|
|
void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
|
|
{
|
|
{
|
|
- MapClient *client;
|
|
|
|
|
|
+ AddressSpaceMapClient *client;
|
|
|
|
|
|
- QEMU_LOCK_GUARD(&map_client_list_lock);
|
|
|
|
- QLIST_FOREACH(client, &map_client_list, link) {
|
|
|
|
|
|
+ QEMU_LOCK_GUARD(&as->map_client_list_lock);
|
|
|
|
+ QLIST_FOREACH(client, &as->map_client_list, link) {
|
|
if (client->bh == bh) {
|
|
if (client->bh == bh) {
|
|
address_space_unregister_map_client_do(client);
|
|
address_space_unregister_map_client_do(client);
|
|
break;
|
|
break;
|
|
@@ -3128,7 +3109,7 @@ void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
|
|
|
|
|
|
static void address_space_notify_map_clients(AddressSpace *as)
|
|
static void address_space_notify_map_clients(AddressSpace *as)
|
|
{
|
|
{
|
|
- QEMU_LOCK_GUARD(&map_client_list_lock);
|
|
|
|
|
|
+ QEMU_LOCK_GUARD(&as->map_client_list_lock);
|
|
address_space_notify_map_clients_locked(as);
|
|
address_space_notify_map_clients_locked(as);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3220,25 +3201,25 @@ void *address_space_map(AddressSpace *as,
|
|
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
|
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
|
|
|
|
|
if (!memory_access_is_direct(mr, is_write)) {
|
|
if (!memory_access_is_direct(mr, is_write)) {
|
|
- if (qatomic_xchg(&bounce.in_use, true)) {
|
|
|
|
|
|
+ if (qatomic_xchg(&as->bounce.in_use, true)) {
|
|
*plen = 0;
|
|
*plen = 0;
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
/* Avoid unbounded allocations */
|
|
/* Avoid unbounded allocations */
|
|
l = MIN(l, TARGET_PAGE_SIZE);
|
|
l = MIN(l, TARGET_PAGE_SIZE);
|
|
- bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
|
|
|
|
- bounce.addr = addr;
|
|
|
|
- bounce.len = l;
|
|
|
|
|
|
+ as->bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
|
|
|
|
+ as->bounce.addr = addr;
|
|
|
|
+ as->bounce.len = l;
|
|
|
|
|
|
memory_region_ref(mr);
|
|
memory_region_ref(mr);
|
|
- bounce.mr = mr;
|
|
|
|
|
|
+ as->bounce.mr = mr;
|
|
if (!is_write) {
|
|
if (!is_write) {
|
|
flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
|
|
flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
|
|
- bounce.buffer, l);
|
|
|
|
|
|
+ as->bounce.buffer, l);
|
|
}
|
|
}
|
|
|
|
|
|
*plen = l;
|
|
*plen = l;
|
|
- return bounce.buffer;
|
|
|
|
|
|
+ return as->bounce.buffer;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3256,7 +3237,7 @@ void *address_space_map(AddressSpace *as,
|
|
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|
bool is_write, hwaddr access_len)
|
|
bool is_write, hwaddr access_len)
|
|
{
|
|
{
|
|
- if (buffer != bounce.buffer) {
|
|
|
|
|
|
+ if (buffer != as->bounce.buffer) {
|
|
MemoryRegion *mr;
|
|
MemoryRegion *mr;
|
|
ram_addr_t addr1;
|
|
ram_addr_t addr1;
|
|
|
|
|
|
@@ -3272,14 +3253,14 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if (is_write) {
|
|
if (is_write) {
|
|
- address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED,
|
|
|
|
- bounce.buffer, access_len);
|
|
|
|
|
|
+ address_space_write(as, as->bounce.addr, MEMTXATTRS_UNSPECIFIED,
|
|
|
|
+ as->bounce.buffer, access_len);
|
|
}
|
|
}
|
|
- qemu_vfree(bounce.buffer);
|
|
|
|
- bounce.buffer = NULL;
|
|
|
|
- memory_region_unref(bounce.mr);
|
|
|
|
|
|
+ qemu_vfree(as->bounce.buffer);
|
|
|
|
+ as->bounce.buffer = NULL;
|
|
|
|
+ memory_region_unref(as->bounce.mr);
|
|
/* Clear in_use before reading map_client_list. */
|
|
/* Clear in_use before reading map_client_list. */
|
|
- qatomic_set_mb(&bounce.in_use, false);
|
|
|
|
|
|
+ qatomic_set_mb(&as->bounce.in_use, false);
|
|
address_space_notify_map_clients(as);
|
|
address_space_notify_map_clients(as);
|
|
}
|
|
}
|
|
|
|
|