Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210112-1' into staging

target-arm queue:
 * arm: Support emulation of ARMv8.4-TTST extension
 * arm: Update cpu.h ID register field definitions
 * arm: Fix breakage of XScale instruction emulation
 * hw/net/lan9118: Fix RX Status FIFO PEEK value
 * npcm7xx: Add ADC and PWM emulation
 * ui/cocoa: Make "open docs" help menu entry work again when binary
   is run from the build tree
 * ui/cocoa: Fix openFile: deprecation on Big Sur
 * docs: Add qemu-storage-daemon(1) manpage to meson.build

# gpg: Signature made Tue 12 Jan 2021 21:22:15 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20210112-1:
  ui/cocoa: Fix openFile: deprecation on Big Sur
  hw/*: Use type casting for SysBusDevice in NPCM7XX
  hw/misc: Add QTest for NPCM7XX PWM Module
  hw/misc: Add a PWM module for NPCM7XX
  hw/adc: Add an ADC module for NPCM7XX
  hw/timer: Refactor NPCM7XX Timer to use CLK clock
  hw/misc: Add clock converter in NPCM7XX CLK module
  hw/net/lan9118: Add symbolic constants for register offsets
  hw/net/lan9118: Fix RX Status FIFO PEEK value
  target/arm: Don't decode insns in the XScale/iWMMXt space as cp insns
  docs: Add qemu-storage-daemon(1) manpage to meson.build
  ui/cocoa: Update path to docs in build tree
  target/arm: add aarch32 ID register fields to cpu.h
  target/arm: add aarch64 ID register fields to cpu.h
  target/arm: add descriptions of CLIDR_EL1, CCSIDR_EL1, CTR_EL0 to cpu.h
  target/arm: make ARMCPU.ctr 64-bit
  target/arm: make ARMCPU.clidr 64-bit
  target/arm: fix typo in cpu.h ID_AA64PFR1 field name
  target/arm: enable Small Translation tables in max CPU
  target/arm: ARMv8.4-TTST extension

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-01-12 21:23:25 +00:00
33 changed files with 3054 additions and 67 deletions
+1
View File
@@ -62,6 +62,7 @@ if build_docs
'qemu-img.1': (have_tools ? 'man1' : ''),
'qemu-nbd.8': (have_tools ? 'man8' : ''),
'qemu-pr-helper.8': (have_tools ? 'man8' : ''),
'qemu-storage-daemon.1': (have_tools ? 'man1' : ''),
'qemu-trace-stap.1': (config_host.has_key('CONFIG_TRACE_SYSTEMTAP') ? 'man1' : ''),
'virtfs-proxy-helper.1': (have_virtfs_proxy_helper ? 'man1' : ''),
'virtiofsd.1': (have_virtiofsd ? 'man1' : ''),
+2 -2
View File
@@ -41,6 +41,8 @@ Supported devices
* Random Number Generator (RNG)
* USB host (USBH)
* GPIO controller
* Analog to Digital Converter (ADC)
* Pulse Width Modulation (PWM)
Missing devices
---------------
@@ -58,10 +60,8 @@ Missing devices
* USB device (USBD)
* SMBus controller (SMBF)
* Peripheral SPI controller (PSPI)
* Analog to Digital Converter (ADC)
* SD/MMC host
* PECI interface
* Pulse Width Modulation (PWM)
* Tachometer
* PCI and PCIe root complex and bridges
* VDM and MCTP support
+1
View File
@@ -1 +1,2 @@
softmmu_ss.add(when: 'CONFIG_STM32F2XX_ADC', if_true: files('stm32f2xx_adc.c'))
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_adc.c'))
+301
View File
@@ -0,0 +1,301 @@
/*
* Nuvoton NPCM7xx ADC 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.
*/
#include "qemu/osdep.h"
#include "hw/adc/npcm7xx_adc.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/registerfields.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/units.h"
#include "trace.h"
REG32(NPCM7XX_ADC_CON, 0x0)
REG32(NPCM7XX_ADC_DATA, 0x4)
/* Register field definitions. */
#define NPCM7XX_ADC_CON_MUX(rv) extract32(rv, 24, 4)
#define NPCM7XX_ADC_CON_INT_EN BIT(21)
#define NPCM7XX_ADC_CON_REFSEL BIT(19)
#define NPCM7XX_ADC_CON_INT BIT(18)
#define NPCM7XX_ADC_CON_EN BIT(17)
#define NPCM7XX_ADC_CON_RST BIT(16)
#define NPCM7XX_ADC_CON_CONV BIT(14)
#define NPCM7XX_ADC_CON_DIV(rv) extract32(rv, 1, 8)
#define NPCM7XX_ADC_MAX_RESULT 1023
#define NPCM7XX_ADC_DEFAULT_IREF 2000000
#define NPCM7XX_ADC_CONV_CYCLES 20
#define NPCM7XX_ADC_RESET_CYCLES 10
#define NPCM7XX_ADC_R0_INPUT 500000
#define NPCM7XX_ADC_R1_INPUT 1500000
static void npcm7xx_adc_reset(NPCM7xxADCState *s)
{
timer_del(&s->conv_timer);
s->con = 0x000c0001;
s->data = 0x00000000;
}
static uint32_t npcm7xx_adc_convert(uint32_t input, uint32_t ref)
{
uint32_t result;
result = input * (NPCM7XX_ADC_MAX_RESULT + 1) / ref;
if (result > NPCM7XX_ADC_MAX_RESULT) {
result = NPCM7XX_ADC_MAX_RESULT;
}
return result;
}
static uint32_t npcm7xx_adc_prescaler(NPCM7xxADCState *s)
{
return 2 * (NPCM7XX_ADC_CON_DIV(s->con) + 1);
}
static void npcm7xx_adc_start_timer(Clock *clk, QEMUTimer *timer,
uint32_t cycles, uint32_t prescaler)
{
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t ticks = cycles;
int64_t ns;
ticks *= prescaler;
ns = clock_ticks_to_ns(clk, ticks);
ns += now;
timer_mod(timer, ns);
}
static void npcm7xx_adc_start_convert(NPCM7xxADCState *s)
{
uint32_t prescaler = npcm7xx_adc_prescaler(s);
npcm7xx_adc_start_timer(s->clock, &s->conv_timer, NPCM7XX_ADC_CONV_CYCLES,
prescaler);
}
static void npcm7xx_adc_convert_done(void *opaque)
{
NPCM7xxADCState *s = opaque;
uint32_t input = NPCM7XX_ADC_CON_MUX(s->con);
uint32_t ref = (s->con & NPCM7XX_ADC_CON_REFSEL)
? s->iref : s->vref;
if (input >= NPCM7XX_ADC_NUM_INPUTS) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid input: %u\n",
__func__, input);
return;
}
s->data = npcm7xx_adc_convert(s->adci[input], ref);
if (s->con & NPCM7XX_ADC_CON_INT_EN) {
s->con |= NPCM7XX_ADC_CON_INT;
qemu_irq_raise(s->irq);
}
s->con &= ~NPCM7XX_ADC_CON_CONV;
}
static void npcm7xx_adc_calibrate(NPCM7xxADCState *adc)
{
adc->calibration_r_values[0] = npcm7xx_adc_convert(NPCM7XX_ADC_R0_INPUT,
adc->iref);
adc->calibration_r_values[1] = npcm7xx_adc_convert(NPCM7XX_ADC_R1_INPUT,
adc->iref);
}
static void npcm7xx_adc_write_con(NPCM7xxADCState *s, uint32_t new_con)
{
uint32_t old_con = s->con;
/* Write ADC_INT to 1 to clear it */
if (new_con & NPCM7XX_ADC_CON_INT) {
new_con &= ~NPCM7XX_ADC_CON_INT;
qemu_irq_lower(s->irq);
} else if (old_con & NPCM7XX_ADC_CON_INT) {
new_con |= NPCM7XX_ADC_CON_INT;
}
s->con = new_con;
if (s->con & NPCM7XX_ADC_CON_RST) {
npcm7xx_adc_reset(s);
return;
}
if ((s->con & NPCM7XX_ADC_CON_EN)) {
if (s->con & NPCM7XX_ADC_CON_CONV) {
if (!(old_con & NPCM7XX_ADC_CON_CONV)) {
npcm7xx_adc_start_convert(s);
}
} else {
timer_del(&s->conv_timer);
}
}
}
static uint64_t npcm7xx_adc_read(void *opaque, hwaddr offset, unsigned size)
{
uint64_t value = 0;
NPCM7xxADCState *s = opaque;
switch (offset) {
case A_NPCM7XX_ADC_CON:
value = s->con;
break;
case A_NPCM7XX_ADC_DATA:
value = s->data;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid offset 0x%04" HWADDR_PRIx "\n",
__func__, offset);
break;
}
trace_npcm7xx_adc_read(DEVICE(s)->canonical_path, offset, value);
return value;
}
static void npcm7xx_adc_write(void *opaque, hwaddr offset, uint64_t v,
unsigned size)
{
NPCM7xxADCState *s = opaque;
trace_npcm7xx_adc_write(DEVICE(s)->canonical_path, offset, v);
switch (offset) {
case A_NPCM7XX_ADC_CON:
npcm7xx_adc_write_con(s, v);
break;
case A_NPCM7XX_ADC_DATA:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
__func__, offset);
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid offset 0x%04" HWADDR_PRIx "\n",
__func__, offset);
break;
}
}
static const struct MemoryRegionOps npcm7xx_adc_ops = {
.read = npcm7xx_adc_read,
.write = npcm7xx_adc_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4,
.unaligned = false,
},
};
static void npcm7xx_adc_enter_reset(Object *obj, ResetType type)
{
NPCM7xxADCState *s = NPCM7XX_ADC(obj);
npcm7xx_adc_reset(s);
}
static void npcm7xx_adc_hold_reset(Object *obj)
{
NPCM7xxADCState *s = NPCM7XX_ADC(obj);
qemu_irq_lower(s->irq);
}
static void npcm7xx_adc_init(Object *obj)
{
NPCM7xxADCState *s = NPCM7XX_ADC(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
int i;
sysbus_init_irq(sbd, &s->irq);
timer_init_ns(&s->conv_timer, QEMU_CLOCK_VIRTUAL,
npcm7xx_adc_convert_done, s);
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
TYPE_NPCM7XX_ADC, 4 * KiB);
sysbus_init_mmio(sbd, &s->iomem);
s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
object_property_add_uint32_ptr(obj, "adci[*]",
&s->adci[i], OBJ_PROP_FLAG_WRITE);
}
object_property_add_uint32_ptr(obj, "vref",
&s->vref, OBJ_PROP_FLAG_WRITE);
npcm7xx_adc_calibrate(s);
}
static const VMStateDescription vmstate_npcm7xx_adc = {
.name = "npcm7xx-adc",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_TIMER(conv_timer, NPCM7xxADCState),
VMSTATE_UINT32(con, NPCM7xxADCState),
VMSTATE_UINT32(data, NPCM7xxADCState),
VMSTATE_CLOCK(clock, NPCM7xxADCState),
VMSTATE_UINT32_ARRAY(adci, NPCM7xxADCState, NPCM7XX_ADC_NUM_INPUTS),
VMSTATE_UINT32(vref, NPCM7xxADCState),
VMSTATE_UINT32(iref, NPCM7xxADCState),
VMSTATE_UINT16_ARRAY(calibration_r_values, NPCM7xxADCState,
NPCM7XX_ADC_NUM_CALIB),
VMSTATE_END_OF_LIST(),
},
};
static Property npcm7xx_timer_properties[] = {
DEFINE_PROP_UINT32("iref", NPCM7xxADCState, iref, NPCM7XX_ADC_DEFAULT_IREF),
DEFINE_PROP_END_OF_LIST(),
};
static void npcm7xx_adc_class_init(ObjectClass *klass, void *data)
{
ResettableClass *rc = RESETTABLE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
dc->desc = "NPCM7xx ADC Module";
dc->vmsd = &vmstate_npcm7xx_adc;
rc->phases.enter = npcm7xx_adc_enter_reset;
rc->phases.hold = npcm7xx_adc_hold_reset;
device_class_set_props(dc, npcm7xx_timer_properties);
}
static const TypeInfo npcm7xx_adc_info = {
.name = TYPE_NPCM7XX_ADC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxADCState),
.class_init = npcm7xx_adc_class_init,
.instance_init = npcm7xx_adc_init,
};
static void npcm7xx_adc_register_types(void)
{
type_register_static(&npcm7xx_adc_info);
}
type_init(npcm7xx_adc_register_types);
+5
View File
@@ -0,0 +1,5 @@
# See docs/devel/tracing.txt for syntax documentation.
# npcm7xx_adc.c
npcm7xx_adc_read(const char *id, uint64_t offset, uint32_t value) " %s offset: 0x%04" PRIx64 " value 0x%04" PRIx32
npcm7xx_adc_write(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value 0x%04" PRIx32
+1
View File
@@ -0,0 +1 @@
#include "trace/trace-hw_adc.h"
+52 -3
View File
@@ -22,6 +22,7 @@
#include "hw/char/serial.h"
#include "hw/loader.h"
#include "hw/misc/unimp.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/units.h"
@@ -50,6 +51,9 @@
#define NPCM7XX_EHCI_BA (0xf0806000)
#define NPCM7XX_OHCI_BA (0xf0807000)
/* ADC Module */
#define NPCM7XX_ADC_BA (0xf000c000)
/* Internal AHB SRAM */
#define NPCM7XX_RAM3_BA (0xc0008000)
#define NPCM7XX_RAM3_SZ (4 * KiB)
@@ -60,6 +64,7 @@
#define NPCM7XX_ROM_BA (0xffff0000)
#define NPCM7XX_ROM_SZ (64 * KiB)
/* Clock configuration values to be fixed up when bypassing bootloader */
/* Run PLL1 at 1600 MHz */
@@ -72,6 +77,7 @@
* interrupts.
*/
enum NPCM7xxInterrupt {
NPCM7XX_ADC_IRQ = 0,
NPCM7XX_UART0_IRQ = 2,
NPCM7XX_UART1_IRQ,
NPCM7XX_UART2_IRQ,
@@ -96,6 +102,8 @@ enum NPCM7xxInterrupt {
NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
NPCM7XX_EHCI_IRQ = 61,
NPCM7XX_OHCI_IRQ = 62,
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
NPCM7XX_GPIO0_IRQ = 116,
NPCM7XX_GPIO1_IRQ,
NPCM7XX_GPIO2_IRQ,
@@ -138,6 +146,12 @@ static const hwaddr npcm7xx_fiu3_flash_addr[] = {
0xb8000000, /* CS3 */
};
/* Register base address for each PWM Module */
static const hwaddr npcm7xx_pwm_addr[] = {
0xf0103000,
0xf0104000,
};
static const struct {
hwaddr regs_addr;
uint32_t unconnected_pins;
@@ -295,6 +309,14 @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
sizeof(value));
}
static void npcm7xx_write_adc_calibration(NPCM7xxState *s)
{
/* Both ADC and the fuse array must have realized. */
QEMU_BUILD_BUG_ON(sizeof(s->adc.calibration_r_values) != 4);
npcm7xx_otp_array_write(&s->fuse_array, s->adc.calibration_r_values,
NPCM7XX_FUSE_ADC_CALIB, sizeof(s->adc.calibration_r_values));
}
static qemu_irq npcm7xx_irq(NPCM7xxState *s, int n)
{
return qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
@@ -321,6 +343,7 @@ static void npcm7xx_init(Object *obj)
TYPE_NPCM7XX_FUSE_ARRAY);
object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC);
object_initialize_child(obj, "rng", &s->rng, TYPE_NPCM7XX_RNG);
object_initialize_child(obj, "adc", &s->adc, TYPE_NPCM7XX_ADC);
for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
@@ -338,6 +361,10 @@ static void npcm7xx_init(Object *obj)
object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
TYPE_NPCM7XX_FIU);
}
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
}
}
static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -413,6 +440,15 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM7XX_MC_BA);
/* ADC Modules. Cannot fail. */
qdev_connect_clock_in(DEVICE(&s->adc), "clock", qdev_get_clock_out(
DEVICE(&s->clk), "adc-clock"));
sysbus_realize(SYS_BUS_DEVICE(&s->adc), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, NPCM7XX_ADC_BA);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
npcm7xx_irq(s, NPCM7XX_ADC_IRQ));
npcm7xx_write_adc_calibration(s);
/* Timer Modules (TIM). Cannot fail. */
QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
@@ -420,6 +456,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
int first_irq;
int j;
/* Connect the timer clock. */
qdev_connect_clock_in(DEVICE(&s->tim[i]), "clock", qdev_get_clock_out(
DEVICE(&s->clk), "timer-clock"));
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, npcm7xx_tim_addr[i]);
@@ -485,6 +525,18 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0,
npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));
/* PWM Modules. Cannot fail. */
QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm));
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]);
qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out(
DEVICE(&s->clk), "apb3-clock"));
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]);
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
}
/*
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
* specified, but this is a programming error.
@@ -523,7 +575,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB);
create_unimplemented_device("npcm7xx.adc", 0xf000c000, 4 * KiB);
create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB);
create_unimplemented_device("npcm7xx.gpio[0]", 0xf0010000, 4 * KiB);
create_unimplemented_device("npcm7xx.gpio[1]", 0xf0011000, 4 * KiB);
@@ -553,8 +604,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
create_unimplemented_device("npcm7xx.pwm[0]", 0xf0103000, 4 * KiB);
create_unimplemented_device("npcm7xx.pwm[1]", 0xf0104000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
+1 -1
View File
@@ -82,7 +82,7 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
uint32_t hw_straps)
{
NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
MachineClass *mc = &nmc->parent;
MachineClass *mc = MACHINE_CLASS(nmc);
Object *obj;
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
+1 -1
View File
@@ -62,7 +62,7 @@ static void npcm7xx_mc_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->mmio, OBJECT(s), &npcm7xx_mc_ops, s, "regs",
NPCM7XX_MC_REGS_SIZE);
sysbus_init_mmio(&s->parent, &s->mmio);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio);
}
static void npcm7xx_mc_class_init(ObjectClass *klass, void *data)
+1
View File
@@ -64,6 +64,7 @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
'npcm7xx_clk.c',
'npcm7xx_gcr.c',
'npcm7xx_pwm.c',
'npcm7xx_rng.c',
))
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files(
+795 -12
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -220,7 +220,7 @@ static void npcm7xx_gcr_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &npcm7xx_gcr_ops, s,
TYPE_NPCM7XX_GCR, 4 * KiB);
sysbus_init_mmio(&s->parent, &s->iomem);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}
static const VMStateDescription vmstate_npcm7xx_gcr = {
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -143,7 +143,7 @@ static void npcm7xx_rng_init(Object *obj)
memory_region_init_io(&s->iomem, obj, &npcm7xx_rng_ops, s, "regs",
NPCM7XX_RNG_REGS_SIZE);
sysbus_init_mmio(&s->parent, &s->iomem);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}
static const VMStateDescription vmstate_npcm7xx_rng = {
+6
View File
@@ -120,6 +120,12 @@ npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " valu
npcm7xx_rng_read(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
# npcm7xx_pwm.c
npcm7xx_pwm_read(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
npcm7xx_pwm_write(const char *id, uint64_t offset, uint32_t value) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
npcm7xx_pwm_update_freq(const char *id, uint8_t index, uint32_t old_value, uint32_t new_value) "%s pwm[%u] Update Freq: old_freq: %u, new_freq: %u"
npcm7xx_pwm_update_duty(const char *id, uint8_t index, uint32_t old_value, uint32_t new_value) "%s pwm[%u] Update Duty: old_duty: %u, new_duty: %u"
# stm32f4xx_syscfg.c
stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d"
stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
+19 -7
View File
@@ -40,6 +40,17 @@ do { hw_error("lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
#endif
/* The tx and rx fifo ports are a range of aliased 32-bit registers */
#define RX_DATA_FIFO_PORT_FIRST 0x00
#define RX_DATA_FIFO_PORT_LAST 0x1f
#define TX_DATA_FIFO_PORT_FIRST 0x20
#define TX_DATA_FIFO_PORT_LAST 0x3f
#define RX_STATUS_FIFO_PORT 0x40
#define RX_STATUS_FIFO_PEEK 0x44
#define TX_STATUS_FIFO_PORT 0x48
#define TX_STATUS_FIFO_PEEK 0x4c
#define CSR_ID_REV 0x50
#define CSR_IRQ_CFG 0x54
#define CSR_INT_STS 0x58
@@ -1020,7 +1031,8 @@ static void lan9118_writel(void *opaque, hwaddr offset,
offset &= 0xff;
//DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val);
if (offset >= 0x20 && offset < 0x40) {
if (offset >= TX_DATA_FIFO_PORT_FIRST &&
offset <= TX_DATA_FIFO_PORT_LAST) {
/* TX FIFO */
tx_fifo_push(s, val);
return;
@@ -1198,18 +1210,18 @@ static uint64_t lan9118_readl(void *opaque, hwaddr offset,
lan9118_state *s = (lan9118_state *)opaque;
//DPRINTF("Read reg 0x%02x\n", (int)offset);
if (offset < 0x20) {
if (offset <= RX_DATA_FIFO_PORT_LAST) {
/* RX FIFO */
return rx_fifo_pop(s);
}
switch (offset) {
case 0x40:
case RX_STATUS_FIFO_PORT:
return rx_status_fifo_pop(s);
case 0x44:
return s->rx_status_fifo[s->tx_status_fifo_head];
case 0x48:
case RX_STATUS_FIFO_PEEK:
return s->rx_status_fifo[s->rx_status_fifo_head];
case TX_STATUS_FIFO_PORT:
return tx_status_fifo_pop(s);
case 0x4c:
case TX_STATUS_FIFO_PEEK:
return s->tx_status_fifo[s->tx_status_fifo_head];
case CSR_ID_REV:
return 0x01180001;
+1 -1
View File
@@ -371,7 +371,7 @@ static void npcm7xx_otp_realize(DeviceState *dev, Error **errp)
{
NPCM7xxOTPClass *oc = NPCM7XX_OTP_GET_CLASS(dev);
NPCM7xxOTPState *s = NPCM7XX_OTP(dev);
SysBusDevice *sbd = &s->parent;
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
memset(s->array, 0, sizeof(s->array));
+1 -1
View File
@@ -498,7 +498,7 @@ static void npcm7xx_fiu_hold_reset(Object *obj)
static void npcm7xx_fiu_realize(DeviceState *dev, Error **errp)
{
NPCM7xxFIUState *s = NPCM7XX_FIU(dev);
SysBusDevice *sbd = &s->parent;
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
int i;
if (s->cs_count <= 0) {
+18 -21
View File
@@ -17,8 +17,8 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/misc/npcm7xx_clk.h"
#include "hw/timer/npcm7xx_timer.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
@@ -128,23 +128,18 @@ static uint32_t npcm7xx_tcsr_prescaler(uint32_t tcsr)
/* Convert a timer cycle count to a time interval in nanoseconds. */
static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
{
int64_t ns = count;
int64_t ticks = count;
ns *= NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ;
ns *= npcm7xx_tcsr_prescaler(t->tcsr);
ticks *= npcm7xx_tcsr_prescaler(t->tcsr);
return ns;
return clock_ticks_to_ns(t->ctrl->clock, ticks);
}
/* Convert a time interval in nanoseconds to a timer cycle count. */
static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
{
int64_t count;
count = ns / (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ);
count /= npcm7xx_tcsr_prescaler(t->tcsr);
return count;
return ns / clock_ticks_to_ns(t->ctrl->clock,
npcm7xx_tcsr_prescaler(t->tcsr));
}
static uint32_t npcm7xx_watchdog_timer_prescaler(const NPCM7xxWatchdogTimer *t)
@@ -166,8 +161,8 @@ static uint32_t npcm7xx_watchdog_timer_prescaler(const NPCM7xxWatchdogTimer *t)
static void npcm7xx_watchdog_timer_reset_cycles(NPCM7xxWatchdogTimer *t,
int64_t cycles)
{
uint32_t prescaler = npcm7xx_watchdog_timer_prescaler(t);
int64_t ns = (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ) * cycles;
int64_t ticks = cycles * npcm7xx_watchdog_timer_prescaler(t);
int64_t ns = clock_ticks_to_ns(t->ctrl->clock, ticks);
/*
* The reset function always clears the current timer. The caller of the
@@ -176,7 +171,6 @@ static void npcm7xx_watchdog_timer_reset_cycles(NPCM7xxWatchdogTimer *t,
*/
npcm7xx_timer_clear(&t->base_timer);
ns *= prescaler;
t->base_timer.remaining_ns = ns;
}
@@ -606,10 +600,11 @@ static void npcm7xx_timer_hold_reset(Object *obj)
qemu_irq_lower(s->watchdog_timer.irq);
}
static void npcm7xx_timer_realize(DeviceState *dev, Error **errp)
static void npcm7xx_timer_init(Object *obj)
{
NPCM7xxTimerCtrlState *s = NPCM7XX_TIMER(dev);
SysBusDevice *sbd = &s->parent;
NPCM7xxTimerCtrlState *s = NPCM7XX_TIMER(obj);
DeviceState *dev = DEVICE(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
int i;
NPCM7xxWatchdogTimer *w;
@@ -627,11 +622,12 @@ static void npcm7xx_timer_realize(DeviceState *dev, Error **errp)
npcm7xx_watchdog_timer_expired, w);
sysbus_init_irq(sbd, &w->irq);
memory_region_init_io(&s->iomem, OBJECT(s), &npcm7xx_timer_ops, s,
memory_region_init_io(&s->iomem, obj, &npcm7xx_timer_ops, s,
TYPE_NPCM7XX_TIMER, 4 * KiB);
sysbus_init_mmio(sbd, &s->iomem);
qdev_init_gpio_out_named(dev, &w->reset_signal,
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
}
static const VMStateDescription vmstate_npcm7xx_base_timer = {
@@ -675,10 +671,11 @@ static const VMStateDescription vmstate_npcm7xx_watchdog_timer = {
static const VMStateDescription vmstate_npcm7xx_timer_ctrl = {
.name = "npcm7xx-timer-ctrl",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32(tisr, NPCM7xxTimerCtrlState),
VMSTATE_CLOCK(clock, NPCM7xxTimerCtrlState),
VMSTATE_STRUCT_ARRAY(timer, NPCM7xxTimerCtrlState,
NPCM7XX_TIMERS_PER_CTRL, 0, vmstate_npcm7xx_timer,
NPCM7xxTimer),
@@ -697,7 +694,6 @@ static void npcm7xx_timer_class_init(ObjectClass *klass, void *data)
QEMU_BUILD_BUG_ON(NPCM7XX_TIMER_REGS_END > NPCM7XX_TIMER_NR_REGS);
dc->desc = "NPCM7xx Timer Controller";
dc->realize = npcm7xx_timer_realize;
dc->vmsd = &vmstate_npcm7xx_timer_ctrl;
rc->phases.enter = npcm7xx_timer_enter_reset;
rc->phases.hold = npcm7xx_timer_hold_reset;
@@ -708,6 +704,7 @@ static const TypeInfo npcm7xx_timer_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxTimerCtrlState),
.class_init = npcm7xx_timer_class_init,
.instance_init = npcm7xx_timer_init,
};
static void npcm7xx_timer_register_type(void)
+69
View File
@@ -0,0 +1,69 @@
/*
* Nuvoton NPCM7xx ADC 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_ADC_H
#define NPCM7XX_ADC_H
#include "hw/clock.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
#define NPCM7XX_ADC_NUM_INPUTS 8
/**
* This value should not be changed unless write_adc_calibration function in
* hw/arm/npcm7xx.c is also changed.
*/
#define NPCM7XX_ADC_NUM_CALIB 2
/**
* struct NPCM7xxADCState - Analog to Digital Converter Module device state.
* @parent: System bus device.
* @iomem: Memory region through which registers are accessed.
* @conv_timer: The timer counts down remaining cycles for the conversion.
* @irq: GIC interrupt line to fire on expiration (if enabled).
* @con: The Control Register.
* @data: The Data Buffer.
* @clock: The ADC Clock.
* @adci: The input voltage in units of uV. 1uv = 1e-6V.
* @vref: The external reference voltage.
* @iref: The internal reference voltage, initialized at launch time.
* @rv: The calibrated output values of 0.5V and 1.5V for the ADC.
*/
typedef struct {
SysBusDevice parent;
MemoryRegion iomem;
QEMUTimer conv_timer;
qemu_irq irq;
uint32_t con;
uint32_t data;
Clock *clock;
/* Voltages are in unit of uV. 1V = 1000000uV. */
uint32_t adci[NPCM7XX_ADC_NUM_INPUTS];
uint32_t vref;
uint32_t iref;
uint16_t calibration_r_values[NPCM7XX_ADC_NUM_CALIB];
} NPCM7xxADCState;
#define TYPE_NPCM7XX_ADC "npcm7xx-adc"
#define NPCM7XX_ADC(obj) \
OBJECT_CHECK(NPCM7xxADCState, (obj), TYPE_NPCM7XX_ADC)
#endif /* NPCM7XX_ADC_H */

Some files were not shown because too many files have changed in this diff Show More