From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KCKjq-00033E-VP for qemu-devel@nongnu.org; Fri, 27 Jun 2008 16:40:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KCKjp-00031x-5T for qemu-devel@nongnu.org; Fri, 27 Jun 2008 16:40:10 -0400 Received: from [199.232.76.173] (port=51158 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KCKjo-00031m-UQ for qemu-devel@nongnu.org; Fri, 27 Jun 2008 16:40:08 -0400 Received: from mx1.redhat.com ([66.187.233.31]:55955) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KCKjp-00080w-74 for qemu-devel@nongnu.org; Fri, 27 Jun 2008 16:40:09 -0400 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m5RKe81N014587 for ; Fri, 27 Jun 2008 16:40:08 -0400 Received: from pobox-2.corp.redhat.com (pobox-2.corp.redhat.com [10.11.255.15]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m5RKe7i8005936 for ; Fri, 27 Jun 2008 16:40:07 -0400 Received: from localhost.localdomain (vpn-4-80.str.redhat.com [10.32.4.80]) by pobox-2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m5RKdadk004563 for ; Fri, 27 Jun 2008 16:40:06 -0400 From: Glauber Costa Date: Fri, 27 Jun 2008 17:38:15 -0300 Message-Id: <1214599103-13846-13-git-send-email-gcosta@redhat.com> In-Reply-To: <1214599103-13846-12-git-send-email-gcosta@redhat.com> References: <1214599103-13846-1-git-send-email-gcosta@redhat.com> <1214599103-13846-2-git-send-email-gcosta@redhat.com> <1214599103-13846-3-git-send-email-gcosta@redhat.com> <1214599103-13846-4-git-send-email-gcosta@redhat.com> <1214599103-13846-5-git-send-email-gcosta@redhat.com> <1214599103-13846-6-git-send-email-gcosta@redhat.com> <1214599103-13846-7-git-send-email-gcosta@redhat.com> <1214599103-13846-8-git-send-email-gcosta@redhat.com> <1214599103-13846-9-git-send-email-gcosta@redhat.com> <1214599103-13846-10-git-send-email-gcosta@redhat.com> <1214599103-13846-11-git-send-email-gcosta@redhat.com> <1214599103-13846-12-git-send-email-gcosta@redhat.com> Subject: [Qemu-devel] [PATCH 12/20] build list of available accelerators Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org instead of hardcoding kqemu_start() in exec.c, which would require such a hack for all available accelerators, semantics of register_qemu_accel() is changed a little bit. It only builds a list of available accelerators. The last one registered is the first tried. This is a temporary solution, since we don't control exactly the order in which things are loaded by the constructor attributes. The final goal is to have command line switches and priority lists to determine that. "info accelerator" is changed to accomodate it. It now prints a list of available accelerators, and only if one of them is active, a detailed description of it is printed. --- accel.h | 43 +++++++++++++++++++++++++++++++++++++++++-- exec.c | 4 +--- kqemu.c | 11 +++++++++-- monitor.c | 18 ++++++++++++++++-- vl.c | 1 + 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/accel.h b/accel.h index 9d5b3a2..99f4742 100644 --- a/accel.h +++ b/accel.h @@ -1,6 +1,8 @@ typedef struct QEMUAccel { + char *name; void (*cpu_interrupt)(CPUState *env); void (*init_env)(CPUState *env); + int (*start)(void); void (*flush_cache)(CPUState *env, int global); void (*flush_page)(CPUState *env, target_ulong addr); int (*info)(CPUState *env, char *buf); @@ -10,11 +12,33 @@ typedef struct QEMUAccel { uint64_t (*get_real_ticks)(void); } QEMUAccel; +typedef struct QEMUCont { + QEMUAccel *acc; + int active; + struct QEMUCont *next; +} QEMUCont; + extern QEMUAccel *current_accel; +extern QEMUCont *head; +void *qemu_mallocz(size_t size); -static inline void register_qemu_accel(QEMUAccel *accel) +static inline int register_qemu_accel(QEMUAccel *accel) { - current_accel = accel; + QEMUCont *new; + + new = qemu_mallocz(sizeof(*head)); + + new->acc = accel; + new->active = 0; + new->next = head; + head = new; + + return 0; +} + +static inline QEMUCont *get_accel_head(void) +{ + return head; } static inline void accel_cpu_interrupt(CPUState *env) @@ -23,6 +47,21 @@ static inline void accel_cpu_interrupt(CPUState *env) current_accel->cpu_interrupt(env); } +static inline void accel_start(void) +{ + /* The top accelerator in the list gets tried first, but if it fails, + * keep trying until one of them succeeds or we exhaust the list */ + QEMUCont *tmp = head; + while (tmp) { + if (tmp->acc && tmp->acc->start && (!(tmp->acc->start())) ) { + tmp->active = 1; + current_accel = tmp->acc; + break; + } + tmp = tmp->next; + } +} + static inline void accel_init_env(CPUState *env) { if (current_accel && current_accel->init_env) diff --git a/exec.c b/exec.c index f62508b..e5d3fea 100644 --- a/exec.c +++ b/exec.c @@ -435,9 +435,7 @@ void cpu_exec_init_all(unsigned long tb_size) #if !defined(CONFIG_USER_ONLY) io_mem_init(); #endif -#ifdef USE_KQEMU - kqemu_start(); -#endif + accel_start(); } void cpu_exec_init(CPUState *env) diff --git a/kqemu.c b/kqemu.c index 9184b26..783b036 100644 --- a/kqemu.c +++ b/kqemu.c @@ -155,7 +155,6 @@ static void kqemu_update_cpuid(CPUState *env) accelerated code */ } -QEMUAccel kqemu_accel; extern int smp_cpus; int kqemu_start(void) @@ -240,7 +239,6 @@ int kqemu_start(void) } nb_pages_to_flush = 0; nb_ram_pages_to_update = 0; - register_qemu_accel(&kqemu_accel); qpi_init(); return 0; @@ -436,8 +434,10 @@ void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, } QEMUAccel kqemu_accel = { + .name = "KQEMU", .cpu_interrupt = kqemu_cpu_interrupt, .init_env = kqemu_init_env, + .start = kqemu_start, .flush_cache = kqemu_flush, .flush_page = kqemu_flush_page, .info = kqemu_info, @@ -450,6 +450,13 @@ QEMUAccel kqemu_accel = { .get_real_ticks = cpu_get_real_ticks, }; +static void __attribute__((constructor)) register_kqemu(void) +{ + if (register_qemu_accel(&kqemu_accel) < 0) + fprintf(logfile, "kqemu: could not register accelerator \n"); +} + + struct fpstate { uint16_t fpuc; diff --git a/monitor.c b/monitor.c index 29a747d..bc5d07b 100644 --- a/monitor.c +++ b/monitor.c @@ -1218,6 +1218,18 @@ static void mem_info(void) } #endif +static int do_accel_do_list(void) +{ + QEMUCont *tmp; + int active = 0; + for (tmp= get_accel_head(); tmp != NULL; tmp = tmp->next) + { + term_printf("%c %s\n", tmp->active ? '*' : ' ', tmp->acc->name); + active |= tmp->active; + } + return active; +} + #define MAX_BUF 1024 static void do_info_accelerator(void) { @@ -1231,8 +1243,10 @@ static void do_info_accelerator(void) return; } - if (accel_info(env, buf)) - term_printf(buf); + if (do_accel_do_list()) { + if (accel_info(env, buf)) + term_printf(buf); + } else term_printf("No accelerator present\n"); } diff --git a/vl.c b/vl.c index b402197..fd26b92 100644 --- a/vl.c +++ b/vl.c @@ -242,6 +242,7 @@ static CPUState *cur_cpu; static CPUState *next_cpu; static int event_pending = 1; QEMUAccel *current_accel; +QEMUCont *head = NULL; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) -- 1.5.5.1