From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LNRZj-000674-L7 for qemu-devel@nongnu.org; Thu, 15 Jan 2009 07:43:55 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LNRZg-00065Y-Tv for qemu-devel@nongnu.org; Thu, 15 Jan 2009 07:43:53 -0500 Received: from [199.232.76.173] (port=53710 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LNRZg-00065Q-JL for qemu-devel@nongnu.org; Thu, 15 Jan 2009 07:43:52 -0500 Received: from az33egw02.freescale.net ([192.88.158.103]:61399) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LNRZf-0002vr-Oc for qemu-devel@nongnu.org; Thu, 15 Jan 2009 07:43:52 -0500 Received: from az33smr02.freescale.net (az33smr02.freescale.net [10.64.34.200]) by az33egw02.freescale.net (8.14.3/az33egw02) with ESMTP id n0FCgIuU022883 for ; Thu, 15 Jan 2009 05:42:19 -0700 (MST) Received: from zch01exm26.fsl.freescale.net (zch01exm26.ap.freescale.net [10.192.129.221]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id n0FCg5WL016752 for ; Thu, 15 Jan 2009 06:42:17 -0600 (CST) From: Liu Yu Date: Thu, 15 Jan 2009 20:34:14 +0800 Message-Id: <1232022857-2315-7-git-send-email-yu.liu@freescale.com> In-Reply-To: <1232022857-2315-6-git-send-email-yu.liu@freescale.com> References: <1232022857-2315-1-git-send-email-yu.liu@freescale.com> <1232022857-2315-2-git-send-email-yu.liu@freescale.com> <1232022857-2315-3-git-send-email-yu.liu@freescale.com> <1232022857-2315-4-git-send-email-yu.liu@freescale.com> <1232022857-2315-5-git-send-email-yu.liu@freescale.com> <1232022857-2315-6-git-send-email-yu.liu@freescale.com> Subject: [Qemu-devel] [PATCH 6/9] powerpc/kvm: Add E500 irq support 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 Cc: Liu Yu , kvm-ppc@vger.kernel.org Signed-off-by: Liu Yu --- hw/ppc.c | 89 +++++++++++++++++++++++++++++++++++++++++++ hw/ppc.h | 1 + target-ppc/cpu.h | 12 ++++++ target-ppc/translate_init.c | 6 ++- 4 files changed, 106 insertions(+), 2 deletions(-) diff --git a/hw/ppc.c b/hw/ppc.c index 60d6e86..fbce211 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -421,6 +421,95 @@ void ppc40x_irq_init (CPUState *env) env, PPC40x_INPUT_NB); } +/* PowerPC E500 internal IRQ controller */ +static void ppce500_set_irq (void *opaque, int pin, int level) +{ + CPUState *env = opaque; + int cur_level; + +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: env %p pin %d level %d\n", __func__, + env, pin, level); + } +#endif + cur_level = (env->irq_input_state >> pin) & 1; + /* Don't generate spurious events */ + if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { + switch (pin) { + case PPCE500_INPUT_MCK: + if (level) { +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: reset the PowerPC system\n", + __func__); + } +#endif + fprintf(stderr,"PowerPC E500 reset core\n"); + qemu_system_reset_request(); + } + break; + case PPCE500_INPUT_RESET_CORE: + if (level) { +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: reset the PowerPC core\n", __func__); + } +#endif + ppc_set_irq(env, PPC_INTERRUPT_MCK, level); + } + break; + case PPCE500_INPUT_CINT: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: set the critical IRQ state to %d\n", + __func__, level); + } +#endif + ppc_set_irq(env, PPC_INTERRUPT_CEXT, level); + break; + case PPCE500_INPUT_INT: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: set the core IRQ state to %d\n", + __func__, level); + } +#endif + ppc_set_irq(env, PPC_INTERRUPT_EXT, level); + break; + case PPCE500_INPUT_DEBUG: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: set the debug pin state to %d\n", + __func__, level); + } +#endif + ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level); + break; + default: + /* Unknown pin - do nothing */ +#if defined(PPC_DEBUG_IRQ) + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin); + } +#endif + return; + } + if (level) + env->irq_input_state |= 1 << pin; + else + env->irq_input_state &= ~(1 << pin); + } +} + +void ppce500_irq_init (CPUState *env) +{ + env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq, + env, PPCE500_INPUT_NB); +} /*****************************************************************************/ /* PowerPC time base and decrementer emulation */ struct ppc_tb_t { diff --git a/hw/ppc.h b/hw/ppc.h index 75eb11a..2ec4680 100644 --- a/hw/ppc.h +++ b/hw/ppc.h @@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[]; void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); void ppc40x_irq_init (CPUState *env); +void ppce500_irq_init (CPUState *env); void ppc6xx_irq_init (CPUState *env); void ppc970_irq_init (CPUState *env); diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index f7a12da..9f92cd8 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1352,6 +1352,18 @@ enum { }; enum { + /* PowerPC E500 input pins */ + PPCE500_INPUT_RESET_CORE = 0, + PPCE500_INPUT_MCK = 1, + PPCE500_INPUT_RESET_SYS = 2, // in order same with 440 + PPCE500_INPUT_CINT = 3, + PPCE500_INPUT_INT = 4, + PPCE500_INPUT_HALT = 5, // in order same with 440 + PPCE500_INPUT_DEBUG = 6, + PPCE500_INPUT_NB, +}; + +enum { /* PowerPC 40x input pins */ PPC40x_INPUT_RESET_CORE = 0, PPC40x_INPUT_RESET_CHIP = 1, diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 5008a3a..7953c69 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -4154,7 +4154,8 @@ static void init_proc_e300 (CPUPPCState *env) POWERPC_FLAG_BUS_CLK) #define check_pow_e500 check_pow_hid0 -__attribute__ (( unused )) +extern void ppce500_irq_init (CPUState *env); + static void init_proc_e500 (CPUPPCState *env) { /* Time base */ @@ -4256,7 +4257,8 @@ static void init_proc_e500 (CPUPPCState *env) init_excp_e200(env); env->dcache_line_size = 32; env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ + /* Allocate hardware IRQ controller */ + ppce500_irq_init(env); } /* Non-embedded PowerPC */ -- 1.5.4