On Fri, 2009-01-09 at 15:56 +0800, Liu Yu wrote:
> As E500 exists in various boards such as MPC8544ds, MPC8572ds, MPC8560ads,
> etc..
> So I would like to implement a general virtual board MPC85xx to simplify the
> case.
>
> When 'cat /proc/cpuinfo' in guest, it will show:
> processor : 0
> cpu : e500v2
> clock : 1499.985015MHz
> revision: 3.0 (pvr 8021 0030)
> bogomips: 285.69
> timebase: 74999250
> platform: MPC8572 DS < Host platform
> model : KVM MPC85xx
>
> The current method is that change guest dts /compatible="host model",
> this seems somewhat dirty. It works for 8544, 8572 but not sure for others.
> I'll change it to search a table next time.
>
> Signed-off-by: Liu Yu
> ---
> Makefile.target |2 +
> hw/boards.h |1 +
> hw/ppc.c| 89 +++
> hw/ppc.h|1 +
> hw/ppce500_mpc85xx.c| 284 ++
> pc-bios/mpc85xx.dtb | Bin 0 -> 12288 bytes
> pc-bios/mpc85xx.dts | 361
> +++
> target-ppc/cpu.h| 12 ++
> target-ppc/machine.c|1 +
> target-ppc/translate_init.c |6 +-
> 10 files changed, 755 insertions(+), 2 deletions(-)
> create mode 100644 hw/ppce500_mpc85xx.c
> create mode 100644 pc-bios/mpc85xx.dtb
> create mode 100644 pc-bios/mpc85xx.dts
>
> diff --git a/Makefile.target b/Makefile.target
> index b66b699..abf0d59 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -657,6 +657,8 @@ OBJS+= unin_pci.o ppc_chrp.o
> # PowerPC 4xx boards
> OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
> OBJS+= ppc440.o ppc440_bamboo.o
> +# PowerPC E500 boards
> +OBJS+= ppce500.o ppce500_mpc85xx.o ppce500_pci.o mpic.o
> ifdef FDT_LIBS
> OBJS+= device_tree.o
> LIBS+= $(FDT_LIBS)
> diff --git a/hw/boards.h b/hw/boards.h
> index bff1cf0..35bd5ae 100644
> --- a/hw/boards.h
> +++ b/hw/boards.h
> @@ -39,6 +39,7 @@ extern QEMUMachine heathrow_machine;
> extern QEMUMachine ref405ep_machine;
> extern QEMUMachine taihu_machine;
> extern QEMUMachine bamboo_machine;
> +extern QEMUMachine mpc85xx_machine;
>
> /* mips_r4k.c */
> extern QEMUMachine mips_machine;
> 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);
> +