diff options
Diffstat (limited to 'include/hw')
-rw-r--r-- | include/hw/arm/armsse-version.h | 42 | ||||
-rw-r--r-- | include/hw/arm/armsse.h | 40 | ||||
-rw-r--r-- | include/hw/arm/aspeed_soc.h | 3 | ||||
-rw-r--r-- | include/hw/arm/virt.h | 1 | ||||
-rw-r--r-- | include/hw/arm/xlnx-zynqmp.h | 5 | ||||
-rw-r--r-- | include/hw/boards.h | 1 | ||||
-rw-r--r-- | include/hw/clock.h | 63 | ||||
-rw-r--r-- | include/hw/dma/xlnx_csu_dma.h | 52 | ||||
-rw-r--r-- | include/hw/elf_ops.h | 2 | ||||
-rw-r--r-- | include/hw/misc/armsse-cpu-pwrctrl.h | 40 | ||||
-rw-r--r-- | include/hw/misc/aspeed_lpc.h | 47 | ||||
-rw-r--r-- | include/hw/misc/iotkit-secctl.h | 2 | ||||
-rw-r--r-- | include/hw/misc/iotkit-sysctl.h | 13 | ||||
-rw-r--r-- | include/hw/misc/iotkit-sysinfo.h | 2 | ||||
-rw-r--r-- | include/hw/misc/mps2-fpgaio.h | 2 | ||||
-rw-r--r-- | include/hw/ppc/pnv_xscom.h | 2 | ||||
-rw-r--r-- | include/hw/qdev-clock.h | 17 | ||||
-rw-r--r-- | include/hw/riscv/virt.h | 1 | ||||
-rw-r--r-- | include/hw/s390x/css.h | 2 | ||||
-rw-r--r-- | include/hw/semihosting/console.h | 69 | ||||
-rw-r--r-- | include/hw/semihosting/semihost.h | 77 | ||||
-rw-r--r-- | include/hw/ssi/xilinx_spips.h | 2 | ||||
-rw-r--r-- | include/hw/timer/sse-counter.h | 105 | ||||
-rw-r--r-- | include/hw/timer/sse-timer.h | 53 |
24 files changed, 457 insertions, 186 deletions
diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h new file mode 100644 index 0000000000..60780fa984 --- /dev/null +++ b/include/hw/arm/armsse-version.h @@ -0,0 +1,42 @@ +/* + * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200 + * + * Copyright (c) 2020 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. + */ + +#ifndef ARMSSE_VERSION_H +#define ARMSSE_VERSION_H + + +/* + * Define an enumeration of the possible values of the sse-version + * property implemented by various sub-devices of the SSE, and + * a validation function that checks that a valid value has been passed. + * These are arbitrary QEMU-internal values (nobody should be creating + * the sub-devices of the SSE except for the SSE object itself), but + * we pick obvious numbers for the benefit of people debugging with gdb. + */ +enum { + ARMSSE_IOTKIT = 0, + ARMSSE_SSE200 = 200, + ARMSSE_SSE300 = 300, +}; + +static inline bool armsse_version_valid(uint32_t sse_version) +{ + switch (sse_version) { + case ARMSSE_IOTKIT: + case ARMSSE_SSE200: + case ARMSSE_SSE300: + return true; + default: + return false; + } +} + +#endif diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 09284ca75c..36592be62c 100644 --- a/include/hw/arm/armsse.h +++ b/include/hw/arm/armsse.h @@ -97,11 +97,14 @@ #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" +#include "hw/timer/sse-counter.h" +#include "hw/timer/sse-timer.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/misc/iotkit-sysctl.h" #include "hw/misc/iotkit-sysinfo.h" #include "hw/misc/armsse-cpuid.h" #include "hw/misc/armsse-mhu.h" +#include "hw/misc/armsse-cpu-pwrctrl.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/clock.h" @@ -120,12 +123,14 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass, */ #define TYPE_IOTKIT "iotkit" #define TYPE_SSE200 "sse-200" +#define TYPE_SSE300 "sse-300" /* We have an IRQ splitter and an OR gate input for each external PPC * and the 2 internal PPCs */ +#define NUM_INTERNAL_PPCS 2 #define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC) -#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2) +#define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS) #define MAX_SRAM_BANKS 4 #if MAX_SRAM_BANKS > IOTS_NUM_MPC @@ -134,15 +139,10 @@ OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass, #define SSE_MAX_CPUS 2 -/* These define what each PPU in the ppu[] index is for */ -#define CPU0CORE_PPU 0 -#define CPU1CORE_PPU 1 -#define DBG_PPU 2 -#define RAM0_PPU 3 -#define RAM1_PPU 4 -#define RAM2_PPU 5 -#define RAM3_PPU 6 -#define NUM_PPUS 7 +#define NUM_PPUS 8 + +/* Number of CPU IRQs used by the SSE itself */ +#define NUM_SSE_IRQS 32 struct ARMSSE { /*< private >*/ @@ -152,12 +152,9 @@ struct ARMSSE { ARMv7MState armv7m[SSE_MAX_CPUS]; CPUClusterState cluster[SSE_MAX_CPUS]; IoTKitSecCtl secctl; - TZPPC apb_ppc0; - TZPPC apb_ppc1; + TZPPC apb_ppc[NUM_INTERNAL_PPCS]; TZMPC mpc[IOTS_NUM_MPC]; - CMSDKAPBTimer timer0; - CMSDKAPBTimer timer1; - CMSDKAPBTimer s32ktimer; + CMSDKAPBTimer timer[3]; qemu_or_irq ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; @@ -165,24 +162,27 @@ struct ARMSSE { qemu_or_irq mpc_irq_orgate; qemu_or_irq nmi_orgate; - SplitIRQ cpu_irq_splitter[32]; + SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS]; CMSDKAPBDualTimer dualtimer; - CMSDKAPBWatchdog s32kwatchdog; - CMSDKAPBWatchdog nswatchdog; - CMSDKAPBWatchdog swatchdog; + CMSDKAPBWatchdog cmsdk_watchdog[3]; + + SSECounter sse_counter; + SSETimer sse_timer[4]; IoTKitSysCtl sysctl; IoTKitSysCtl sysinfo; ARMSSEMHU mhu[2]; - UnimplementedDeviceState ppu[NUM_PPUS]; + UnimplementedDeviceState unimp[NUM_PPUS]; UnimplementedDeviceState cachectrl[SSE_MAX_CPUS]; UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS]; ARMSSECPUID cpuid[SSE_MAX_CPUS]; + ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS]; + /* * 'container' holds all devices seen by all CPUs. * 'cpu_container[i]' is the view that CPU i has: this has the diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 11cfe6e358..9359d6da33 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -28,6 +28,7 @@ #include "hw/sd/aspeed_sdhci.h" #include "hw/usb/hcd-ehci.h" #include "qom/object.h" +#include "hw/misc/aspeed_lpc.h" #define ASPEED_SPIS_NUM 2 #define ASPEED_EHCIS_NUM 2 @@ -61,6 +62,7 @@ struct AspeedSoCState { AspeedGPIOState gpio_1_8v; AspeedSDHCIState sdhci; AspeedSDHCIState emmc; + AspeedLPCState lpc; }; #define TYPE_ASPEED_SOC "aspeed-soc" @@ -130,6 +132,7 @@ enum { ASPEED_DEV_SDRAM, ASPEED_DEV_XDMA, ASPEED_DEV_EMMC, + ASPEED_DEV_KCS, }; #endif /* ASPEED_SOC_H */ diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index ee9a93101e..921416f918 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -153,7 +153,6 @@ struct VirtMachineState { MemMapEntry *memmap; char *pciehb_nodename; const int *irqmap; - void *fdt; int fdt_size; uint32_t clock_phandle; uint32_t gic_phandle; diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 0678b419a2..1676a84ec8 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -35,6 +35,7 @@ #include "target/arm/cpu.h" #include "qom/object.h" #include "net/can_emu.h" +#include "hw/dma/xlnx_csu_dma.h" #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) @@ -60,7 +61,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) #define XLNX_ZYNQMP_GIC_REGIONS 6 -/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets +/* + * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets * and under-decodes the 64k region. This mirrors the 4k regions to every 4k * aligned address in the 64k region. To implement each GIC region needs a * number of memory region aliases. @@ -107,6 +109,7 @@ struct XlnxZynqMPState { XlnxZynqMPRTC rtc; XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH]; XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH]; + XlnxCSUDMA qspi_dma; char *boot_cpu; ARMCPU *boot_cpu_ptr; diff --git a/include/hw/boards.h b/include/hw/boards.h index a46dfe5d1a..5fda5fd128 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -258,6 +258,7 @@ struct MachineState { /*< public >*/ + void *fdt; char *dtb; char *dumpdtb; int phandle_start; diff --git a/include/hw/clock.h b/include/hw/clock.h index e5f45e2626..a7187eab95 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -22,7 +22,18 @@ #define TYPE_CLOCK "clock" OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK) -typedef void ClockCallback(void *opaque); +/* + * Argument to ClockCallback functions indicating why the callback + * has been called. A mask of these values logically ORed together + * is used to specify which events are interesting when the callback + * is registered, so these values must all be different bit values. + */ +typedef enum ClockEvent { + ClockUpdate = 1, /* Clock period has just updated */ + ClockPreUpdate = 2, /* Clock period is about to update */ +} ClockEvent; + +typedef void ClockCallback(void *opaque, ClockEvent event); /* * clock store a value representing the clock's period in 2^-32ns unit. @@ -50,6 +61,7 @@ typedef void ClockCallback(void *opaque); * @canonical_path: clock path string cache (used for trace purpose) * @callback: called when clock changes * @callback_opaque: argument for @callback + * @callback_events: mask of events when callback should be called * @source: source (or parent in clock tree) of the clock * @children: list of clocks connected to this one (it is their source) * @sibling: structure used to form a clock list @@ -67,6 +79,7 @@ struct Clock { char *canonical_path; ClockCallback *callback; void *callback_opaque; + unsigned int callback_events; /* Clocks are organized in a clock tree */ Clock *source; @@ -114,10 +127,15 @@ Clock *clock_new(Object *parent, const char *name); * @clk: the clock to register the callback into * @cb: the callback function * @opaque: the argument to the callback + * @events: the events the callback should be called for + * (logical OR of ClockEvent enum values) * * Register a callback called on every clock update. + * Note that a clock has only one callback: you cannot register + * different callback functions for different events. */ -void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque); +void clock_set_callback(Clock *clk, ClockCallback *cb, + void *opaque, unsigned int events); /** * clock_clear_callback: @@ -269,6 +287,47 @@ static inline uint64_t clock_ticks_to_ns(const Clock *clk, uint64_t ticks) } /** + * clock_ns_to_ticks: + * @clk: the clock to query + * @ns: duration in nanoseconds + * + * Returns the number of ticks this clock would make in the given + * number of nanoseconds. Because a clock can have a period which + * is not a whole number of nanoseconds, it is important to use this + * function rather than attempting to obtain a "period in nanoseconds" + * value and then dividing the duration by that value. + * + * If the clock is stopped (ie it has period zero), returns 0. + * + * For some inputs the result could overflow a 64-bit value (because + * the clock's period is short and the duration is long). In these + * cases we truncate the result to a 64-bit value. This is on the + * assumption that generally the result is going to be used to report + * a 32-bit or 64-bit guest register value, so wrapping either cannot + * happen or is the desired behaviour. + */ +static inline uint64_t clock_ns_to_ticks(const Clock *clk, uint64_t ns) +{ + /* + * ticks = duration_in_ns / period_in_ns + * = ns / (period / 2^32) + * = (ns * 2^32) / period + * The hi, lo inputs to divu128() are (ns << 32) as a 128 bit value. + */ + uint64_t lo = ns << 32; + uint64_t hi = ns >> 32; + if (clk->period == 0) { + return 0; + } + /* + * Ignore divu128() return value as we've caught div-by-zero and don't + * need different behaviour for overflow. + */ + divu128(&lo, &hi, clk->period); + return lo; +} + +/** * clock_is_enabled: * @clk: a clock * diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h new file mode 100644 index 0000000000..204d94c673 --- /dev/null +++ b/include/hw/dma/xlnx_csu_dma.h @@ -0,0 +1,52 @@ +/* + * Xilinx Platform CSU Stream DMA emulation + * + * This implementation is based on + * https://github.com/Xilinx/qemu/blob/master/hw/dma/csu_stream_dma.c + * + * 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 XLNX_CSU_DMA_H +#define XLNX_CSU_DMA_H + +#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma" + +#define XLNX_CSU_DMA_R_MAX (0x2c / 4) + +typedef struct XlnxCSUDMA { + SysBusDevice busdev; + MemoryRegion iomem; + MemTxAttrs attr; + MemoryRegion *dma_mr; + AddressSpace *dma_as; + qemu_irq irq; + StreamSink *tx_dev; /* Used as generic StreamSink */ + ptimer_state *src_timer; + + uint16_t width; + bool is_dst; + bool r_size_last_word; + + StreamCanPushNotifyFn notify; + void *notify_opaque; + + uint32_t regs[XLNX_CSU_DMA_R_MAX]; + RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX]; +} XlnxCSUDMA; + +#define XLNX_CSU_DMA(obj) \ + OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA) + +#endif diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index 78409ab34a..6ee458e7bc 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -417,7 +417,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, /* * Since we want to be able to modify the mapped buffer, we set the - * 'writeble' parameter to 'true'. Modifications to the buffer are not + * 'writable' parameter to 'true'. Modifications to the buffer are not * written back to the file. */ mapped_file = g_mapped_file_new_from_fd(fd, true, NULL); diff --git a/include/hw/misc/armsse-cpu-pwrctrl.h b/include/hw/misc/armsse-cpu-pwrctrl.h new file mode 100644 index 0000000000..51d45ede7d --- /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/aspeed_lpc.h b/include/hw/misc/aspeed_lpc.h new file mode 100644 index 0000000000..df418cfcd3 --- /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/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h index 227d44abe4..79a3628320 100644 --- a/include/hw/misc/iotkit-secctl.h +++ b/include/hw/misc/iotkit-secctl.h @@ -120,6 +120,8 @@ struct IoTKitSecCtl { 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 index 2bc391138d..481e27f4db 100644 --- a/include/hw/misc/iotkit-sysctl.h +++ b/include/hw/misc/iotkit-sysctl.h @@ -17,9 +17,8 @@ * "system control register" blocks. * * QEMU interface: - * + QOM property "SYS_VERSION": value of the SYS_VERSION register of the - * system information block of the SSE - * (used to identify whether to provide SSE-200-only registers) + * + 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 */ @@ -54,19 +53,21 @@ struct IoTKitSysCtl { 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 sys_version; + uint32_t sse_version; uint32_t cpuwait_rst; uint32_t initsvtor0_rst; uint32_t initsvtor1_rst; - - bool is_sse200; }; #endif diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h index 055771d209..91c23f90d2 100644 --- a/include/hw/misc/iotkit-sysinfo.h +++ b/include/hw/misc/iotkit-sysinfo.h @@ -38,6 +38,8 @@ struct IoTKitSysInfo { /* Properties */ uint32_t sys_version; uint32_t sys_config; + uint32_t sse_version; + uint32_t iidr; }; #endif diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index e04fd590b6..7b8bd604de 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -39,10 +39,12 @@ struct MPS2FPGAIO { 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; diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 8578f5a207..2ff9f7a8d6 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -139,7 +139,7 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset, void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset, MemoryRegion *mr); void pnv_xscom_region_init(MemoryRegion *mr, - struct Object *owner, + Object *owner, const MemoryRegionOps *ops, void *opaque, const char *name, diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index 64ca4d266f..ffa0f7ba09 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -22,6 +22,8 @@ * @name: the name of the clock (can't be NULL). * @callback: optional callback to be called on update or NULL. * @opaque: argument for the callback + * @events: the events the callback should be called for + * (logical OR of ClockEvent enum values) * @returns: a pointer to the newly added clock * * Add an input clock to device @dev as a clock named @name. @@ -29,7 +31,8 @@ * The callback will be called with @opaque as opaque parameter. */ Clock *qdev_init_clock_in(DeviceState *dev, const char *name, - ClockCallback *callback, void *opaque); + ClockCallback *callback, void *opaque, + unsigned int events); /** * qdev_init_clock_out: @@ -105,6 +108,7 @@ void qdev_finalize_clocklist(DeviceState *dev); * @output: indicates whether the clock is input or output * @callback: for inputs, optional callback to be called on clock's update * with device as opaque + * @callback_events: mask of ClockEvent values for when callback is called * @offset: optional offset to store the ClockIn or ClockOut pointer in device * state structure (0 means unused) */ @@ -112,6 +116,7 @@ struct ClockPortInitElem { const char *name; bool is_output; ClockCallback *callback; + unsigned int callback_events; size_t offset; }; @@ -119,10 +124,11 @@ struct ClockPortInitElem { (offsetof(devstate, field) + \ type_check(Clock *, typeof_field(devstate, field))) -#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \ +#define QDEV_CLOCK(out_not_in, devstate, field, cb, cbevents) { \ .name = (stringify(field)), \ .is_output = out_not_in, \ .callback = cb, \ + .callback_events = cbevents, \ .offset = clock_offset_value(devstate, field), \ } @@ -133,14 +139,15 @@ struct ClockPortInitElem { * @field: a field in @_devstate (must be Clock*) * @callback: (for input only) callback (or NULL) to be called with the device * state as argument + * @cbevents: (for input only) ClockEvent mask for when callback is called * * The name of the clock will be derived from @field */ -#define QDEV_CLOCK_IN(devstate, field, callback) \ - QDEV_CLOCK(false, devstate, field, callback) +#define QDEV_CLOCK_IN(devstate, field, callback, cbevents) \ + QDEV_CLOCK(false, devstate, field, callback, cbevents) #define QDEV_CLOCK_OUT(devstate, field) \ - QDEV_CLOCK(true, devstate, field, NULL) + QDEV_CLOCK(true, devstate, field, NULL, 0) #define QDEV_CLOCK_END { .name = NULL } diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 84b7a3848f..632da52018 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -41,7 +41,6 @@ struct RISCVVirtState { DeviceState *plic[VIRT_SOCKETS_MAX]; PFlashCFI01 *flash[2]; - void *fdt; int fdt_size; }; diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h index 08c869ab0a..7901ab276c 100644 --- a/include/hw/s390x/css.h +++ b/include/hw/s390x/css.h @@ -133,7 +133,7 @@ struct SubchDev { bool ccw_fmt_1; bool thinint_active; uint8_t ccw_no_data_cnt; - uint16_t migrated_schid; /* used for missmatch detection */ + uint16_t migrated_schid; /* used for mismatch detection */ CcwDataStream cds; /* transport-provided data: */ int (*ccw_cb) (SubchDev *, CCW1); diff --git a/include/hw/semihosting/console.h b/include/hw/semihosting/console.h deleted file mode 100644 index 0238f540f4..0000000000 --- a/include/hw/semihosting/console.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Semihosting Console - * - * Copyright (c) 2019 Linaro Ltd - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef SEMIHOST_CONSOLE_H -#define SEMIHOST_CONSOLE_H - -#include "cpu.h" - -/** - * qemu_semihosting_console_outs: - * @env: CPUArchState - * @s: host address of null terminated guest string - * - * Send a null terminated guest string to the debug console. This may - * be the remote gdb session if a softmmu guest is currently being - * debugged. - * - * Returns: number of bytes written. - */ -int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s); - -/** - * qemu_semihosting_console_outc: - * @env: CPUArchState - * @s: host address of null terminated guest string - * - * Send single character from guest memory to the debug console. This - * may be the remote gdb session if a softmmu guest is currently being - * debugged. - * - * Returns: nothing - */ -void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c); - -/** - * qemu_semihosting_console_inc: - * @env: CPUArchState - * - * Receive single character from debug console. This may be the remote - * gdb session if a softmmu guest is currently being debugged. As this - * call may block if no data is available we suspend the CPU and will - * re-execute the instruction when data is there. Therefore two - * conditions must be met: - * - CPUState is synchronized before calling this function - * - pc is only updated once the character is successfully returned - * - * Returns: character read OR cpu_loop_exit! - */ -target_ulong qemu_semihosting_console_inc(CPUArchState *env); - -/** - * qemu_semihosting_log_out: - * @s: pointer to string - * @len: length of string - * - * Send a string to the debug output. Unlike console_out these strings - * can't be sent to a remote gdb instance as they don't exist in guest - * memory. - * - * Returns: number of bytes written - */ -int qemu_semihosting_log_out(const char *s, int len); - -#endif /* SEMIHOST_CONSOLE_H */ diff --git a/include/hw/semihosting/semihost.h b/include/hw/semihosting/semihost.h deleted file mode 100644 index 0c55ade3ac..0000000000 --- a/include/hw/semihosting/semihost.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Semihosting support - * - * Copyright (c) 2015 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 SEMIHOST_H -#define SEMIHOST_H - -typedef enum SemihostingTarget { - SEMIHOSTING_TARGET_AUTO = 0, - SEMIHOSTING_TARGET_NATIVE, - SEMIHOSTING_TARGET_GDB -} SemihostingTarget; - -#ifdef CONFIG_USER_ONLY -static inline bool semihosting_enabled(void) -{ - return true; -} - -static inline SemihostingTarget semihosting_get_target(void) -{ - return SEMIHOSTING_TARGET_AUTO; -} - -static inline const char *semihosting_get_arg(int i) -{ - return NULL; -} - -static inline int semihosting_get_argc(void) -{ - return 0; -} - -static inline const char *semihosting_get_cmdline(void) -{ - return NULL; -} - -static inline Chardev *semihosting_get_chardev(void) -{ - return NULL; -} -static inline void qemu_semihosting_console_init(void) -{ -} -#else /* !CONFIG_USER_ONLY */ -bool semihosting_enabled(void); -SemihostingTarget semihosting_get_target(void); -const char *semihosting_get_arg(int i); -int semihosting_get_argc(void); -const char *semihosting_get_cmdline(void); -void semihosting_arg_fallback(const char *file, const char *cmd); -Chardev *semihosting_get_chardev(void); -/* for vl.c hooks */ -void qemu_semihosting_enable(void); -int qemu_semihosting_config_options(const char *opt); -void qemu_semihosting_connect_chardevs(void); -void qemu_semihosting_console_init(void); -#endif /* CONFIG_USER_ONLY */ - -#endif /* SEMIHOST_H */ diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h index 3eae73480e..06bfd18312 100644 --- a/include/hw/ssi/xilinx_spips.h +++ b/include/hw/ssi/xilinx_spips.h @@ -34,7 +34,7 @@ typedef struct XilinxSPIPS XilinxSPIPS; #define XLNX_SPIPS_R_MAX (0x100 / 4) -#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4) +#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4) /* Bite off 4k chunks at a time */ #define LQSPI_CACHE_SIZE 1024 diff --git a/include/hw/timer/sse-counter.h b/include/hw/timer/sse-counter.h new file mode 100644 index 0000000000..b433e58d37 --- /dev/null +++ b/include/hw/timer/sse-counter.h @@ -0,0 +1,105 @@ +/* + * Arm SSE Subsystem System Counter + * + * Copyright (c) 2020 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 counter" which is documented in + * the Arm SSE-123 Example Subsystem Technical Reference Manual: + * https://developer.arm.com/documentation/101370/latest/ + * + * QEMU interface: + * + Clock input "CLK": clock + * + sysbus MMIO region 0: the control register frame + * + sysbus MMIO region 1: the status register frame + * + * Consumers of the system counter's timestamp, such as the SSE + * System Timer device, can also use the APIs sse_counter_for_timestamp(), + * sse_counter_tick_to_time() and sse_counter_register_consumer() to + * interact with an instance of the System Counter. Generally the + * consumer device should have a QOM link property which the board + * code can set to the appropriate instance of the system counter. + */ + +#ifndef SSE_COUNTER_H +#define SSE_COUNTER_H + +#include "hw/sysbus.h" +#include "qom/object.h" +#include "qemu/notify.h" + +#define TYPE_SSE_COUNTER "sse-counter" +OBJECT_DECLARE_SIMPLE_TYPE(SSECounter, SSE_COUNTER) + +struct SSECounter { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion control_mr; + MemoryRegion status_mr; + Clock *clk; + NotifierList notifier_list; + + uint32_t cntcr; + uint32_t cntscr0; + + /* + * These are used for handling clock frequency changes: they are a + * tuple of (QEMU_CLOCK_VIRTUAL timestamp, CNTCV at that time), + * taken when the clock frequency changes. sse_cntcv() needs them + * to calculate the current CNTCV. + */ + uint64_t ns_then; + uint64_t ticks_then; +}; + +/* + * These functions are the interface by which a consumer of + * the system timestamp (such as the SSE system timer device) + * can communicate with the SSECounter. + */ + +/** + * sse_counter_for_timestamp: + * @counter: SSECounter + * @ns: timestamp of QEMU_CLOCK_VIRTUAL in nanoseconds + * + * Returns the value of the timestamp counter at the specified + * point in time (assuming that no changes to scale factor, enable, etc + * happen in the meantime). + */ +uint64_t sse_counter_for_timestamp(SSECounter *counter, uint64_t ns); + +/** + * sse_counter_tick_to_time: + * @counter: SSECounter + * @tick: tick value + * + * Returns the time (a QEMU_CLOCK_VIRTUAL timestamp in nanoseconds) + * when the timestamp counter will reach the specified tick count. + * If the counter is not currently running, returns UINT64_MAX. + */ +uint64_t sse_counter_tick_to_time(SSECounter *counter, uint64_t tick); + +/** + * sse_counter_register_consumer: + * @counter: SSECounter + * @notifier: Notifier which is notified on counter changes + * + * Registers @notifier with the SSECounter. When the counter's + * configuration changes in a way that might invalidate information + * previously returned via sse_counter_for_timestamp() or + * sse_counter_tick_to_time(), the notifier will be called. + * Devices which consume the timestamp counter can use this as + * a cue to recalculate timer events. + */ +void sse_counter_register_consumer(SSECounter *counter, Notifier *notifier); + +#endif diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h new file mode 100644 index 0000000000..b4ee8e7f6c --- /dev/null +++ b/include/hw/timer/sse-timer.h @@ -0,0 +1,53 @@ +/* + * Arm SSE Subsystem System Timer + * + * Copyright (c) 2020 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 timer" which is documented in + * the Arm SSE-123 Example Subsystem Technical Reference Manual: + * https://developer.arm.com/documentation/101370/latest/ + * + * QEMU interface: + * + QOM property "counter": link property to be set to the + * TYPE_SSE_COUNTER timestamp counter device this timer runs off + * + sysbus MMIO region 0: the register bank + * + sysbus IRQ 0: timer interrupt + */ + +#ifndef SSE_TIMER_H +#define SSE_TIMER_H + +#include "hw/sysbus.h" +#include "qom/object.h" +#include "hw/timer/sse-counter.h" + +#define TYPE_SSE_TIMER "sse-timer" +OBJECT_DECLARE_SIMPLE_TYPE(SSETimer, SSE_TIMER) + +struct SSETimer { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq irq; + SSECounter *counter; + QEMUTimer timer; + Notifier counter_notifier; + + uint32_t cntfrq; + uint32_t cntp_ctl; + uint64_t cntp_cval; + uint64_t cntp_aival; + uint32_t cntp_aival_ctl; + uint32_t cntp_aival_reload; +}; + +#endif |