diff options
author | 2023-10-10 11:40:56 +0000 | |
---|---|---|
committer | 2023-10-10 11:40:56 +0000 | |
commit | e02cda008591317b1625707ff8e115a4841aa889 (patch) | |
tree | aee302e3cf8b59ec2d32ec481be3d1afddfc8968 /include/hw/misc | |
parent | cc668e6b7e0ffd8c9d130513d12053cf5eda1d3b (diff) |
Introduce Virtio-loopback epsilon release:
Epsilon release introduces a new compatibility layer which make virtio-loopback
design to work with QEMU and rust-vmm vhost-user backend without require any
changes.
Signed-off-by: Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
Change-Id: I52e57563e08a7d0bdc002f8e928ee61ba0c53dd9
Diffstat (limited to 'include/hw/misc')
84 files changed, 7151 insertions, 0 deletions
diff --git a/include/hw/misc/a9scu.h b/include/hw/misc/a9scu.h new file mode 100644 index 000000000..c3759fb8c --- /dev/null +++ b/include/hw/misc/a9scu.h @@ -0,0 +1,32 @@ +/* + * Cortex-A9MPCore Snoop Control Unit (SCU) emulation. + * + * Copyright (c) 2009 CodeSourcery. + * Copyright (c) 2011 Linaro Limited. + * Written by Paul Brook, Peter Maydell. + * + * This code is licensed under the GPL. + */ +#ifndef HW_MISC_A9SCU_H +#define HW_MISC_A9SCU_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +/* A9MP private memory region. */ + +struct A9SCUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + uint32_t control; + uint32_t status; + uint32_t num_cpu; +}; + +#define TYPE_A9_SCU "a9-scu" +OBJECT_DECLARE_SIMPLE_TYPE(A9SCUState, A9_SCU) + +#endif diff --git a/include/hw/misc/allwinner-cpucfg.h b/include/hw/misc/allwinner-cpucfg.h new file mode 100644 index 000000000..a717b4729 --- /dev/null +++ b/include/hw/misc/allwinner-cpucfg.h @@ -0,0 +1,51 @@ +/* + * Allwinner CPU Configuration Module emulation + * + * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_MISC_ALLWINNER_CPUCFG_H +#define HW_MISC_ALLWINNER_CPUCFG_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +/** + * Object model + * @{ + */ + +#define TYPE_AW_CPUCFG "allwinner-cpucfg" +OBJECT_DECLARE_SIMPLE_TYPE(AwCpuCfgState, AW_CPUCFG) + +/** @} */ + +/** + * Allwinner CPU Configuration Module instance state + */ +struct AwCpuCfgState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + uint32_t gen_ctrl; + uint32_t super_standby; + uint32_t entry_addr; + +}; + +#endif /* HW_MISC_ALLWINNER_CPUCFG_H */ diff --git a/include/hw/misc/allwinner-h3-ccu.h b/include/hw/misc/allwinner-h3-ccu.h new file mode 100644 index 000000000..a04875bfc --- /dev/null +++ b/include/hw/misc/allwinner-h3-ccu.h @@ -0,0 +1,65 @@ +/* + * Allwinner H3 Clock Control Unit emulation + * + * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_MISC_ALLWINNER_H3_CCU_H +#define HW_MISC_ALLWINNER_H3_CCU_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +/** + * @name Constants + * @{ + */ + +/** Size of register I/O address space used by CCU device */ +#define AW_H3_CCU_IOSIZE (0x400) + +/** Total number of known registers */ +#define AW_H3_CCU_REGS_NUM (AW_H3_CCU_IOSIZE / sizeof(uint32_t)) + +/** @} */ + +/** + * @name Object model + * @{ + */ + +#define TYPE_AW_H3_CCU "allwinner-h3-ccu" +OBJECT_DECLARE_SIMPLE_TYPE(AwH3ClockCtlState, AW_H3_CCU) + +/** @} */ + +/** + * Allwinner H3 CCU object instance state. + */ +struct AwH3ClockCtlState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Maps I/O registers in physical memory */ + MemoryRegion iomem; + + /** Array of hardware registers */ + uint32_t regs[AW_H3_CCU_REGS_NUM]; + +}; + +#endif /* HW_MISC_ALLWINNER_H3_CCU_H */ diff --git a/include/hw/misc/allwinner-h3-dramc.h b/include/hw/misc/allwinner-h3-dramc.h new file mode 100644 index 000000000..0b6c877ef --- /dev/null +++ b/include/hw/misc/allwinner-h3-dramc.h @@ -0,0 +1,105 @@ +/* + * Allwinner H3 SDRAM Controller emulation + * + * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_MISC_ALLWINNER_H3_DRAMC_H +#define HW_MISC_ALLWINNER_H3_DRAMC_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "exec/hwaddr.h" + +/** + * Constants + * @{ + */ + +/** Highest register address used by DRAMCOM module */ +#define AW_H3_DRAMCOM_REGS_MAXADDR (0x804) + +/** Total number of known DRAMCOM registers */ +#define AW_H3_DRAMCOM_REGS_NUM (AW_H3_DRAMCOM_REGS_MAXADDR / \ + sizeof(uint32_t)) + +/** Highest register address used by DRAMCTL module */ +#define AW_H3_DRAMCTL_REGS_MAXADDR (0x88c) + +/** Total number of known DRAMCTL registers */ +#define AW_H3_DRAMCTL_REGS_NUM (AW_H3_DRAMCTL_REGS_MAXADDR / \ + sizeof(uint32_t)) + +/** Highest register address used by DRAMPHY module */ +#define AW_H3_DRAMPHY_REGS_MAXADDR (0x4) + +/** Total number of known DRAMPHY registers */ +#define AW_H3_DRAMPHY_REGS_NUM (AW_H3_DRAMPHY_REGS_MAXADDR / \ + sizeof(uint32_t)) + +/** @} */ + +/** + * Object model + * @{ + */ + +#define TYPE_AW_H3_DRAMC "allwinner-h3-dramc" +OBJECT_DECLARE_SIMPLE_TYPE(AwH3DramCtlState, AW_H3_DRAMC) + +/** @} */ + +/** + * Allwinner H3 SDRAM Controller object instance state. + */ +struct AwH3DramCtlState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Physical base address for start of RAM */ + hwaddr ram_addr; + + /** Total RAM size in megabytes */ + uint32_t ram_size; + + /** + * @name Memory Regions + * @{ + */ + + MemoryRegion row_mirror; /**< Simulates rows for RAM size detection */ + MemoryRegion row_mirror_alias; /**< Alias of the row which is mirrored */ + MemoryRegion dramcom_iomem; /**< DRAMCOM module I/O registers */ + MemoryRegion dramctl_iomem; /**< DRAMCTL module I/O registers */ + MemoryRegion dramphy_iomem; /**< DRAMPHY module I/O registers */ + + /** @} */ + + /** + * @name Hardware Registers + * @{ + */ + + uint32_t dramcom[AW_H3_DRAMCOM_REGS_NUM]; /**< Array of DRAMCOM registers */ + uint32_t dramctl[AW_H3_DRAMCTL_REGS_NUM]; /**< Array of DRAMCTL registers */ + uint32_t dramphy[AW_H3_DRAMPHY_REGS_NUM] ;/**< Array of DRAMPHY registers */ + + /** @} */ + +}; + +#endif /* HW_MISC_ALLWINNER_H3_DRAMC_H */ diff --git a/include/hw/misc/allwinner-h3-sysctrl.h b/include/hw/misc/allwinner-h3-sysctrl.h new file mode 100644 index 000000000..ec1c22053 --- /dev/null +++ b/include/hw/misc/allwinner-h3-sysctrl.h @@ -0,0 +1,66 @@ +/* + * Allwinner H3 System Control emulation + * + * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_MISC_ALLWINNER_H3_SYSCTRL_H +#define HW_MISC_ALLWINNER_H3_SYSCTRL_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +/** + * @name Constants + * @{ + */ + +/** Highest register address used by System Control device */ +#define AW_H3_SYSCTRL_REGS_MAXADDR (0x30) + +/** Total number of known registers */ +#define AW_H3_SYSCTRL_REGS_NUM ((AW_H3_SYSCTRL_REGS_MAXADDR / \ + sizeof(uint32_t)) + 1) + +/** @} */ + +/** + * @name Object model + * @{ + */ + +#define TYPE_AW_H3_SYSCTRL "allwinner-h3-sysctrl" +OBJECT_DECLARE_SIMPLE_TYPE(AwH3SysCtrlState, AW_H3_SYSCTRL) + +/** @} */ + +/** + * Allwinner H3 System Control object instance state + */ +struct AwH3SysCtrlState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Maps I/O registers in physical memory */ + MemoryRegion iomem; + + /** Array of hardware registers */ + uint32_t regs[AW_H3_SYSCTRL_REGS_NUM]; + +}; + +#endif /* HW_MISC_ALLWINNER_H3_SYSCTRL_H */ diff --git a/include/hw/misc/allwinner-sid.h b/include/hw/misc/allwinner-sid.h new file mode 100644 index 000000000..3bfa887a9 --- /dev/null +++ b/include/hw/misc/allwinner-sid.h @@ -0,0 +1,59 @@ +/* + * Allwinner Security ID emulation + * + * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_MISC_ALLWINNER_SID_H +#define HW_MISC_ALLWINNER_SID_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "qemu/uuid.h" + +/** + * Object model + * @{ + */ + +#define TYPE_AW_SID "allwinner-sid" +OBJECT_DECLARE_SIMPLE_TYPE(AwSidState, AW_SID) + +/** @} */ + +/** + * Allwinner Security ID object instance state + */ +struct AwSidState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Maps I/O registers in physical memory */ + MemoryRegion iomem; + + /** Control register defines how and what to read */ + uint32_t control; + + /** RdKey register contains the data retrieved by the device */ + uint32_t rdkey; + + /** Stores the emulated device identifier */ + QemuUUID identifier; + +}; + +#endif /* HW_MISC_ALLWINNER_SID_H */ diff --git a/include/hw/misc/arm11scu.h b/include/hw/misc/arm11scu.h new file mode 100644 index 000000000..e5c0282ae --- /dev/null +++ b/include/hw/misc/arm11scu.h @@ -0,0 +1,30 @@ +/* + * ARM11MPCore Snoop Control Unit (SCU) emulation + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2013 SUSE LINUX Products GmbH + * Written by Paul Brook and Andreas Färber + * + * This code is licensed under the GPL. + */ + +#ifndef HW_MISC_ARM11SCU_H +#define HW_MISC_ARM11SCU_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ARM11_SCU "arm11-scu" +OBJECT_DECLARE_SIMPLE_TYPE(ARM11SCUState, ARM11_SCU) + +struct ARM11SCUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint32_t control; + uint32_t num_cpu; + MemoryRegion iomem; +}; + +#endif diff --git a/include/hw/misc/arm_integrator_debug.h b/include/hw/misc/arm_integrator_debug.h new file mode 100644 index 000000000..798b08216 --- /dev/null +++ b/include/hw/misc/arm_integrator_debug.h @@ -0,0 +1,19 @@ +/* + * ARM Integrator Board Debug, switch and LED section + * + * Browse the data sheet: + * + * https://developer.arm.com/documentation/dui0159/b/peripherals-and-interfaces/debug-leds-and-dip-switch-interface + * + * Copyright (c) 2013 Alex Bennée <alex@bennee.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef ARM_INTEGRATOR_DEBUG_H +#define ARM_INTEGRATOR_DEBUG_H + +#define TYPE_INTEGRATOR_DEBUG "integrator_debug" + +#endif diff --git a/include/hw/misc/armsse-cpu-pwrctrl.h b/include/hw/misc/armsse-cpu-pwrctrl.h new file mode 100644 index 000000000..51d45ede7 --- /dev/null +++ b/include/hw/misc/armsse-cpu-pwrctrl.h @@ -0,0 +1,40 @@ +/* + * ARM SSE CPU PWRCTRL register block + * + * Copyright (c) 2021 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "CPU<N>_PWRCTRL block" which is part of the + * Arm Corstone SSE-300 Example Subsystem and documented in + * https://developer.arm.com/documentation/101773/0000 + * + * QEMU interface: + * + sysbus MMIO region 0: the register bank + */ + +#ifndef HW_MISC_ARMSSE_CPU_PWRCTRL_H +#define HW_MISC_ARMSSE_CPU_PWRCTRL_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ARMSSE_CPU_PWRCTRL "armsse-cpu-pwrctrl" +OBJECT_DECLARE_SIMPLE_TYPE(ARMSSECPUPwrCtrl, ARMSSE_CPU_PWRCTRL) + +struct ARMSSECPUPwrCtrl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t cpupwrcfg; +}; + +#endif diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h new file mode 100644 index 000000000..9c0926322 --- /dev/null +++ b/include/hw/misc/armsse-cpuid.h @@ -0,0 +1,42 @@ +/* + * ARM SSE-200 CPU_IDENTITY register block + * + * Copyright (c) 2019 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "CPU_IDENTITY" register block which is part of the + * Arm SSE-200 and documented in + * https://developer.arm.com/documentation/101104/latest/ + * + * QEMU interface: + * + QOM property "CPUID": the value to use for the CPUID register + * + sysbus MMIO region 0: the system information register bank + */ + +#ifndef HW_MISC_ARMSSE_CPUID_H +#define HW_MISC_ARMSSE_CPUID_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ARMSSE_CPUID "armsse-cpuid" +OBJECT_DECLARE_SIMPLE_TYPE(ARMSSECPUID, ARMSSE_CPUID) + +struct ARMSSECPUID { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + /* Properties */ + uint32_t cpuid; +}; + +#endif diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h new file mode 100644 index 000000000..41925ded8 --- /dev/null +++ b/include/hw/misc/armsse-mhu.h @@ -0,0 +1,45 @@ +/* + * ARM SSE-200 Message Handling Unit (MHU) + * + * Copyright (c) 2019 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the Message Handling Unit (MHU) which is part of the + * Arm SSE-200 and documented in + * https://developer.arm.com/documentation/101104/latest/ + * + * QEMU interface: + * + sysbus MMIO region 0: the system information register bank + * + sysbus IRQ 0: interrupt for CPU 0 + * + sysbus IRQ 1: interrupt for CPU 1 + */ + +#ifndef HW_MISC_ARMSSE_MHU_H +#define HW_MISC_ARMSSE_MHU_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ARMSSE_MHU "armsse-mhu" +OBJECT_DECLARE_SIMPLE_TYPE(ARMSSEMHU, ARMSSE_MHU) + +struct ARMSSEMHU { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq cpu0irq; + qemu_irq cpu1irq; + + uint32_t cpu0intr; + uint32_t cpu1intr; +}; + +#endif diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h new file mode 100644 index 000000000..ba6daccf3 --- /dev/null +++ b/include/hw/misc/armv7m_ras.h @@ -0,0 +1,37 @@ +/* + * Arm M-profile RAS (Reliability, Availability and Serviceability) block + * + * Copyright (c) 2021 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the RAS register block of an M-profile CPU + * (the registers starting at 0xE0005000 with ERRFRn). + * + * QEMU interface: + * + sysbus MMIO region 0: the register bank + * + * The QEMU implementation currently provides "minimal RAS" only. + */ + +#ifndef HW_MISC_ARMV7M_RAS_H +#define HW_MISC_ARMV7M_RAS_H + +#include "hw/sysbus.h" + +#define TYPE_ARMV7M_RAS "armv7m-ras" +OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS) + +struct ARMv7MRAS { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; +}; + +#endif diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h new file mode 100644 index 000000000..94d5ada95 --- /dev/null +++ b/include/hw/misc/aspeed_hace.h @@ -0,0 +1,43 @@ +/* + * ASPEED Hash and Crypto Engine + * + * Copyright (C) 2021 IBM Corp. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ASPEED_HACE_H +#define ASPEED_HACE_H + +#include "hw/sysbus.h" + +#define TYPE_ASPEED_HACE "aspeed.hace" +#define TYPE_ASPEED_AST2400_HACE TYPE_ASPEED_HACE "-ast2400" +#define TYPE_ASPEED_AST2500_HACE TYPE_ASPEED_HACE "-ast2500" +#define TYPE_ASPEED_AST2600_HACE TYPE_ASPEED_HACE "-ast2600" +OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE) + +#define ASPEED_HACE_NR_REGS (0x64 >> 2) + +struct AspeedHACEState { + SysBusDevice parent; + + MemoryRegion iomem; + qemu_irq irq; + + uint32_t regs[ASPEED_HACE_NR_REGS]; + + MemoryRegion *dram_mr; + AddressSpace dram_as; +}; + + +struct AspeedHACEClass { + SysBusDeviceClass parent_class; + + uint32_t src_mask; + uint32_t dest_mask; + uint32_t hash_mask; +}; + +#endif /* _ASPEED_HACE_H_ */ diff --git a/include/hw/misc/aspeed_lpc.h b/include/hw/misc/aspeed_lpc.h new file mode 100644 index 000000000..df418cfcd --- /dev/null +++ b/include/hw/misc/aspeed_lpc.h @@ -0,0 +1,47 @@ +/* + * ASPEED LPC Controller + * + * Copyright (C) 2017-2018 IBM Corp. + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + */ + +#ifndef ASPEED_LPC_H +#define ASPEED_LPC_H + +#include "hw/sysbus.h" + +#include <stdint.h> + +#define TYPE_ASPEED_LPC "aspeed.lpc" +#define ASPEED_LPC(obj) OBJECT_CHECK(AspeedLPCState, (obj), TYPE_ASPEED_LPC) + +#define ASPEED_LPC_NR_REGS (0x260 >> 2) + +enum aspeed_lpc_subdevice { + aspeed_lpc_kcs_1 = 0, + aspeed_lpc_kcs_2, + aspeed_lpc_kcs_3, + aspeed_lpc_kcs_4, + aspeed_lpc_ibt, +}; + +#define ASPEED_LPC_NR_SUBDEVS 5 + +typedef struct AspeedLPCState { + /* <private> */ + SysBusDevice parent; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq irq; + + qemu_irq subdevice_irqs[ASPEED_LPC_NR_SUBDEVS]; + uint32_t subdevice_irqs_pending; + + uint32_t regs[ASPEED_LPC_NR_REGS]; + uint32_t hicr7; +} AspeedLPCState; + +#endif /* _ASPEED_LPC_H_ */ diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h new file mode 100644 index 000000000..c14aff2bc --- /dev/null +++ b/include/hw/misc/aspeed_scu.h @@ -0,0 +1,319 @@ +/* + * ASPEED System Control Unit + * + * Andrew Jeffery <andrew@aj.id.au> + * + * Copyright 2016 IBM Corp. + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + */ +#ifndef ASPEED_SCU_H +#define ASPEED_SCU_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ASPEED_SCU "aspeed.scu" +OBJECT_DECLARE_TYPE(AspeedSCUState, AspeedSCUClass, ASPEED_SCU) +#define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400" +#define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500" +#define TYPE_ASPEED_2600_SCU TYPE_ASPEED_SCU "-ast2600" + +#define ASPEED_SCU_NR_REGS (0x1A8 >> 2) +#define ASPEED_AST2600_SCU_NR_REGS (0xE20 >> 2) + +struct AspeedSCUState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t regs[ASPEED_AST2600_SCU_NR_REGS]; + uint32_t silicon_rev; + uint32_t hw_strap1; + uint32_t hw_strap2; + uint32_t hw_prot_key; +}; + +#define AST2400_A0_SILICON_REV 0x02000303U +#define AST2400_A1_SILICON_REV 0x02010303U +#define AST2500_A0_SILICON_REV 0x04000303U +#define AST2500_A1_SILICON_REV 0x04010303U +#define AST2600_A0_SILICON_REV 0x05000303U +#define AST2600_A1_SILICON_REV 0x05010303U +#define AST2600_A2_SILICON_REV 0x05020303U +#define AST2600_A3_SILICON_REV 0x05030303U + +#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04) + +extern bool is_supported_silicon_rev(uint32_t silicon_rev); + + +struct AspeedSCUClass { + SysBusDeviceClass parent_class; + + const uint32_t *resets; + uint32_t (*calc_hpll)(AspeedSCUState *s, uint32_t hpll_reg); + uint32_t apb_divider; + uint32_t nr_regs; + const MemoryRegionOps *ops; +}; + +#define ASPEED_SCU_PROT_KEY 0x1688A8A8 + +uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s); + +/* + * Extracted from Aspeed SDK v00.03.21. Fixes and extra definitions + * were added. + * + * Original header file : + * arch/arm/mach-aspeed/include/mach/regs-scu.h + * + * Copyright (C) 2012-2020 ASPEED Technology Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * History : + * 1. 2012/12/29 Ryan Chen Create + */ + +/* SCU08 Clock Selection Register + * + * 31 Enable Video Engine clock dynamic slow down + * 30:28 Video Engine clock slow down setting + * 27 2D Engine GCLK clock source selection + * 26 2D Engine GCLK clock throttling enable + * 25:23 APB PCLK divider selection + * 22:20 LPC Host LHCLK divider selection + * 19 LPC Host LHCLK clock generation/output enable control + * 18:16 MAC AHB bus clock divider selection + * 15 SD/SDIO clock running enable + * 14:12 SD/SDIO divider selection + * 11 Reserved + * 10:8 Video port output clock delay control bit + * 7 ARM CPU/AHB clock slow down enable + * 6:4 ARM CPU/AHB clock slow down setting + * 3:2 ECLK clock source selection + * 1 CPU/AHB clock slow down idle timer + * 0 CPU/AHB clock dynamic slow down enable (defined in bit[6:4]) + */ +#define SCU_CLK_GET_PCLK_DIV(x) (((x) >> 23) & 0x7) + +/* SCU24 H-PLL Parameter Register (for Aspeed AST2400 SOC) + * + * 18 H-PLL parameter selection + * 0: Select H-PLL by strapping resistors + * 1: Select H-PLL by the programmed registers (SCU24[17:0]) + * 17 Enable H-PLL bypass mode + * 16 Turn off H-PLL + * 10:5 H-PLL Numerator + * 4 H-PLL Output Divider + * 3:0 H-PLL Denumerator + * + * (Output frequency) = 24MHz * (2-OD) * [(Numerator+2) / (Denumerator+1)] + */ + +#define SCU_AST2400_H_PLL_PROGRAMMED (0x1 << 18) +#define SCU_AST2400_H_PLL_BYPASS_EN (0x1 << 17) +#define SCU_AST2400_H_PLL_OFF (0x1 << 16) + +/* SCU24 H-PLL Parameter Register (for Aspeed AST2500 SOC) + * + * 21 Enable H-PLL reset + * 20 Enable H-PLL bypass mode + * 19 Turn off H-PLL + * 18:13 H-PLL Post Divider + * 12:5 H-PLL Numerator (M) + * 4:0 H-PLL Denumerator (N) + * + * (Output frequency) = CLKIN(24MHz) * [(M+1) / (N+1)] / (P+1) + * + * The default frequency is 792Mhz when CLKIN = 24MHz + */ + +#define SCU_H_PLL_BYPASS_EN (0x1 << 20) +#define SCU_H_PLL_OFF (0x1 << 19) + +/* SCU70 Hardware Strapping Register definition (for Aspeed AST2400 SOC) + * + * 31:29 Software defined strapping registers + * 28:27 DRAM size setting (for VGA driver use) + * 26:24 DRAM configuration setting + * 23 Enable 25 MHz reference clock input + * 22 Enable GPIOE pass-through mode + * 21 Enable GPIOD pass-through mode + * 20 Disable LPC to decode SuperIO 0x2E/0x4E address + * 19 Disable ACPI function + * 23,18 Clock source selection + * 17 Enable BMC 2nd boot watchdog timer + * 16 SuperIO configuration address selection + * 15 VGA Class Code selection + * 14 Enable LPC dedicated reset pin function + * 13:12 SPI mode selection + * 11:10 CPU/AHB clock frequency ratio selection + * 9:8 H-PLL default clock frequency selection + * 7 Define MAC#2 interface + * 6 Define MAC#1 interface + * 5 Enable VGA BIOS ROM + * 4 Boot flash memory extended option + * 3:2 VGA memory size selection + * 1:0 BMC CPU boot code selection + */ +#define SCU_AST2400_HW_STRAP_SW_DEFINE(x) ((x) << 29) +#define SCU_AST2400_HW_STRAP_SW_DEFINE_MASK (0x7 << 29) + +#define SCU_AST2400_HW_STRAP_DRAM_SIZE(x) ((x) << 27) +#define SCU_AST2400_HW_STRAP_DRAM_SIZE_MASK (0x3 << 27) +#define DRAM_SIZE_64MB 0 +#define DRAM_SIZE_128MB 1 +#define DRAM_SIZE_256MB 2 +#define DRAM_SIZE_512MB 3 + +#define SCU_AST2400_HW_STRAP_DRAM_CONFIG(x) ((x) << 24) +#define SCU_AST2400_HW_STRAP_DRAM_CONFIG_MASK (0x7 << 24) + +#define SCU_HW_STRAP_GPIOE_PT_EN (0x1 << 22) +#define SCU_HW_STRAP_GPIOD_PT_EN (0x1 << 21) +#define SCU_HW_STRAP_LPC_DEC_SUPER_IO (0x1 << 20) +#define SCU_AST2400_HW_STRAP_ACPI_DIS (0x1 << 19) + +/* bit 23, 18 [1,0] */ +#define SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(x) (((((x) & 0x3) >> 1) << 23) \ + | (((x) & 0x1) << 18)) +#define SCU_AST2400_HW_STRAP_GET_CLK_SOURCE(x) (((((x) >> 23) & 0x1) << 1) \ + | (((x) >> 18) & 0x1)) +#define SCU_AST2400_HW_STRAP_CLK_SOURCE_MASK ((0x1 << 23) | (0x1 << 18)) +#define SCU_HW_STRAP_CLK_25M_IN (0x1 << 23) +#define AST2400_CLK_24M_IN 0 +#define AST2400_CLK_48M_IN 1 +#define AST2400_CLK_25M_IN_24M_USB_CKI 2 +#define AST2400_CLK_25M_IN_48M_USB_CKI 3 + +#define SCU_HW_STRAP_CLK_48M_IN (0x1 << 18) +#define SCU_HW_STRAP_2ND_BOOT_WDT (0x1 << 17) +#define SCU_HW_STRAP_SUPER_IO_CONFIG (0x1 << 16) +#define SCU_HW_STRAP_VGA_CLASS_CODE (0x1 << 15) +#define SCU_HW_STRAP_LPC_RESET_PIN (0x1 << 14) + +#define SCU_HW_STRAP_SPI_MODE(x) ((x) << 12) +#define SCU_HW_STRAP_SPI_MODE_MASK (0x3 << 12) +#define SCU_HW_STRAP_SPI_DIS 0 +#define SCU_HW_STRAP_SPI_MASTER 1 +#define SCU_HW_STRAP_SPI_M_S_EN 2 +#define SCU_HW_STRAP_SPI_PASS_THROUGH 3 + +#define SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(x) ((x) << 10) +#define SCU_AST2400_HW_STRAP_GET_CPU_AHB_RATIO(x) (((x) >> 10) & 3) +#define SCU_AST2400_HW_STRAP_CPU_AHB_RATIO_MASK (0x3 << 10) +#define AST2400_CPU_AHB_RATIO_1_1 0 +#define AST2400_CPU_AHB_RATIO_2_1 1 +#define AST2400_CPU_AHB_RATIO_4_1 2 +#define AST2400_CPU_AHB_RATIO_3_1 3 + +#define SCU_AST2400_HW_STRAP_GET_H_PLL_CLK(x) (((x) >> 8) & 0x3) +#define SCU_AST2400_HW_STRAP_H_PLL_CLK_MASK (0x3 << 8) +#define AST2400_CPU_384MHZ 0 +#define AST2400_CPU_360MHZ 1 +#define AST2400_CPU_336MHZ 2 +#define AST2400_CPU_408MHZ 3 + +#define SCU_HW_STRAP_MAC1_RGMII (0x1 << 7) +#define SCU_HW_STRAP_MAC0_RGMII (0x1 << 6) +#define SCU_HW_STRAP_VGA_BIOS_ROM (0x1 << 5) +#define SCU_HW_STRAP_SPI_WIDTH (0x1 << 4) + +#define SCU_HW_STRAP_VGA_SIZE_GET(x) (((x) >> 2) & 0x3) +#define SCU_HW_STRAP_VGA_MASK (0x3 << 2) +#define SCU_HW_STRAP_VGA_SIZE_SET(x) ((x) << 2) +#define VGA_8M_DRAM 0 +#define VGA_16M_DRAM 1 +#define VGA_32M_DRAM 2 +#define VGA_64M_DRAM 3 + +#define SCU_AST2400_HW_STRAP_BOOT_MODE(x) (x) +#define AST2400_NOR_BOOT 0 +#define AST2400_NAND_BOOT 1 +#define AST2400_SPI_BOOT 2 +#define AST2400_DIS_BOOT 3 + +/* + * SCU70 Hardware strapping register definition (for Aspeed AST2500 + * SoC and higher) + * + * 31 Enable SPI Flash Strap Auto Fetch Mode + * 30 Enable GPIO Strap Mode + * 29 Select UART Debug Port + * 28 Reserved (1) + * 27 Enable fast reset mode for ARM ICE debugger + * 26 Enable eSPI flash mode + * 25 Enable eSPI mode + * 24 Select DDR4 SDRAM + * 23 Select 25 MHz reference clock input mode + * 22 Enable GPIOE pass-through mode + * 21 Enable GPIOD pass-through mode + * 20 Disable LPC to decode SuperIO 0x2E/0x4E address + * 19 Enable ACPI function + * 18 Select USBCKI input frequency + * 17 Enable BMC 2nd boot watchdog timer + * 16 SuperIO configuration address selection + * 15 VGA Class Code selection + * 14 Select dedicated LPC reset input + * 13:12 SPI mode selection + * 11:9 AXI/AHB clock frequency ratio selection + * 8 Reserved (0) + * 7 Define MAC#2 interface + * 6 Define MAC#1 interface + * 5 Enable dedicated VGA BIOS ROM + * 4 Reserved (0) + * 3:2 VGA memory size selection + * 1 Reserved (1) + * 0 Disable CPU boot + */ +#define SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE (0x1 << 31) +#define SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE (0x1 << 30) +#define SCU_AST2500_HW_STRAP_UART_DEBUG (0x1 << 29) +#define UART_DEBUG_UART1 0 +#define UART_DEBUG_UART5 1 +#define SCU_AST2500_HW_STRAP_RESERVED28 (0x1 << 28) + +#define SCU_AST2500_HW_STRAP_FAST_RESET_DBG (0x1 << 27) +#define SCU_AST2500_HW_STRAP_ESPI_FLASH_ENABLE (0x1 << 26) +#define SCU_AST2500_HW_STRAP_ESPI_ENABLE (0x1 << 25) +#define SCU_AST2500_HW_STRAP_DDR4_ENABLE (0x1 << 24) +#define SCU_AST2500_HW_STRAP_25HZ_CLOCK_MODE (0x1 << 23) + +#define SCU_AST2500_HW_STRAP_ACPI_ENABLE (0x1 << 19) +#define SCU_AST2500_HW_STRAP_USBCKI_FREQ (0x1 << 18) +#define USBCKI_FREQ_24MHZ 0 +#define USBCKI_FREQ_28MHZ 1 + +#define SCU_AST2500_HW_STRAP_SET_AXI_AHB_RATIO(x) ((x) << 9) +#define SCU_AST2500_HW_STRAP_GET_AXI_AHB_RATIO(x) (((x) >> 9) & 7) +#define SCU_AST2500_HW_STRAP_CPU_AXI_RATIO_MASK (0x7 << 9) +#define AXI_AHB_RATIO_UNDEFINED 0 +#define AXI_AHB_RATIO_2_1 1 +#define AXI_AHB_RATIO_3_1 2 +#define AXI_AHB_RATIO_4_1 3 +#define AXI_AHB_RATIO_5_1 4 +#define AXI_AHB_RATIO_6_1 5 +#define AXI_AHB_RATIO_7_1 6 +#define AXI_AHB_RATIO_8_1 7 + +#define SCU_AST2500_HW_STRAP_RESERVED1 (0x1 << 1) +#define SCU_AST2500_HW_STRAP_DIS_BOOT (0x1 << 0) + +#define AST2500_HW_STRAP1_DEFAULTS ( \ + SCU_AST2500_HW_STRAP_RESERVED28 | \ + SCU_HW_STRAP_2ND_BOOT_WDT | \ + SCU_HW_STRAP_VGA_CLASS_CODE | \ + SCU_HW_STRAP_LPC_RESET_PIN | \ + SCU_AST2500_HW_STRAP_SET_AXI_AHB_RATIO(AXI_AHB_RATIO_2_1) | \ + SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \ + SCU_AST2500_HW_STRAP_RESERVED1) + +#endif /* ASPEED_SCU_H */ diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h new file mode 100644 index 000000000..ec2d59a14 --- /dev/null +++ b/include/hw/misc/aspeed_sdmc.h @@ -0,0 +1,56 @@ +/* + * ASPEED SDRAM Memory Controller + * + * Copyright (C) 2016 IBM Corp. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#ifndef ASPEED_SDMC_H +#define ASPEED_SDMC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ASPEED_SDMC "aspeed.sdmc" +OBJECT_DECLARE_TYPE(AspeedSDMCState, AspeedSDMCClass, ASPEED_SDMC) +#define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400" +#define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500" +#define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600" + +/* + * SDMC has 174 documented registers. In addition the u-boot device tree + * describes the following regions: + * - PHY status regs at offset 0x400, length 0x200 + * - PHY setting regs at offset 0x100, length 0x300 + * + * There are two sets of MRS (Mode Registers) configuration in ast2600 memory + * system: one is in the SDRAM MC (memory controller) which is used in run + * time, and the other is in the DDR-PHY IP which is used during DDR-PHY + * training. + */ +#define ASPEED_SDMC_NR_REGS (0x500 >> 2) + +struct AspeedSDMCState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t regs[ASPEED_SDMC_NR_REGS]; + uint64_t ram_size; + uint64_t max_ram_size; +}; + + +struct AspeedSDMCClass { + SysBusDeviceClass parent_class; + + uint64_t max_ram_size; + const uint64_t *valid_ram_sizes; + uint32_t (*compute_conf)(AspeedSDMCState *s, uint32_t data); + void (*write)(AspeedSDMCState *s, uint32_t reg, uint32_t data); +}; + +#endif /* ASPEED_SDMC_H */ diff --git a/include/hw/misc/aspeed_xdma.h b/include/hw/misc/aspeed_xdma.h new file mode 100644 index 000000000..b1478fd1c --- /dev/null +++ b/include/hw/misc/aspeed_xdma.h @@ -0,0 +1,46 @@ +/* + * ASPEED XDMA Controller + * Eddie James <eajames@linux.ibm.com> + * + * Copyright (C) 2019 IBM Corp. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ASPEED_XDMA_H +#define ASPEED_XDMA_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_ASPEED_XDMA "aspeed.xdma" +#define TYPE_ASPEED_2400_XDMA TYPE_ASPEED_XDMA "-ast2400" +#define TYPE_ASPEED_2500_XDMA TYPE_ASPEED_XDMA "-ast2500" +#define TYPE_ASPEED_2600_XDMA TYPE_ASPEED_XDMA "-ast2600" +OBJECT_DECLARE_TYPE(AspeedXDMAState, AspeedXDMAClass, ASPEED_XDMA) + +#define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE / sizeof(uint32_t)) +#define ASPEED_XDMA_REG_SIZE 0x7C + +struct AspeedXDMAState { + SysBusDevice parent; + + MemoryRegion iomem; + qemu_irq irq; + + char bmc_cmdq_readp_set; + uint32_t regs[ASPEED_XDMA_NUM_REGS]; +}; + +struct AspeedXDMAClass { + SysBusDeviceClass parent_class; + + uint8_t cmdq_endp; + uint8_t cmdq_wrp; + uint8_t cmdq_rdp; + uint8_t intr_ctrl; + uint32_t intr_ctrl_mask; + uint8_t intr_status; + uint32_t intr_complete; +}; + +#endif /* ASPEED_XDMA_H */ diff --git a/include/hw/misc/auxbus.h b/include/hw/misc/auxbus.h new file mode 100644 index 000000000..b05799d2f --- /dev/null +++ b/include/hw/misc/auxbus.h @@ -0,0 +1,142 @@ +/* + * auxbus.h + * + * Copyright (C)2014 : GreenSocs Ltd + * http://www.greensocs.com/ , email: info@greensocs.com + * + * Developed by : + * Frederic Konrad <fred.konrad@greensocs.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option)any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef HW_MISC_AUXBUS_H +#define HW_MISC_AUXBUS_H + +#include "exec/memory.h" +#include "hw/qdev-core.h" +#include "qom/object.h" + +typedef struct AUXSlave AUXSlave; +typedef enum AUXCommand AUXCommand; +typedef enum AUXReply AUXReply; + +#define TYPE_AUXTOI2C "aux-to-i2c-bridge" +OBJECT_DECLARE_SIMPLE_TYPE(AUXTOI2CState, AUXTOI2C) + +enum AUXCommand { + WRITE_I2C = 0, + READ_I2C = 1, + WRITE_I2C_STATUS = 2, + WRITE_I2C_MOT = 4, + READ_I2C_MOT = 5, + WRITE_AUX = 8, + READ_AUX = 9 +}; + +enum AUXReply { + AUX_I2C_ACK = 0, + AUX_NACK = 1, + AUX_DEFER = 2, + AUX_I2C_NACK = 4, + AUX_I2C_DEFER = 8 +}; + +#define TYPE_AUX_BUS "aux-bus" +OBJECT_DECLARE_SIMPLE_TYPE(AUXBus, AUX_BUS) + +struct AUXBus { + /* < private > */ + BusState qbus; + + /* < public > */ + AUXSlave *current_dev; + AUXSlave *dev; + uint32_t last_i2c_address; + AUXCommand last_transaction; + + AUXTOI2CState *bridge; + + MemoryRegion *aux_io; + AddressSpace aux_addr_space; +}; + +#define TYPE_AUX_SLAVE "aux-slave" +OBJECT_DECLARE_SIMPLE_TYPE(AUXSlave, AUX_SLAVE) + +struct AUXSlave { + /* < private > */ + DeviceState parent_obj; + + /* < public > */ + MemoryRegion *mmio; +}; + +/** + * aux_bus_init: Initialize an AUX bus. + * + * Returns the new AUX bus created. + * + * @parent The device where this bus is located. + * @name The name of the bus. + */ +AUXBus *aux_bus_init(DeviceState *parent, const char *name); + +/** + * aux_bus_realize: Realize an AUX bus. + * + * @bus: The AUX bus. + */ +void aux_bus_realize(AUXBus *bus); + +/* + * aux_request: Make a request on the bus. + * + * Returns the reply of the request. + * + * @bus Ths bus where the request happen. + * @cmd The command requested. + * @address The 20bits address of the slave. + * @len The length of the read or write. + * @data The data array which will be filled or read during transfer. + */ +AUXReply aux_request(AUXBus *bus, AUXCommand cmd, uint32_t address, + uint8_t len, uint8_t *data); + +/* + * aux_get_i2c_bus: Get the i2c bus for I2C over AUX command. + * + * Returns the i2c bus associated to this AUX bus. + * + * @bus The AUX bus. + */ +I2CBus *aux_get_i2c_bus(AUXBus *bus); + +/* + * aux_init_mmio: Init an mmio for an AUX slave. + * + * @aux_slave The AUX slave. + * @mmio The mmio to be registered. + */ +void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio); + +/* aux_map_slave: Map the mmio for an AUX slave on the bus. + * + * @dev The AUX slave. + * @addr The address for the slave's mmio. + */ +void aux_map_slave(AUXSlave *dev, hwaddr addr); + +#endif /* HW_MISC_AUXBUS_H */ diff --git a/include/hw/misc/avr_power.h b/include/hw/misc/avr_power.h new file mode 100644 index 000000000..388e421aa --- /dev/null +++ b/include/hw/misc/avr_power.h @@ -0,0 +1,46 @@ +/* + * AVR Power Reduction Management + * + * Copyright (c) 2019-2020 Michael Rolnik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_MISC_AVR_POWER_H +#define HW_MISC_AVR_POWER_H + +#include "hw/sysbus.h" +#include "qom/object.h" + + +#define TYPE_AVR_MASK "avr-power" +OBJECT_DECLARE_SIMPLE_TYPE(AVRMaskState, AVR_MASK) + +struct AVRMaskState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion iomem; + + uint8_t val; + qemu_irq irq[8]; +}; + +#endif /* HW_MISC_AVR_POWER_H */ diff --git a/include/hw/misc/bcm2835_cprman.h b/include/hw/misc/bcm2835_cprman.h new file mode 100644 index 000000000..3df4ceedd --- /dev/null +++ b/include/hw/misc/bcm2835_cprman.h @@ -0,0 +1,210 @@ +/* + * BCM2835 CPRMAN clock manager + * + * Copyright (c) 2020 Luc Michel <luc@lmichel.fr> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_CPRMAN_H +#define HW_MISC_CPRMAN_H + +#include "hw/sysbus.h" +#include "hw/qdev-clock.h" + +#define TYPE_BCM2835_CPRMAN "bcm2835-cprman" + +typedef struct BCM2835CprmanState BCM2835CprmanState; + +DECLARE_INSTANCE_CHECKER(BCM2835CprmanState, CPRMAN, + TYPE_BCM2835_CPRMAN) + +#define CPRMAN_NUM_REGS (0x2000 / sizeof(uint32_t)) + +typedef enum CprmanPll { + CPRMAN_PLLA = 0, + CPRMAN_PLLC, + CPRMAN_PLLD, + CPRMAN_PLLH, + CPRMAN_PLLB, + + CPRMAN_NUM_PLL +} CprmanPll; + +typedef enum CprmanPllChannel { + CPRMAN_PLLA_CHANNEL_DSI0 = 0, + CPRMAN_PLLA_CHANNEL_CORE, + CPRMAN_PLLA_CHANNEL_PER, + CPRMAN_PLLA_CHANNEL_CCP2, + + CPRMAN_PLLC_CHANNEL_CORE2, + CPRMAN_PLLC_CHANNEL_CORE1, + CPRMAN_PLLC_CHANNEL_PER, + CPRMAN_PLLC_CHANNEL_CORE0, + + CPRMAN_PLLD_CHANNEL_DSI0, + CPRMAN_PLLD_CHANNEL_CORE, + CPRMAN_PLLD_CHANNEL_PER, + CPRMAN_PLLD_CHANNEL_DSI1, + + CPRMAN_PLLH_CHANNEL_AUX, + CPRMAN_PLLH_CHANNEL_RCAL, + CPRMAN_PLLH_CHANNEL_PIX, + + CPRMAN_PLLB_CHANNEL_ARM, + + CPRMAN_NUM_PLL_CHANNEL, + + /* Special values used when connecting clock sources to clocks */ + CPRMAN_CLOCK_SRC_NORMAL = -1, + CPRMAN_CLOCK_SRC_FORCE_GROUND = -2, + CPRMAN_CLOCK_SRC_DSI0HSCK = -3, +} CprmanPllChannel; + +typedef enum CprmanClockMux { + CPRMAN_CLOCK_GNRIC, + CPRMAN_CLOCK_VPU, + CPRMAN_CLOCK_SYS, + CPRMAN_CLOCK_PERIA, + CPRMAN_CLOCK_PERII, + CPRMAN_CLOCK_H264, + CPRMAN_CLOCK_ISP, + CPRMAN_CLOCK_V3D, + CPRMAN_CLOCK_CAM0, + CPRMAN_CLOCK_CAM1, + CPRMAN_CLOCK_CCP2, + CPRMAN_CLOCK_DSI0E, + CPRMAN_CLOCK_DSI0P, + CPRMAN_CLOCK_DPI, + CPRMAN_CLOCK_GP0, + CPRMAN_CLOCK_GP1, + CPRMAN_CLOCK_GP2, + CPRMAN_CLOCK_HSM, + CPRMAN_CLOCK_OTP, + CPRMAN_CLOCK_PCM, + CPRMAN_CLOCK_PWM, + CPRMAN_CLOCK_SLIM, + CPRMAN_CLOCK_SMI, + CPRMAN_CLOCK_TEC, + CPRMAN_CLOCK_TD0, + CPRMAN_CLOCK_TD1, + CPRMAN_CLOCK_TSENS, + CPRMAN_CLOCK_TIMER, + CPRMAN_CLOCK_UART, + CPRMAN_CLOCK_VEC, + CPRMAN_CLOCK_PULSE, + CPRMAN_CLOCK_SDC, + CPRMAN_CLOCK_ARM, + CPRMAN_CLOCK_AVEO, + CPRMAN_CLOCK_EMMC, + CPRMAN_CLOCK_EMMC2, + + CPRMAN_NUM_CLOCK_MUX +} CprmanClockMux; + +typedef enum CprmanClockMuxSource { + CPRMAN_CLOCK_SRC_GND = 0, + CPRMAN_CLOCK_SRC_XOSC, + CPRMAN_CLOCK_SRC_TD0, + CPRMAN_CLOCK_SRC_TD1, + CPRMAN_CLOCK_SRC_PLLA, + CPRMAN_CLOCK_SRC_PLLC, + CPRMAN_CLOCK_SRC_PLLD, + CPRMAN_CLOCK_SRC_PLLH, + CPRMAN_CLOCK_SRC_PLLC_CORE1, + CPRMAN_CLOCK_SRC_PLLC_CORE2, + + CPRMAN_NUM_CLOCK_MUX_SRC +} CprmanClockMuxSource; + +typedef struct CprmanPllState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + CprmanPll id; + + uint32_t *reg_cm; + uint32_t *reg_a2w_ctrl; + uint32_t *reg_a2w_ana; /* ANA[0] .. ANA[3] */ + uint32_t prediv_mask; /* prediv bit in ana[1] */ + uint32_t *reg_a2w_frac; + + Clock *xosc_in; + Clock *out; +} CprmanPllState; + +typedef struct CprmanPllChannelState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + CprmanPllChannel id; + CprmanPll parent; + + uint32_t *reg_cm; + uint32_t hold_mask; + uint32_t load_mask; + uint32_t *reg_a2w_ctrl; + int fixed_divider; + + Clock *pll_in; + Clock *out; +} CprmanPllChannelState; + +typedef struct CprmanClockMuxState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + CprmanClockMux id; + + uint32_t *reg_ctl; + uint32_t *reg_div; + int int_bits; + int frac_bits; + + Clock *srcs[CPRMAN_NUM_CLOCK_MUX_SRC]; + Clock *out; + + /* + * Used by clock srcs update callback to retrieve both the clock and the + * source number. + */ + struct CprmanClockMuxState *backref[CPRMAN_NUM_CLOCK_MUX_SRC]; +} CprmanClockMuxState; + +typedef struct CprmanDsi0HsckMuxState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + CprmanClockMux id; + + uint32_t *reg_cm; + + Clock *plla_in; + Clock *plld_in; + Clock *out; +} CprmanDsi0HsckMuxState; + +struct BCM2835CprmanState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + CprmanPllState plls[CPRMAN_NUM_PLL]; + CprmanPllChannelState channels[CPRMAN_NUM_PLL_CHANNEL]; + CprmanClockMuxState clock_muxes[CPRMAN_NUM_CLOCK_MUX]; + CprmanDsi0HsckMuxState dsi0hsck_mux; + + uint32_t regs[CPRMAN_NUM_REGS]; + uint32_t xosc_freq; + + Clock *xosc; + Clock *gnd; +}; + +#endif diff --git a/include/hw/misc/bcm2835_cprman_internals.h b/include/hw/misc/bcm2835_cprman_internals.h new file mode 100644 index 000000000..339759b30 --- /dev/null +++ b/include/hw/misc/bcm2835_cprman_internals.h @@ -0,0 +1,1019 @@ +/* + * BCM2835 CPRMAN clock manager + * + * Copyright (c) 2020 Luc Michel <luc@lmichel.fr> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_CPRMAN_INTERNALS_H +#define HW_MISC_CPRMAN_INTERNALS_H + +#include "hw/registerfields.h" +#include "hw/misc/bcm2835_cprman.h" + +#define TYPE_CPRMAN_PLL "bcm2835-cprman-pll" +#define TYPE_CPRMAN_PLL_CHANNEL "bcm2835-cprman-pll-channel" +#define TYPE_CPRMAN_CLOCK_MUX "bcm2835-cprman-clock-mux" +#define TYPE_CPRMAN_DSI0HSCK_MUX "bcm2835-cprman-dsi0hsck-mux" + +DECLARE_INSTANCE_CHECKER(CprmanPllState, CPRMAN_PLL, + TYPE_CPRMAN_PLL) +DECLARE_INSTANCE_CHECKER(CprmanPllChannelState, CPRMAN_PLL_CHANNEL, + TYPE_CPRMAN_PLL_CHANNEL) +DECLARE_INSTANCE_CHECKER(CprmanClockMuxState, CPRMAN_CLOCK_MUX, + TYPE_CPRMAN_CLOCK_MUX) +DECLARE_INSTANCE_CHECKER(CprmanDsi0HsckMuxState, CPRMAN_DSI0HSCK_MUX, + TYPE_CPRMAN_DSI0HSCK_MUX) + +/* Register map */ + +/* PLLs */ +REG32(CM_PLLA, 0x104) + FIELD(CM_PLLA, LOADDSI0, 0, 1) + FIELD(CM_PLLA, HOLDDSI0, 1, 1) + FIELD(CM_PLLA, LOADCCP2, 2, 1) + FIELD(CM_PLLA, HOLDCCP2, 3, 1) + FIELD(CM_PLLA, LOADCORE, 4, 1) + FIELD(CM_PLLA, HOLDCORE, 5, 1) + FIELD(CM_PLLA, LOADPER, 6, 1) + FIELD(CM_PLLA, HOLDPER, 7, 1) + FIELD(CM_PLLx, ANARST, 8, 1) +REG32(CM_PLLC, 0x108) + FIELD(CM_PLLC, LOADCORE0, 0, 1) + FIELD(CM_PLLC, HOLDCORE0, 1, 1) + FIELD(CM_PLLC, LOADCORE1, 2, 1) + FIELD(CM_PLLC, HOLDCORE1, 3, 1) + FIELD(CM_PLLC, LOADCORE2, 4, 1) + FIELD(CM_PLLC, HOLDCORE2, 5, 1) + FIELD(CM_PLLC, LOADPER, 6, 1) + FIELD(CM_PLLC, HOLDPER, 7, 1) +REG32(CM_PLLD, 0x10c) + FIELD(CM_PLLD, LOADDSI0, 0, 1) + FIELD(CM_PLLD, HOLDDSI0, 1, 1) + FIELD(CM_PLLD, LOADDSI1, 2, 1) + FIELD(CM_PLLD, HOLDDSI1, 3, 1) + FIELD(CM_PLLD, LOADCORE, 4, 1) + FIELD(CM_PLLD, HOLDCORE, 5, 1) + FIELD(CM_PLLD, LOADPER, 6, 1) + FIELD(CM_PLLD, HOLDPER, 7, 1) +REG32(CM_PLLH, 0x110) + FIELD(CM_PLLH, LOADPIX, 0, 1) + FIELD(CM_PLLH, LOADAUX, 1, 1) + FIELD(CM_PLLH, LOADRCAL, 2, 1) +REG32(CM_PLLB, 0x170) + FIELD(CM_PLLB, LOADARM, 0, 1) + FIELD(CM_PLLB, HOLDARM, 1, 1) + +REG32(A2W_PLLA_CTRL, 0x1100) + FIELD(A2W_PLLx_CTRL, NDIV, 0, 10) + FIELD(A2W_PLLx_CTRL, PDIV, 12, 3) + FIELD(A2W_PLLx_CTRL, PWRDN, 16, 1) + FIELD(A2W_PLLx_CTRL, PRST_DISABLE, 17, 1) +REG32(A2W_PLLC_CTRL, 0x1120) +REG32(A2W_PLLD_CTRL, 0x1140) +REG32(A2W_PLLH_CTRL, 0x1160) +REG32(A2W_PLLB_CTRL, 0x11e0) + +REG32(A2W_PLLA_ANA0, 0x1010) +REG32(A2W_PLLA_ANA1, 0x1014) + FIELD(A2W_PLLx_ANA1, FB_PREDIV, 14, 1) +REG32(A2W_PLLA_ANA2, 0x1018) +REG32(A2W_PLLA_ANA3, 0x101c) + +REG32(A2W_PLLC_ANA0, 0x1030) +REG32(A2W_PLLC_ANA1, 0x1034) +REG32(A2W_PLLC_ANA2, 0x1038) +REG32(A2W_PLLC_ANA3, 0x103c) + +REG32(A2W_PLLD_ANA0, 0x1050) +REG32(A2W_PLLD_ANA1, 0x1054) +REG32(A2W_PLLD_ANA2, 0x1058) +REG32(A2W_PLLD_ANA3, 0x105c) + +REG32(A2W_PLLH_ANA0, 0x1070) +REG32(A2W_PLLH_ANA1, 0x1074) + FIELD(A2W_PLLH_ANA1, FB_PREDIV, 11, 1) +REG32(A2W_PLLH_ANA2, 0x1078) +REG32(A2W_PLLH_ANA3, 0x107c) + +REG32(A2W_PLLB_ANA0, 0x10f0) +REG32(A2W_PLLB_ANA1, 0x10f4) +REG32(A2W_PLLB_ANA2, 0x10f8) +REG32(A2W_PLLB_ANA3, 0x10fc) + +REG32(A2W_PLLA_FRAC, 0x1200) + FIELD(A2W_PLLx_FRAC, FRAC, 0, 20) +REG32(A2W_PLLC_FRAC, 0x1220) +REG32(A2W_PLLD_FRAC, 0x1240) +REG32(A2W_PLLH_FRAC, 0x1260) +REG32(A2W_PLLB_FRAC, 0x12e0) + +/* PLL channels */ +REG32(A2W_PLLA_DSI0, 0x1300) + FIELD(A2W_PLLx_CHANNELy, DIV, 0, 8) + FIELD(A2W_PLLx_CHANNELy, DISABLE, 8, 1) +REG32(A2W_PLLA_CORE, 0x1400) +REG32(A2W_PLLA_PER, 0x1500) +REG32(A2W_PLLA_CCP2, 0x1600) + +REG32(A2W_PLLC_CORE2, 0x1320) +REG32(A2W_PLLC_CORE1, 0x1420) +REG32(A2W_PLLC_PER, 0x1520) +REG32(A2W_PLLC_CORE0, 0x1620) + +REG32(A2W_PLLD_DSI0, 0x1340) +REG32(A2W_PLLD_CORE, 0x1440) +REG32(A2W_PLLD_PER, 0x1540) +REG32(A2W_PLLD_DSI1, 0x1640) + +REG32(A2W_PLLH_AUX, 0x1360) +REG32(A2W_PLLH_RCAL, 0x1460) +REG32(A2W_PLLH_PIX, 0x1560) +REG32(A2W_PLLH_STS, 0x1660) + +REG32(A2W_PLLB_ARM, 0x13e0) + +/* Clock muxes */ +REG32(CM_GNRICCTL, 0x000) + FIELD(CM_CLOCKx_CTL, SRC, 0, 4) + FIELD(CM_CLOCKx_CTL, ENABLE, 4, 1) + FIELD(CM_CLOCKx_CTL, KILL, 5, 1) + FIELD(CM_CLOCKx_CTL, GATE, 6, 1) + FIELD(CM_CLOCKx_CTL, BUSY, 7, 1) + FIELD(CM_CLOCKx_CTL, BUSYD, 8, 1) + FIELD(CM_CLOCKx_CTL, MASH, 9, 2) + FIELD(CM_CLOCKx_CTL, FLIP, 11, 1) +REG32(CM_GNRICDIV, 0x004) + FIELD(CM_CLOCKx_DIV, FRAC, 0, 12) +REG32(CM_VPUCTL, 0x008) +REG32(CM_VPUDIV, 0x00c) +REG32(CM_SYSCTL, 0x010) +REG32(CM_SYSDIV, 0x014) +REG32(CM_PERIACTL, 0x018) +REG32(CM_PERIADIV, 0x01c) +REG32(CM_PERIICTL, 0x020) +REG32(CM_PERIIDIV, 0x024) +REG32(CM_H264CTL, 0x028) +REG32(CM_H264DIV, 0x02c) +REG32(CM_ISPCTL, 0x030) +REG32(CM_ISPDIV, 0x034) +REG32(CM_V3DCTL, 0x038) +REG32(CM_V3DDIV, 0x03c) +REG32(CM_CAM0CTL, 0x040) +REG32(CM_CAM0DIV, 0x044) +REG32(CM_CAM1CTL, 0x048) +REG32(CM_CAM1DIV, 0x04c) +REG32(CM_CCP2CTL, 0x050) +REG32(CM_CCP2DIV, 0x054) +REG32(CM_DSI0ECTL, 0x058) +REG32(CM_DSI0EDIV, 0x05c) +REG32(CM_DSI0PCTL, 0x060) +REG32(CM_DSI0PDIV, 0x064) +REG32(CM_DPICTL, 0x068) +REG32(CM_DPIDIV, 0x06c) +REG32(CM_GP0CTL, 0x070) +REG32(CM_GP0DIV, 0x074) +REG32(CM_GP1CTL, 0x078) +REG32(CM_GP1DIV, 0x07c) +REG32(CM_GP2CTL, 0x080) +REG32(CM_GP2DIV, 0x084) +REG32(CM_HSMCTL, 0x088) +REG32(CM_HSMDIV, 0x08c) +REG32(CM_OTPCTL, 0x090) +REG32(CM_OTPDIV, 0x094) +REG32(CM_PCMCTL, 0x098) +REG32(CM_PCMDIV, 0x09c) +REG32(CM_PWMCTL, 0x0a0) +REG32(CM_PWMDIV, 0x0a4) +REG32(CM_SLIMCTL, 0x0a8) +REG32(CM_SLIMDIV, 0x0ac) +REG32(CM_SMICTL, 0x0b0) +REG32(CM_SMIDIV, 0x0b4) +REG32(CM_TCNTCTL, 0x0c0) +REG32(CM_TCNTCNT, 0x0c4) +REG32(CM_TECCTL, 0x0c8) +REG32(CM_TECDIV, 0x0cc) +REG32(CM_TD0CTL, 0x0d0) +REG32(CM_TD0DIV, 0x0d4) +REG32(CM_TD1CTL, 0x0d8) +REG32(CM_TD1DIV, 0x0dc) +REG32(CM_TSENSCTL, 0x0e0) +REG32(CM_TSENSDIV, 0x0e4) +REG32(CM_TIMERCTL, 0x0e8) +REG32(CM_TIMERDIV, 0x0ec) +REG32(CM_UARTCTL, 0x0f0) +REG32(CM_UARTDIV, 0x0f4) +REG32(CM_VECCTL, 0x0f8) +REG32(CM_VECDIV, 0x0fc) +REG32(CM_PULSECTL, 0x190) +REG32(CM_PULSEDIV, 0x194) +REG32(CM_SDCCTL, 0x1a8) +REG32(CM_SDCDIV, 0x1ac) +REG32(CM_ARMCTL, 0x1b0) +REG32(CM_AVEOCTL, 0x1b8) +REG32(CM_AVEODIV, 0x1bc) +REG32(CM_EMMCCTL, 0x1c0) +REG32(CM_EMMCDIV, 0x1c4) +REG32(CM_EMMC2CTL, 0x1d0) +REG32(CM_EMMC2DIV, 0x1d4) + +/* misc registers */ +REG32(CM_LOCK, 0x114) + FIELD(CM_LOCK, FLOCKH, 12, 1) + FIELD(CM_LOCK, FLOCKD, 11, 1) + FIELD(CM_LOCK, FLOCKC, 10, 1) + FIELD(CM_LOCK, FLOCKB, 9, 1) + FIELD(CM_LOCK, FLOCKA, 8, 1) + +REG32(CM_DSI0HSCK, 0x120) + FIELD(CM_DSI0HSCK, SELPLLD, 0, 1) + +/* + * This field is common to all registers. Each register write value must match + * the CPRMAN_PASSWORD magic value in its 8 MSB. + */ +FIELD(CPRMAN, PASSWORD, 24, 8) +#define CPRMAN_PASSWORD 0x5a + +/* PLL init info */ +typedef struct PLLInitInfo { + const char *name; + size_t cm_offset; + size_t a2w_ctrl_offset; + size_t a2w_ana_offset; + uint32_t prediv_mask; /* Prediv bit in ana[1] */ + size_t a2w_frac_offset; +} PLLInitInfo; + +#define FILL_PLL_INIT_INFO(pll_) \ + .cm_offset = R_CM_ ## pll_, \ + .a2w_ctrl_offset = R_A2W_ ## pll_ ## _CTRL, \ + .a2w_ana_offset = R_A2W_ ## pll_ ## _ANA0, \ + .a2w_frac_offset = R_A2W_ ## pll_ ## _FRAC + +static const PLLInitInfo PLL_INIT_INFO[] = { + [CPRMAN_PLLA] = { + .name = "plla", + .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, + FILL_PLL_INIT_INFO(PLLA), + }, + [CPRMAN_PLLC] = { + .name = "pllc", + .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, + FILL_PLL_INIT_INFO(PLLC), + }, + [CPRMAN_PLLD] = { + .name = "plld", + .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, + FILL_PLL_INIT_INFO(PLLD), + }, + [CPRMAN_PLLH] = { + .name = "pllh", + .prediv_mask = R_A2W_PLLH_ANA1_FB_PREDIV_MASK, + FILL_PLL_INIT_INFO(PLLH), + }, + [CPRMAN_PLLB] = { + .name = "pllb", + .prediv_mask = R_A2W_PLLx_ANA1_FB_PREDIV_MASK, + FILL_PLL_INIT_INFO(PLLB), + }, +}; + +#undef FILL_PLL_CHANNEL_INIT_INFO + +static inline void set_pll_init_info(BCM2835CprmanState *s, + CprmanPllState *pll, + CprmanPll id) +{ + pll->id = id; + pll->reg_cm = &s->regs[PLL_INIT_INFO[id].cm_offset]; + pll->reg_a2w_ctrl = &s->regs[PLL_INIT_INFO[id].a2w_ctrl_offset]; + pll->reg_a2w_ana = &s->regs[PLL_INIT_INFO[id].a2w_ana_offset]; + pll->prediv_mask = PLL_INIT_INFO[id].prediv_mask; + pll->reg_a2w_frac = &s->regs[PLL_INIT_INFO[id].a2w_frac_offset]; +} + + +/* PLL channel init info */ +typedef struct PLLChannelInitInfo { + const char *name; + CprmanPll parent; + size_t cm_offset; + uint32_t cm_hold_mask; + uint32_t cm_load_mask; + size_t a2w_ctrl_offset; + unsigned int fixed_divider; +} PLLChannelInitInfo; + +#define FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_) \ + .parent = CPRMAN_ ## pll_, \ + .cm_offset = R_CM_ ## pll_, \ + .cm_load_mask = R_CM_ ## pll_ ## _ ## LOAD ## channel_ ## _MASK, \ + .a2w_ctrl_offset = R_A2W_ ## pll_ ## _ ## channel_ + +#define FILL_PLL_CHANNEL_INIT_INFO(pll_, channel_) \ + FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_), \ + .cm_hold_mask = R_CM_ ## pll_ ## _ ## HOLD ## channel_ ## _MASK, \ + .fixed_divider = 1 + +#define FILL_PLL_CHANNEL_INIT_INFO_nohold(pll_, channel_) \ + FILL_PLL_CHANNEL_INIT_INFO_common(pll_, channel_), \ + .cm_hold_mask = 0 + +static PLLChannelInitInfo PLL_CHANNEL_INIT_INFO[] = { + [CPRMAN_PLLA_CHANNEL_DSI0] = { + .name = "plla-dsi0", + FILL_PLL_CHANNEL_INIT_INFO(PLLA, DSI0), + }, + [CPRMAN_PLLA_CHANNEL_CORE] = { + .name = "plla-core", + FILL_PLL_CHANNEL_INIT_INFO(PLLA, CORE), + }, + [CPRMAN_PLLA_CHANNEL_PER] = { + .name = "plla-per", + FILL_PLL_CHANNEL_INIT_INFO(PLLA, PER), + }, + [CPRMAN_PLLA_CHANNEL_CCP2] = { + .name = "plla-ccp2", + FILL_PLL_CHANNEL_INIT_INFO(PLLA, CCP2), + }, + + [CPRMAN_PLLC_CHANNEL_CORE2] = { + .name = "pllc-core2", + FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE2), + }, + [CPRMAN_PLLC_CHANNEL_CORE1] = { + .name = "pllc-core1", + FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE1), + }, + [CPRMAN_PLLC_CHANNEL_PER] = { + .name = "pllc-per", + FILL_PLL_CHANNEL_INIT_INFO(PLLC, PER), + }, + [CPRMAN_PLLC_CHANNEL_CORE0] = { + .name = "pllc-core0", + FILL_PLL_CHANNEL_INIT_INFO(PLLC, CORE0), + }, + + [CPRMAN_PLLD_CHANNEL_DSI0] = { + .name = "plld-dsi0", + FILL_PLL_CHANNEL_INIT_INFO(PLLD, DSI0), + }, + [CPRMAN_PLLD_CHANNEL_CORE] = { + .name = "plld-core", + FILL_PLL_CHANNEL_INIT_INFO(PLLD, CORE), + }, + [CPRMAN_PLLD_CHANNEL_PER] = { + .name = "plld-per", + FILL_PLL_CHANNEL_INIT_INFO(PLLD, PER), + }, + [CPRMAN_PLLD_CHANNEL_DSI1] = { + .name = "plld-dsi1", + FILL_PLL_CHANNEL_INIT_INFO(PLLD, DSI1), + }, + + [CPRMAN_PLLH_CHANNEL_AUX] = { + .name = "pllh-aux", + .fixed_divider = 1, + FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, AUX), + }, + [CPRMAN_PLLH_CHANNEL_RCAL] = { + .name = "pllh-rcal", + .fixed_divider = 10, + FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, RCAL), + }, + [CPRMAN_PLLH_CHANNEL_PIX] = { + .name = "pllh-pix", + .fixed_divider = 10, + FILL_PLL_CHANNEL_INIT_INFO_nohold(PLLH, PIX), + }, + + [CPRMAN_PLLB_CHANNEL_ARM] = { + .name = "pllb-arm", + FILL_PLL_CHANNEL_INIT_INFO(PLLB, ARM), + }, +}; + +#undef FILL_PLL_CHANNEL_INIT_INFO_nohold +#undef FILL_PLL_CHANNEL_INIT_INFO +#undef FILL_PLL_CHANNEL_INIT_INFO_common + +static inline void set_pll_channel_init_info(BCM2835CprmanState *s, + CprmanPllChannelState *channel, + CprmanPllChannel id) +{ + channel->id = id; + channel->parent = PLL_CHANNEL_INIT_INFO[id].parent; + channel->reg_cm = &s->regs[PLL_CHANNEL_INIT_INFO[id].cm_offset]; + channel->hold_mask = PLL_CHANNEL_INIT_INFO[id].cm_hold_mask; + channel->load_mask = PLL_CHANNEL_INIT_INFO[id].cm_load_mask; + channel->reg_a2w_ctrl = &s->regs[PLL_CHANNEL_INIT_INFO[id].a2w_ctrl_offset]; + channel->fixed_divider = PLL_CHANNEL_INIT_INFO[id].fixed_divider; +} + +/* Clock mux init info */ +typedef struct ClockMuxInitInfo { + const char *name; + size_t cm_offset; /* cm_offset[0]->CM_CTL, cm_offset[1]->CM_DIV */ + int int_bits; + int frac_bits; + + CprmanPllChannel src_mapping[CPRMAN_NUM_CLOCK_MUX_SRC]; +} ClockMuxInitInfo; + +/* + * Each clock mux can have up to 10 sources. Sources 0 to 3 are always the + * same (ground, xosc, td0, td1). Sources 4 to 9 are mux specific, and are not + * always populated. The following macros catch all those cases. + */ + +/* Unknown mapping. Connect everything to ground */ +#define SRC_MAPPING_INFO_unknown \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* gnd */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* xosc */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* test debug 0 */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* test debug 1 */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll a */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll d */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll h */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c, core1 */ \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, /* pll c, core2 */ \ + } + +/* Only the oscillator and the two test debug clocks */ +#define SRC_MAPPING_INFO_xosc \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + } + +/* All the PLL "core" channels */ +#define SRC_MAPPING_INFO_core \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_PLLA_CHANNEL_CORE, \ + CPRMAN_PLLC_CHANNEL_CORE0, \ + CPRMAN_PLLD_CHANNEL_CORE, \ + CPRMAN_PLLH_CHANNEL_AUX, \ + CPRMAN_PLLC_CHANNEL_CORE1, \ + CPRMAN_PLLC_CHANNEL_CORE2, \ + } + +/* All the PLL "per" channels */ +#define SRC_MAPPING_INFO_periph \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_PLLA_CHANNEL_PER, \ + CPRMAN_PLLC_CHANNEL_PER, \ + CPRMAN_PLLD_CHANNEL_PER, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + } + +/* + * The DSI0 channels. This one got an intermediate mux between the PLL channels + * and the clock input. + */ +#define SRC_MAPPING_INFO_dsi0 \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_DSI0HSCK, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + } + +/* The DSI1 channel */ +#define SRC_MAPPING_INFO_dsi1 \ + .src_mapping = { \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_CLOCK_SRC_NORMAL, \ + CPRMAN_PLLD_CHANNEL_DSI1, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + CPRMAN_CLOCK_SRC_FORCE_GROUND, \ + } + +#define FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO(kind_) \ + SRC_MAPPING_INFO_ ## kind_ + +#define FILL_CLOCK_MUX_INIT_INFO(clock_, kind_) \ + .cm_offset = R_CM_ ## clock_ ## CTL, \ + FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO(kind_) + +static ClockMuxInitInfo CLOCK_MUX_INIT_INFO[] = { + [CPRMAN_CLOCK_GNRIC] = { + .name = "gnric", + FILL_CLOCK_MUX_INIT_INFO(GNRIC, unknown), + }, + [CPRMAN_CLOCK_VPU] = { + .name = "vpu", + .int_bits = 12, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(VPU, core), + }, + [CPRMAN_CLOCK_SYS] = { + .name = "sys", + FILL_CLOCK_MUX_INIT_INFO(SYS, unknown), + }, + [CPRMAN_CLOCK_PERIA] = { + .name = "peria", + FILL_CLOCK_MUX_INIT_INFO(PERIA, unknown), + }, + [CPRMAN_CLOCK_PERII] = { + .name = "perii", + FILL_CLOCK_MUX_INIT_INFO(PERII, unknown), + }, + [CPRMAN_CLOCK_H264] = { + .name = "h264", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(H264, core), + }, + [CPRMAN_CLOCK_ISP] = { + .name = "isp", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(ISP, core), + }, + [CPRMAN_CLOCK_V3D] = { + .name = "v3d", + FILL_CLOCK_MUX_INIT_INFO(V3D, core), + }, + [CPRMAN_CLOCK_CAM0] = { + .name = "cam0", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(CAM0, periph), + }, + [CPRMAN_CLOCK_CAM1] = { + .name = "cam1", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(CAM1, periph), + }, + [CPRMAN_CLOCK_CCP2] = { + .name = "ccp2", + FILL_CLOCK_MUX_INIT_INFO(CCP2, unknown), + }, + [CPRMAN_CLOCK_DSI0E] = { + .name = "dsi0e", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(DSI0E, dsi0), + }, + [CPRMAN_CLOCK_DSI0P] = { + .name = "dsi0p", + .int_bits = 0, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(DSI0P, dsi0), + }, + [CPRMAN_CLOCK_DPI] = { + .name = "dpi", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(DPI, periph), + }, + [CPRMAN_CLOCK_GP0] = { + .name = "gp0", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(GP0, periph), + }, + [CPRMAN_CLOCK_GP1] = { + .name = "gp1", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(GP1, periph), + }, + [CPRMAN_CLOCK_GP2] = { + .name = "gp2", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(GP2, periph), + }, + [CPRMAN_CLOCK_HSM] = { + .name = "hsm", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(HSM, periph), + }, + [CPRMAN_CLOCK_OTP] = { + .name = "otp", + .int_bits = 4, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(OTP, xosc), + }, + [CPRMAN_CLOCK_PCM] = { + .name = "pcm", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(PCM, periph), + }, + [CPRMAN_CLOCK_PWM] = { + .name = "pwm", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(PWM, periph), + }, + [CPRMAN_CLOCK_SLIM] = { + .name = "slim", + .int_bits = 12, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(SLIM, periph), + }, + [CPRMAN_CLOCK_SMI] = { + .name = "smi", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(SMI, periph), + }, + [CPRMAN_CLOCK_TEC] = { + .name = "tec", + .int_bits = 6, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(TEC, xosc), + }, + [CPRMAN_CLOCK_TD0] = { + .name = "td0", + FILL_CLOCK_MUX_INIT_INFO(TD0, unknown), + }, + [CPRMAN_CLOCK_TD1] = { + .name = "td1", + FILL_CLOCK_MUX_INIT_INFO(TD1, unknown), + }, + [CPRMAN_CLOCK_TSENS] = { + .name = "tsens", + .int_bits = 5, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(TSENS, xosc), + }, + [CPRMAN_CLOCK_TIMER] = { + .name = "timer", + .int_bits = 6, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(TIMER, xosc), + }, + [CPRMAN_CLOCK_UART] = { + .name = "uart", + .int_bits = 10, + .frac_bits = 12, + FILL_CLOCK_MUX_INIT_INFO(UART, periph), + }, + [CPRMAN_CLOCK_VEC] = { + .name = "vec", + .int_bits = 4, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(VEC, periph), + }, + [CPRMAN_CLOCK_PULSE] = { + .name = "pulse", + FILL_CLOCK_MUX_INIT_INFO(PULSE, xosc), + }, + [CPRMAN_CLOCK_SDC] = { + .name = "sdram", + .int_bits = 6, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(SDC, core), + }, + [CPRMAN_CLOCK_ARM] = { + .name = "arm", + FILL_CLOCK_MUX_INIT_INFO(ARM, unknown), + }, + [CPRMAN_CLOCK_AVEO] = { + .name = "aveo", + .int_bits = 4, + .frac_bits = 0, + FILL_CLOCK_MUX_INIT_INFO(AVEO, periph), + }, + [CPRMAN_CLOCK_EMMC] = { + .name = "emmc", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(EMMC, periph), + }, + [CPRMAN_CLOCK_EMMC2] = { + .name = "emmc2", + .int_bits = 4, + .frac_bits = 8, + FILL_CLOCK_MUX_INIT_INFO(EMMC2, unknown), + }, +}; + +#undef FILL_CLOCK_MUX_INIT_INFO +#undef FILL_CLOCK_MUX_SRC_MAPPING_INIT_INFO +#undef SRC_MAPPING_INFO_dsi1 +#undef SRC_MAPPING_INFO_dsi0 +#undef SRC_MAPPING_INFO_periph +#undef SRC_MAPPING_INFO_core +#undef SRC_MAPPING_INFO_xosc +#undef SRC_MAPPING_INFO_unknown + +static inline void set_clock_mux_init_info(BCM2835CprmanState *s, + CprmanClockMuxState *mux, + CprmanClockMux id) +{ + mux->id = id; + mux->reg_ctl = &s->regs[CLOCK_MUX_INIT_INFO[id].cm_offset]; + mux->reg_div = &s->regs[CLOCK_MUX_INIT_INFO[id].cm_offset + 1]; + mux->int_bits = CLOCK_MUX_INIT_INFO[id].int_bits; + mux->frac_bits = CLOCK_MUX_INIT_INFO[id].frac_bits; +} + + +/* + * Object reset info + * Those values have been dumped from a Raspberry Pi 3 Model B v1.2 using the + * clk debugfs interface in Linux. + */ +typedef struct PLLResetInfo { + uint32_t cm; + uint32_t a2w_ctrl; + uint32_t a2w_ana[4]; + uint32_t a2w_frac; +} PLLResetInfo; + +static const PLLResetInfo PLL_RESET_INFO[] = { + [CPRMAN_PLLA] = { + .cm = 0x0000008a, + .a2w_ctrl = 0x0002103a, + .a2w_frac = 0x00098000, + .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 } + }, + + [CPRMAN_PLLC] = { + .cm = 0x00000228, + .a2w_ctrl = 0x0002103e, + .a2w_frac = 0x00080000, + .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 } + }, + + [CPRMAN_PLLD] = { + .cm = 0x0000020a, + .a2w_ctrl = 0x00021034, + .a2w_frac = 0x00015556, + .a2w_ana = { 0x00000000, 0x00144000, 0x00000000, 0x00000100 } + }, + + [CPRMAN_PLLH] = { + .cm = 0x00000000, + .a2w_ctrl = 0x0002102d, + .a2w_frac = 0x00000000, + .a2w_ana = { 0x00900000, 0x0000000c, 0x00000000, 0x00000000 } + }, + + [CPRMAN_PLLB] = { + /* unknown */ + .cm = 0x00000000, + .a2w_ctrl = 0x00000000, + .a2w_frac = 0x00000000, + .a2w_ana = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 } + } +}; + +typedef struct PLLChannelResetInfo { + /* + * Even though a PLL channel has a CM register, it shares it with its + * parent PLL. The parent already takes care of the reset value. + */ + uint32_t a2w_ctrl; +} PLLChannelResetInfo; + +static const PLLChannelResetInfo PLL_CHANNEL_RESET_INFO[] = { + [CPRMAN_PLLA_CHANNEL_DSI0] = { .a2w_ctrl = 0x00000100 }, + [CPRMAN_PLLA_CHANNEL_CORE] = { .a2w_ctrl = 0x00000003 }, + [CPRMAN_PLLA_CHANNEL_PER] = { .a2w_ctrl = 0x00000000 }, /* unknown */ + [CPRMAN_PLLA_CHANNEL_CCP2] = { .a2w_ctrl = 0x00000100 }, + + [CPRMAN_PLLC_CHANNEL_CORE2] = { .a2w_ctrl = 0x00000100 }, + [CPRMAN_PLLC_CHANNEL_CORE1] = { .a2w_ctrl = 0x00000100 }, + [CPRMAN_PLLC_CHANNEL_PER] = { .a2w_ctrl = 0x00000002 }, + [CPRMAN_PLLC_CHANNEL_CORE0] = { .a2w_ctrl = 0x00000002 }, + + [CPRMAN_PLLD_CHANNEL_DSI0] = { .a2w_ctrl = 0x00000100 }, + [CPRMAN_PLLD_CHANNEL_CORE] = { .a2w_ctrl = 0x00000004 }, + [CPRMAN_PLLD_CHANNEL_PER] = { .a2w_ctrl = 0x00000004 }, + [CPRMAN_PLLD_CHANNEL_DSI1] = { .a2w_ctrl = 0x00000100 }, + + [CPRMAN_PLLH_CHANNEL_AUX] = { .a2w_ctrl = 0x00000004 }, + [CPRMAN_PLLH_CHANNEL_RCAL] = { .a2w_ctrl = 0x00000000 }, + [CPRMAN_PLLH_CHANNEL_PIX] = { .a2w_ctrl = 0x00000000 }, + + [CPRMAN_PLLB_CHANNEL_ARM] = { .a2w_ctrl = 0x00000000 }, /* unknown */ +}; + +typedef struct ClockMuxResetInfo { + uint32_t cm_ctl; + uint32_t cm_div; +} ClockMuxResetInfo; + +static const ClockMuxResetInfo CLOCK_MUX_RESET_INFO[] = { + [CPRMAN_CLOCK_GNRIC] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_VPU] = { + .cm_ctl = 0x00000245, + .cm_div = 0x00003000, + }, + + [CPRMAN_CLOCK_SYS] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_PERIA] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_PERII] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_H264] = { + .cm_ctl = 0x00000244, + .cm_div = 0x00003000, + }, + + [CPRMAN_CLOCK_ISP] = { + .cm_ctl = 0x00000244, + .cm_div = 0x00003000, + }, + + [CPRMAN_CLOCK_V3D] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_CAM0] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_CAM1] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_CCP2] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_DSI0E] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_DSI0P] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_DPI] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_GP0] = { + .cm_ctl = 0x00000200, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_GP1] = { + .cm_ctl = 0x00000096, + .cm_div = 0x00014000, + }, + + [CPRMAN_CLOCK_GP2] = { + .cm_ctl = 0x00000291, + .cm_div = 0x00249f00, + }, + + [CPRMAN_CLOCK_HSM] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_OTP] = { + .cm_ctl = 0x00000091, + .cm_div = 0x00004000, + }, + + [CPRMAN_CLOCK_PCM] = { + .cm_ctl = 0x00000200, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_PWM] = { + .cm_ctl = 0x00000200, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_SLIM] = { + .cm_ctl = 0x00000200, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_SMI] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_TEC] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_TD0] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_TD1] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_TSENS] = { + .cm_ctl = 0x00000091, + .cm_div = 0x0000a000, + }, + + [CPRMAN_CLOCK_TIMER] = { + .cm_ctl = 0x00000291, + .cm_div = 0x00013333, + }, + + [CPRMAN_CLOCK_UART] = { + .cm_ctl = 0x00000296, + .cm_div = 0x0000a6ab, + }, + + [CPRMAN_CLOCK_VEC] = { + .cm_ctl = 0x00000097, + .cm_div = 0x00002000, + }, + + [CPRMAN_CLOCK_PULSE] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_SDC] = { + .cm_ctl = 0x00004006, + .cm_div = 0x00003000, + }, + + [CPRMAN_CLOCK_ARM] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, + + [CPRMAN_CLOCK_AVEO] = { + .cm_ctl = 0x00000000, + .cm_div = 0x00000000, + }, + + [CPRMAN_CLOCK_EMMC] = { + .cm_ctl = 0x00000295, + .cm_div = 0x00006000, + }, + + [CPRMAN_CLOCK_EMMC2] = { + .cm_ctl = 0, /* unknown */ + .cm_div = 0 + }, +}; + +#endif diff --git a/include/hw/misc/bcm2835_mbox.h b/include/hw/misc/bcm2835_mbox.h new file mode 100644 index 000000000..ade27af25 --- /dev/null +++ b/include/hw/misc/bcm2835_mbox.h @@ -0,0 +1,39 @@ +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_MBOX_H +#define BCM2835_MBOX_H + +#include "bcm2835_mbox_defs.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_BCM2835_MBOX "bcm2835-mbox" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835MboxState, BCM2835_MBOX) + +typedef struct { + uint32_t reg[MBOX_SIZE]; + uint32_t count; + uint32_t status; + uint32_t config; +} BCM2835Mbox; + +struct BCM2835MboxState { + /*< private >*/ + SysBusDevice busdev; + /*< public >*/ + MemoryRegion *mbox_mr; + AddressSpace mbox_as; + MemoryRegion iomem; + qemu_irq arm_irq; + + bool mbox_irq_disabled; + bool available[MBOX_CHAN_COUNT]; + BCM2835Mbox mbox[2]; +}; + +#endif diff --git a/include/hw/misc/bcm2835_mbox_defs.h b/include/hw/misc/bcm2835_mbox_defs.h new file mode 100644 index 000000000..9670bf33a --- /dev/null +++ b/include/hw/misc/bcm2835_mbox_defs.h @@ -0,0 +1,29 @@ +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_MBOX_DEFS_H +#define BCM2835_MBOX_DEFS_H + +/* Constants shared with the ARM identifying separate mailbox channels */ +#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ +#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ +#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ +#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ +#define MBOX_CHAN_COUNT 9 + +#define MBOX_SIZE 32 +#define MBOX_INVALID_DATA 0x0f + +/* Layout of the private address space used for communication between + * the mbox device emulation, and child devices: each channel occupies + * 16 bytes of address space, but only two registers are presently defined. + */ +#define MBOX_AS_CHAN_SHIFT 4 +#define MBOX_AS_DATA 0 /* request / response data (RW at offset 0) */ +#define MBOX_AS_PENDING 4 /* pending response status (RO at offset 4) */ + +#endif /* BCM2835_MBOX_DEFS_H */ diff --git a/include/hw/misc/bcm2835_mphi.h b/include/hw/misc/bcm2835_mphi.h new file mode 100644 index 000000000..751363f49 --- /dev/null +++ b/include/hw/misc/bcm2835_mphi.h @@ -0,0 +1,44 @@ +/* + * BCM2835 SOC MPHI state definitions + * + * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + */ + +#ifndef HW_MISC_BCM2835_MPHI_H +#define HW_MISC_BCM2835_MPHI_H + +#include "hw/irq.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +#define MPHI_MMIO_SIZE 0x1000 + +typedef struct BCM2835MphiState BCM2835MphiState; + +struct BCM2835MphiState { + SysBusDevice parent_obj; + qemu_irq irq; + MemoryRegion iomem; + + uint32_t outdda; + uint32_t outddb; + uint32_t ctrl; + uint32_t intstat; + uint32_t swirq; +}; + +#define TYPE_BCM2835_MPHI "bcm2835-mphi" + +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835MphiState, BCM2835_MPHI) + +#endif diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h new file mode 100644 index 000000000..303b9a6f6 --- /dev/null +++ b/include/hw/misc/bcm2835_powermgt.h @@ -0,0 +1,29 @@ +/* + * BCM2835 Power Management emulation + * + * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com> + * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_POWERMGT_H +#define BCM2835_POWERMGT_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT) + +struct BCM2835PowerMgtState { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t rstc; + uint32_t rsts; + uint32_t wdog; +}; + +#endif diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h new file mode 100644 index 000000000..712b76b7a --- /dev/null +++ b/include/hw/misc/bcm2835_property.h @@ -0,0 +1,36 @@ +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_PROPERTY_H +#define BCM2835_PROPERTY_H + +#include "hw/sysbus.h" +#include "net/net.h" +#include "hw/display/bcm2835_fb.h" +#include "qom/object.h" + +#define TYPE_BCM2835_PROPERTY "bcm2835-property" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PropertyState, BCM2835_PROPERTY) + +struct BCM2835PropertyState { + /*< private >*/ + SysBusDevice busdev; + /*< public >*/ + + MemoryRegion *dma_mr; + AddressSpace dma_as; + MemoryRegion iomem; + qemu_irq mbox_irq; + BCM2835FBState *fbdev; + + MACAddr macaddr; + uint32_t board_rev; + uint32_t addr; + bool pending; +}; + +#endif diff --git a/include/hw/misc/bcm2835_rng.h b/include/hw/misc/bcm2835_rng.h new file mode 100644 index 000000000..7c1fb3ef4 --- /dev/null +++ b/include/hw/misc/bcm2835_rng.h @@ -0,0 +1,27 @@ +/* + * BCM2835 Random Number Generator emulation + * + * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_RNG_H +#define BCM2835_RNG_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_BCM2835_RNG "bcm2835-rng" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835RngState, BCM2835_RNG) + +struct BCM2835RngState { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t rng_ctrl; + uint32_t rng_status; +}; + +#endif diff --git a/include/hw/misc/bcm2835_thermal.h b/include/hw/misc/bcm2835_thermal.h new file mode 100644 index 000000000..f90f9e487 --- /dev/null +++ b/include/hw/misc/bcm2835_thermal.h @@ -0,0 +1,27 @@ +/* + * BCM2835 dummy thermal sensor + * + * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_BCM2835_THERMAL_H +#define HW_MISC_BCM2835_THERMAL_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_BCM2835_THERMAL "bcm2835-thermal" + +OBJECT_DECLARE_SIMPLE_TYPE(Bcm2835ThermalState, BCM2835_THERMAL) + +struct Bcm2835ThermalState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + MemoryRegion iomem; + uint32_t ctl; +}; + +#endif diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h new file mode 100644 index 000000000..533498402 --- /dev/null +++ b/include/hw/misc/cbus.h @@ -0,0 +1,31 @@ +/* + * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma / + * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms. + * Based on reverse-engineering of a linux driver. + * + * Copyright (C) 2008 Nokia Corporation + * Written by Andrzej Zaborowski + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_MISC_CBUS_H +#define HW_MISC_CBUS_H + + +typedef struct { + qemu_irq clk; + qemu_irq dat; + qemu_irq sel; +} CBus; + +CBus *cbus_init(qemu_irq dat_out); +void cbus_attach(CBus *bus, void *slave_opaque); + +void *retu_init(qemu_irq irq, int vilma); +void *tahvo_init(qemu_irq irq, int betty); + +void retu_key_event(void *retu, int state); + +#endif diff --git a/include/hw/misc/empty_slot.h b/include/hw/misc/empty_slot.h new file mode 100644 index 000000000..dec56e56a --- /dev/null +++ b/include/hw/misc/empty_slot.h @@ -0,0 +1,19 @@ +/* + * QEMU Empty Slot + * + * The empty_slot device emulates known to a bus but not connected devices. + * + * Copyright (c) 2010 Artyom Tarasenko + * + * This code is licensed under the GNU GPL v2 or (at your option) any later + * version. + */ + +#ifndef HW_EMPTY_SLOT_H +#define HW_EMPTY_SLOT_H + +#include "exec/hwaddr.h" + +void empty_slot_init(const char *name, hwaddr addr, uint64_t slot_size); + +#endif diff --git a/include/hw/misc/grlib_ahb_apb_pnp.h b/include/hw/misc/grlib_ahb_apb_pnp.h new file mode 100644 index 000000000..bab0b5f47 --- /dev/null +++ b/include/hw/misc/grlib_ahb_apb_pnp.h @@ -0,0 +1,57 @@ +/* + * GRLIB AHB APB PNP + * + * Copyright (C) 2019 AdaCore + * + * Developed by : + * Frederic Konrad <frederic.konrad@adacore.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef GRLIB_AHB_APB_PNP_H +#define GRLIB_AHB_APB_PNP_H +#include "qom/object.h" + +#define TYPE_GRLIB_AHB_PNP "grlib-ahbpnp" +OBJECT_DECLARE_SIMPLE_TYPE(AHBPnp, GRLIB_AHB_PNP) + +#define TYPE_GRLIB_APB_PNP "grlib-apbpnp" +OBJECT_DECLARE_SIMPLE_TYPE(APBPnp, GRLIB_APB_PNP) + +void grlib_ahb_pnp_add_entry(AHBPnp *dev, uint32_t address, uint32_t mask, + uint8_t vendor, uint16_t device, int slave, + int type); +void grlib_apb_pnp_add_entry(APBPnp *dev, uint32_t address, uint32_t mask, + uint8_t vendor, uint16_t device, uint8_t version, + uint8_t irq, int type); + +/* VENDORS */ +#define GRLIB_VENDOR_GAISLER (0x01) +/* DEVICES */ +#define GRLIB_LEON3_DEV (0x03) +#define GRLIB_APBMST_DEV (0x06) +#define GRLIB_APBUART_DEV (0x0C) +#define GRLIB_IRQMP_DEV (0x0D) +#define GRLIB_GPTIMER_DEV (0x11) +/* TYPE */ +#define GRLIB_CPU_AREA (0x00) +#define GRLIB_APBIO_AREA (0x01) +#define GRLIB_AHBMEM_AREA (0x02) + +#define GRLIB_AHB_MASTER (0x00) +#define GRLIB_AHB_SLAVE (0x01) + +#endif /* GRLIB_AHB_APB_PNP_H */ diff --git a/include/hw/misc/imx25_ccm.h b/include/hw/misc/imx25_ccm.h new file mode 100644 index 000000000..c3b89018c --- /dev/null +++ b/include/hw/misc/imx25_ccm.h @@ -0,0 +1,80 @@ +/* + * IMX25 Clock Control Module + * + * Copyright (C) 2012 NICTA + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX25_CCM_H +#define IMX25_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qom/object.h" + +#define IMX25_CCM_MPCTL_REG 0 +#define IMX25_CCM_UPCTL_REG 1 +#define IMX25_CCM_CCTL_REG 2 +#define IMX25_CCM_CGCR0_REG 3 +#define IMX25_CCM_CGCR1_REG 4 +#define IMX25_CCM_CGCR2_REG 5 +#define IMX25_CCM_PCDR0_REG 6 +#define IMX25_CCM_PCDR1_REG 7 +#define IMX25_CCM_PCDR2_REG 8 +#define IMX25_CCM_PCDR3_REG 9 +#define IMX25_CCM_RCSR_REG 10 +#define IMX25_CCM_CRDR_REG 11 +#define IMX25_CCM_DCVR0_REG 12 +#define IMX25_CCM_DCVR1_REG 13 +#define IMX25_CCM_DCVR2_REG 14 +#define IMX25_CCM_DCVR3_REG 15 +#define IMX25_CCM_LTR0_REG 16 +#define IMX25_CCM_LTR1_REG 17 +#define IMX25_CCM_LTR2_REG 18 +#define IMX25_CCM_LTR3_REG 19 +#define IMX25_CCM_LTBR0_REG 20 +#define IMX25_CCM_LTBR1_REG 21 +#define IMX25_CCM_PMCR0_REG 22 +#define IMX25_CCM_PMCR1_REG 23 +#define IMX25_CCM_PMCR2_REG 24 +#define IMX25_CCM_MCR_REG 25 +#define IMX25_CCM_LPIMR0_REG 26 +#define IMX25_CCM_LPIMR1_REG 27 +#define IMX25_CCM_MAX_REG 28 + +/* CCTL */ +#define CCTL_ARM_CLK_DIV_SHIFT (30) +#define CCTL_ARM_CLK_DIV_MASK (0x3) +#define CCTL_AHB_CLK_DIV_SHIFT (28) +#define CCTL_AHB_CLK_DIV_MASK (0x3) +#define CCTL_MPLL_BYPASS_SHIFT (22) +#define CCTL_MPLL_BYPASS_MASK (0x1) +#define CCTL_USB_DIV_SHIFT (16) +#define CCTL_USB_DIV_MASK (0x3F) +#define CCTL_ARM_SRC_SHIFT (13) +#define CCTL_ARM_SRC_MASK (0x1) +#define CCTL_UPLL_DIS_SHIFT (23) +#define CCTL_UPLL_DIS_MASK (0x1) + +#define EXTRACT(value, name) (((value) >> CCTL_##name##_SHIFT) \ + & CCTL_##name##_MASK) +#define INSERT(value, name) (((value) & CCTL_##name##_MASK) << \ + CCTL_##name##_SHIFT) + +#define TYPE_IMX25_CCM "imx25.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX25CCMState, IMX25_CCM) + +struct IMX25CCMState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + MemoryRegion iomem; + + uint32_t reg[IMX25_CCM_MAX_REG]; + +}; + +#endif /* IMX25_CCM_H */ diff --git a/include/hw/misc/imx31_ccm.h b/include/hw/misc/imx31_ccm.h new file mode 100644 index 000000000..18e08ee84 --- /dev/null +++ b/include/hw/misc/imx31_ccm.h @@ -0,0 +1,89 @@ +/* + * IMX31 Clock Control Module + * + * Copyright (C) 2012 NICTA + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX31_CCM_H +#define IMX31_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qom/object.h" + +#define IMX31_CCM_CCMR_REG 0 +#define IMX31_CCM_PDR0_REG 1 +#define IMX31_CCM_PDR1_REG 2 +#define IMX31_CCM_RCSR_REG 3 +#define IMX31_CCM_MPCTL_REG 4 +#define IMX31_CCM_UPCTL_REG 5 +#define IMX31_CCM_SPCTL_REG 6 +#define IMX31_CCM_COSR_REG 7 +#define IMX31_CCM_CGR0_REG 8 +#define IMX31_CCM_CGR1_REG 9 +#define IMX31_CCM_CGR2_REG 10 +#define IMX31_CCM_WIMR_REG 11 +#define IMX31_CCM_LDC_REG 12 +#define IMX31_CCM_DCVR0_REG 13 +#define IMX31_CCM_DCVR1_REG 14 +#define IMX31_CCM_DCVR2_REG 15 +#define IMX31_CCM_DCVR3_REG 16 +#define IMX31_CCM_LTR0_REG 17 +#define IMX31_CCM_LTR1_REG 18 +#define IMX31_CCM_LTR2_REG 19 +#define IMX31_CCM_LTR3_REG 20 +#define IMX31_CCM_LTBR0_REG 21 +#define IMX31_CCM_LTBR1_REG 22 +#define IMX31_CCM_PMCR0_REG 23 +#define IMX31_CCM_PMCR1_REG 24 +#define IMX31_CCM_PDR2_REG 25 +#define IMX31_CCM_MAX_REG 26 + +/* CCMR */ +#define CCMR_FPME (1<<0) +#define CCMR_MPE (1<<3) +#define CCMR_MDS (1<<7) +#define CCMR_FPMF (1<<26) +#define CCMR_PRCS (3<<1) + +#define PMCR0_DFSUP1 (1<<31) + +/* PDR0 */ +#define PDR0_MCU_PODF_SHIFT (0) +#define PDR0_MCU_PODF_MASK (0x7) +#define PDR0_MAX_PODF_SHIFT (3) +#define PDR0_MAX_PODF_MASK (0x7) +#define PDR0_IPG_PODF_SHIFT (6) +#define PDR0_IPG_PODF_MASK (0x3) +#define PDR0_NFC_PODF_SHIFT (8) +#define PDR0_NFC_PODF_MASK (0x7) +#define PDR0_HSP_PODF_SHIFT (11) +#define PDR0_HSP_PODF_MASK (0x7) +#define PDR0_PER_PODF_SHIFT (16) +#define PDR0_PER_PODF_MASK (0x1f) +#define PDR0_CSI_PODF_SHIFT (23) +#define PDR0_CSI_PODF_MASK (0x1ff) + +#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \ + & PDR0_##name##_PODF_MASK) +#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \ + PDR0_##name##_PODF_SHIFT) + +#define TYPE_IMX31_CCM "imx31.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX31CCMState, IMX31_CCM) + +struct IMX31CCMState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + MemoryRegion iomem; + + uint32_t reg[IMX31_CCM_MAX_REG]; + +}; + +#endif /* IMX31_CCM_H */ diff --git a/include/hw/misc/imx6_ccm.h b/include/hw/misc/imx6_ccm.h new file mode 100644 index 000000000..ccf46d735 --- /dev/null +++ b/include/hw/misc/imx6_ccm.h @@ -0,0 +1,198 @@ +/* + * IMX6 Clock Control Module + * + * Copyright (C) 2012 NICTA + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX6_CCM_H +#define IMX6_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qemu/bitops.h" +#include "qom/object.h" + +#define CCM_CCR 0 +#define CCM_CCDR 1 +#define CCM_CSR 2 +#define CCM_CCSR 3 +#define CCM_CACRR 4 +#define CCM_CBCDR 5 +#define CCM_CBCMR 6 +#define CCM_CSCMR1 7 +#define CCM_CSCMR2 8 +#define CCM_CSCDR1 9 +#define CCM_CS1CDR 10 +#define CCM_CS2CDR 11 +#define CCM_CDCDR 12 +#define CCM_CHSCCDR 13 +#define CCM_CSCDR2 14 +#define CCM_CSCDR3 15 +#define CCM_CDHIPR 18 +#define CCM_CTOR 20 +#define CCM_CLPCR 21 +#define CCM_CISR 22 +#define CCM_CIMR 23 +#define CCM_CCOSR 24 +#define CCM_CGPR 25 +#define CCM_CCGR0 26 +#define CCM_CCGR1 27 +#define CCM_CCGR2 28 +#define CCM_CCGR3 29 +#define CCM_CCGR4 30 +#define CCM_CCGR5 31 +#define CCM_CCGR6 32 +#define CCM_CMEOR 34 +#define CCM_MAX 35 + +#define CCM_ANALOG_PLL_ARM 0 +#define CCM_ANALOG_PLL_ARM_SET 1 +#define CCM_ANALOG_PLL_ARM_CLR 2 +#define CCM_ANALOG_PLL_ARM_TOG 3 +#define CCM_ANALOG_PLL_USB1 4 +#define CCM_ANALOG_PLL_USB1_SET 5 +#define CCM_ANALOG_PLL_USB1_CLR 6 +#define CCM_ANALOG_PLL_USB1_TOG 7 +#define CCM_ANALOG_PLL_USB2 8 +#define CCM_ANALOG_PLL_USB2_SET 9 +#define CCM_ANALOG_PLL_USB2_CLR 10 +#define CCM_ANALOG_PLL_USB2_TOG 11 +#define CCM_ANALOG_PLL_SYS 12 +#define CCM_ANALOG_PLL_SYS_SET 13 +#define CCM_ANALOG_PLL_SYS_CLR 14 +#define CCM_ANALOG_PLL_SYS_TOG 15 +#define CCM_ANALOG_PLL_SYS_SS 16 +#define CCM_ANALOG_PLL_SYS_NUM 20 +#define CCM_ANALOG_PLL_SYS_DENOM 24 +#define CCM_ANALOG_PLL_AUDIO 28 +#define CCM_ANALOG_PLL_AUDIO_SET 29 +#define CCM_ANALOG_PLL_AUDIO_CLR 30 +#define CCM_ANALOG_PLL_AUDIO_TOG 31 +#define CCM_ANALOG_PLL_AUDIO_NUM 32 +#define CCM_ANALOG_PLL_AUDIO_DENOM 36 +#define CCM_ANALOG_PLL_VIDEO 40 +#define CCM_ANALOG_PLL_VIDEO_SET 41 +#define CCM_ANALOG_PLL_VIDEO_CLR 42 +#define CCM_ANALOG_PLL_VIDEO_TOG 44 +#define CCM_ANALOG_PLL_VIDEO_NUM 46 +#define CCM_ANALOG_PLL_VIDEO_DENOM 48 +#define CCM_ANALOG_PLL_MLB 52 +#define CCM_ANALOG_PLL_MLB_SET 53 +#define CCM_ANALOG_PLL_MLB_CLR 54 +#define CCM_ANALOG_PLL_MLB_TOG 55 +#define CCM_ANALOG_PLL_ENET 56 +#define CCM_ANALOG_PLL_ENET_SET 57 +#define CCM_ANALOG_PLL_ENET_CLR 58 +#define CCM_ANALOG_PLL_ENET_TOG 59 +#define CCM_ANALOG_PFD_480 60 +#define CCM_ANALOG_PFD_480_SET 61 +#define CCM_ANALOG_PFD_480_CLR 62 +#define CCM_ANALOG_PFD_480_TOG 63 +#define CCM_ANALOG_PFD_528 64 +#define CCM_ANALOG_PFD_528_SET 65 +#define CCM_ANALOG_PFD_528_CLR 66 +#define CCM_ANALOG_PFD_528_TOG 67 + +/* PMU registers */ +#define PMU_REG_1P1 68 +#define PMU_REG_3P0 72 +#define PMU_REG_2P5 76 +#define PMU_REG_CORE 80 + +#define CCM_ANALOG_MISC0 84 +#define PMU_MISC0 84 +#define CCM_ANALOG_MISC0_SET 85 +#define CCM_ANALOG_MISC0_CLR 86 +#define CCM_ANALOG_MISC0_TOG 87 + +#define PMU_MISC1 88 +#define PMU_MISC1_SET 89 +#define PMU_MISC1_CLR 90 +#define PMU_MISC1_TOG 91 + +#define CCM_ANALOG_MISC2 92 +#define PMU_MISC2 92 +#define CCM_ANALOG_MISC2_SET 93 +#define CCM_ANALOG_MISC2_CLR 94 +#define CCM_ANALOG_MISC2_TOG 95 + +#define USB_ANALOG_USB1_VBUS_DETECT 104 +#define USB_ANALOG_USB1_VBUS_DETECT_SET 105 +#define USB_ANALOG_USB1_VBUS_DETECT_CLR 106 +#define USB_ANALOG_USB1_VBUS_DETECT_TOG 107 +#define USB_ANALOG_USB1_CHRG_DETECT 108 +#define USB_ANALOG_USB1_CHRG_DETECT_SET 109 +#define USB_ANALOG_USB1_CHRG_DETECT_CLR 110 +#define USB_ANALOG_USB1_CHRG_DETECT_TOG 111 +#define USB_ANALOG_USB1_VBUS_DETECT_STAT 112 +#define USB_ANALOG_USB1_CHRG_DETECT_STAT 116 +#define USB_ANALOG_USB1_MISC 124 +#define USB_ANALOG_USB1_MISC_SET 125 +#define USB_ANALOG_USB1_MISC_CLR 126 +#define USB_ANALOG_USB1_MISC_TOG 127 +#define USB_ANALOG_USB2_VBUS_DETECT 128 +#define USB_ANALOG_USB2_VBUS_DETECT_SET 129 +#define USB_ANALOG_USB2_VBUS_DETECT_CLR 130 +#define USB_ANALOG_USB2_VBUS_DETECT_TOG 131 +#define USB_ANALOG_USB2_CHRG_DETECT 132 +#define USB_ANALOG_USB2_CHRG_DETECT_SET 133 +#define USB_ANALOG_USB2_CHRG_DETECT_CLR 134 +#define USB_ANALOG_USB2_CHRG_DETECT_TOG 135 +#define USB_ANALOG_USB2_VBUS_DETECT_STAT 136 +#define USB_ANALOG_USB2_CHRG_DETECT_STAT 140 +#define USB_ANALOG_USB2_MISC 148 +#define USB_ANALOG_USB2_MISC_SET 149 +#define USB_ANALOG_USB2_MISC_CLR 150 +#define USB_ANALOG_USB2_MISC_TOG 151 +#define USB_ANALOG_DIGPROG 152 +#define CCM_ANALOG_MAX 153 + +/* CCM_CBCMR */ +#define PRE_PERIPH_CLK_SEL_SHIFT (18) +#define PRE_PERIPH_CLK_SEL_LENGTH (2) + +/* CCM_CBCDR */ +#define AHB_PODF_SHIFT (10) +#define AHB_PODF_LENGTH (3) +#define IPG_PODF_SHIFT (8) +#define IPG_PODF_LENGTH (2) + +/* CCM_CSCMR1 */ +#define PERCLK_PODF_SHIFT (0) +#define PERCLK_PODF_LENGTH (6) + +/* CCM_ANALOG_PFD_528 */ +#define PFD0_FRAC_SHIFT (0) +#define PFD0_FRAC_LENGTH (6) +#define PFD2_FRAC_SHIFT (16) +#define PFD2_FRAC_LENGTH (6) + +/* CCM_ANALOG_PLL_SYS */ +#define DIV_SELECT_SHIFT (0) +#define DIV_SELECT_LENGTH (1) + +#define CCM_ANALOG_PLL_LOCK (1 << 31); + +#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH) + +#define TYPE_IMX6_CCM "imx6.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX6CCMState, IMX6_CCM) + +struct IMX6CCMState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + MemoryRegion container; + MemoryRegion ioccm; + MemoryRegion ioanalog; + + uint32_t ccm[CCM_MAX]; + uint32_t analog[CCM_ANALOG_MAX]; + +}; + +#endif /* IMX6_CCM_H */ diff --git a/include/hw/misc/imx6_src.h b/include/hw/misc/imx6_src.h new file mode 100644 index 000000000..f380da381 --- /dev/null +++ b/include/hw/misc/imx6_src.h @@ -0,0 +1,74 @@ +/* + * IMX6 System Reset Controller + * + * Copyright (C) 2012 NICTA + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX6_SRC_H +#define IMX6_SRC_H + +#include "hw/sysbus.h" +#include "qemu/bitops.h" +#include "qom/object.h" + +#define SRC_SCR 0 +#define SRC_SBMR1 1 +#define SRC_SRSR 2 +#define SRC_SISR 5 +#define SRC_SIMR 6 +#define SRC_SBMR2 7 +#define SRC_GPR1 8 +#define SRC_GPR2 9 +#define SRC_GPR3 10 +#define SRC_GPR4 11 +#define SRC_GPR5 12 +#define SRC_GPR6 13 +#define SRC_GPR7 14 +#define SRC_GPR8 15 +#define SRC_GPR9 16 +#define SRC_GPR10 17 +#define SRC_MAX 18 + +/* SRC_SCR */ +#define CORE3_ENABLE_SHIFT 24 +#define CORE3_ENABLE_LENGTH 1 +#define CORE2_ENABLE_SHIFT 23 +#define CORE2_ENABLE_LENGTH 1 +#define CORE1_ENABLE_SHIFT 22 +#define CORE1_ENABLE_LENGTH 1 +#define CORE3_RST_SHIFT 16 +#define CORE3_RST_LENGTH 1 +#define CORE2_RST_SHIFT 15 +#define CORE2_RST_LENGTH 1 +#define CORE1_RST_SHIFT 14 +#define CORE1_RST_LENGTH 1 +#define CORE0_RST_SHIFT 13 +#define CORE0_RST_LENGTH 1 +#define SW_IPU1_RST_SHIFT 3 +#define SW_IPU1_RST_LENGTH 1 +#define SW_IPU2_RST_SHIFT 12 +#define SW_IPU2_RST_LENGTH 1 +#define WARM_RST_ENABLE_SHIFT 0 +#define WARM_RST_ENABLE_LENGTH 1 + +#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH) + +#define TYPE_IMX6_SRC "imx6.src" +OBJECT_DECLARE_SIMPLE_TYPE(IMX6SRCState, IMX6_SRC) + +struct IMX6SRCState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion iomem; + + uint32_t regs[SRC_MAX]; + +}; + +#endif /* IMX6_SRC_H */ diff --git a/include/hw/misc/imx6ul_ccm.h b/include/hw/misc/imx6ul_ccm.h new file mode 100644 index 000000000..edb5f784d --- /dev/null +++ b/include/hw/misc/imx6ul_ccm.h @@ -0,0 +1,227 @@ +/* + * IMX6UL Clock Control Module + * + * Copyright (C) 2018 by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX6UL_CCM_H +#define IMX6UL_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qemu/bitops.h" +#include "qom/object.h" + +#define CCM_CCR 0 +#define CCM_CCDR 1 +#define CCM_CSR 2 +#define CCM_CCSR 3 +#define CCM_CACRR 4 +#define CCM_CBCDR 5 +#define CCM_CBCMR 6 +#define CCM_CSCMR1 7 +#define CCM_CSCMR2 8 +#define CCM_CSCDR1 9 +#define CCM_CS1CDR 10 +#define CCM_CS2CDR 11 +#define CCM_CDCDR 12 +#define CCM_CHSCCDR 13 +#define CCM_CSCDR2 14 +#define CCM_CSCDR3 15 +#define CCM_CDHIPR 18 +#define CCM_CTOR 20 +#define CCM_CLPCR 21 +#define CCM_CISR 22 +#define CCM_CIMR 23 +#define CCM_CCOSR 24 +#define CCM_CGPR 25 +#define CCM_CCGR0 26 +#define CCM_CCGR1 27 +#define CCM_CCGR2 28 +#define CCM_CCGR3 29 +#define CCM_CCGR4 30 +#define CCM_CCGR5 31 +#define CCM_CCGR6 32 +#define CCM_CMEOR 34 +#define CCM_MAX 35 + +#define CCM_ANALOG_PLL_ARM 0 +#define CCM_ANALOG_PLL_ARM_SET 1 +#define CCM_ANALOG_PLL_ARM_CLR 2 +#define CCM_ANALOG_PLL_ARM_TOG 3 +#define CCM_ANALOG_PLL_USB1 4 +#define CCM_ANALOG_PLL_USB1_SET 5 +#define CCM_ANALOG_PLL_USB1_CLR 6 +#define CCM_ANALOG_PLL_USB1_TOG 7 +#define CCM_ANALOG_PLL_USB2 8 +#define CCM_ANALOG_PLL_USB2_SET 9 +#define CCM_ANALOG_PLL_USB2_CLR 10 +#define CCM_ANALOG_PLL_USB2_TOG 11 +#define CCM_ANALOG_PLL_SYS 12 +#define CCM_ANALOG_PLL_SYS_SET 13 +#define CCM_ANALOG_PLL_SYS_CLR 14 +#define CCM_ANALOG_PLL_SYS_TOG 15 +#define CCM_ANALOG_PLL_SYS_SS 16 +#define CCM_ANALOG_PLL_SYS_NUM 20 +#define CCM_ANALOG_PLL_SYS_DENOM 24 +#define CCM_ANALOG_PLL_AUDIO 28 +#define CCM_ANALOG_PLL_AUDIO_SET 29 +#define CCM_ANALOG_PLL_AUDIO_CLR 30 +#define CCM_ANALOG_PLL_AUDIO_TOG 31 +#define CCM_ANALOG_PLL_AUDIO_NUM 32 +#define CCM_ANALOG_PLL_AUDIO_DENOM 36 +#define CCM_ANALOG_PLL_VIDEO 40 +#define CCM_ANALOG_PLL_VIDEO_SET 41 +#define CCM_ANALOG_PLL_VIDEO_CLR 42 +#define CCM_ANALOG_PLL_VIDEO_TOG 44 +#define CCM_ANALOG_PLL_VIDEO_NUM 46 +#define CCM_ANALOG_PLL_VIDEO_DENOM 48 +#define CCM_ANALOG_PLL_ENET 56 +#define CCM_ANALOG_PLL_ENET_SET 57 +#define CCM_ANALOG_PLL_ENET_CLR 58 +#define CCM_ANALOG_PLL_ENET_TOG 59 +#define CCM_ANALOG_PFD_480 60 +#define CCM_ANALOG_PFD_480_SET 61 +#define CCM_ANALOG_PFD_480_CLR 62 +#define CCM_ANALOG_PFD_480_TOG 63 +#define CCM_ANALOG_PFD_528 64 +#define CCM_ANALOG_PFD_528_SET 65 +#define CCM_ANALOG_PFD_528_CLR 66 +#define CCM_ANALOG_PFD_528_TOG 67 + +/* PMU registers */ +#define PMU_REG_1P1 68 +#define PMU_REG_3P0 72 +#define PMU_REG_2P5 76 +#define PMU_REG_CORE 80 + +#define CCM_ANALOG_MISC0 84 +#define PMU_MISC0 CCM_ANALOG_MISC0 +#define CCM_ANALOG_MISC0_SET 85 +#define PMU_MISC0_SET CCM_ANALOG_MISC0_SET +#define CCM_ANALOG_MISC0_CLR 86 +#define PMU_MISC0_CLR CCM_ANALOG_MISC0_CLR +#define CCM_ANALOG_MISC0_TOG 87 +#define PMU_MISC0_TOG CCM_ANALOG_MISC0_TOG + +#define CCM_ANALOG_MISC1 88 +#define PMU_MISC1 CCM_ANALOG_MISC1 +#define CCM_ANALOG_MISC1_SET 89 +#define PMU_MISC1_SET CCM_ANALOG_MISC1_SET +#define CCM_ANALOG_MISC1_CLR 90 +#define PMU_MISC1_CLR CCM_ANALOG_MISC1_CLR +#define CCM_ANALOG_MISC1_TOG 91 +#define PMU_MISC1_TOG CCM_ANALOG_MISC1_TOG + +#define CCM_ANALOG_MISC2 92 +#define PMU_MISC2 CCM_ANALOG_MISC2 +#define CCM_ANALOG_MISC2_SET 93 +#define PMU_MISC2_SET CCM_ANALOG_MISC2_SET +#define CCM_ANALOG_MISC2_CLR 94 +#define PMU_MISC2_CLR CCM_ANALOG_MISC2_CLR +#define CCM_ANALOG_MISC2_TOG 95 +#define PMU_MISC2_TOG CCM_ANALOG_MISC2_TOG + +#define TEMPMON_TEMPSENSE0 96 +#define TEMPMON_TEMPSENSE0_SET 97 +#define TEMPMON_TEMPSENSE0_CLR 98 +#define TEMPMON_TEMPSENSE0_TOG 99 +#define TEMPMON_TEMPSENSE1 100 +#define TEMPMON_TEMPSENSE1_SET 101 +#define TEMPMON_TEMPSENSE1_CLR 102 +#define TEMPMON_TEMPSENSE1_TOG 103 +#define TEMPMON_TEMPSENSE2 164 +#define TEMPMON_TEMPSENSE2_SET 165 +#define TEMPMON_TEMPSENSE2_CLR 166 +#define TEMPMON_TEMPSENSE2_TOG 167 + +#define PMU_LOWPWR_CTRL 155 +#define PMU_LOWPWR_CTRL_SET 156 +#define PMU_LOWPWR_CTRL_CLR 157 +#define PMU_LOWPWR_CTRL_TOG 158 + +#define USB_ANALOG_USB1_VBUS_DETECT 104 +#define USB_ANALOG_USB1_VBUS_DETECT_SET 105 +#define USB_ANALOG_USB1_VBUS_DETECT_CLR 106 +#define USB_ANALOG_USB1_VBUS_DETECT_TOG 107 +#define USB_ANALOG_USB1_CHRG_DETECT 108 +#define USB_ANALOG_USB1_CHRG_DETECT_SET 109 +#define USB_ANALOG_USB1_CHRG_DETECT_CLR 110 +#define USB_ANALOG_USB1_CHRG_DETECT_TOG 111 +#define USB_ANALOG_USB1_VBUS_DETECT_STAT 112 +#define USB_ANALOG_USB1_CHRG_DETECT_STAT 116 +#define USB_ANALOG_USB1_MISC 124 +#define USB_ANALOG_USB1_MISC_SET 125 +#define USB_ANALOG_USB1_MISC_CLR 126 +#define USB_ANALOG_USB1_MISC_TOG 127 +#define USB_ANALOG_USB2_VBUS_DETECT 128 +#define USB_ANALOG_USB2_VBUS_DETECT_SET 129 +#define USB_ANALOG_USB2_VBUS_DETECT_CLR 130 +#define USB_ANALOG_USB2_VBUS_DETECT_TOG 131 +#define USB_ANALOG_USB2_CHRG_DETECT 132 +#define USB_ANALOG_USB2_CHRG_DETECT_SET 133 +#define USB_ANALOG_USB2_CHRG_DETECT_CLR 134 +#define USB_ANALOG_USB2_CHRG_DETECT_TOG 135 +#define USB_ANALOG_USB2_VBUS_DETECT_STAT 136 +#define USB_ANALOG_USB2_CHRG_DETECT_STAT 140 +#define USB_ANALOG_USB2_MISC 148 +#define USB_ANALOG_USB2_MISC_SET 149 +#define USB_ANALOG_USB2_MISC_CLR 150 +#define USB_ANALOG_USB2_MISC_TOG 151 +#define USB_ANALOG_DIGPROG 152 +#define CCM_ANALOG_MAX 4096 + +/* CCM_CBCMR */ +#define R_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT (18) +#define R_CBCMR_PRE_PERIPH_CLK_SEL_LENGTH (2) +#define R_CBCMR_PERIPH_CLK2_SEL_SHIFT (12) +#define R_CBCMR_PERIPH_CLK2_SEL_LENGTH (2) + +/* CCM_CBCDR */ +#define R_CBCDR_AHB_PODF_SHIFT (10) +#define R_CBCDR_AHB_PODF_LENGTH (3) +#define R_CBCDR_IPG_PODF_SHIFT (8) +#define R_CBCDR_IPG_PODF_LENGTH (2) +#define R_CBCDR_PERIPH_CLK_SEL_SHIFT (25) +#define R_CBCDR_PERIPH_CLK_SEL_LENGTH (1) +#define R_CBCDR_PERIPH_CLK2_PODF_SHIFT (27) +#define R_CBCDR_PERIPH_CLK2_PODF_LENGTH (3) + +/* CCM_CSCMR1 */ +#define R_CSCMR1_PERCLK_PODF_SHIFT (0) +#define R_CSCMR1_PERCLK_PODF_LENGTH (6) +#define R_CSCMR1_PERCLK_CLK_SEL_SHIFT (6) +#define R_CSCMR1_PERCLK_CLK_SEL_LENGTH (1) + +/* CCM_ANALOG_PFD_528 */ +#define R_ANALOG_PFD_528_PFD0_FRAC_SHIFT (0) +#define R_ANALOG_PFD_528_PFD0_FRAC_LENGTH (6) +#define R_ANALOG_PFD_528_PFD2_FRAC_SHIFT (16) +#define R_ANALOG_PFD_528_PFD2_FRAC_LENGTH (6) + +/* CCM_ANALOG_PLL_SYS */ +#define R_ANALOG_PLL_SYS_DIV_SELECT_SHIFT (0) +#define R_ANALOG_PLL_SYS_DIV_SELECT_LENGTH (1) + +#define CCM_ANALOG_PLL_LOCK (1 << 31); + +#define TYPE_IMX6UL_CCM "imx6ul.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX6ULCCMState, IMX6UL_CCM) + +struct IMX6ULCCMState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + MemoryRegion container; + MemoryRegion ioccm; + MemoryRegion ioanalog; + + uint32_t ccm[CCM_MAX]; + uint32_t analog[CCM_ANALOG_MAX]; + +}; + +#endif /* IMX6UL_CCM_H */ diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h new file mode 100644 index 000000000..dcaebfb4e --- /dev/null +++ b/include/hw/misc/imx7_ccm.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, Impinj, Inc. + * + * i.MX7 CCM, PMU and ANALOG IP blocks emulation code + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX7_CCM_H +#define IMX7_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qemu/bitops.h" +#include "qom/object.h" + +enum IMX7AnalogRegisters { + ANALOG_PLL_ARM, + ANALOG_PLL_ARM_SET, + ANALOG_PLL_ARM_CLR, + ANALOG_PLL_ARM_TOG, + ANALOG_PLL_DDR, + ANALOG_PLL_DDR_SET, + ANALOG_PLL_DDR_CLR, + ANALOG_PLL_DDR_TOG, + ANALOG_PLL_DDR_SS, + ANALOG_PLL_DDR_SS_SET, + ANALOG_PLL_DDR_SS_CLR, + ANALOG_PLL_DDR_SS_TOG, + ANALOG_PLL_DDR_NUM, + ANALOG_PLL_DDR_NUM_SET, + ANALOG_PLL_DDR_NUM_CLR, + ANALOG_PLL_DDR_NUM_TOG, + ANALOG_PLL_DDR_DENOM, + ANALOG_PLL_DDR_DENOM_SET, + ANALOG_PLL_DDR_DENOM_CLR, + ANALOG_PLL_DDR_DENOM_TOG, + ANALOG_PLL_480, + ANALOG_PLL_480_SET, + ANALOG_PLL_480_CLR, + ANALOG_PLL_480_TOG, + ANALOG_PLL_480A, + ANALOG_PLL_480A_SET, + ANALOG_PLL_480A_CLR, + ANALOG_PLL_480A_TOG, + ANALOG_PLL_480B, + ANALOG_PLL_480B_SET, + ANALOG_PLL_480B_CLR, + ANALOG_PLL_480B_TOG, + ANALOG_PLL_ENET, + ANALOG_PLL_ENET_SET, + ANALOG_PLL_ENET_CLR, + ANALOG_PLL_ENET_TOG, + ANALOG_PLL_AUDIO, + ANALOG_PLL_AUDIO_SET, + ANALOG_PLL_AUDIO_CLR, + ANALOG_PLL_AUDIO_TOG, + ANALOG_PLL_AUDIO_SS, + ANALOG_PLL_AUDIO_SS_SET, + ANALOG_PLL_AUDIO_SS_CLR, + ANALOG_PLL_AUDIO_SS_TOG, + ANALOG_PLL_AUDIO_NUM, + ANALOG_PLL_AUDIO_NUM_SET, + ANALOG_PLL_AUDIO_NUM_CLR, + ANALOG_PLL_AUDIO_NUM_TOG, + ANALOG_PLL_AUDIO_DENOM, + ANALOG_PLL_AUDIO_DENOM_SET, + ANALOG_PLL_AUDIO_DENOM_CLR, + ANALOG_PLL_AUDIO_DENOM_TOG, + ANALOG_PLL_VIDEO, + ANALOG_PLL_VIDEO_SET, + ANALOG_PLL_VIDEO_CLR, + ANALOG_PLL_VIDEO_TOG, + ANALOG_PLL_VIDEO_SS, + ANALOG_PLL_VIDEO_SS_SET, + ANALOG_PLL_VIDEO_SS_CLR, + ANALOG_PLL_VIDEO_SS_TOG, + ANALOG_PLL_VIDEO_NUM, + ANALOG_PLL_VIDEO_NUM_SET, + ANALOG_PLL_VIDEO_NUM_CLR, + ANALOG_PLL_VIDEO_NUM_TOG, + ANALOG_PLL_VIDEO_DENOM, + ANALOG_PLL_VIDEO_DENOM_SET, + ANALOG_PLL_VIDEO_DENOM_CLR, + ANALOG_PLL_VIDEO_DENOM_TOG, + ANALOG_PLL_MISC0, + ANALOG_PLL_MISC0_SET, + ANALOG_PLL_MISC0_CLR, + ANALOG_PLL_MISC0_TOG, + + ANALOG_DIGPROG = 0x800 / sizeof(uint32_t), + ANALOG_MAX, + + ANALOG_PLL_LOCK = BIT(31) +}; + +enum IMX7CCMRegisters { + CCM_MAX = 0xBE00 / sizeof(uint32_t) + 1, +}; + +enum IMX7PMURegisters { + PMU_MAX = 0x140 / sizeof(uint32_t), +}; + +#define TYPE_IMX7_CCM "imx7.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX7CCMState, IMX7_CCM) + +struct IMX7CCMState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + MemoryRegion iomem; + + uint32_t ccm[CCM_MAX]; +}; + + +#define TYPE_IMX7_ANALOG "imx7.analog" +OBJECT_DECLARE_SIMPLE_TYPE(IMX7AnalogState, IMX7_ANALOG) + +struct IMX7AnalogState { + /* <private> */ + IMXCCMState parent_obj; + + /* <public> */ + struct { + MemoryRegion container; + MemoryRegion analog; + MemoryRegion digprog; + MemoryRegion pmu; + } mmio; + + uint32_t analog[ANALOG_MAX]; + uint32_t pmu[PMU_MAX]; +}; + +#endif /* IMX7_CCM_H */ diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h new file mode 100644 index 000000000..df364bd8f --- /dev/null +++ b/include/hw/misc/imx7_gpr.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, Impinj, Inc. + * + * i.MX7 GPR IP block emulation code + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX7_GPR_H +#define IMX7_GPR_H + +#include "qemu/bitops.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_IMX7_GPR "imx7.gpr" +OBJECT_DECLARE_SIMPLE_TYPE(IMX7GPRState, IMX7_GPR) + +struct IMX7GPRState { + /* <private> */ + SysBusDevice parent_obj; + + MemoryRegion mmio; +}; + +#endif /* IMX7_GPR_H */ diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h new file mode 100644 index 000000000..14a1d6fe6 --- /dev/null +++ b/include/hw/misc/imx7_snvs.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, Impinj, Inc. + * + * i.MX7 SNVS block emulation code + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX7_SNVS_H +#define IMX7_SNVS_H + +#include "qemu/bitops.h" +#include "hw/sysbus.h" +#include "qom/object.h" + + +enum IMX7SNVSRegisters { + SNVS_LPCR = 0x38, + SNVS_LPCR_TOP = BIT(6), + SNVS_LPCR_DP_EN = BIT(5) +}; + +#define TYPE_IMX7_SNVS "imx7.snvs" +OBJECT_DECLARE_SIMPLE_TYPE(IMX7SNVSState, IMX7_SNVS) + +struct IMX7SNVSState { + /* <private> */ + SysBusDevice parent_obj; + + MemoryRegion mmio; +}; + +#endif /* IMX7_SNVS_H */ diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h new file mode 100644 index 000000000..7e5678e97 --- /dev/null +++ b/include/hw/misc/imx_ccm.h @@ -0,0 +1,63 @@ +/* + * IMX Clock Control Module base class + * + * Copyright (C) 2012 NICTA + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX_CCM_H +#define IMX_CCM_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define CKIL_FREQ 32768 /* nominal 32khz clock */ + +/* PLL control registers */ +#define PD(v) (((v) >> 26) & 0xf) +#define MFD(v) (((v) >> 16) & 0x3ff) +#define MFI(v) (((v) >> 10) & 0xf); +#define MFN(v) ((v) & 0x3ff) + +#define PLL_PD(x) (((x) & 0xf) << 26) +#define PLL_MFD(x) (((x) & 0x3ff) << 16) +#define PLL_MFI(x) (((x) & 0xf) << 10) +#define PLL_MFN(x) (((x) & 0x3ff) << 0) + +#define TYPE_IMX_CCM "imx.ccm" +OBJECT_DECLARE_TYPE(IMXCCMState, IMXCCMClass, IMX_CCM) + +struct IMXCCMState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + +}; + +typedef enum { + CLK_NONE, + CLK_IPG, + CLK_IPG_HIGH, + CLK_32k, + CLK_EXT, + CLK_HIGH_DIV, + CLK_HIGH, +} IMXClk; + +struct IMXCCMClass { + /* <private> */ + SysBusDeviceClass parent_class; + + /* <public> */ + uint32_t (*get_clock_frequency)(IMXCCMState *s, IMXClk clk); +}; + +uint32_t imx_ccm_calc_pll(uint32_t pllreg, uint32_t base_freq); + +uint32_t imx_ccm_get_clock_frequency(IMXCCMState *s, IMXClk clock); + +#endif /* IMX_CCM_H */ diff --git a/include/hw/misc/imx_rngc.h b/include/hw/misc/imx_rngc.h new file mode 100644 index 000000000..34ad69922 --- /dev/null +++ b/include/hw/misc/imx_rngc.h @@ -0,0 +1,36 @@ +/* + * Freescale i.MX RNGC emulation + * + * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef IMX_RNGC_H +#define IMX_RNGC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_IMX_RNGC "imx.rngc" +OBJECT_DECLARE_SIMPLE_TYPE(IMXRNGCState, IMX_RNGC) + +struct IMXRNGCState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint8_t op_self_test; + uint8_t op_seed; + uint8_t mask; + bool auto_seed; + + QEMUBH *self_test_bh; + QEMUBH *seed_bh; + qemu_irq irq; +}; + +#endif /* IMX_RNGC_H */ diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h new file mode 100644 index 000000000..79a362832 --- /dev/null +++ b/include/hw/misc/iotkit-secctl.h @@ -0,0 +1,127 @@ +/* + * ARM IoT Kit security controller + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the security controller which is part of the + * Arm IoT Kit and documented in + * https://developer.arm.com/documentation/ecm0601256/latest + * + * QEMU interface: + * + sysbus MMIO region 0 is the "secure privilege control block" registers + * + sysbus MMIO region 1 is the "non-secure privilege control block" registers + * + named GPIO output "sec_resp_cfg" indicating whether blocked accesses + * should RAZ/WI or bus error + * + named GPIO output "nsc_cfg" whose value tracks the NSCCFG register value + * + named GPIO output "msc_irq" for the combined IRQ line from the MSCs + * Controlling the 2 APB PPCs in the IoTKit: + * + named GPIO outputs apb_ppc0_nonsec[0..2] and apb_ppc1_nonsec + * + named GPIO outputs apb_ppc0_ap[0..2] and apb_ppc1_ap + * + named GPIO outputs apb_ppc{0,1}_irq_enable + * + named GPIO outputs apb_ppc{0,1}_irq_clear + * + named GPIO inputs apb_ppc{0,1}_irq_status + * Controlling each of the 4 expansion APB PPCs which a system using the IoTKit + * might provide: + * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status + * Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit + * might provide: + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status + * Controlling the (up to) 4 MPCs in the IoTKit/SSE: + * + named GPIO inputs mpc_status[0..3] + * Controlling each of the 16 expansion MPCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] + */ + +#ifndef IOTKIT_SECCTL_H +#define IOTKIT_SECCTL_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_IOTKIT_SECCTL "iotkit-secctl" +OBJECT_DECLARE_SIMPLE_TYPE(IoTKitSecCtl, IOTKIT_SECCTL) + +#define IOTS_APB_PPC0_NUM_PORTS 3 +#define IOTS_APB_PPC1_NUM_PORTS 1 +#define IOTS_PPC_NUM_PORTS 16 +#define IOTS_NUM_APB_PPC 2 +#define IOTS_NUM_APB_EXP_PPC 4 +#define IOTS_NUM_AHB_EXP_PPC 4 +#define IOTS_NUM_EXP_MPC 16 +#define IOTS_NUM_MPC 4 +#define IOTS_NUM_EXP_MSC 16 + + +/* State and IRQ lines relating to a PPC. For the + * PPCs in the IoTKit not all the IRQ lines are used. + */ +typedef struct IoTKitSecCtlPPC { + qemu_irq nonsec[IOTS_PPC_NUM_PORTS]; + qemu_irq ap[IOTS_PPC_NUM_PORTS]; + qemu_irq irq_enable; + qemu_irq irq_clear; + + uint32_t ns; + uint32_t sp; + uint32_t nsp; + + /* Number of ports actually present */ + int numports; + /* Offset of this PPC's interrupt bits in SECPPCINTSTAT */ + int irq_bit_offset; + IoTKitSecCtl *parent; +} IoTKitSecCtlPPC; + +struct IoTKitSecCtl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + qemu_irq sec_resp_cfg; + qemu_irq nsc_cfg_irq; + + MemoryRegion s_regs; + MemoryRegion ns_regs; + + uint32_t secppcintstat; + uint32_t secppcinten; + uint32_t secrespcfg; + uint32_t nsccfg; + uint32_t brginten; + uint32_t mpcintstatus; + + uint32_t secmscintstat; + uint32_t secmscinten; + uint32_t nsmscexp; + qemu_irq mscexp_clear[IOTS_NUM_EXP_MSC]; + qemu_irq mscexp_ns[IOTS_NUM_EXP_MSC]; + qemu_irq msc_irq; + + IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC]; + IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC]; + IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC]; + + uint32_t sse_version; +}; + +#endif diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h new file mode 100644 index 000000000..481e27f4d --- /dev/null +++ b/include/hw/misc/iotkit-sysctl.h @@ -0,0 +1,73 @@ +/* + * ARM IoTKit system control element + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system control element" which is part of the + * Arm IoTKit and documented in + * https://developer.arm.com/documentation/ecm0601256/latest + * Specifically, it implements the "system information block" and + * "system control register" blocks. + * + * QEMU interface: + * + QOM property "sse-version": indicates which SSE version this is part of + * (used to identify whether to provide SSE-200-only registers, etc) + * + sysbus MMIO region 0: the system information register bank + * + sysbus MMIO region 1: the system control register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSCTL_H +#define HW_MISC_IOTKIT_SYSCTL_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_IOTKIT_SYSCTL "iotkit-sysctl" +OBJECT_DECLARE_SIMPLE_TYPE(IoTKitSysCtl, IOTKIT_SYSCTL) + +struct IoTKitSysCtl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t secure_debug; + uint32_t reset_syndrome; + uint32_t reset_mask; + uint32_t gretreg; + uint32_t initsvtor0; + uint32_t cpuwait; + uint32_t wicctrl; + uint32_t scsecctrl; + uint32_t fclk_div; + uint32_t sysclk_div; + uint32_t clock_force; + uint32_t initsvtor1; + uint32_t nmi_enable; + uint32_t ewctrl; + uint32_t pwrctrl; + uint32_t pdcm_pd_sys_sense; + uint32_t pdcm_pd_sram0_sense; + uint32_t pdcm_pd_sram1_sense; + uint32_t pdcm_pd_sram2_sense; + uint32_t pdcm_pd_sram3_sense; + uint32_t pdcm_pd_cpu0_sense; + uint32_t pdcm_pd_vmr0_sense; + uint32_t pdcm_pd_vmr1_sense; + + /* Properties */ + uint32_t sse_version; + uint32_t cpuwait_rst; + uint32_t initsvtor0_rst; + uint32_t initsvtor1_rst; +}; + +#endif diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h new file mode 100644 index 000000000..91c23f90d --- /dev/null +++ b/include/hw/misc/iotkit-sysinfo.h @@ -0,0 +1,45 @@ +/* + * ARM IoTKit system information block + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system information block" which is part of the + * Arm IoTKit and documented in + * https://developer.arm.com/documentation/ecm0601256/latest + * QEMU interface: + * + QOM property "SYS_VERSION": value to use for SYS_VERSION register + * + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register + * + sysbus MMIO region 0: the system information register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSINFO_H +#define HW_MISC_IOTKIT_SYSINFO_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo" +OBJECT_DECLARE_SIMPLE_TYPE(IoTKitSysInfo, IOTKIT_SYSINFO) + +struct IoTKitSysInfo { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + /* Properties */ + uint32_t sys_version; + uint32_t sys_config; + uint32_t sse_version; + uint32_t iidr; +}; + +#endif diff --git a/include/hw/misc/ivshmem.h b/include/hw/misc/ivshmem.h new file mode 100644 index 000000000..433ef53d7 --- /dev/null +++ b/include/hw/misc/ivshmem.h @@ -0,0 +1,25 @@ + +/* + * Inter-VM Shared Memory PCI device. + * + * Author: + * Cam Macdonell <cam@cs.ualberta.ca> + * + * Based On: cirrus_vga.c + * Copyright (c) 2004 Fabrice Bellard + * Copyright (c) 2004 Makoto Suzuki (suzu) + * + * and rtl8139.c + * Copyright (c) 2006 Igor Kovalenko + * + * This code is licensed under the GNU GPL v2. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ +#ifndef IVSHMEM_H +#define IVSHMEM_H + +#define IVSHMEM_PROTOCOL_VERSION 0 + +#endif /* IVSHMEM_H */ diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h new file mode 100644 index 000000000..29c087957 --- /dev/null +++ b/include/hw/misc/led.h @@ -0,0 +1,98 @@ +/* + * QEMU single LED device + * + * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef HW_MISC_LED_H +#define HW_MISC_LED_H + +#include "qom/object.h" +#include "hw/qdev-core.h" + +#define TYPE_LED "led" + +/** + * LEDColor: Color of a LED + * + * This set is restricted to physically available LED colors. + * + * LED colors from 'Table 1. Product performance of LUXEON Rebel Color + * Line' of the 'DS68 LUXEON Rebel Color Line' datasheet available at: + * https://www.lumileds.com/products/color-leds/luxeon-rebel-color/ + */ +typedef enum { /* Coarse wavelength range */ + LED_COLOR_VIOLET, /* 425 nm */ + LED_COLOR_BLUE, /* 475 nm */ + LED_COLOR_CYAN, /* 500 nm */ + LED_COLOR_GREEN, /* 535 nm */ + LED_COLOR_YELLOW, /* 567 nm */ + LED_COLOR_AMBER, /* 590 nm */ + LED_COLOR_ORANGE, /* 615 nm */ + LED_COLOR_RED, /* 630 nm */ +} LEDColor; + +struct LEDState { + /* Private */ + DeviceState parent_obj; + /* Public */ + + uint8_t intensity_percent; + qemu_irq irq; + + /* Properties */ + char *description; + char *color; + /* + * Determines whether a GPIO is using a positive (active-high) + * logic (when used with GPIO, the intensity at reset is related + * to the GPIO polarity). + */ + bool gpio_active_high; +}; +typedef struct LEDState LEDState; +DECLARE_INSTANCE_CHECKER(LEDState, LED, TYPE_LED) + +/** + * led_set_intensity: Set the intensity of a LED device + * @s: the LED object + * @intensity_percent: intensity as percentage in range 0 to 100. + */ +void led_set_intensity(LEDState *s, unsigned intensity_percent); + +/** + * led_get_intensity: + * @s: the LED object + * + * Returns: The LED intensity as percentage in range 0 to 100. + */ +unsigned led_get_intensity(LEDState *s); + +/** + * led_set_state: Set the state of a LED device + * @s: the LED object + * @is_emitting: boolean indicating whether the LED is emitting + * + * This utility is meant for LED connected to GPIO. + */ +void led_set_state(LEDState *s, bool is_emitting); + +/** + * led_create_simple: Create and realize a LED device + * @parentobj: the parent object + * @gpio_polarity: GPIO polarity + * @color: color of the LED + * @description: description of the LED (optional) + * + * Create the device state structure, initialize it, and + * drop the reference to it (the device is realized). + * + * Returns: The newly allocated and instantiated LED object. + */ +LEDState *led_create_simple(Object *parentobj, + GpioPolarity gpio_polarity, + LEDColor color, + const char *description); + +#endif /* HW_MISC_LED_H */ diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h new file mode 100644 index 000000000..b44556586 --- /dev/null +++ b/include/hw/misc/mac_via.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2011-2018 Laurent Vivier + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_MISC_MAC_VIA_H +#define HW_MISC_MAC_VIA_H + +#include "exec/memory.h" +#include "hw/sysbus.h" +#include "hw/misc/mos6522.h" +#include "qom/object.h" + + +#define VIA_SIZE 0x2000 + +/* VIA 1 */ +#define VIA1_IRQ_ONE_SECOND_BIT 0 +#define VIA1_IRQ_60HZ_BIT 1 +#define VIA1_IRQ_ADB_READY_BIT 2 +#define VIA1_IRQ_ADB_DATA_BIT 3 +#define VIA1_IRQ_ADB_CLOCK_BIT 4 + +#define VIA1_IRQ_NB 8 + +#define VIA1_IRQ_ONE_SECOND (1 << VIA1_IRQ_ONE_SECOND_BIT) +#define VIA1_IRQ_60HZ (1 << VIA1_IRQ_60HZ_BIT) +#define VIA1_IRQ_ADB_READY (1 << VIA1_IRQ_ADB_READY_BIT) +#define VIA1_IRQ_ADB_DATA (1 << VIA1_IRQ_ADB_DATA_BIT) +#define VIA1_IRQ_ADB_CLOCK (1 << VIA1_IRQ_ADB_CLOCK_BIT) + + +#define TYPE_MOS6522_Q800_VIA1 "mos6522-q800-via1" +OBJECT_DECLARE_SIMPLE_TYPE(MOS6522Q800VIA1State, MOS6522_Q800_VIA1) + +struct MOS6522Q800VIA1State { + /*< private >*/ + MOS6522State parent_obj; + + MemoryRegion via_mem; + + qemu_irq irqs[VIA1_IRQ_NB]; + qemu_irq auxmode_irq; + uint8_t last_b; + + /* RTC */ + uint8_t PRAM[256]; + BlockBackend *blk; + VMChangeStateEntry *vmstate; + + uint32_t tick_offset; + + uint8_t data_out; + int data_out_cnt; + uint8_t data_in; + uint8_t data_in_cnt; + uint8_t cmd; + int wprotect; + int alt; + + /* ADB */ + ADBBusState adb_bus; + qemu_irq adb_data_ready; + int adb_data_in_size; + int adb_data_in_index; + int adb_data_out_index; + uint8_t adb_data_in[128]; + uint8_t adb_data_out[16]; + uint8_t adb_autopoll_cmd; + + /* external timers */ + QEMUTimer *one_second_timer; + int64_t next_second; + QEMUTimer *sixty_hz_timer; + int64_t next_sixty_hz; +}; + + +/* VIA 2 */ +#define VIA2_IRQ_SCSI_DATA_BIT 0 +#define VIA2_IRQ_NUBUS_BIT 1 +#define VIA2_IRQ_UNUSED_BIT 2 +#define VIA2_IRQ_SCSI_BIT 3 +#define VIA2_IRQ_ASC_BIT 4 + +#define VIA2_IRQ_NB 8 + +#define VIA2_IRQ_SCSI_DATA (1 << VIA2_IRQ_SCSI_DATA_BIT) +#define VIA2_IRQ_NUBUS (1 << VIA2_IRQ_NUBUS_BIT) +#define VIA2_IRQ_UNUSED (1 << VIA2_IRQ_SCSI_BIT) +#define VIA2_IRQ_SCSI (1 << VIA2_IRQ_UNUSED_BIT) +#define VIA2_IRQ_ASC (1 << VIA2_IRQ_ASC_BIT) + +#define VIA2_NUBUS_IRQ_NB 7 + +#define VIA2_NUBUS_IRQ_9 0 +#define VIA2_NUBUS_IRQ_A 1 +#define VIA2_NUBUS_IRQ_B 2 +#define VIA2_NUBUS_IRQ_C 3 +#define VIA2_NUBUS_IRQ_D 4 +#define VIA2_NUBUS_IRQ_E 5 +#define VIA2_NUBUS_IRQ_INTVIDEO 6 + +#define TYPE_MOS6522_Q800_VIA2 "mos6522-q800-via2" +OBJECT_DECLARE_SIMPLE_TYPE(MOS6522Q800VIA2State, MOS6522_Q800_VIA2) + +struct MOS6522Q800VIA2State { + /*< private >*/ + MOS6522State parent_obj; + + MemoryRegion via_mem; +}; + +#endif diff --git a/include/hw/misc/macio/cuda.h b/include/hw/misc/macio/cuda.h new file mode 100644 index 000000000..a71deec96 --- /dev/null +++ b/include/hw/misc/macio/cuda.h @@ -0,0 +1,102 @@ +/* + * QEMU PowerMac CUDA device support + * + * Copyright (c) 2004-2007 Fabrice Bellard + * Copyright (c) 2007 Jocelyn Mayer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef CUDA_H +#define CUDA_H + +#include "hw/misc/mos6522.h" +#include "qom/object.h" + +/* CUDA commands (2nd byte) */ +#define CUDA_WARM_START 0x0 +#define CUDA_AUTOPOLL 0x1 +#define CUDA_GET_6805_ADDR 0x2 +#define CUDA_GET_TIME 0x3 +#define CUDA_GET_PRAM 0x7 +#define CUDA_SET_6805_ADDR 0x8 +#define CUDA_SET_TIME 0x9 +#define CUDA_POWERDOWN 0xa +#define CUDA_POWERUP_TIME 0xb +#define CUDA_SET_PRAM 0xc +#define CUDA_MS_RESET 0xd +#define CUDA_SEND_DFAC 0xe +#define CUDA_BATTERY_SWAP_SENSE 0x10 +#define CUDA_RESET_SYSTEM 0x11 +#define CUDA_SET_IPL 0x12 +#define CUDA_FILE_SERVER_FLAG 0x13 +#define CUDA_SET_AUTO_RATE 0x14 +#define CUDA_GET_AUTO_RATE 0x16 +#define CUDA_SET_DEVICE_LIST 0x19 +#define CUDA_GET_DEVICE_LIST 0x1a +#define CUDA_SET_ONE_SECOND_MODE 0x1b +#define CUDA_SET_POWER_MESSAGES 0x21 +#define CUDA_GET_SET_IIC 0x22 +#define CUDA_WAKEUP 0x23 +#define CUDA_TIMER_TICKLE 0x24 +#define CUDA_COMBINED_FORMAT_IIC 0x25 + + +/* MOS6522 CUDA */ +struct MOS6522CUDAState { + /*< private >*/ + MOS6522State parent_obj; +}; + +#define TYPE_MOS6522_CUDA "mos6522-cuda" +OBJECT_DECLARE_SIMPLE_TYPE(MOS6522CUDAState, MOS6522_CUDA) + +/* Cuda */ +#define TYPE_CUDA "cuda" +OBJECT_DECLARE_SIMPLE_TYPE(CUDAState, CUDA) + +struct CUDAState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + MemoryRegion mem; + + ADBBusState adb_bus; + MOS6522CUDAState mos6522_cuda; + + uint32_t tick_offset; + uint64_t tb_frequency; + + uint8_t last_b; + uint8_t last_acr; + + /* MacOS 9 is racy and requires a delay upon setting the SR_INT bit */ + uint64_t sr_delay_ns; + QEMUTimer *sr_delay_timer; + + int data_in_size; + int data_in_index; + int data_out_index; + + qemu_irq irq; + uint8_t data_in[128]; + uint8_t data_out[16]; +}; + +#endif /* CUDA_H */ diff --git a/include/hw/misc/macio/gpio.h b/include/hw/misc/macio/gpio.h new file mode 100644 index 000000000..7d2aa886c --- /dev/null +++ b/include/hw/misc/macio/gpio.h @@ -0,0 +1,49 @@ +/* + * PowerMac NewWorld MacIO GPIO emulation + * + * Copyright (c) 2016 Benjamin Herrenschmidt + * Copyright (c) 2018 Mark Cave-Ayland + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MACIO_GPIO_H +#define MACIO_GPIO_H + +#include "hw/ppc/openpic.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_MACIO_GPIO "macio-gpio" +OBJECT_DECLARE_SIMPLE_TYPE(MacIOGPIOState, MACIO_GPIO) + +struct MacIOGPIOState { + /*< private >*/ + SysBusDevice parent; + /*< public >*/ + + MemoryRegion gpiomem; + qemu_irq gpio_extirqs[10]; + uint8_t gpio_levels[8]; + uint8_t gpio_regs[36]; /* XXX Check count */ +}; + +void macio_set_gpio(MacIOGPIOState *s, uint32_t gpio, bool state); + +#endif diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h new file mode 100644 index 000000000..6c05f3bfd --- /dev/null +++ b/include/hw/misc/macio/macio.h @@ -0,0 +1,123 @@ +/* + * PowerMac MacIO device emulation + * + * Copyright (c) 2005-2007 Fabrice Bellard + * Copyright (c) 2007 Jocelyn Mayer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MACIO_H +#define MACIO_H + +#include "hw/char/escc.h" +#include "hw/pci/pci.h" +#include "hw/ide/internal.h" +#include "hw/intc/heathrow_pic.h" +#include "hw/misc/macio/cuda.h" +#include "hw/misc/macio/gpio.h" +#include "hw/misc/macio/pmu.h" +#include "hw/ppc/mac.h" +#include "hw/ppc/mac_dbdma.h" +#include "hw/ppc/openpic.h" +#include "qom/object.h" + +/* MacIO virtual bus */ +#define TYPE_MACIO_BUS "macio-bus" +OBJECT_DECLARE_SIMPLE_TYPE(MacIOBusState, MACIO_BUS) + +struct MacIOBusState { + /*< private >*/ + BusState parent_obj; +}; + +/* MacIO IDE */ +#define TYPE_MACIO_IDE "macio-ide" +OBJECT_DECLARE_SIMPLE_TYPE(MACIOIDEState, MACIO_IDE) + +struct MACIOIDEState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + uint32_t addr; + uint32_t channel; + qemu_irq real_ide_irq; + qemu_irq real_dma_irq; + qemu_irq ide_irq; + qemu_irq dma_irq; + + MemoryRegion mem; + IDEBus bus; + IDEDMA dma; + void *dbdma; + bool dma_active; + uint32_t timing_reg; + uint32_t irq_reg; +}; + +void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); +void macio_ide_register_dma(MACIOIDEState *ide); + +#define TYPE_MACIO "macio" +OBJECT_DECLARE_SIMPLE_TYPE(MacIOState, MACIO) + +struct MacIOState { + /*< private >*/ + PCIDevice parent; + /*< public >*/ + + MacIOBusState macio_bus; + MemoryRegion bar; + CUDAState cuda; + PMUState pmu; + DBDMAState dbdma; + ESCCState escc; + uint64_t frequency; +}; + +#define TYPE_OLDWORLD_MACIO "macio-oldworld" +OBJECT_DECLARE_SIMPLE_TYPE(OldWorldMacIOState, OLDWORLD_MACIO) + +struct OldWorldMacIOState { + /*< private >*/ + MacIOState parent_obj; + /*< public >*/ + + HeathrowState pic; + + MacIONVRAMState nvram; + MACIOIDEState ide[2]; +}; + +#define TYPE_NEWWORLD_MACIO "macio-newworld" +OBJECT_DECLARE_SIMPLE_TYPE(NewWorldMacIOState, NEWWORLD_MACIO) + +struct NewWorldMacIOState { + /*< private >*/ + MacIOState parent_obj; + /*< public >*/ + + bool has_pmu; + bool has_adb; + OpenPICState pic; + MACIOIDEState ide[2]; + MacIOGPIOState gpio; +}; + +#endif /* MACIO_H */ diff --git a/include/hw/misc/macio/pmu.h b/include/hw/misc/macio/pmu.h new file mode 100644 index 000000000..78237d99a --- /dev/null +++ b/include/hw/misc/macio/pmu.h @@ -0,0 +1,236 @@ +/* + * Definitions for talking to the PMU. The PMU is a microcontroller + * which controls battery charging and system power on PowerBook 3400 + * and 2400 models as well as the RTC and various other things. + * + * Copyright (C) 1998 Paul Mackerras. + * Copyright (C) 2016 Ben Herrenschmidt + */ + +#ifndef PMU_H +#define PMU_H + +#include "hw/misc/mos6522.h" +#include "hw/misc/macio/gpio.h" +#include "qom/object.h" + +/* + * PMU commands + */ + +#define PMU_POWER_CTRL0 0x10 /* control power of some devices */ +#define PMU_POWER_CTRL 0x11 /* control power of some devices */ +#define PMU_ADB_CMD 0x20 /* send ADB packet */ +#define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */ +#define PMU_WRITE_NVRAM 0x33 /* write non-volatile RAM */ +#define PMU_READ_NVRAM 0x3b /* read non-volatile RAM */ +#define PMU_SET_RTC 0x30 /* set real-time clock */ +#define PMU_READ_RTC 0x38 /* read real-time clock */ +#define PMU_SET_VOLBUTTON 0x40 /* set volume up/down position */ +#define PMU_BACKLIGHT_BRIGHT 0x41 /* set backlight brightness */ +#define PMU_GET_VOLBUTTON 0x48 /* get volume up/down position */ +#define PMU_PCEJECT 0x4c /* eject PC-card from slot */ +#define PMU_BATTERY_STATE 0x6b /* report battery state etc. */ +#define PMU_SMART_BATTERY_STATE 0x6f /* report battery state (new way) */ +#define PMU_SET_INTR_MASK 0x70 /* set PMU interrupt mask */ +#define PMU_INT_ACK 0x78 /* read interrupt bits */ +#define PMU_SHUTDOWN 0x7e /* turn power off */ +#define PMU_CPU_SPEED 0x7d /* control CPU speed on some models */ +#define PMU_SLEEP 0x7f /* put CPU to sleep */ +#define PMU_POWER_EVENTS 0x8f /* Send power-event commands to PMU */ +#define PMU_I2C_CMD 0x9a /* I2C operations */ +#define PMU_RESET 0xd0 /* reset CPU */ +#define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */ +#define PMU_GET_COVER 0xdc /* report cover open/closed */ +#define PMU_SYSTEM_READY 0xdf /* tell PMU we are awake */ +#define PMU_DOWNLOAD_STATUS 0xe2 /* Called by MacOS during boot... */ +#define PMU_READ_PMU_RAM 0xe8 /* read the PMU RAM... ??? */ +#define PMU_GET_VERSION 0xea /* read the PMU version */ + +/* Bits to use with the PMU_POWER_CTRL0 command */ +#define PMU_POW0_ON 0x80 /* OR this to power ON the device */ +#define PMU_POW0_OFF 0x00 /* leave bit 7 to 0 to power it OFF */ +#define PMU_POW0_HARD_DRIVE 0x04 /* Hard drive power + * (on wallstreet/lombard ?) */ + +/* Bits to use with the PMU_POWER_CTRL command */ +#define PMU_POW_ON 0x80 /* OR this to power ON the device */ +#define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */ +#define PMU_POW_BACKLIGHT 0x01 /* backlight power */ +#define PMU_POW_CHARGER 0x02 /* battery charger power */ +#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) */ +#define PMU_POW_MEDIABAY 0x08 /* media bay power + * (wallstreet/lombard ?) */ + +/* Bits in PMU interrupt and interrupt mask bytes */ +#define PMU_INT_PCEJECT 0x04 /* PC-card eject buttons */ +#define PMU_INT_SNDBRT 0x08 /* sound/brightness up/down buttons */ +#define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */ +#define PMU_INT_BATTERY 0x20 /* Battery state change */ +#define PMU_INT_ENVIRONMENT 0x40 /* Environment interrupts */ +#define PMU_INT_TICK 0x80 /* 1-second tick interrupt */ + +/* Other bits in PMU interrupt valid when PMU_INT_ADB is set */ +#define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */ +#define PMU_INT_WAITING_CHARGER 0x01 /* ??? */ +#define PMU_INT_AUTO_SRQ_POLL 0x02 /* ??? */ + +/* Bits in the environement message (either obtained via PMU_GET_COVER, + * or via PMU_INT_ENVIRONMENT on core99 */ +#define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */ + +/* I2C related definitions */ +#define PMU_I2C_MODE_SIMPLE 0 +#define PMU_I2C_MODE_STDSUB 1 +#define PMU_I2C_MODE_COMBINED 2 + +#define PMU_I2C_BUS_STATUS 0 +#define PMU_I2C_BUS_SYSCLK 1 +#define PMU_I2C_BUS_POWER 2 + +#define PMU_I2C_STATUS_OK 0 +#define PMU_I2C_STATUS_DATAREAD 1 +#define PMU_I2C_STATUS_BUSY 0xfe + +/* Kind of PMU (model) */ +enum { + PMU_UNKNOWN, + PMU_OHARE_BASED, /* 2400, 3400, 3500 (old G3 powerbook) */ + PMU_HEATHROW_BASED, /* PowerBook G3 series */ + PMU_PADDINGTON_BASED, /* 1999 PowerBook G3 */ + PMU_KEYLARGO_BASED, /* Core99 motherboard (PMU99) */ + PMU_68K_V1, /* 68K PMU, version 1 */ + PMU_68K_V2, /* 68K PMU, version 2 */ +}; + +/* PMU PMU_POWER_EVENTS commands */ +enum { + PMU_PWR_GET_POWERUP_EVENTS = 0x00, + PMU_PWR_SET_POWERUP_EVENTS = 0x01, + PMU_PWR_CLR_POWERUP_EVENTS = 0x02, + PMU_PWR_GET_WAKEUP_EVENTS = 0x03, + PMU_PWR_SET_WAKEUP_EVENTS = 0x04, + PMU_PWR_CLR_WAKEUP_EVENTS = 0x05, +}; + +/* Power events wakeup bits */ +enum { + PMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */ + PMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */ + PMU_PWR_WAKEUP_AC_CHANGE = 0x04, + PMU_PWR_WAKEUP_LID_OPEN = 0x08, + PMU_PWR_WAKEUP_RING = 0x10, +}; + +/* + * This table indicates for each PMU opcode: + * - the number of data bytes to be sent with the command, or -1 + * if a length byte should be sent, + * - the number of response bytes which the PMU will return, or + * -1 if it will send a length byte. + */ + +static const int8_t pmu_data_len[256][2] = { +/* 0 1 2 3 4 5 6 7 */ + {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + {-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 1},{ 0, 1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{ 0, 0}, + {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, -1},{ 0, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{ 0, -1}, + { 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 4},{ 0, 20},{ 2, -1},{ 2, 1},{ 3, -1},{-1, -1},{-1, -1},{ 4, 0}, + { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 1},{ 0, 1},{-1, -1},{ 1, 0},{ 1, 0},{-1, -1},{-1, -1},{-1, -1}, + { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0}, + { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0, -1},{-1, -1},{-1, -1},{-1, -1}, + { 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0, -1},{ 0, -1},{-1, -1},{-1, -1}, + { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, -1},{ 0, -1},{-1, -1},{-1, -1},{-1, -1},{ 5, 1},{ 4, 1},{ 4, 1}, + { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 5},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 0, 1},{ 0, 1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + { 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0}, + { 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + {-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + {-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, + { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + { 1, 1},{ 1, 1},{-1, -1},{-1, -1},{ 0, 1},{ 0, -1},{-1, -1},{-1, -1}, + {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0}, + { 3, -1},{-1, -1},{ 0, 1},{-1, -1},{ 0, -1},{-1, -1},{-1, -1},{ 0, 0}, + {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0}, + {-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1},{-1, -1}, +}; + +/* Command protocol state machine */ +typedef enum { + pmu_state_idle, /* Waiting for command */ + pmu_state_cmd, /* Receiving command */ + pmu_state_rsp, /* Responding to command */ +} PMUCmdState; + +/* MOS6522 PMU */ +struct MOS6522PMUState { + /*< private >*/ + MOS6522State parent_obj; +}; + +#define TYPE_MOS6522_PMU "mos6522-pmu" +OBJECT_DECLARE_SIMPLE_TYPE(MOS6522PMUState, MOS6522_PMU) +/** + * PMUState: + * @last_b: last value of B register + */ + +struct PMUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion mem; + uint64_t frequency; + qemu_irq via_irq; + bool via_irq_state; + + /* PMU state */ + MOS6522PMUState mos6522_pmu; + + /* PMU low level protocol state */ + PMUCmdState cmd_state; + uint8_t last_b; + uint8_t cmd; + uint32_t cmdlen; + uint32_t rsplen; + uint8_t cmd_buf_pos; + uint8_t cmd_buf[128]; + uint8_t cmd_rsp_pos; + uint8_t cmd_rsp_sz; + uint8_t cmd_rsp[128]; + + /* PMU events/interrupts */ + uint8_t intbits; + uint8_t intmask; + + /* ADB */ + bool has_adb; + ADBBusState adb_bus; + uint8_t adb_reply_size; + uint8_t adb_reply[ADB_MAX_OUT_LEN]; + + /* RTC */ + uint32_t tick_offset; + QEMUTimer *one_sec_timer; + int64_t one_sec_target; + + /* GPIO */ + MacIOGPIOState *gpio; +}; + +#define TYPE_VIA_PMU "via-pmu" +OBJECT_DECLARE_SIMPLE_TYPE(PMUState, VIA_PMU) + +#endif /* PMU_H */ diff --git a/include/hw/misc/mchp_pfsoc_dmc.h b/include/hw/misc/mchp_pfsoc_dmc.h new file mode 100644 index 000000000..2baa1413b --- /dev/null +++ b/include/hw/misc/mchp_pfsoc_dmc.h @@ -0,0 +1,56 @@ +/* + * Microchip PolarFire SoC DDR Memory Controller module emulation + * + * Copyright (c) 2020 Wind River Systems, Inc. + * + * Author: + * Bin Meng <bin.meng@windriver.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MCHP_PFSOC_DMC_H +#define MCHP_PFSOC_DMC_H + +/* DDR SGMII PHY module */ + +#define MCHP_PFSOC_DDR_SGMII_PHY_REG_SIZE 0x1000 + +typedef struct MchpPfSoCDdrSgmiiPhyState { + SysBusDevice parent; + MemoryRegion sgmii_phy; +} MchpPfSoCDdrSgmiiPhyState; + +#define TYPE_MCHP_PFSOC_DDR_SGMII_PHY "mchp.pfsoc.ddr_sgmii_phy" + +#define MCHP_PFSOC_DDR_SGMII_PHY(obj) \ + OBJECT_CHECK(MchpPfSoCDdrSgmiiPhyState, (obj), \ + TYPE_MCHP_PFSOC_DDR_SGMII_PHY) + +/* DDR CFG module */ + +#define MCHP_PFSOC_DDR_CFG_REG_SIZE 0x40000 + +typedef struct MchpPfSoCDdrCfgState { + SysBusDevice parent; + MemoryRegion cfg; +} MchpPfSoCDdrCfgState; + +#define TYPE_MCHP_PFSOC_DDR_CFG "mchp.pfsoc.ddr_cfg" + +#define MCHP_PFSOC_DDR_CFG(obj) \ + OBJECT_CHECK(MchpPfSoCDdrCfgState, (obj), \ + TYPE_MCHP_PFSOC_DDR_CFG) + +#endif /* MCHP_PFSOC_DMC_H */ diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h new file mode 100644 index 000000000..9235523e3 --- /dev/null +++ b/include/hw/misc/mchp_pfsoc_ioscb.h @@ -0,0 +1,50 @@ +/* + * Microchip PolarFire SoC IOSCB module emulation + * + * Copyright (c) 2020 Wind River Systems, Inc. + * + * Author: + * Bin Meng <bin.meng@windriver.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MCHP_PFSOC_IOSCB_H +#define MCHP_PFSOC_IOSCB_H + +typedef struct MchpPfSoCIoscbState { + SysBusDevice parent; + MemoryRegion container; + MemoryRegion lane01; + MemoryRegion lane23; + MemoryRegion ctrl; + MemoryRegion cfg; + MemoryRegion pll_mss; + MemoryRegion cfm_mss; + MemoryRegion pll_ddr; + MemoryRegion bc_ddr; + MemoryRegion io_calib_ddr; + MemoryRegion pll_sgmii; + MemoryRegion dll_sgmii; + MemoryRegion cfm_sgmii; + MemoryRegion bc_sgmii; + MemoryRegion io_calib_sgmii; +} MchpPfSoCIoscbState; + +#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb" + +#define MCHP_PFSOC_IOSCB(obj) \ + OBJECT_CHECK(MchpPfSoCIoscbState, (obj), TYPE_MCHP_PFSOC_IOSCB) + +#endif /* MCHP_PFSOC_IOSCB_H */ diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h new file mode 100644 index 000000000..546ba68f6 --- /dev/null +++ b/include/hw/misc/mchp_pfsoc_sysreg.h @@ -0,0 +1,39 @@ +/* + * Microchip PolarFire SoC SYSREG module emulation + * + * Copyright (c) 2020 Wind River Systems, Inc. + * + * Author: + * Bin Meng <bin.meng@windriver.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MCHP_PFSOC_SYSREG_H +#define MCHP_PFSOC_SYSREG_H + +#define MCHP_PFSOC_SYSREG_REG_SIZE 0x2000 + +typedef struct MchpPfSoCSysregState { + SysBusDevice parent; + MemoryRegion sysreg; +} MchpPfSoCSysregState; + +#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg" + +#define MCHP_PFSOC_SYSREG(obj) \ + OBJECT_CHECK(MchpPfSoCSysregState, (obj), \ + TYPE_MCHP_PFSOC_SYSREG) + +#endif /* MCHP_PFSOC_SYSREG_H */ diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h new file mode 100644 index 000000000..9fa58942d --- /dev/null +++ b/include/hw/misc/mips_cmgcr.h @@ -0,0 +1,91 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2015 Imagination Technologies + * + */ + +#ifndef MIPS_CMGCR_H +#define MIPS_CMGCR_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_MIPS_GCR "mips-gcr" +OBJECT_DECLARE_SIMPLE_TYPE(MIPSGCRState, MIPS_GCR) + +#define GCR_BASE_ADDR 0x1fbf8000ULL +#define GCR_ADDRSPACE_SZ 0x8000 + +/* Offsets to register blocks */ +#define MIPS_GCB_OFS 0x0000 /* Global Control Block */ +#define MIPS_CLCB_OFS 0x2000 /* Core Local Control Block */ +#define MIPS_COCB_OFS 0x4000 /* Core Other Control Block */ +#define MIPS_GDB_OFS 0x6000 /* Global Debug Block */ + +/* Global Control Block Register Map */ +#define GCR_CONFIG_OFS 0x0000 +#define GCR_BASE_OFS 0x0008 +#define GCR_REV_OFS 0x0030 +#define GCR_GIC_BASE_OFS 0x0080 +#define GCR_CPC_BASE_OFS 0x0088 +#define GCR_GIC_STATUS_OFS 0x00D0 +#define GCR_CPC_STATUS_OFS 0x00F0 +#define GCR_L2_CONFIG_OFS 0x0130 + +/* Core Local and Core Other Block Register Map */ +#define GCR_CL_CONFIG_OFS 0x0010 +#define GCR_CL_OTHER_OFS 0x0018 +#define GCR_CL_RESETBASE_OFS 0x0020 + +/* GCR_L2_CONFIG register fields */ +#define GCR_L2_CONFIG_BYPASS_SHF 20 +#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF) + +/* GCR_BASE register fields */ +#define GCR_BASE_GCRBASE_MSK 0xffffffff8000ULL + +/* GCR_GIC_BASE register fields */ +#define GCR_GIC_BASE_GICEN_MSK 1 +#define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL +#define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK) + +/* GCR_CPC_BASE register fields */ +#define GCR_CPC_BASE_CPCEN_MSK 1 +#define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL +#define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK) + +/* GCR_CL_OTHER_OFS register fields */ +#define GCR_CL_OTHER_VPOTHER_MSK 0x7 +#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK + +/* GCR_CL_RESETBASE_OFS register fields */ +#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U +#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK + +typedef struct MIPSGCRVPState MIPSGCRVPState; +struct MIPSGCRVPState { + uint32_t other; + uint64_t reset_base; +}; + +struct MIPSGCRState { + SysBusDevice parent_obj; + + int32_t gcr_rev; + int32_t num_vps; + hwaddr gcr_base; + MemoryRegion iomem; + MemoryRegion *cpc_mr; + MemoryRegion *gic_mr; + + uint64_t cpc_base; + uint64_t gic_base; + + /* VP Local/Other Registers */ + MIPSGCRVPState *vps; +}; + +#endif /* MIPS_CMGCR_H */ diff --git a/include/hw/misc/mips_cpc.h b/include/hw/misc/mips_cpc.h new file mode 100644 index 000000000..fcafbd5e0 --- /dev/null +++ b/include/hw/misc/mips_cpc.h @@ -0,0 +1,50 @@ +/* + * Cluster Power Controller emulation + * + * Copyright (c) 2016 Imagination Technologies + * + * 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/>. + */ + +#ifndef MIPS_CPC_H +#define MIPS_CPC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define CPC_ADDRSPACE_SZ 0x6000 + +/* CPC blocks offsets relative to base address */ +#define CPC_CL_BASE_OFS 0x2000 +#define CPC_CO_BASE_OFS 0x4000 + +/* CPC register offsets relative to block offsets */ +#define CPC_VP_STOP_OFS 0x20 +#define CPC_VP_RUN_OFS 0x28 +#define CPC_VP_RUNNING_OFS 0x30 + +#define TYPE_MIPS_CPC "mips-cpc" +OBJECT_DECLARE_SIMPLE_TYPE(MIPSCPCState, MIPS_CPC) + +struct MIPSCPCState { + SysBusDevice parent_obj; + + uint32_t num_vp; + uint64_t vp_start_running; /* VPs running from restart */ + + MemoryRegion mr; + uint64_t vp_running; /* Indicates which VPs are in the run state */ +}; + +#endif /* MIPS_CPC_H */ diff --git a/include/hw/misc/mips_itu.h b/include/hw/misc/mips_itu.h new file mode 100644 index 000000000..50d961106 --- /dev/null +++ b/include/hw/misc/mips_itu.h @@ -0,0 +1,83 @@ +/* + * Inter-Thread Communication Unit emulation. + * + * Copyright (c) 2016 Imagination Technologies + * + * 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/>. + */ + +#ifndef MIPS_ITU_H +#define MIPS_ITU_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_MIPS_ITU "mips-itu" +OBJECT_DECLARE_SIMPLE_TYPE(MIPSITUState, MIPS_ITU) + +#define ITC_CELL_DEPTH_SHIFT 2 +#define ITC_CELL_DEPTH (1u << ITC_CELL_DEPTH_SHIFT) + +typedef struct ITCStorageCell { + struct { + uint8_t FIFODepth; /* Log2 of the cell depth */ + uint8_t FIFOPtr; /* Number of elements in a FIFO cell */ + uint8_t FIFO; /* 1 - FIFO cell, 0 - Semaphore cell */ + uint8_t T; /* Trap Bit */ + uint8_t F; /* Full Bit */ + uint8_t E; /* Empty Bit */ + } tag; + + /* Index of the oldest element in the queue */ + uint8_t fifo_out; + + /* Circular buffer for FIFO. Semaphore cells use index 0 only */ + uint64_t data[ITC_CELL_DEPTH]; + + /* Bitmap tracking blocked threads on the cell. + TODO: support >64 threads ? */ + uint64_t blocked_threads; +} ITCStorageCell; + +#define ITC_ADDRESSMAP_NUM 2 + +struct MIPSITUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + int32_t num_fifo; + int32_t num_semaphores; + + /* ITC Storage */ + ITCStorageCell *cell; + MemoryRegion storage_io; + + /* ITC Configuration Tags */ + uint64_t ITCAddressMap[ITC_ADDRESSMAP_NUM]; + MemoryRegion tag_io; + + /* ITU Control Register */ + uint64_t icr0; + + /* SAAR */ + bool saar_present; + void *saar; + +}; + +/* Get ITC Configuration Tag memory region. */ +MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu); + +#endif /* MIPS_ITU_H */ diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h new file mode 100644 index 000000000..fc95d22b0 --- /dev/null +++ b/include/hw/misc/mos6522.h @@ -0,0 +1,150 @@ +/* + * QEMU MOS6522 VIA emulation + * + * Copyright (c) 2004-2007 Fabrice Bellard + * Copyright (c) 2007 Jocelyn Mayer + * Copyright (c) 2018 Mark Cave-Ayland + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MOS6522_H +#define MOS6522_H + +#include "exec/memory.h" +#include "hw/sysbus.h" +#include "hw/input/adb.h" +#include "qom/object.h" + +/* Bits in ACR */ +#define SR_CTRL 0x1c /* Shift register control bits */ +#define SR_EXT 0x0c /* Shift on external clock */ +#define SR_OUT 0x10 /* Shift out if 1 */ + +/* Bits in IFR and IER */ +#define IER_SET 0x80 /* set bits in IER */ +#define IER_CLR 0 /* clear bits in IER */ + +#define CA2_INT 0x01 +#define CA1_INT 0x02 +#define SR_INT 0x04 /* Shift register full/empty */ +#define CB2_INT 0x08 +#define CB1_INT 0x10 +#define T2_INT 0x20 /* Timer 2 interrupt */ +#define T1_INT 0x40 /* Timer 1 interrupt */ + +/* Bits in ACR */ +#define T1MODE 0xc0 /* Timer 1 mode */ +#define T1MODE_CONT 0x40 /* continuous interrupts */ + +/* VIA registers */ +#define VIA_REG_B 0x00 +#define VIA_REG_A 0x01 +#define VIA_REG_DIRB 0x02 +#define VIA_REG_DIRA 0x03 +#define VIA_REG_T1CL 0x04 +#define VIA_REG_T1CH 0x05 +#define VIA_REG_T1LL 0x06 +#define VIA_REG_T1LH 0x07 +#define VIA_REG_T2CL 0x08 +#define VIA_REG_T2CH 0x09 +#define VIA_REG_SR 0x0a +#define VIA_REG_ACR 0x0b +#define VIA_REG_PCR 0x0c +#define VIA_REG_IFR 0x0d +#define VIA_REG_IER 0x0e +#define VIA_REG_ANH 0x0f + +/** + * MOS6522Timer: + * @counter_value: counter value at load time + */ +typedef struct MOS6522Timer { + int index; + uint16_t latch; + uint16_t counter_value; + int64_t load_time; + int64_t next_irq_time; + uint64_t frequency; + QEMUTimer *timer; +} MOS6522Timer; + +/** + * MOS6522State: + * @b: B-side data + * @a: A-side data + * @dirb: B-side direction (1=output) + * @dira: A-side direction (1=output) + * @sr: Shift register + * @acr: Auxiliary control register + * @pcr: Peripheral control register + * @ifr: Interrupt flag register + * @ier: Interrupt enable register + * @anh: A-side data, no handshake + * @last_b: last value of B register + * @last_acr: last value of ACR register + */ +struct MOS6522State { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion mem; + /* VIA registers */ + uint8_t b; + uint8_t a; + uint8_t dirb; + uint8_t dira; + uint8_t sr; + uint8_t acr; + uint8_t pcr; + uint8_t ifr; + uint8_t ier; + + MOS6522Timer timers[2]; + uint64_t frequency; + + qemu_irq irq; +}; + +#define TYPE_MOS6522 "mos6522" +OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522) + +struct MOS6522DeviceClass { + DeviceClass parent_class; + + DeviceReset parent_reset; + void (*set_sr_int)(MOS6522State *dev); + void (*portB_write)(MOS6522State *dev); + void (*portA_write)(MOS6522State *dev); + void (*update_irq)(MOS6522State *dev); + /* These are used to influence the CUDA MacOS timebase calibration */ + uint64_t (*get_timer1_counter_value)(MOS6522State *dev, MOS6522Timer *ti); + uint64_t (*get_timer2_counter_value)(MOS6522State *dev, MOS6522Timer *ti); + uint64_t (*get_timer1_load_time)(MOS6522State *dev, MOS6522Timer *ti); + uint64_t (*get_timer2_load_time)(MOS6522State *dev, MOS6522Timer *ti); +}; + + +extern const VMStateDescription vmstate_mos6522; + +uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size); +void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); + +#endif /* MOS6522_H */ diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h new file mode 100644 index 000000000..7b8bd604d --- /dev/null +++ b/include/hw/misc/mps2-fpgaio.h @@ -0,0 +1,62 @@ +/* + * ARM MPS2 FPGAIO emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the FPGAIO register block in the AN505 + * FPGA image for the MPS2 dev board; it is documented in the + * application note: + * https://developer.arm.com/documentation/dai0505/latest/ + * + * QEMU interface: + * + sysbus MMIO region 0: the register bank + */ + +#ifndef MPS2_FPGAIO_H +#define MPS2_FPGAIO_H + +#include "hw/sysbus.h" +#include "hw/misc/led.h" +#include "qom/object.h" + +#define TYPE_MPS2_FPGAIO "mps2-fpgaio" +OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO) + +#define MPS2FPGAIO_MAX_LEDS 32 + +struct MPS2FPGAIO { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + LEDState *led[MPS2FPGAIO_MAX_LEDS]; + uint32_t num_leds; + bool has_switches; + bool has_dbgctrl; + + uint32_t led0; + uint32_t prescale; + uint32_t misc; + uint32_t dbgctrl; + + /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */ + int64_t pscntr_sync_ticks; + /* Values of COUNTER and PSCNTR at time pscntr_sync_ticks */ + uint32_t counter; + uint32_t pscntr; + + uint32_t prescale_clk; + + /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was zero */ + int64_t clk1hz_tick_offset; + int64_t clk100hz_tick_offset; +}; + +#endif diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h new file mode 100644 index 000000000..3b2d13ac9 --- /dev/null +++ b/include/hw/misc/mps2-scc.h @@ -0,0 +1,69 @@ +/* + * ARM MPS2 SCC emulation + * + * Copyright (c) 2017 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the Serial Communication Controller (SCC) + * block found in most MPS FPGA images. + * + * QEMU interface: + * + sysbus MMIO region 0: the register bank + * + QOM property "scc-cfg4": value of the read-only CFG4 register + * + QOM property "scc-aid": value of the read-only SCC_AID register + * + QOM property "scc-id": value of the read-only SCC_ID register + * + QOM property "scc-cfg0": reset value of the CFG0 register + * + QOM property array "oscclk": reset values of the OSCCLK registers + * (which are accessed via the SYS_CFG channel provided by this device) + * + named GPIO output "remap": this tracks the value of CFG0 register + * bit 0. Boards where this bit controls memory remapping should + * connect this GPIO line to a function performing that mapping. + * Boards where bit 0 has no special function should leave the GPIO + * output disconnected. + */ +#ifndef MPS2_SCC_H +#define MPS2_SCC_H + +#include "hw/sysbus.h" +#include "hw/misc/led.h" +#include "qom/object.h" + +#define TYPE_MPS2_SCC "mps2-scc" +OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC) + +struct MPS2SCC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + LEDState *led[8]; + + uint32_t cfg0; + uint32_t cfg1; + uint32_t cfg2; + uint32_t cfg4; + uint32_t cfg5; + uint32_t cfg6; + uint32_t cfgdata_rtn; + uint32_t cfgdata_out; + uint32_t cfgctrl; + uint32_t cfgstat; + uint32_t dll; + uint32_t aid; + uint32_t id; + uint32_t num_oscclk; + uint32_t *oscclk; + uint32_t *oscclk_reset; + uint32_t cfg0_reset; + + qemu_irq remap; +}; + +#endif diff --git a/include/hw/misc/msf2-sysreg.h b/include/hw/misc/msf2-sysreg.h new file mode 100644 index 000000000..fc1890e71 --- /dev/null +++ b/include/hw/misc/msf2-sysreg.h @@ -0,0 +1,78 @@ +/* + * Microsemi SmartFusion2 SYSREG + * + * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_MSF2_SYSREG_H +#define HW_MSF2_SYSREG_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +enum { + ESRAM_CR = 0x00 / 4, + ESRAM_MAX_LAT, + DDR_CR, + ENVM_CR, + ENVM_REMAP_BASE_CR, + ENVM_REMAP_FAB_CR, + CC_CR, + CC_REGION_CR, + CC_LOCK_BASE_ADDR_CR, + CC_FLUSH_INDX_CR, + DDRB_BUF_TIMER_CR, + DDRB_NB_ADDR_CR, + DDRB_NB_SIZE_CR, + DDRB_CR, + + SOFT_RESET_CR = 0x48 / 4, + M3_CR, + + GPIO_SYSRESET_SEL_CR = 0x58 / 4, + + MDDR_CR = 0x60 / 4, + + MSSDDR_PLL_STATUS_LOW_CR = 0x90 / 4, + MSSDDR_PLL_STATUS_HIGH_CR, + MSSDDR_FACC1_CR, + MSSDDR_FACC2_CR, + + MSSDDR_PLL_STATUS = 0x150 / 4, +}; + +#define MSF2_SYSREG_MMIO_SIZE 0x300 + +#define TYPE_MSF2_SYSREG "msf2-sysreg" +OBJECT_DECLARE_SIMPLE_TYPE(MSF2SysregState, MSF2_SYSREG) + +struct MSF2SysregState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + + uint8_t apb0div; + uint8_t apb1div; + + uint32_t regs[MSF2_SYSREG_MMIO_SIZE / 4]; +}; + +#endif /* HW_MSF2_SYSREG_H */ diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h new file mode 100644 index 000000000..d5c8d16ca --- /dev/null +++ b/include/hw/misc/npcm7xx_clk.h @@ -0,0 +1,180 @@ +/* + * Nuvoton NPCM7xx Clock Control Registers. + * + * Copyright 2020 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#ifndef NPCM7XX_CLK_H +#define NPCM7XX_CLK_H + +#include "exec/memory.h" +#include "hw/clock.h" +#include "hw/sysbus.h" + +/* + * Number of registers in our device state structure. Don't change this without + * incrementing the version_id in the vmstate. + */ +#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t)) + +#define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in" + +/* Maximum amount of clock inputs in a SEL module. */ +#define NPCM7XX_CLK_SEL_MAX_INPUT 5 + +/* PLLs in CLK module. */ +typedef enum NPCM7xxClockPLL { + NPCM7XX_CLOCK_PLL0, + NPCM7XX_CLOCK_PLL1, + NPCM7XX_CLOCK_PLL2, + NPCM7XX_CLOCK_PLLG, + NPCM7XX_CLOCK_NR_PLLS, +} NPCM7xxClockPLL; + +/* SEL/MUX in CLK module. */ +typedef enum NPCM7xxClockSEL { + NPCM7XX_CLOCK_PIXCKSEL, + NPCM7XX_CLOCK_MCCKSEL, + NPCM7XX_CLOCK_CPUCKSEL, + NPCM7XX_CLOCK_CLKOUTSEL, + NPCM7XX_CLOCK_UARTCKSEL, + NPCM7XX_CLOCK_TIMCKSEL, + NPCM7XX_CLOCK_SDCKSEL, + NPCM7XX_CLOCK_GFXMSEL, + NPCM7XX_CLOCK_SUCKSEL, + NPCM7XX_CLOCK_NR_SELS, +} NPCM7xxClockSEL; + +/* Dividers in CLK module. */ +typedef enum NPCM7xxClockDivider { + NPCM7XX_CLOCK_PLL1D2, /* PLL1/2 */ + NPCM7XX_CLOCK_PLL2D2, /* PLL2/2 */ + NPCM7XX_CLOCK_MC_DIVIDER, + NPCM7XX_CLOCK_AXI_DIVIDER, + NPCM7XX_CLOCK_AHB_DIVIDER, + NPCM7XX_CLOCK_AHB3_DIVIDER, + NPCM7XX_CLOCK_SPI0_DIVIDER, + NPCM7XX_CLOCK_SPIX_DIVIDER, + NPCM7XX_CLOCK_APB1_DIVIDER, + NPCM7XX_CLOCK_APB2_DIVIDER, + NPCM7XX_CLOCK_APB3_DIVIDER, + NPCM7XX_CLOCK_APB4_DIVIDER, + NPCM7XX_CLOCK_APB5_DIVIDER, + NPCM7XX_CLOCK_CLKOUT_DIVIDER, + NPCM7XX_CLOCK_UART_DIVIDER, + NPCM7XX_CLOCK_TIMER_DIVIDER, + NPCM7XX_CLOCK_ADC_DIVIDER, + NPCM7XX_CLOCK_MMC_DIVIDER, + NPCM7XX_CLOCK_SDHC_DIVIDER, + NPCM7XX_CLOCK_GFXM_DIVIDER, /* divide by 3 */ + NPCM7XX_CLOCK_UTMI_DIVIDER, + NPCM7XX_CLOCK_NR_DIVIDERS, +} NPCM7xxClockConverter; + +typedef struct NPCM7xxCLKState NPCM7xxCLKState; + +/** + * struct NPCM7xxClockPLLState - A PLL module in CLK module. + * @name: The name of the module. + * @clk: The CLK module that owns this module. + * @clock_in: The input clock of this module. + * @clock_out: The output clock of this module. + * @reg: The control registers for this PLL module. + */ +typedef struct NPCM7xxClockPLLState { + DeviceState parent; + + const char *name; + NPCM7xxCLKState *clk; + Clock *clock_in; + Clock *clock_out; + + int reg; +} NPCM7xxClockPLLState; + +/** + * struct NPCM7xxClockSELState - A SEL module in CLK module. + * @name: The name of the module. + * @clk: The CLK module that owns this module. + * @input_size: The size of inputs of this module. + * @clock_in: The input clocks of this module. + * @clock_out: The output clocks of this module. + * @offset: The offset of this module in the control register. + * @len: The length of this module in the control register. + */ +typedef struct NPCM7xxClockSELState { + DeviceState parent; + + const char *name; + NPCM7xxCLKState *clk; + uint8_t input_size; + Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT]; + Clock *clock_out; + + int offset; + int len; +} NPCM7xxClockSELState; + +/** + * struct NPCM7xxClockDividerState - A Divider module in CLK module. + * @name: The name of the module. + * @clk: The CLK module that owns this module. + * @clock_in: The input clock of this module. + * @clock_out: The output clock of this module. + * @divide: The function the divider uses to divide the input. + * @reg: The index of the control register that contains the divisor. + * @offset: The offset of the divisor in the control register. + * @len: The length of the divisor in the control register. + * @divisor: The divisor for a constant divisor + */ +typedef struct NPCM7xxClockDividerState { + DeviceState parent; + + const char *name; + NPCM7xxCLKState *clk; + Clock *clock_in; + Clock *clock_out; + + uint32_t (*divide)(struct NPCM7xxClockDividerState *s); + union { + struct { + int reg; + int offset; + int len; + }; + int divisor; + }; +} NPCM7xxClockDividerState; + +struct NPCM7xxCLKState { + SysBusDevice parent; + + MemoryRegion iomem; + + /* Clock converters */ + NPCM7xxClockPLLState plls[NPCM7XX_CLOCK_NR_PLLS]; + NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS]; + NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS]; + + uint32_t regs[NPCM7XX_CLK_NR_REGS]; + + /* Time reference for SECCNT and CNTR25M, initialized by power on reset */ + int64_t ref_ns; + + /* The incoming reference clock. */ + Clock *clkref; +}; + +#define TYPE_NPCM7XX_CLK "npcm7xx-clk" +#define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), TYPE_NPCM7XX_CLK) + +#endif /* NPCM7XX_CLK_H */ diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h new file mode 100644 index 000000000..13109d9d3 --- /dev/null +++ b/include/hw/misc/npcm7xx_gcr.h @@ -0,0 +1,43 @@ +/* + * Nuvoton NPCM7xx System Global Control Registers. + * + * Copyright 2020 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#ifndef NPCM7XX_GCR_H +#define NPCM7XX_GCR_H + +#include "exec/memory.h" +#include "hw/sysbus.h" + +/* + * Number of registers in our device state structure. Don't change this without + * incrementing the version_id in the vmstate. + */ +#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t)) + +typedef struct NPCM7xxGCRState { + SysBusDevice parent; + + MemoryRegion iomem; + + uint32_t regs[NPCM7XX_GCR_NR_REGS]; + + uint32_t reset_pwron; + uint32_t reset_mdlr; + uint32_t reset_intcr3; +} NPCM7xxGCRState; + +#define TYPE_NPCM7XX_GCR "npcm7xx-gcr" +#define NPCM7XX_GCR(obj) OBJECT_CHECK(NPCM7xxGCRState, (obj), TYPE_NPCM7XX_GCR) + +#endif /* NPCM7XX_GCR_H */ diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h new file mode 100644 index 000000000..36785e3ba --- /dev/null +++ b/include/hw/misc/npcm7xx_mft.h @@ -0,0 +1,70 @@ +/* + * Nuvoton NPCM7xx MFT Module + * + * Copyright 2021 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#ifndef NPCM7XX_MFT_H +#define NPCM7XX_MFT_H + +#include "exec/memory.h" +#include "hw/clock.h" +#include "hw/irq.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +/* Max Fan input number. */ +#define NPCM7XX_MFT_MAX_FAN_INPUT 19 + +/* + * Number of registers in one MFT module. Don't change this without increasing + * the version_id in vmstate. + */ +#define NPCM7XX_MFT_NR_REGS (0x20 / sizeof(uint16_t)) + +/* + * The MFT can take up to 4 inputs: A0, B0, A1, B1. It can measure one A and one + * B simultaneously. NPCM7XX_MFT_INASEL and NPCM7XX_MFT_INBSEL are used to + * select which A or B input are used. + */ +#define NPCM7XX_MFT_FANIN_COUNT 4 + +/** + * struct NPCM7xxMFTState - Multi Functional Tachometer device state. + * @parent: System bus device. + * @iomem: Memory region through which registers are accessed. + * @clock_in: The input clock for MFT from CLK module. + * @clock_{1,2}: The counter clocks for NPCM7XX_MFT_CNT{1,2} + * @irq: The IRQ for this MFT state. + * @regs: The MMIO registers. + * @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1. + * @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY. + */ +typedef struct NPCM7xxMFTState { + SysBusDevice parent; + + MemoryRegion iomem; + + Clock *clock_in; + Clock *clock_1, *clock_2; + qemu_irq irq; + uint16_t regs[NPCM7XX_MFT_NR_REGS]; + + uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT]; + uint32_t duty[NPCM7XX_MFT_FANIN_COUNT]; +} NPCM7xxMFTState; + +#define TYPE_NPCM7XX_MFT "npcm7xx-mft" +#define NPCM7XX_MFT(obj) \ + OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT) + +#endif /* NPCM7XX_MFT_H */ diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h new file mode 100644 index 000000000..7ad632a93 --- /dev/null +++ b/include/hw/misc/npcm7xx_pwm.h @@ -0,0 +1,107 @@ +/* + * Nuvoton NPCM7xx PWM Module + * + * Copyright 2020 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#ifndef NPCM7XX_PWM_H +#define NPCM7XX_PWM_H + +#include "hw/clock.h" +#include "hw/sysbus.h" +#include "hw/irq.h" + +/* Each PWM module holds 4 PWM channels. */ +#define NPCM7XX_PWM_PER_MODULE 4 + +/* + * Number of registers in one pwm module. Don't change this without increasing + * the version_id in vmstate. + */ +#define NPCM7XX_PWM_NR_REGS (0x54 / sizeof(uint32_t)) + +/* + * The maximum duty values. Each duty unit represents 1/NPCM7XX_PWM_MAX_DUTY + * cycles. For example, if NPCM7XX_PWM_MAX_DUTY=1,000,000 and a PWM has a duty + * value of 100,000 the duty cycle for that PWM is 10%. + */ +#define NPCM7XX_PWM_MAX_DUTY 1000000 + +typedef struct NPCM7xxPWMState NPCM7xxPWMState; + +/** + * struct NPCM7xxPWM - The state of a single PWM channel. + * @module: The PWM module that contains this channel. + * @irq: GIC interrupt line to fire on expiration if enabled. + * @running: Whether this PWM channel is generating output. + * @inverted: Whether this PWM channel is inverted. + * @index: The index of this PWM channel. + * @cnr: The counter register. + * @cmr: The comparator register. + * @pdr: The data register. + * @pwdr: The watchdog register. + * @freq: The frequency of this PWM channel. + * @duty: The duty cycle of this PWM channel. One unit represents + * 1/NPCM7XX_MAX_DUTY cycles. + */ +typedef struct NPCM7xxPWM { + NPCM7xxPWMState *module; + + qemu_irq irq; + + bool running; + bool inverted; + + uint8_t index; + uint32_t cnr; + uint32_t cmr; + uint32_t pdr; + uint32_t pwdr; + + uint32_t freq; + uint32_t duty; +} NPCM7xxPWM; + +/** + * struct NPCM7xxPWMState - Pulse Width Modulation device state. + * @parent: System bus device. + * @iomem: Memory region through which registers are accessed. + * @clock: The PWM clock. + * @pwm: The PWM channels owned by this module. + * @duty_gpio_out: The duty cycle of each PWM channels as a output GPIO. + * @ppr: The prescaler register. + * @csr: The clock selector register. + * @pcr: The control register. + * @pier: The interrupt enable register. + * @piir: The interrupt indication register. + */ +struct NPCM7xxPWMState { + SysBusDevice parent; + + MemoryRegion iomem; + + Clock *clock; + NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE]; + qemu_irq duty_gpio_out[NPCM7XX_PWM_PER_MODULE]; + + uint32_t ppr; + uint32_t csr; + uint32_t pcr; + uint32_t pier; + uint32_t piir; +}; + +#define TYPE_NPCM7XX_PWM "npcm7xx-pwm" +#define NPCM7XX_PWM(obj) \ + OBJECT_CHECK(NPCM7xxPWMState, (obj), TYPE_NPCM7XX_PWM) + +#endif /* NPCM7XX_PWM_H */ diff --git a/include/hw/misc/npcm7xx_rng.h b/include/hw/misc/npcm7xx_rng.h new file mode 100644 index 000000000..5e85fd439 --- /dev/null +++ b/include/hw/misc/npcm7xx_rng.h @@ -0,0 +1,34 @@ +/* + * Nuvoton NPCM7xx Random Number Generator. + * + * Copyright 2020 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#ifndef NPCM7XX_RNG_H +#define NPCM7XX_RNG_H + +#include "hw/sysbus.h" + +typedef struct NPCM7xxRNGState { + SysBusDevice parent; + + MemoryRegion iomem; + + uint8_t rngcs; + uint8_t rngd; + uint8_t rngmode; +} NPCM7xxRNGState; + +#define TYPE_NPCM7XX_RNG "npcm7xx-rng" +#define NPCM7XX_RNG(obj) OBJECT_CHECK(NPCM7xxRNGState, (obj), TYPE_NPCM7XX_RNG) + +#endif /* NPCM7XX_RNG_H */ diff --git a/include/hw/misc/nrf51_rng.h b/include/hw/misc/nrf51_rng.h new file mode 100644 index 000000000..9aff9a76f --- /dev/null +++ b/include/hw/misc/nrf51_rng.h @@ -0,0 +1,85 @@ +/* + * nRF51 Random Number Generator + * + * QEMU interface: + * + Property "period_unfiltered_us": Time between two biased values in + * microseconds. + * + Property "period_filtered_us": Time between two unbiased values in + * microseconds. + * + sysbus MMIO regions 0: Memory Region with tasks, events and registers + * to be mapped to the peripherals instance address by the SOC. + * + Named GPIO output "irq": Interrupt line of the peripheral. Must be + * connected to the associated peripheral interrupt line of the NVIC. + * + Named GPIO output "eep_valrdy": Event set when new random value is ready + * to be read. + * + Named GPIO input "tep_start": Task that triggers start of continuous + * generation of random values. + * + Named GPIO input "tep_stop": Task that ends continuous generation of + * random values. + * + * Accuracy of the peripheral model: + * + Stochastic properties of different configurations of the random source + * are not modeled. + * + Generation of unfiltered and filtered random values take at least the + * average generation time stated in the production specification; + * non-deterministic generation times are not modeled. + * + * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de> + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef NRF51_RNG_H +#define NRF51_RNG_H + +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "qom/object.h" +#define TYPE_NRF51_RNG "nrf51_soc.rng" +OBJECT_DECLARE_SIMPLE_TYPE(NRF51RNGState, NRF51_RNG) + +#define NRF51_RNG_SIZE 0x1000 + +#define NRF51_RNG_TASK_START 0x000 +#define NRF51_RNG_TASK_STOP 0x004 +#define NRF51_RNG_EVENT_VALRDY 0x100 +#define NRF51_RNG_REG_SHORTS 0x200 +#define NRF51_RNG_REG_SHORTS_VALRDY_STOP 0 +#define NRF51_RNG_REG_INTEN 0x300 +#define NRF51_RNG_REG_INTEN_VALRDY 0 +#define NRF51_RNG_REG_INTENSET 0x304 +#define NRF51_RNG_REG_INTENCLR 0x308 +#define NRF51_RNG_REG_CONFIG 0x504 +#define NRF51_RNG_REG_CONFIG_DECEN 0 +#define NRF51_RNG_REG_VALUE 0x508 + +struct NRF51RNGState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + qemu_irq irq; + + /* Event End Points */ + qemu_irq eep_valrdy; + + QEMUTimer timer; + + /* Time between generation of successive unfiltered values in us */ + uint16_t period_unfiltered_us; + /* Time between generation of successive filtered values in us */ + uint16_t period_filtered_us; + + uint8_t value; + + uint32_t active; + uint32_t event_valrdy; + uint32_t shortcut_stop_on_valrdy; + uint32_t interrupt_enabled; + uint32_t filter_enabled; + +}; + + +#endif /* NRF51_RNG_H */ diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h new file mode 100644 index 000000000..b6f4e264f --- /dev/null +++ b/include/hw/misc/pca9552.h @@ -0,0 +1,37 @@ +/* + * PCA9552 I2C LED blinker + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ +#ifndef PCA9552_H +#define PCA9552_H + +#include "hw/i2c/i2c.h" +#include "qom/object.h" + +#define TYPE_PCA9552 "pca9552" +#define TYPE_PCA955X "pca955x" +typedef struct PCA955xState PCA955xState; +DECLARE_INSTANCE_CHECKER(PCA955xState, PCA955X, + TYPE_PCA955X) + +#define PCA955X_NR_REGS 10 +#define PCA955X_PIN_COUNT_MAX 16 + +struct PCA955xState { + /*< private >*/ + I2CSlave i2c; + /*< public >*/ + + uint8_t len; + uint8_t pointer; + + uint8_t regs[PCA955X_NR_REGS]; + qemu_irq gpio[PCA955X_PIN_COUNT_MAX]; + char *description; /* For debugging purpose only */ +}; + +#endif diff --git a/include/hw/misc/pca9552_regs.h b/include/hw/misc/pca9552_regs.h new file mode 100644 index 000000000..d8051cfbd --- /dev/null +++ b/include/hw/misc/pca9552_regs.h @@ -0,0 +1,32 @@ +/* + * PCA9552 I2C LED blinker registers + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ +#ifndef PCA9552_REGS_H +#define PCA9552_REGS_H + +/* + * Bits [0:3] are used to address a specific register. + */ +#define PCA9552_INPUT0 0 /* read only input register 0 */ +#define PCA9552_INPUT1 1 /* read only input register 1 */ +#define PCA9552_PSC0 2 /* read/write frequency prescaler 0 */ +#define PCA9552_PWM0 3 /* read/write PWM register 0 */ +#define PCA9552_PSC1 4 /* read/write frequency prescaler 1 */ +#define PCA9552_PWM1 5 /* read/write PWM register 1 */ +#define PCA9552_LS0 6 /* read/write LED0 to LED3 selector */ +#define PCA9552_LS1 7 /* read/write LED4 to LED7 selector */ +#define PCA9552_LS2 8 /* read/write LED8 to LED11 selector */ +#define PCA9552_LS3 9 /* read/write LED12 to LED15 selector */ + +/* + * Bit [4] is used to activate the Auto-Increment option of the + * register address + */ +#define PCA9552_AUTOINC (1 << 4) + +#endif diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h new file mode 100644 index 000000000..ca3c5bb53 --- /dev/null +++ b/include/hw/misc/pvpanic.h @@ -0,0 +1,53 @@ +/* + * QEMU simulated pvpanic device. + * + * Copyright Fujitsu, Corp. 2013 + * + * Authors: + * Wen Congyang <wency@cn.fujitsu.com> + * Hu Tao <hutao@cn.fujitsu.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef HW_MISC_PVPANIC_H +#define HW_MISC_PVPANIC_H + +#include "qom/object.h" + +#define TYPE_PVPANIC_ISA_DEVICE "pvpanic" +#define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci" + +#define PVPANIC_IOPORT_PROP "ioport" + +/* The bit of supported pv event, TODO: include uapi header and remove this */ +#define PVPANIC_F_PANICKED 0 +#define PVPANIC_F_CRASHLOADED 1 + +/* The pv event value */ +#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED) +#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED) + +/* + * PVPanicState for any device type + */ +typedef struct PVPanicState PVPanicState; +struct PVPanicState { + MemoryRegion mr; + uint8_t events; +}; + +void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size); + +static inline uint16_t pvpanic_port(void) +{ + Object *o = object_resolve_path_type("", TYPE_PVPANIC_ISA_DEVICE, NULL); + if (!o) { + return 0; + } + return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL); +} + +#endif diff --git a/include/hw/misc/sifive_e_prci.h b/include/hw/misc/sifive_e_prci.h new file mode 100644 index 000000000..262ca1618 --- /dev/null +++ b/include/hw/misc/sifive_e_prci.h @@ -0,0 +1,73 @@ +/* + * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt) interface + * + * Copyright (c) 2017 SiFive, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_SIFIVE_E_PRCI_H +#define HW_SIFIVE_E_PRCI_H +#include "qom/object.h" + +enum { + SIFIVE_E_PRCI_HFROSCCFG = 0x0, + SIFIVE_E_PRCI_HFXOSCCFG = 0x4, + SIFIVE_E_PRCI_PLLCFG = 0x8, + SIFIVE_E_PRCI_PLLOUTDIV = 0xC +}; + +enum { + SIFIVE_E_PRCI_HFROSCCFG_RDY = (1 << 31), + SIFIVE_E_PRCI_HFROSCCFG_EN = (1 << 30) +}; + +enum { + SIFIVE_E_PRCI_HFXOSCCFG_RDY = (1 << 31), + SIFIVE_E_PRCI_HFXOSCCFG_EN = (1 << 30) +}; + +enum { + SIFIVE_E_PRCI_PLLCFG_PLLSEL = (1 << 16), + SIFIVE_E_PRCI_PLLCFG_REFSEL = (1 << 17), + SIFIVE_E_PRCI_PLLCFG_BYPASS = (1 << 18), + SIFIVE_E_PRCI_PLLCFG_LOCK = (1 << 31) +}; + +enum { + SIFIVE_E_PRCI_PLLOUTDIV_DIV1 = (1 << 8) +}; + +#define SIFIVE_E_PRCI_REG_SIZE 0x1000 + +#define TYPE_SIFIVE_E_PRCI "riscv.sifive.e.prci" + +typedef struct SiFiveEPRCIState SiFiveEPRCIState; +DECLARE_INSTANCE_CHECKER(SiFiveEPRCIState, SIFIVE_E_PRCI, + TYPE_SIFIVE_E_PRCI) + +struct SiFiveEPRCIState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + uint32_t hfrosccfg; + uint32_t hfxosccfg; + uint32_t pllcfg; + uint32_t plloutdiv; +}; + +DeviceState *sifive_e_prci_create(hwaddr addr); + +#endif diff --git a/include/hw/misc/sifive_test.h b/include/hw/misc/sifive_test.h new file mode 100644 index 000000000..88a38d00c --- /dev/null +++ b/include/hw/misc/sifive_test.h @@ -0,0 +1,47 @@ +/* + * QEMU Test Finisher interface + * + * Copyright (c) 2018 SiFive, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_SIFIVE_TEST_H +#define HW_SIFIVE_TEST_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_SIFIVE_TEST "riscv.sifive.test" + +typedef struct SiFiveTestState SiFiveTestState; +DECLARE_INSTANCE_CHECKER(SiFiveTestState, SIFIVE_TEST, + TYPE_SIFIVE_TEST) + +struct SiFiveTestState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; +}; + +enum { + FINISHER_FAIL = 0x3333, + FINISHER_PASS = 0x5555, + FINISHER_RESET = 0x7777 +}; + +DeviceState *sifive_test_create(hwaddr addr); + +#endif diff --git a/include/hw/misc/sifive_u_otp.h b/include/hw/misc/sifive_u_otp.h new file mode 100644 index 000000000..5d0d7df45 --- /dev/null +++ b/include/hw/misc/sifive_u_otp.h @@ -0,0 +1,87 @@ +/* + * QEMU SiFive U OTP (One-Time Programmable) Memory interface + * + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_SIFIVE_U_OTP_H +#define HW_SIFIVE_U_OTP_H +#include "qom/object.h" + +#define SIFIVE_U_OTP_PA 0x00 +#define SIFIVE_U_OTP_PAIO 0x04 +#define SIFIVE_U_OTP_PAS 0x08 +#define SIFIVE_U_OTP_PCE 0x0C +#define SIFIVE_U_OTP_PCLK 0x10 +#define SIFIVE_U_OTP_PDIN 0x14 +#define SIFIVE_U_OTP_PDOUT 0x18 +#define SIFIVE_U_OTP_PDSTB 0x1C +#define SIFIVE_U_OTP_PPROG 0x20 +#define SIFIVE_U_OTP_PTC 0x24 +#define SIFIVE_U_OTP_PTM 0x28 +#define SIFIVE_U_OTP_PTM_REP 0x2C +#define SIFIVE_U_OTP_PTR 0x30 +#define SIFIVE_U_OTP_PTRIM 0x34 +#define SIFIVE_U_OTP_PWE 0x38 + +#define SIFIVE_U_OTP_PWE_EN (1 << 0) + +#define SIFIVE_U_OTP_PCE_EN (1 << 0) + +#define SIFIVE_U_OTP_PDSTB_EN (1 << 0) + +#define SIFIVE_U_OTP_PTRIM_EN (1 << 0) + +#define SIFIVE_U_OTP_PA_MASK 0xfff +#define SIFIVE_U_OTP_NUM_FUSES 0x1000 +#define SIFIVE_U_OTP_FUSE_WORD 4 +#define SIFIVE_U_OTP_SERIAL_ADDR 0xfc + +#define SIFIVE_U_OTP_REG_SIZE 0x1000 + +#define TYPE_SIFIVE_U_OTP "riscv.sifive.u.otp" + +typedef struct SiFiveUOTPState SiFiveUOTPState; +DECLARE_INSTANCE_CHECKER(SiFiveUOTPState, SIFIVE_U_OTP, + TYPE_SIFIVE_U_OTP) + +struct SiFiveUOTPState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + uint32_t pa; + uint32_t paio; + uint32_t pas; + uint32_t pce; + uint32_t pclk; + uint32_t pdin; + uint32_t pdstb; + uint32_t pprog; + uint32_t ptc; + uint32_t ptm; + uint32_t ptm_rep; + uint32_t ptr; + uint32_t ptrim; + uint32_t pwe; + uint32_t fuse[SIFIVE_U_OTP_NUM_FUSES]; + uint32_t fuse_wo[SIFIVE_U_OTP_NUM_FUSES]; + /* config */ + uint32_t serial; + BlockBackend *blk; +}; + +#endif /* HW_SIFIVE_U_OTP_H */ diff --git a/include/hw/misc/sifive_u_prci.h b/include/hw/misc/sifive_u_prci.h new file mode 100644 index 000000000..d9ebf40b7 --- /dev/null +++ b/include/hw/misc/sifive_u_prci.h @@ -0,0 +1,93 @@ +/* + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt) interface + * + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_SIFIVE_U_PRCI_H +#define HW_SIFIVE_U_PRCI_H +#include "qom/object.h" + +#define SIFIVE_U_PRCI_HFXOSCCFG 0x00 +#define SIFIVE_U_PRCI_COREPLLCFG0 0x04 +#define SIFIVE_U_PRCI_DDRPLLCFG0 0x0C +#define SIFIVE_U_PRCI_DDRPLLCFG1 0x10 +#define SIFIVE_U_PRCI_GEMGXLPLLCFG0 0x1C +#define SIFIVE_U_PRCI_GEMGXLPLLCFG1 0x20 +#define SIFIVE_U_PRCI_CORECLKSEL 0x24 +#define SIFIVE_U_PRCI_DEVICESRESET 0x28 +#define SIFIVE_U_PRCI_CLKMUXSTATUS 0x2C + +/* + * Current FU540-C000 manual says ready bit is at bit 29, but + * freedom-u540-c000-bootloader codes (ux00prci.h) says it is at bit 31. + * We have to trust the actual code that works. + * + * see https://github.com/sifive/freedom-u540-c000-bootloader + */ + +#define SIFIVE_U_PRCI_HFXOSCCFG_EN (1 << 30) +#define SIFIVE_U_PRCI_HFXOSCCFG_RDY (1 << 31) + +/* xxxPLLCFG0 register bits */ +#define SIFIVE_U_PRCI_PLLCFG0_DIVR (1 << 0) +#define SIFIVE_U_PRCI_PLLCFG0_DIVF (31 << 6) +#define SIFIVE_U_PRCI_PLLCFG0_DIVQ (3 << 15) +#define SIFIVE_U_PRCI_PLLCFG0_FSE (1 << 25) +#define SIFIVE_U_PRCI_PLLCFG0_LOCK (1 << 31) + +/* xxxPLLCFG1 register bits */ +#define SIFIVE_U_PRCI_PLLCFG1_CKE (1 << 24) + +/* coreclksel register bits */ +#define SIFIVE_U_PRCI_CORECLKSEL_HFCLK (1 << 0) + + +#define SIFIVE_U_PRCI_REG_SIZE 0x1000 + +#define TYPE_SIFIVE_U_PRCI "riscv.sifive.u.prci" + +typedef struct SiFiveUPRCIState SiFiveUPRCIState; +DECLARE_INSTANCE_CHECKER(SiFiveUPRCIState, SIFIVE_U_PRCI, + TYPE_SIFIVE_U_PRCI) + +struct SiFiveUPRCIState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + uint32_t hfxosccfg; + uint32_t corepllcfg0; + uint32_t ddrpllcfg0; + uint32_t ddrpllcfg1; + uint32_t gemgxlpllcfg0; + uint32_t gemgxlpllcfg1; + uint32_t coreclksel; + uint32_t devicesreset; + uint32_t clkmuxstatus; +}; + +/* + * Clock indexes for use by Device Tree data and the PRCI driver. + * + * These values are from sifive-fu540-prci.h in the Linux kernel. + */ +#define PRCI_CLK_COREPLL 0 +#define PRCI_CLK_DDRPLL 1 +#define PRCI_CLK_GEMGXLPLL 2 +#define PRCI_CLK_TLCLK 3 + +#endif /* HW_SIFIVE_U_PRCI_H */ diff --git a/include/hw/misc/stm32f2xx_syscfg.h b/include/hw/misc/stm32f2xx_syscfg.h new file mode 100644 index 000000000..8595a3b31 --- /dev/null +++ b/include/hw/misc/stm32f2xx_syscfg.h @@ -0,0 +1,58 @@ +/* + * STM32F2XX SYSCFG + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_STM32F2XX_SYSCFG_H +#define HW_STM32F2XX_SYSCFG_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define SYSCFG_MEMRMP 0x00 +#define SYSCFG_PMC 0x04 +#define SYSCFG_EXTICR1 0x08 +#define SYSCFG_EXTICR2 0x0C +#define SYSCFG_EXTICR3 0x10 +#define SYSCFG_EXTICR4 0x14 +#define SYSCFG_CMPCR 0x20 + +#define TYPE_STM32F2XX_SYSCFG "stm32f2xx-syscfg" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F2XXSyscfgState, STM32F2XX_SYSCFG) + +struct STM32F2XXSyscfgState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion mmio; + + uint32_t syscfg_memrmp; + uint32_t syscfg_pmc; + uint32_t syscfg_exticr1; + uint32_t syscfg_exticr2; + uint32_t syscfg_exticr3; + uint32_t syscfg_exticr4; + uint32_t syscfg_cmpcr; +}; + +#endif /* HW_STM32F2XX_SYSCFG_H */ diff --git a/include/hw/misc/stm32f4xx_exti.h b/include/hw/misc/stm32f4xx_exti.h new file mode 100644 index 000000000..ea6b0097b --- /dev/null +++ b/include/hw/misc/stm32f4xx_exti.h @@ -0,0 +1,59 @@ +/* + * STM32F4XX EXTI + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_STM_EXTI_H +#define HW_STM_EXTI_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define EXTI_IMR 0x00 +#define EXTI_EMR 0x04 +#define EXTI_RTSR 0x08 +#define EXTI_FTSR 0x0C +#define EXTI_SWIER 0x10 +#define EXTI_PR 0x14 + +#define TYPE_STM32F4XX_EXTI "stm32f4xx-exti" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F4xxExtiState, STM32F4XX_EXTI) + +#define NUM_GPIO_EVENT_IN_LINES 16 +#define NUM_INTERRUPT_OUT_LINES 16 + +struct STM32F4xxExtiState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + + uint32_t exti_imr; + uint32_t exti_emr; + uint32_t exti_rtsr; + uint32_t exti_ftsr; + uint32_t exti_swier; + uint32_t exti_pr; + + qemu_irq irq[NUM_INTERRUPT_OUT_LINES]; +}; + +#endif diff --git a/include/hw/misc/stm32f4xx_syscfg.h b/include/hw/misc/stm32f4xx_syscfg.h new file mode 100644 index 000000000..6f8ca4922 --- /dev/null +++ b/include/hw/misc/stm32f4xx_syscfg.h @@ -0,0 +1,60 @@ +/* + * STM32F4xx SYSCFG + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_STM_SYSCFG_H +#define HW_STM_SYSCFG_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define SYSCFG_MEMRMP 0x00 +#define SYSCFG_PMC 0x04 +#define SYSCFG_EXTICR1 0x08 +#define SYSCFG_EXTICR2 0x0C +#define SYSCFG_EXTICR3 0x10 +#define SYSCFG_EXTICR4 0x14 +#define SYSCFG_CMPCR 0x20 + +#define TYPE_STM32F4XX_SYSCFG "stm32f4xx-syscfg" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F4xxSyscfgState, STM32F4XX_SYSCFG) + +#define SYSCFG_NUM_EXTICR 4 + +struct STM32F4xxSyscfgState { + /* <private> */ + SysBusDevice parent_obj; + + /* <public> */ + MemoryRegion mmio; + + uint32_t syscfg_memrmp; + uint32_t syscfg_pmc; + uint32_t syscfg_exticr[SYSCFG_NUM_EXTICR]; + uint32_t syscfg_cmpcr; + + qemu_irq irq; + qemu_irq gpio_out[16]; +}; + +#endif diff --git a/include/hw/misc/tz-mpc.h b/include/hw/misc/tz-mpc.h new file mode 100644 index 000000000..74d5d822c --- /dev/null +++ b/include/hw/misc/tz-mpc.h @@ -0,0 +1,80 @@ +/* + * ARM AHB5 TrustZone Memory Protection Controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the TrustZone memory protection controller (MPC). + * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM + * (DDI 0571G): + * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g + * + * The MPC sits in front of memory and allows secure software to + * configure it to either pass through or reject transactions. + * Rejected transactions may be configured to either be aborted, or to + * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction. + * + * The MPC has a register interface which the guest uses to configure it. + * + * QEMU interface: + * + sysbus MMIO region 0: MemoryRegion for the MPC's config registers + * + sysbus MMIO region 1: MemoryRegion for the upstream end of the MPC + * + Property "downstream": MemoryRegion defining the downstream memory + * + Named GPIO output "irq": set for a transaction-failed interrupt + */ + +#ifndef TZ_MPC_H +#define TZ_MPC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_TZ_MPC "tz-mpc" +OBJECT_DECLARE_SIMPLE_TYPE(TZMPC, TZ_MPC) + +#define TZ_NUM_PORTS 16 + +#define TYPE_TZ_MPC_IOMMU_MEMORY_REGION "tz-mpc-iommu-memory-region" + + +struct TZMPC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State */ + uint32_t ctrl; + uint32_t blk_idx; + uint32_t int_stat; + uint32_t int_en; + uint32_t int_info1; + uint32_t int_info2; + + uint32_t *blk_lut; + + qemu_irq irq; + + /* Properties */ + MemoryRegion *downstream; + + hwaddr blocksize; + uint32_t blk_max; + + /* MemoryRegions exposed to user */ + MemoryRegion regmr; + IOMMUMemoryRegion upstream; + + /* MemoryRegion used internally */ + MemoryRegion blocked_io; + + AddressSpace downstream_as; + AddressSpace blocked_io_as; +}; + +#endif diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h new file mode 100644 index 000000000..77cc7f240 --- /dev/null +++ b/include/hw/misc/tz-msc.h @@ -0,0 +1,80 @@ +/* + * ARM TrustZone master security controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the TrustZone master security controller (MSC). + * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM + * (DDI 0571G): + * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g + * + * The MSC sits in front of a device which can be a bus master (such as + * a DMA controller) and allows secure software to configure it to either + * pass through or reject transactions made by that bus master. + * Rejected transactions may be configured to either be aborted, or to + * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction. + * + * The MSC has no register interface -- it is configured purely by a + * collection of input signals from other hardware in the system. Typically + * they are either hardwired or exposed in an ad-hoc register interface by + * the SoC that uses the MSC. + * + * We don't currently implement the irq_enable GPIO input, because on + * the MPS2 FPGA images it is always tied high, which is awkward to + * implement in QEMU. + * + * QEMU interface: + * + Named GPIO input "cfg_nonsec": set to 1 if the bus master should be + * treated as nonsecure, or 0 for secure + * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction should + * result in a transaction error, or 0 for the transaction to RAZ/WI + * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt + * + Named GPIO output "irq": set for a transaction-failed interrupt + * + Property "downstream": MemoryRegion defining where bus master transactions + * are made if they are not blocked + * + Property "idau": an object implementing IDAUInterface, which defines which + * addresses should be treated as secure and which as non-secure. + * This need not be the same IDAU as the one used by the CPU. + * + sysbus MMIO region 0: MemoryRegion defining the upstream end of the MSC; + * this should be passed to the bus master device as the region it should + * make memory transactions to + */ + +#ifndef TZ_MSC_H +#define TZ_MSC_H + +#include "hw/sysbus.h" +#include "target/arm/idau.h" +#include "qom/object.h" + +#define TYPE_TZ_MSC "tz-msc" +OBJECT_DECLARE_SIMPLE_TYPE(TZMSC, TZ_MSC) + +struct TZMSC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State: these just track the values of our input signals */ + bool cfg_nonsec; + bool cfg_sec_resp; + bool irq_clear; + /* State: are we asserting irq ? */ + bool irq_status; + + qemu_irq irq; + MemoryRegion *downstream; + AddressSpace downstream_as; + MemoryRegion upstream; + IDAUInterface *idau; +}; + +#endif diff --git a/include/hw/misc/tz-ppc.h b/include/hw/misc/tz-ppc.h new file mode 100644 index 000000000..021d671b2 --- /dev/null +++ b/include/hw/misc/tz-ppc.h @@ -0,0 +1,107 @@ +/* + * ARM TrustZone peripheral protection controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the TrustZone peripheral protection controller (PPC). + * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM + * (DDI 0571G): + * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g + * + * The PPC sits in front of peripherals and allows secure software to + * configure it to either pass through or reject transactions. + * Rejected transactions may be configured to either be aborted, or to + * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction. + * + * The PPC has no register interface -- it is configured purely by a + * collection of input signals from other hardware in the system. Typically + * they are either hardwired or exposed in an ad-hoc register interface by + * the SoC that uses the PPC. + * + * This QEMU model can be used to model either the AHB5 or APB4 TZ PPC, + * since the only difference between them is that the AHB version has a + * "default" port which has no security checks applied. In QEMU the default + * port can be emulated simply by wiring its downstream devices directly + * into the parent address space, since the PPC does not need to intercept + * transactions there. + * + * In the hardware, selection of which downstream port to use is done by + * the user's decode logic asserting one of the hsel[] signals. In QEMU, + * we provide 16 MMIO regions, one per port, and the user maps these into + * the desired addresses to implement the address decode. + * + * QEMU interface: + * + sysbus MMIO regions 0..15: MemoryRegions defining the upstream end + * of each of the 16 ports of the PPC. When a port is unused (i.e. no + * downstream MemoryRegion is connected to it) at the end of the 0..15 + * range then no sysbus MMIO region is created for its upstream. When an + * unused port lies in the middle of the range with other used ports at + * higher port numbers, a dummy MMIO region is created to ensure that + * port N's upstream is always sysbus MMIO region N. Dummy regions should + * not be mapped, and will assert if any access is made to them. + * + Property "port[0..15]": MemoryRegion defining the downstream device(s) + * for each of the 16 ports of the PPC + * + Named GPIO inputs "cfg_nonsec[0..15]": set to 1 if the port should be + * accessible to NonSecure transactions + * + Named GPIO inputs "cfg_ap[0..15]": set to 1 if the port should be + * accessible to non-privileged transactions + * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction should + * result in a transaction error, or 0 for the transaction to RAZ/WI + * + Named GPIO input "irq_enable": set to 1 to enable interrupts + * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt + * + Named GPIO output "irq": set for a transaction-failed interrupt + * + Property "NONSEC_MASK": if a bit is set in this mask then accesses to + * the associated port do not have the TZ security check performed. (This + * corresponds to the hardware allowing this to be set as a Verilog + * parameter.) + */ + +#ifndef TZ_PPC_H +#define TZ_PPC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_TZ_PPC "tz-ppc" +OBJECT_DECLARE_SIMPLE_TYPE(TZPPC, TZ_PPC) + +#define TZ_NUM_PORTS 16 + + +typedef struct TZPPCPort { + TZPPC *ppc; + MemoryRegion upstream; + AddressSpace downstream_as; + MemoryRegion *downstream; +} TZPPCPort; + +struct TZPPC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State: these just track the values of our input signals */ + bool cfg_nonsec[TZ_NUM_PORTS]; + bool cfg_ap[TZ_NUM_PORTS]; + bool cfg_sec_resp; + bool irq_enable; + bool irq_clear; + /* State: are we asserting irq ? */ + bool irq_status; + + qemu_irq irq; + + /* Properties */ + uint32_t nonsec_mask; + + TZPPCPort port[TZ_NUM_PORTS]; +}; + +#endif diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h new file mode 100644 index 000000000..518d627dc --- /dev/null +++ b/include/hw/misc/unimp.h @@ -0,0 +1,54 @@ +/* + * "Unimplemented" device + * + * Copyright Linaro Limited, 2017 + * Written by Peter Maydell + */ + +#ifndef HW_MISC_UNIMP_H +#define HW_MISC_UNIMP_H + +#include "hw/qdev-properties.h" +#include "hw/sysbus.h" +#include "qapi/error.h" +#include "qom/object.h" + +#define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device" + +OBJECT_DECLARE_SIMPLE_TYPE(UnimplementedDeviceState, UNIMPLEMENTED_DEVICE) + +struct UnimplementedDeviceState { + SysBusDevice parent_obj; + MemoryRegion iomem; + unsigned offset_fmt_width; + char *name; + uint64_t size; +}; + +/** + * create_unimplemented_device: create and map a dummy device + * @name: name of the device for debug logging + * @base: base address of the device's MMIO region + * @size: size of the device's MMIO region + * + * This utility function creates and maps an instance of unimplemented-device, + * which is a dummy device which simply logs all guest accesses to + * it via the qemu_log LOG_UNIMP debug log. + * The device is mapped at priority -1000, which means that you can + * use it to cover a large region and then map other devices on top of it + * if necessary. + */ +static inline void create_unimplemented_device(const char *name, + hwaddr base, + hwaddr size) +{ + DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); + + qdev_prop_set_string(dev, "name", name); + qdev_prop_set_uint64(dev, "size", size); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, base, -1000); +} + +#endif diff --git a/include/hw/misc/virt_ctrl.h b/include/hw/misc/virt_ctrl.h new file mode 100644 index 000000000..25a237e51 --- /dev/null +++ b/include/hw/misc/virt_ctrl.h @@ -0,0 +1,22 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Virt system Controller + */ + +#ifndef VIRT_CTRL_H +#define VIRT_CTRL_H + +#define TYPE_VIRT_CTRL "virt-ctrl" +OBJECT_DECLARE_SIMPLE_TYPE(VirtCtrlState, VIRT_CTRL) + +struct VirtCtrlState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + qemu_irq irq; + + uint32_t irq_enabled; +}; + +#endif diff --git a/include/hw/misc/vmcoreinfo.h b/include/hw/misc/vmcoreinfo.h new file mode 100644 index 000000000..0b7b55d40 --- /dev/null +++ b/include/hw/misc/vmcoreinfo.h @@ -0,0 +1,41 @@ +/* + * Virtual Machine coreinfo device + * + * Copyright (C) 2017 Red Hat, Inc. + * + * Authors: Marc-André Lureau <marcandre.lureau@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#ifndef VMCOREINFO_H +#define VMCOREINFO_H + +#include "hw/qdev-core.h" +#include "standard-headers/linux/qemu_fw_cfg.h" +#include "qom/object.h" + +#define VMCOREINFO_DEVICE "vmcoreinfo" +typedef struct VMCoreInfoState VMCoreInfoState; +DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, + VMCOREINFO_DEVICE) + +typedef struct fw_cfg_vmcoreinfo FWCfgVMCoreInfo; + +struct VMCoreInfoState { + DeviceState parent_obj; + + bool has_vmcoreinfo; + FWCfgVMCoreInfo vmcoreinfo; +}; + +/* returns NULL unless there is exactly one device */ +static inline VMCoreInfoState *vmcoreinfo_find(void) +{ + Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL); + + return o ? VMCOREINFO(o) : NULL; +} + +#endif diff --git a/include/hw/misc/xlnx-versal-xramc.h b/include/hw/misc/xlnx-versal-xramc.h new file mode 100644 index 000000000..d3d186267 --- /dev/null +++ b/include/hw/misc/xlnx-versal-xramc.h @@ -0,0 +1,97 @@ +/* + * QEMU model of the Xilinx XRAM Controller. + * + * Copyright (c) 2021 Xilinx Inc. + * SPDX-License-Identifier: GPL-2.0-or-later + * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com> + */ + +#ifndef XLNX_VERSAL_XRAMC_H +#define XLNX_VERSAL_XRAMC_H + +#include "hw/sysbus.h" +#include "hw/register.h" + +#define TYPE_XLNX_XRAM_CTRL "xlnx.versal-xramc" + +#define XLNX_XRAM_CTRL(obj) \ + OBJECT_CHECK(XlnxXramCtrl, (obj), TYPE_XLNX_XRAM_CTRL) + +REG32(XRAM_ERR_CTRL, 0x0) + FIELD(XRAM_ERR_CTRL, UE_RES, 3, 1) + FIELD(XRAM_ERR_CTRL, PWR_ERR_RES, 2, 1) + FIELD(XRAM_ERR_CTRL, PZ_ERR_RES, 1, 1) + FIELD(XRAM_ERR_CTRL, APB_ERR_RES, 0, 1) +REG32(XRAM_ISR, 0x4) + FIELD(XRAM_ISR, INV_APB, 0, 1) +REG32(XRAM_IMR, 0x8) + FIELD(XRAM_IMR, INV_APB, 0, 1) +REG32(XRAM_IEN, 0xc) + FIELD(XRAM_IEN, INV_APB, 0, 1) +REG32(XRAM_IDS, 0x10) + FIELD(XRAM_IDS, INV_APB, 0, 1) +REG32(XRAM_ECC_CNTL, 0x14) + FIELD(XRAM_ECC_CNTL, FI_MODE, 2, 1) + FIELD(XRAM_ECC_CNTL, DET_ONLY, 1, 1) + FIELD(XRAM_ECC_CNTL, ECC_ON_OFF, 0, 1) +REG32(XRAM_CLR_EXE, 0x18) + FIELD(XRAM_CLR_EXE, MON_7, 7, 1) + FIELD(XRAM_CLR_EXE, MON_6, 6, 1) + FIELD(XRAM_CLR_EXE, MON_5, 5, 1) + FIELD(XRAM_CLR_EXE, MON_4, 4, 1) + FIELD(XRAM_CLR_EXE, MON_3, 3, 1) + FIELD(XRAM_CLR_EXE, MON_2, 2, 1) + FIELD(XRAM_CLR_EXE, MON_1, 1, 1) + FIELD(XRAM_CLR_EXE, MON_0, 0, 1) +REG32(XRAM_CE_FFA, 0x1c) + FIELD(XRAM_CE_FFA, ADDR, 0, 20) +REG32(XRAM_CE_FFD0, 0x20) +REG32(XRAM_CE_FFD1, 0x24) +REG32(XRAM_CE_FFD2, 0x28) +REG32(XRAM_CE_FFD3, 0x2c) +REG32(XRAM_CE_FFE, 0x30) + FIELD(XRAM_CE_FFE, SYNDROME, 0, 16) +REG32(XRAM_UE_FFA, 0x34) + FIELD(XRAM_UE_FFA, ADDR, 0, 20) +REG32(XRAM_UE_FFD0, 0x38) +REG32(XRAM_UE_FFD1, 0x3c) +REG32(XRAM_UE_FFD2, 0x40) +REG32(XRAM_UE_FFD3, 0x44) +REG32(XRAM_UE_FFE, 0x48) + FIELD(XRAM_UE_FFE, SYNDROME, 0, 16) +REG32(XRAM_FI_D0, 0x4c) +REG32(XRAM_FI_D1, 0x50) +REG32(XRAM_FI_D2, 0x54) +REG32(XRAM_FI_D3, 0x58) +REG32(XRAM_FI_SY, 0x5c) + FIELD(XRAM_FI_SY, DATA, 0, 16) +REG32(XRAM_RMW_UE_FFA, 0x70) + FIELD(XRAM_RMW_UE_FFA, ADDR, 0, 20) +REG32(XRAM_FI_CNTR, 0x74) + FIELD(XRAM_FI_CNTR, COUNT, 0, 24) +REG32(XRAM_IMP, 0x80) + FIELD(XRAM_IMP, SIZE, 0, 4) +REG32(XRAM_PRDY_DBG, 0x84) + FIELD(XRAM_PRDY_DBG, ISLAND3, 12, 4) + FIELD(XRAM_PRDY_DBG, ISLAND2, 8, 4) + FIELD(XRAM_PRDY_DBG, ISLAND1, 4, 4) + FIELD(XRAM_PRDY_DBG, ISLAND0, 0, 4) +REG32(XRAM_SAFETY_CHK, 0xff8) + +#define XRAM_CTRL_R_MAX (R_XRAM_SAFETY_CHK + 1) + +typedef struct XlnxXramCtrl { + SysBusDevice parent_obj; + MemoryRegion ram; + qemu_irq irq; + + struct { + uint64_t size; + unsigned int encoded_size; + } cfg; + + RegisterInfoArray *reg_array; + uint32_t regs[XRAM_CTRL_R_MAX]; + RegisterInfo regs_info[XRAM_CTRL_R_MAX]; +} XlnxXramCtrl; +#endif |