Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions include/system/penguin.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ typedef int (*kvm_penguin_hypercall_cb_t)(CPUState *cs, uint64_t nr,
uint64_t a4, uint64_t a5,
uint64_t *ret);

typedef uint64_t (*penguin_mmio_read_cb_t)(uint64_t addr, unsigned size,
void *opaque);
typedef void (*penguin_mmio_write_cb_t)(uint64_t addr, uint64_t data,
unsigned size, void *opaque);

void set_penguin_guest_hypercall_callback(penguin_guest_hypercall_cb_t cb,
void *opaque);
void set_kvm_penguin_hypercall_callback(kvm_penguin_hypercall_cb_t cb);
Expand All @@ -31,4 +36,10 @@ bool penguin_handle_guest_hypercall(CPUState *cs, uint64_t nr,
uint64_t a4, uint64_t a5,
uint64_t *ret);

int penguin_qemu_add_mmio_region(uint64_t base, uint64_t size,
const char *name,
penguin_mmio_read_cb_t read_cb,
penguin_mmio_write_cb_t write_cb,
void *opaque);

#endif /* QEMU_SYSTEM_PENGUIN_H */
9 changes: 9 additions & 0 deletions scripts/penguin-cffi-gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@

typedef int (*kvm_penguin_after_guest_init_cb_t)(MachineState *machine,
void *opaque);
typedef uint64_t (*penguin_mmio_read_cb_t)(uint64_t addr, unsigned size,
void *opaque);
typedef void (*penguin_mmio_write_cb_t)(uint64_t addr, uint64_t data,
unsigned size, void *opaque);

extern MachineState *current_machine;
extern int (*qemu_main)(void);
Expand Down Expand Up @@ -105,6 +109,11 @@
uint64_t a2, uint64_t a3,
uint64_t a4, uint64_t a5,
uint64_t *ret);
int penguin_qemu_add_mmio_region(uint64_t base, uint64_t size,
const char *name,
penguin_mmio_read_cb_t read_cb,
penguin_mmio_write_cb_t write_cb,
void *opaque);
"""


Expand Down
67 changes: 67 additions & 0 deletions system/penguin.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
#include "qemu/osdep.h"
#include "system/penguin.h"
#include "system/address-spaces.h"
#include "system/memory.h"

typedef struct PenguinMmioRegion {
MemoryRegion mr;
MemoryRegionOps ops;
penguin_mmio_read_cb_t read_cb;
penguin_mmio_write_cb_t write_cb;
void *opaque;
char *name;
} PenguinMmioRegion;

static penguin_guest_hypercall_cb_t penguin_guest_hypercall_cb;
static void *penguin_guest_hypercall_opaque;
Expand Down Expand Up @@ -38,3 +49,59 @@ bool penguin_handle_guest_hypercall(CPUState *cs, uint64_t nr,

return false;
}

static uint64_t penguin_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
PenguinMmioRegion *region = opaque;

if (!region->read_cb) {
return 0;
}

return region->read_cb(addr, size, region->opaque);
}

static void penguin_mmio_write(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
PenguinMmioRegion *region = opaque;

if (!region->write_cb) {
return;
}

region->write_cb(addr, data, size, region->opaque);
}

int __attribute__((visibility("default")))
penguin_qemu_add_mmio_region(uint64_t base, uint64_t size,
const char *name,
penguin_mmio_read_cb_t read_cb,
penguin_mmio_write_cb_t write_cb,
void *opaque)
{
PenguinMmioRegion *region;

if (!size || !name || (!read_cb && !write_cb)) {
return -1;
}

region = g_new0(PenguinMmioRegion, 1);
region->read_cb = read_cb;
region->write_cb = write_cb;
region->opaque = opaque;
region->name = g_strdup(name);
region->ops.read = penguin_mmio_read;
region->ops.write = penguin_mmio_write;
region->ops.endianness = DEVICE_NATIVE_ENDIAN;
region->ops.valid.min_access_size = 1;
region->ops.valid.max_access_size = 8;
region->ops.impl.min_access_size = 1;
region->ops.impl.max_access_size = 8;

memory_region_init_io(&region->mr, NULL, &region->ops, region,
region->name, size);
memory_region_add_subregion_overlap(get_system_memory(), base,
&region->mr, -1000);
return 0;
}
Loading