2012-04-06 16:39:03 +04:00
|
|
|
/*
|
|
|
|
* QEMU PowerPC CPU
|
|
|
|
*
|
|
|
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, see
|
|
|
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
|
|
|
*/
|
|
|
|
#ifndef QEMU_PPC_CPU_QOM_H
|
|
|
|
#define QEMU_PPC_CPU_QOM_H
|
|
|
|
|
2019-07-09 18:20:52 +03:00
|
|
|
#include "hw/core/cpu.h"
|
2012-04-06 16:39:03 +04:00
|
|
|
|
|
|
|
#ifdef TARGET_PPC64
|
|
|
|
#define TYPE_POWERPC_CPU "powerpc64-cpu"
|
|
|
|
#else
|
|
|
|
#define TYPE_POWERPC_CPU "powerpc-cpu"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define POWERPC_CPU_CLASS(klass) \
|
|
|
|
OBJECT_CLASS_CHECK(PowerPCCPUClass, (klass), TYPE_POWERPC_CPU)
|
|
|
|
#define POWERPC_CPU(obj) \
|
|
|
|
OBJECT_CHECK(PowerPCCPU, (obj), TYPE_POWERPC_CPU)
|
|
|
|
#define POWERPC_CPU_GET_CLASS(obj) \
|
|
|
|
OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU)
|
|
|
|
|
2013-09-02 16:14:24 +04:00
|
|
|
typedef struct PowerPCCPU PowerPCCPU;
|
2016-03-15 15:49:25 +03:00
|
|
|
typedef struct CPUPPCState CPUPPCState;
|
|
|
|
typedef struct ppc_tb_t ppc_tb_t;
|
|
|
|
typedef struct ppc_dcr_t ppc_dcr_t;
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* MMU model */
|
|
|
|
typedef enum powerpc_mmu_t powerpc_mmu_t;
|
|
|
|
enum powerpc_mmu_t {
|
|
|
|
POWERPC_MMU_UNKNOWN = 0x00000000,
|
|
|
|
/* Standard 32 bits PowerPC MMU */
|
|
|
|
POWERPC_MMU_32B = 0x00000001,
|
|
|
|
/* PowerPC 6xx MMU with software TLB */
|
|
|
|
POWERPC_MMU_SOFT_6xx = 0x00000002,
|
|
|
|
/* PowerPC 74xx MMU with software TLB */
|
|
|
|
POWERPC_MMU_SOFT_74xx = 0x00000003,
|
|
|
|
/* PowerPC 4xx MMU with software TLB */
|
|
|
|
POWERPC_MMU_SOFT_4xx = 0x00000004,
|
|
|
|
/* PowerPC 4xx MMU with software TLB and zones protections */
|
|
|
|
POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
|
|
|
|
/* PowerPC MMU in real mode only */
|
|
|
|
POWERPC_MMU_REAL = 0x00000006,
|
|
|
|
/* Freescale MPC8xx MMU model */
|
|
|
|
POWERPC_MMU_MPC8xx = 0x00000007,
|
|
|
|
/* BookE MMU model */
|
|
|
|
POWERPC_MMU_BOOKE = 0x00000008,
|
|
|
|
/* BookE 2.06 MMU model */
|
|
|
|
POWERPC_MMU_BOOKE206 = 0x00000009,
|
|
|
|
/* PowerPC 601 MMU model (specific BATs format) */
|
|
|
|
POWERPC_MMU_601 = 0x0000000A,
|
|
|
|
#define POWERPC_MMU_64 0x00010000
|
|
|
|
/* 64 bits PowerPC MMU */
|
|
|
|
POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
|
|
|
|
/* Architecture 2.03 and later (has LPCR) */
|
|
|
|
POWERPC_MMU_2_03 = POWERPC_MMU_64 | 0x00000002,
|
|
|
|
/* Architecture 2.06 variant */
|
2018-03-23 06:11:07 +03:00
|
|
|
POWERPC_MMU_2_06 = POWERPC_MMU_64 | 0x00000003,
|
2016-03-15 15:49:25 +03:00
|
|
|
/* Architecture 2.07 variant */
|
2018-03-23 06:11:07 +03:00
|
|
|
POWERPC_MMU_2_07 = POWERPC_MMU_64 | 0x00000004,
|
2017-02-10 08:25:51 +03:00
|
|
|
/* Architecture 3.00 variant */
|
2018-03-23 08:42:45 +03:00
|
|
|
POWERPC_MMU_3_00 = POWERPC_MMU_64 | 0x00000005,
|
2016-03-15 15:49:25 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Exception model */
|
|
|
|
typedef enum powerpc_excp_t powerpc_excp_t;
|
|
|
|
enum powerpc_excp_t {
|
|
|
|
POWERPC_EXCP_UNKNOWN = 0,
|
|
|
|
/* Standard PowerPC exception model */
|
|
|
|
POWERPC_EXCP_STD,
|
|
|
|
/* PowerPC 40x exception model */
|
|
|
|
POWERPC_EXCP_40x,
|
|
|
|
/* PowerPC 601 exception model */
|
|
|
|
POWERPC_EXCP_601,
|
|
|
|
/* PowerPC 602 exception model */
|
|
|
|
POWERPC_EXCP_602,
|
|
|
|
/* PowerPC 603 exception model */
|
|
|
|
POWERPC_EXCP_603,
|
|
|
|
/* PowerPC 603e exception model */
|
|
|
|
POWERPC_EXCP_603E,
|
|
|
|
/* PowerPC G2 exception model */
|
|
|
|
POWERPC_EXCP_G2,
|
|
|
|
/* PowerPC 604 exception model */
|
|
|
|
POWERPC_EXCP_604,
|
|
|
|
/* PowerPC 7x0 exception model */
|
|
|
|
POWERPC_EXCP_7x0,
|
|
|
|
/* PowerPC 7x5 exception model */
|
|
|
|
POWERPC_EXCP_7x5,
|
|
|
|
/* PowerPC 74xx exception model */
|
|
|
|
POWERPC_EXCP_74xx,
|
|
|
|
/* BookE exception model */
|
|
|
|
POWERPC_EXCP_BOOKE,
|
|
|
|
/* PowerPC 970 exception model */
|
|
|
|
POWERPC_EXCP_970,
|
|
|
|
/* POWER7 exception model */
|
|
|
|
POWERPC_EXCP_POWER7,
|
|
|
|
/* POWER8 exception model */
|
|
|
|
POWERPC_EXCP_POWER8,
|
2019-02-15 19:16:44 +03:00
|
|
|
/* POWER9 exception model */
|
|
|
|
POWERPC_EXCP_POWER9,
|
2016-03-15 15:49:25 +03:00
|
|
|
};
|
|
|
|
|
2016-06-22 00:48:55 +03:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* PM instructions */
|
|
|
|
typedef enum {
|
|
|
|
PPC_PM_DOZE,
|
|
|
|
PPC_PM_NAP,
|
|
|
|
PPC_PM_SLEEP,
|
|
|
|
PPC_PM_RVWINKLE,
|
2019-02-15 19:16:41 +03:00
|
|
|
PPC_PM_STOP,
|
2016-06-22 00:48:55 +03:00
|
|
|
} powerpc_pm_insn_t;
|
|
|
|
|
2016-03-15 15:49:25 +03:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* Input pins model */
|
|
|
|
typedef enum powerpc_input_t powerpc_input_t;
|
|
|
|
enum powerpc_input_t {
|
|
|
|
PPC_FLAGS_INPUT_UNKNOWN = 0,
|
|
|
|
/* PowerPC 6xx bus */
|
|
|
|
PPC_FLAGS_INPUT_6xx,
|
|
|
|
/* BookE bus */
|
|
|
|
PPC_FLAGS_INPUT_BookE,
|
|
|
|
/* PowerPC 405 bus */
|
|
|
|
PPC_FLAGS_INPUT_405,
|
|
|
|
/* PowerPC 970 bus */
|
|
|
|
PPC_FLAGS_INPUT_970,
|
|
|
|
/* PowerPC POWER7 bus */
|
|
|
|
PPC_FLAGS_INPUT_POWER7,
|
2019-02-15 19:16:47 +03:00
|
|
|
/* PowerPC POWER9 bus */
|
|
|
|
PPC_FLAGS_INPUT_POWER9,
|
2016-03-15 15:49:25 +03:00
|
|
|
/* PowerPC 401 bus */
|
|
|
|
PPC_FLAGS_INPUT_401,
|
|
|
|
/* Freescale RCPU bus */
|
|
|
|
PPC_FLAGS_INPUT_RCPU,
|
|
|
|
};
|
|
|
|
|
2018-03-23 05:31:52 +03:00
|
|
|
typedef struct PPCHash64Options PPCHash64Options;
|
2013-09-02 16:14:24 +04:00
|
|
|
|
2012-04-06 16:39:03 +04:00
|
|
|
/**
|
|
|
|
* PowerPCCPUClass:
|
2013-01-16 06:55:14 +04:00
|
|
|
* @parent_realize: The parent class' realize handler.
|
2012-04-06 16:39:03 +04:00
|
|
|
* @parent_reset: The parent class' reset handler.
|
|
|
|
*
|
|
|
|
* A PowerPC CPU model.
|
|
|
|
*/
|
|
|
|
typedef struct PowerPCCPUClass {
|
|
|
|
/*< private >*/
|
|
|
|
CPUClass parent_class;
|
|
|
|
/*< public >*/
|
|
|
|
|
2013-01-16 06:55:14 +04:00
|
|
|
DeviceRealize parent_realize;
|
2016-10-20 14:26:04 +03:00
|
|
|
DeviceUnrealize parent_unrealize;
|
cpu: Use DeviceClass reset instead of a special CPUClass reset
The CPUClass has a 'reset' method. This is a legacy from when
TYPE_CPU used not to inherit from TYPE_DEVICE. We don't need it any
more, as we can simply use the TYPE_DEVICE reset. The 'cpu_reset()'
function is kept as the API which most places use to reset a CPU; it
is now a wrapper which calls device_cold_reset() and then the
tracepoint function.
This change should not cause CPU objects to be reset more often
than they are at the moment, because:
* nobody is directly calling device_cold_reset() or
qdev_reset_all() on CPU objects
* no CPU object is on a qbus, so they will not be reset either
by somebody calling qbus_reset_all()/bus_cold_reset(), or
by the main "reset sysbus and everything in the qbus tree"
reset that most devices are reset by
Note that this does not change the need for each machine or whatever
to use qemu_register_reset() to arrange to call cpu_reset() -- that
is necessary because CPU objects are not on any qbus, so they don't
get reset when the qbus tree rooted at the sysbus bus is reset, and
this isn't being changed here.
All the changes to the files under target/ were made using the
included Coccinelle script, except:
(1) the deletion of the now-inaccurate and not terribly useful
"CPUClass::reset" comments was done with a perl one-liner afterwards:
perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c
(2) this bit of the s390 change was done by hand, because the
Coccinelle script is not sophisticated enough to handle the
parent_reset call being inside another function:
| @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
| S390CPU *cpu = S390_CPU(s);
| S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
| CPUS390XState *env = &cpu->env;
|+ DeviceState *dev = DEVICE(s);
|
|- scc->parent_reset(s);
|+ scc->parent_reset(dev);
| cpu->env.sigp_order = 0;
| s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20200303100511.5498-1-peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2020-03-03 13:05:11 +03:00
|
|
|
DeviceReset parent_reset;
|
2017-10-09 22:50:59 +03:00
|
|
|
void (*parent_parse_features)(const char *type, char *str, Error **errp);
|
2013-01-06 12:31:30 +04:00
|
|
|
|
2013-02-18 03:16:41 +04:00
|
|
|
uint32_t pvr;
|
2014-07-03 18:48:55 +04:00
|
|
|
bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr);
|
2016-06-07 18:39:37 +03:00
|
|
|
uint64_t pcr_mask; /* Available bits in PCR register */
|
|
|
|
uint64_t pcr_supported; /* Bits for supported PowerISA versions */
|
2013-02-18 03:16:41 +04:00
|
|
|
uint32_t svr;
|
|
|
|
uint64_t insns_flags;
|
|
|
|
uint64_t insns_flags2;
|
|
|
|
uint64_t msr_mask;
|
2020-01-06 08:35:10 +03:00
|
|
|
uint64_t lpcr_mask; /* Available bits in the LPCR */
|
2017-11-23 20:05:24 +03:00
|
|
|
uint64_t lpcr_pm; /* Power-saving mode Exit Cause Enable bits */
|
2013-02-18 03:16:41 +04:00
|
|
|
powerpc_mmu_t mmu_model;
|
|
|
|
powerpc_excp_t excp_model;
|
|
|
|
powerpc_input_t bus_model;
|
|
|
|
uint32_t flags;
|
|
|
|
int bfd_mach;
|
2013-04-07 23:08:19 +04:00
|
|
|
uint32_t l1_dcache_size, l1_icache_size;
|
2019-02-06 19:51:33 +03:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
unsigned int gdb_num_sprs;
|
|
|
|
const char *gdb_spr_xml;
|
|
|
|
#endif
|
2018-03-23 05:31:52 +03:00
|
|
|
const PPCHash64Options *hash64_opts;
|
2017-03-20 02:46:43 +03:00
|
|
|
struct ppc_radix_page_info *radix_page_info;
|
2019-03-01 05:43:15 +03:00
|
|
|
uint32_t lrg_decr_bits;
|
2019-08-27 07:57:51 +03:00
|
|
|
int n_host_threads;
|
2013-02-18 03:16:41 +04:00
|
|
|
void (*init_proc)(CPUPPCState *env);
|
|
|
|
int (*check_pow)(CPUPPCState *env);
|
2016-03-15 17:12:16 +03:00
|
|
|
int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
|
2014-05-19 21:59:05 +04:00
|
|
|
bool (*interrupts_big_endian)(PowerPCCPU *cpu);
|
2012-04-06 16:39:03 +04:00
|
|
|
} PowerPCCPUClass;
|
|
|
|
|
2013-07-18 23:32:54 +04:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2014-05-01 14:37:09 +04:00
|
|
|
typedef struct PPCTimebase {
|
|
|
|
uint64_t guest_timebase;
|
|
|
|
int64_t time_of_the_day_ns;
|
2019-07-11 22:47:02 +03:00
|
|
|
bool runstate_paused;
|
2014-05-01 14:37:09 +04:00
|
|
|
} PPCTimebase;
|
|
|
|
|
2019-08-12 08:23:44 +03:00
|
|
|
extern const VMStateDescription vmstate_ppc_timebase;
|
2014-05-01 14:37:09 +04:00
|
|
|
|
|
|
|
#define VMSTATE_PPC_TIMEBASE_V(_field, _state, _version) { \
|
|
|
|
.name = (stringify(_field)), \
|
|
|
|
.version_id = (_version), \
|
|
|
|
.size = sizeof(PPCTimebase), \
|
|
|
|
.vmsd = &vmstate_ppc_timebase, \
|
|
|
|
.flags = VMS_STRUCT, \
|
|
|
|
.offset = vmstate_offset_value(_state, _field, PPCTimebase), \
|
|
|
|
}
|
2017-01-27 15:24:58 +03:00
|
|
|
|
|
|
|
void cpu_ppc_clock_vm_state_change(void *opaque, int running,
|
|
|
|
RunState state);
|
2013-07-18 23:32:54 +04:00
|
|
|
#endif
|
|
|
|
|
2012-04-06 16:39:03 +04:00
|
|
|
#endif
|