From: Sasha Levin Date: Thu, 26 May 2011 10:30:05 +0000 (+0300) Subject: kvm tools: Add basic ioport dynamic allocation X-Git-Tag: next-20110824~3^2~260 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6d149cd2802b0c8788ed0bf13fb3319e293e1bba;p=karo-tx-linux.git kvm tools: Add basic ioport dynamic allocation Add a very simple allocation of ioports. This prevents the need to coordinate ioports between different modules. Signed-off-by: Sasha Levin Signed-off-by: Pekka Enberg --- diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h index 67b4a6facc19..49f919f514c8 100644 --- a/tools/kvm/include/kvm/ioport.h +++ b/tools/kvm/include/kvm/ioport.h @@ -9,6 +9,9 @@ /* some ports we reserve for own use */ #define IOPORT_DBG 0xe0 +#define IOPORT_START 0x6200 +#define IOPORT_SIZE 0x400 + #define IOPORT_VESA 0xa200 #define IOPORT_VESA_SIZE 256 #define IOPORT_VIRTIO_P9 0xb200 /* Virtio 9P device */ @@ -22,6 +25,8 @@ #define IOPORT_VIRTIO_RNG 0xf200 /* Virtio network device */ #define IOPORT_VIRTIO_RNG_SIZE 256 +#define IOPORT_EMPTY USHRT_MAX + struct kvm; struct ioport { @@ -37,7 +42,7 @@ struct ioport_operations { void ioport__setup_legacy(void); -void ioport__register(u16 port, struct ioport_operations *ops, int count, void *param); +u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param); static inline u8 ioport__read8(u8 *data) { diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c index 92ad15297d96..492ce1642ae1 100644 --- a/tools/kvm/ioport.c +++ b/tools/kvm/ioport.c @@ -3,6 +3,9 @@ #include "kvm/kvm.h" #include "kvm/util.h" +#include "kvm/rbtree-interval.h" +#include "kvm/mutex.h" + #include /* for KVM_EXIT_* */ #include @@ -14,9 +17,23 @@ #define ioport_node(n) rb_entry(n, struct ioport, node) +static u16 free_io_port_idx; +DEFINE_MUTEX(free_io_port_idx_lock); static struct rb_root ioport_tree = RB_ROOT; bool ioport_debug; +static u16 ioport__find_free_port(void) +{ + u16 free_port; + + mutex_lock(&free_io_port_idx_lock); + free_port = IOPORT_START + free_io_port_idx * IOPORT_SIZE; + free_io_port_idx++; + mutex_unlock(&free_io_port_idx_lock); + + return free_port; +} + static struct ioport *ioport_search(struct rb_root *root, u64 addr) { struct rb_int_node *node; @@ -61,10 +78,13 @@ static struct ioport_operations dummy_write_only_ioport_ops = { .io_out = dummy_io_out, }; -void ioport__register(u16 port, struct ioport_operations *ops, int count, void *param) +u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param) { struct ioport *entry; + if (port == IOPORT_EMPTY) + port = ioport__find_free_port(); + entry = ioport_search(&ioport_tree, port); if (entry) { pr_warning("ioport re-registered: %x", port); @@ -82,6 +102,8 @@ void ioport__register(u16 port, struct ioport_operations *ops, int count, void * }; ioport_insert(&ioport_tree, entry); + + return port; } static const char *to_direction(int direction)