[PATCH v4 3/6] Add i.MX6UL missing devices.

2023-08-25 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add 4 missing PWM devices

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/fsl-imx6ul.c | 16 
 include/hw/arm/fsl-imx6ul.h |  2 +-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 06a32aff64..e37b69a5e1 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -583,6 +583,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX6UL_PWM2_ADDR,
 FSL_IMX6UL_PWM3_ADDR,
 FSL_IMX6UL_PWM4_ADDR,
+FSL_IMX6UL_PWM5_ADDR,
+FSL_IMX6UL_PWM6_ADDR,
+FSL_IMX6UL_PWM7_ADDR,
+FSL_IMX6UL_PWM8_ADDR,
 };
 
 snprintf(name, NAME_SIZE, "pwm%d", i);
@@ -636,6 +640,18 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
 FSL_IMX6UL_LCDIF_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
+FSL_IMX6UL_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
+FSL_IMX6UL_TZASC_SIZE);
+
 /*
  * ROM memory
  */
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
index f7bf684b42..63012628ff 100644
--- a/include/hw/arm/fsl-imx6ul.h
+++ b/include/hw/arm/fsl-imx6ul.h
@@ -60,7 +60,7 @@ enum FslIMX6ULConfiguration {
 FSL_IMX6UL_NUM_USBS = 2,
 FSL_IMX6UL_NUM_SAIS = 3,
 FSL_IMX6UL_NUM_CANS = 2,
-FSL_IMX6UL_NUM_PWMS = 4,
+FSL_IMX6UL_NUM_PWMS = 8,
 };
 
 struct FslIMX6ULState {
-- 
2.34.1




[PATCH v4 5/6] Add i.MX7 missing TZ devices and memory regions

2023-08-25 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add various memory segments
  - OCRAM
  - OCRAM EPDC
  - OCRAM PXP
  - OCRAM S
  - ROM
  - CAAM

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/fsl-imx7.c | 63 +++
 include/hw/arm/fsl-imx7.h |  7 +
 2 files changed, 70 insertions(+)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index e976053539..97e982bf06 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -664,6 +664,69 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
 FSL_IMX7_PCIE_PHY_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
+FSL_IMX7_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
+FSL_IMX7_TZASC_SIZE);
+
+/*
+ * OCRAM memory
+ */
+memory_region_init_ram(>ocram, NULL, "imx7.ocram",
+   FSL_IMX7_OCRAM_MEM_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
+>ocram);
+
+/*
+ * OCRAM EPDC memory
+ */
+memory_region_init_ram(>ocram_epdc, NULL, "imx7.ocram_epdc",
+   FSL_IMX7_OCRAM_EPDC_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
+>ocram_epdc);
+
+/*
+ * OCRAM PXP memory
+ */
+memory_region_init_ram(>ocram_pxp, NULL, "imx7.ocram_pxp",
+   FSL_IMX7_OCRAM_PXP_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
+>ocram_pxp);
+
+/*
+ * OCRAM_S memory
+ */
+memory_region_init_ram(>ocram_s, NULL, "imx7.ocram_s",
+   FSL_IMX7_OCRAM_S_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
+>ocram_s);
+
+/*
+ * ROM memory
+ */
+memory_region_init_rom(>rom, OBJECT(dev), "imx7.rom",
+   FSL_IMX7_ROM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
+>rom);
+
+/*
+ * CAAM memory
+ */
+memory_region_init_rom(>caam, OBJECT(dev), "imx7.caam",
+   FSL_IMX7_CAAM_MEM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
+>caam);
 }
 
 static Property fsl_imx7_properties[] = {
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 06b2c5e4ac..01e15004d7 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -84,6 +84,13 @@ struct FslIMX7State {
 IMX7GPRState   gpr;
 ChipideaState  usb[FSL_IMX7_NUM_USBS];
 DesignwarePCIEHost pcie;
+MemoryRegion   rom;
+MemoryRegion   caam;
+MemoryRegion   ocram;
+MemoryRegion   ocram_epdc;
+MemoryRegion   ocram_pxp;
+MemoryRegion   ocram_s;
+
 uint32_t   phy_num[FSL_IMX7_NUM_ETHS];
 bool   phy_connected[FSL_IMX7_NUM_ETHS];
 };
-- 
2.34.1




[PATCH v4 6/6] Add i.MX7 SRC device implementation

2023-08-25 Thread Jean-Christophe Dubois
The SRC device is normally used to start the secondary CPU.

When running Linux directly, QEMU is emulating a PSCI interface that UBOOT
is installing at boot time and therefore the fact that the SRC device is
unimplemented is hidden as Qemu respond directly to PSCI requets without
using the SRC device.

But if you try to run a more bare metal application (maybe uboot itself),
then it is not possible to start the secondary CPU as the SRC is an
unimplemented device.

This patch adds the ability to start the secondary CPU through the SRC
device so that you can use this feature in bare metal applications.

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Peter Maydell 
---
 hw/arm/fsl-imx7.c  |   8 +-
 hw/misc/imx7_src.c | 276 +
 hw/misc/meson.build|   1 +
 hw/misc/trace-events   |   4 +
 include/hw/arm/fsl-imx7.h  |   3 +-
 include/hw/misc/imx7_src.h |  66 +
 6 files changed, 356 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 97e982bf06..474cfdc87c 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -82,6 +82,11 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * SRC
+ */
+object_initialize_child(obj, "src", >src, TYPE_IMX7_SRC);
+
 /*
  * ECSPIs
  */
@@ -488,7 +493,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 /*
  * SRC
  */
-create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
+sysbus_realize(SYS_BUS_DEVICE(>src), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>src), 0, FSL_IMX7_SRC_ADDR);
 
 /*
  * Watchdogs
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
new file mode 100644
index 00..983251e86f
--- /dev/null
+++ b/hw/misc/imx7_src.c
@@ -0,0 +1,276 @@
+/*
+ * IMX7 System Reset Controller
+ *
+ * Copyright (c) 2023 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_src.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "target/arm/arm-powerctl.h"
+#include "hw/core/cpu.h"
+#include "hw/registerfields.h"
+
+#include "trace.h"
+
+static const char *imx7_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_A7RCR0:
+return "SRC_A7RCR0";
+case SRC_A7RCR1:
+return "SRC_A7RCR1";
+case SRC_M4RCR:
+return "SRC_M4RCR";
+case SRC_ERCR:
+return "SRC_ERCR";
+case SRC_HSICPHY_RCR:
+return "SRC_HSICPHY_RCR";
+case SRC_USBOPHY1_RCR:
+return "SRC_USBOPHY1_RCR";
+case SRC_USBOPHY2_RCR:
+return "SRC_USBOPHY2_RCR";
+case SRC_PCIEPHY_RCR:
+return "SRC_PCIEPHY_RCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%u ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx7_src = {
+.name = TYPE_IMX7_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx7_src_reset(DeviceState *dev)
+{
+IMX7SRCState *s = IMX7_SRC(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+
+/* Set reset values */
+s->regs[SRC_SCR] = 0xA0;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static uint64_t imx7_src_read(void *opaque, hwaddr offset, unsigned size)
+{
+u

[PATCH v4 2/6] Refactor i.MX6UL processor code

2023-08-25 Thread Jean-Christophe Dubois
* Add Addr and size definition for most i.MX6UL devices in i.MX6UL header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 147 
 include/hw/arm/fsl-imx6ul.h | 134 +---
 2 files changed, 221 insertions(+), 60 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 0fdd2782ba..06a32aff64 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -64,7 +64,7 @@ static void fsl_imx6ul_init(Object *obj)
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
 /*
- * GPIOs 1 to 5
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -72,7 +72,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -80,7 +80,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 snprintf(name, NAME_SIZE, "epit%d", i + 1);
@@ -88,7 +88,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * eCSPI
+ * eCSPIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
@@ -96,7 +96,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * I2C
+ * I2Cs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
@@ -104,7 +104,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -112,25 +112,31 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
 object_initialize_child(obj, name, >eth[i], TYPE_IMX_ENET);
 }
 
-/* USB */
+/*
+ * USB PHYs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
 snprintf(name, NAME_SIZE, "usbphy%d", i);
 object_initialize_child(obj, name, >usbphy[i], TYPE_IMX_USBPHY);
 }
+
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -138,7 +144,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -184,10 +190,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX6UL_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
@@ -212,7 +218,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
@@ -237,7 +243,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * GPIO
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
@@ -279,17 +285,12 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * IOMUXC and IOMUXC_GPR
+ * IOMUXC
  */
-for (i = 0; i < 1; i++) {
-static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
-FSL_IMX6UL_IOMUXC_ADDR,
-FSL_IMX6UL_IOMUXC_GPR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
-}
+create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
+FSL_IMX6UL_IOMUXC_SIZE);
+create_unimplemented_device("iomuxc_gpr"

[PATCH v4 4/6] Refactor i.MX7 processor code

2023-08-25 Thread Jean-Christophe Dubois
* Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 130 ++-
 include/hw/arm/fsl-imx7.h | 326 --
 2 files changed, 333 insertions(+), 123 deletions(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 9e41d4b677..e976053539 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -36,6 +36,9 @@ static void fsl_imx7_init(Object *obj)
 char name[NAME_SIZE];
 int i;
 
+/*
+ * CPUs
+ */
 for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
 snprintf(name, NAME_SIZE, "cpu%d", i);
 object_initialize_child(obj, name, >cpu[i],
@@ -49,7 +52,7 @@ static void fsl_imx7_init(Object *obj)
 TYPE_A15MPCORE_PRIV);
 
 /*
- * GPIOs 1 to 7
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -57,7 +60,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -79,19 +82,24 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * ECSPIs
+ */
 for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
 object_initialize_child(obj, name, >spi[i], TYPE_IMX_SPI);
 }
 
-
+/*
+ * I2Cs
+ */
 for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
 object_initialize_child(obj, name, >i2c[i], TYPE_IMX_I2C);
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -99,7 +107,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
@@ -107,7 +115,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -120,7 +128,7 @@ static void fsl_imx7_init(Object *obj)
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -132,8 +140,14 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
+/*
+ * PCIE
+ */
 object_initialize_child(obj, "pcie", >pcie, TYPE_DESIGNWARE_PCIE_HOST);
 
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
@@ -156,6 +170,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 return;
 }
 
+/*
+ * CPUs
+ */
 for (i = 0; i < smp_cpus; i++) {
 o = OBJECT(>cpu[i]);
 
@@ -206,10 +223,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX7_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
@@ -234,6 +251,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_GPTn_IRQ[i]));
 }
 
+/*
+ * GPIOs
+ */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
 FSL_IMX7_GPIO1_ADDR,
@@ -281,16 +301,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 /*
  * IOMUXC and IOMUXC_LPSR
  */
-for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
-static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
-FSL_IMX7_IOMUXC_ADDR,
-FSL_IMX7_IOMUXC_LPSR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
- 

[PATCH v4 1/6] Remove i.MX7 IOMUX GPR device from i.MX6UL

2023-08-25 Thread Jean-Christophe Dubois
i.MX7 IOMUX GPR device is not equivalent to i.MX6UL IOMUXC GPR device.
In particular, register 22 is not present on i.MX6UL and this is actualy
The only register that is really emulated in the i.MX7 IOMUX GPR device.

Note: The i.MX6UL code is actually also implementing the IOMUX GPR device
as an unimplemented device at the same bus adress and the 2 instantiations
were actualy colliding. So we go back to the unimplemented device for now.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 11 ---
 include/hw/arm/fsl-imx6ul.h |  2 --
 2 files changed, 13 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 2189dcbb72..0fdd2782ba 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -63,11 +63,6 @@ static void fsl_imx6ul_init(Object *obj)
  */
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
-/*
- * GPR
- */
-object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
-
 /*
  * GPIOs 1 to 5
  */
@@ -537,12 +532,6 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX6UL_WDOGn_IRQ[i]));
 }
 
-/*
- * GPR
- */
-sysbus_realize(SYS_BUS_DEVICE(>gpr), _abort);
-sysbus_mmio_map(SYS_BUS_DEVICE(>gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
-
 /*
  * SDMA
  */
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
index 9ee15ae38d..3bec6bb3fb 100644
--- a/include/hw/arm/fsl-imx6ul.h
+++ b/include/hw/arm/fsl-imx6ul.h
@@ -22,7 +22,6 @@
 #include "hw/misc/imx6ul_ccm.h"
 #include "hw/misc/imx6_src.h"
 #include "hw/misc/imx7_snvs.h"
-#include "hw/misc/imx7_gpr.h"
 #include "hw/intc/imx_gpcv2.h"
 #include "hw/watchdog/wdt_imx2.h"
 #include "hw/gpio/imx_gpio.h"
@@ -74,7 +73,6 @@ struct FslIMX6ULState {
 IMX6SRCState   src;
 IMX7SNVSState  snvs;
 IMXGPCv2State  gpcv2;
-IMX7GPRState   gpr;
 IMXSPIStatespi[FSL_IMX6UL_NUM_ECSPIS];
 IMXI2CStatei2c[FSL_IMX6UL_NUM_I2CS];
 IMXSerialState uart[FSL_IMX6UL_NUM_UARTS];
-- 
2.34.1




[PATCH v4 0/6] Complete i.MX6UL and i.MX7 processor for bare metal application.

2023-08-25 Thread Jean-Christophe Dubois
This patch adds a few unimplemented TZ devices (TZASC and CSU) to
i.MX6UL and i.MX7 processors to avoid bare metal application to
experiment "bus error" when acccessing these devices.

It also adds some internal memory segments (OCRAM) to the i.MX7 to
allow bare metal application to use them.

Last, it adds the SRC device to the i.MX7 processor to allow bare
metal application to start the secondary Cortex-A7 core.

Note: When running Linux inside Qemu, the secondary core is started
by calling PSCI API and Qemu is emulating PSCI without needing access
to the SRC device. This is why Linux is using the 2 cores in Qemu
even if the SRC is not implemented. This is not the case when running
bare metal application (like u-boot itself) that do not rely on the
PSCI service being available.

Changes since v3:
* Add a specific patch to remove IOMUXC GPR device from i.MX6UL
* remove unimplemented IOMUXC GPR device frome i.MX7D
* move the initialisation of PWM devices 5 to 8 to 3rd patch
* put the init of i.MX7d devices in previous order to ease review
* Remove device memory size from header file when the device is actually
  implemented in QEMU (the device implementation defines the memory
  size it manages).

Changes since v2:
* use GiB, MiB, KiB constant defined in qemu/units.h after code review

Changes since v1:
* split the i.MX6UL patch into a refactor patch and an addon patch.
* Split the i.MX7 patch into a refactor patch and an addon patch.
* Fix SRC code after few comments in code review.

Jean-Christophe Dubois (6):
  Remove i.MX7 IOMUX GPR device from i.MX6UL
  Refactor i.MX6UL processor code
  Add i.MX6UL missing devices.
  Refactor i.MX7 processor code
  Add i.MX7 missing TZ devices and memory regions
  Add i.MX7 SRC device implementation

 hw/arm/fsl-imx6ul.c | 174 ---
 hw/arm/fsl-imx7.c   | 201 +-
 hw/misc/imx7_src.c  | 276 +
 hw/misc/meson.build |   1 +
 hw/misc/trace-events|   4 +
 include/hw/arm/fsl-imx6ul.h | 136 +--
 include/hw/arm/fsl-imx7.h   | 334 +++-
 include/hw/misc/imx7_src.h  |  66 +++
 8 files changed, 995 insertions(+), 197 deletions(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

-- 
2.34.1




Re: [PATCH v3 1/5] Refactor i.MX6UL processor code

2023-08-03 Thread Jean-Christophe DUBOIS

Le 02/08/2023 à 23:32, Philippe Mathieu-Daudé a écrit :

Hi Jean-Christophe,

On 2/8/23 23:08, Jean-Christophe Dubois wrote:
* Add Addr and size definition for all i.MX6UL devices in i.MX6UL 
header file.


I'm OK with your patch, but some addr/size are added, while other
are changed. It is hard to review. Having one patch for changes
and another for additions would help review.


I tried to set addresses and sizes following the order set for devices 
in the i.MX6UL reference manual. I found it easier to follow then (and 
make reasonably sure I didn't miss some).


I certainly understand that the reorder is annoying for the review. I 
can try to do as you intended but I am not sure the reorder review would 
be really easier.





* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
   - SAI
   - PWM (add missing PWM instances)
   - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
  hw/arm/fsl-imx6ul.c | 149 +++
  include/hw/arm/fsl-imx6ul.h | 150 +---
  2 files changed, 240 insertions(+), 59 deletions(-)




diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
index 9ee15ae38d..5d381740ef 100644
--- a/include/hw/arm/fsl-imx6ul.h
+++ b/include/hw/arm/fsl-imx6ul.h


For example here:


+    FSL_IMX6UL_SNVS_HP_SIZE = (4 * KiB),
+
  FSL_IMX6UL_USBPHY2_ADDR = 0x020CA000,
-    FSL_IMX6UL_USBPHY2_SIZE = (4 * 1024),



-    FSL_IMX6UL_USBPHY1_SIZE = (4 * 1024),
+    FSL_IMX6UL_USBPHYn_SIZE = 0x100,


Don't we also need:


Well, I did not modify the i.MX USB PHY file by itself. It is a fact 
that the last i.MX USB PHY register is at 0x80 offset and a 0x1000 
memory region for the device is certainly oversized even if the 
processor memory map is actually provisioning a 0x1000 address space 
between distinct USB PHY devices.  My intent in lowering the device 
register region size as close to the real size as possible was that in 
case a device was not "implemented" in Qemu we could just map it as an 
unimplemented device (allowing dummy access to the register range) but 
get some kind of platform "bus error" if the software was trying to 
access some "registers" in the upper part of the memory region (as you 
would on the real hardware?).


So 0x1000 is not wrong per se as the USB phy device implementation code 
is logging the illegal access when software is doing access over 0x80 
offset. This would just not trigger a processor hardware access fault 
(when it could/should?).




-- >8 --
--- a/hw/usb/imx-usb-phy.c
+++ b/hw/usb/imx-usb-phy.c
@@ -210,7 +210,7 @@ static void imx_usbphy_realize(DeviceState *dev, 
Error **errp)

 IMXUSBPHYState *s = IMX_USBPHY(dev);

 memory_region_init_io(>iomem, OBJECT(s), _usbphy_ops, s,
-  "imx-usbphy", 0x1000);
+  "imx-usbphy", 0x100);
 sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
 }

---

?

Thanks,

Phil.






[PATCH v3 3/5] Refactor i.MX7 processor code

2023-08-02 Thread Jean-Christophe Dubois
* Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 134 ++-
 include/hw/arm/fsl-imx7.h | 340 --
 2 files changed, 350 insertions(+), 124 deletions(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 9e41d4b677..3bb0da6850 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -36,6 +36,9 @@ static void fsl_imx7_init(Object *obj)
 char name[NAME_SIZE];
 int i;
 
+/*
+ * CPUs
+ */
 for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
 snprintf(name, NAME_SIZE, "cpu%d", i);
 object_initialize_child(obj, name, >cpu[i],
@@ -49,7 +52,7 @@ static void fsl_imx7_init(Object *obj)
 TYPE_A15MPCORE_PRIV);
 
 /*
- * GPIOs 1 to 7
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -57,7 +60,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -79,19 +82,24 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * ECSPIs
+ */
 for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
 object_initialize_child(obj, name, >spi[i], TYPE_IMX_SPI);
 }
 
-
+/*
+ * I2Cs
+ */
 for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
 object_initialize_child(obj, name, >i2c[i], TYPE_IMX_I2C);
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -99,7 +107,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
@@ -107,7 +115,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -120,7 +128,7 @@ static void fsl_imx7_init(Object *obj)
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -132,8 +140,14 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
+/*
+ * PCIE
+ */
 object_initialize_child(obj, "pcie", >pcie, TYPE_DESIGNWARE_PCIE_HOST);
 
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
@@ -156,6 +170,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 return;
 }
 
+/*
+ * CPUs
+ */
 for (i = 0; i < smp_cpus; i++) {
 o = OBJECT(>cpu[i]);
 
@@ -206,10 +223,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX7_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
@@ -234,6 +251,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_GPTn_IRQ[i]));
 }
 
+/*
+ * GPIOs
+ */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
 FSL_IMX7_GPIO1_ADDR,
@@ -279,18 +299,14 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * IOMUXC and IOMUXC_LPSR
+ * IOMUXC, IOMUXC_GPR and IOMUXC_LPSR
  */
-for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
-static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
-FSL_IMX7_IOMUXC_ADDR,
-FSL_IMX7_IOMUXC_LPSR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
-

[PATCH v3 2/5] Add i.MX6UL TZ missing devices.

2023-08-02 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 910316b628..0811163ddd 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -651,6 +651,18 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
 FSL_IMX6UL_LCDIF_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
+FSL_IMX6UL_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
+FSL_IMX6UL_TZASC_SIZE);
+
 /*
  * ROM memory
  */
-- 
2.34.1




[PATCH v3 5/5] Add i.MX7 SRC device implementation

2023-08-02 Thread Jean-Christophe Dubois
The SRC device is normaly used to start the secondary CPU.

When running Linux directly, Qemu is emulating a PSCI interface that UBOOT
is installing at boot time and therefore the fact that the SRC device is
unimplemented is hidden as Qemu respond directly to PSCI requets without
using the SRC device.

But if you try to run a more bare metal application (maybe uboot itself),
then it is not possible to start the secondary CPU as the SRC is an
unimplemented device.

This patch adds the ability to start the secondary CPU through the SRC
device so that you can use this feature in bare metal application.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c  |   8 +-
 hw/misc/imx7_src.c | 276 +
 hw/misc/meson.build|   1 +
 hw/misc/trace-events   |   4 +
 include/hw/arm/fsl-imx7.h  |   2 +
 include/hw/misc/imx7_src.h |  66 +
 6 files changed, 356 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 7ca105fd24..e7fe4f808e 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -82,6 +82,11 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * SRC
+ */
+object_initialize_child(obj, "src", >src, TYPE_IMX7_SRC);
+
 /*
  * ECSPIs
  */
@@ -490,7 +495,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 /*
  * SRC
  */
-create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
+sysbus_realize(SYS_BUS_DEVICE(>src), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>src), 0, FSL_IMX7_SRC_ADDR);
 
 /*
  * Watchdogs
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
new file mode 100644
index 00..983251e86f
--- /dev/null
+++ b/hw/misc/imx7_src.c
@@ -0,0 +1,276 @@
+/*
+ * IMX7 System Reset Controller
+ *
+ * Copyright (c) 2023 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_src.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "target/arm/arm-powerctl.h"
+#include "hw/core/cpu.h"
+#include "hw/registerfields.h"
+
+#include "trace.h"
+
+static const char *imx7_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_A7RCR0:
+return "SRC_A7RCR0";
+case SRC_A7RCR1:
+return "SRC_A7RCR1";
+case SRC_M4RCR:
+return "SRC_M4RCR";
+case SRC_ERCR:
+return "SRC_ERCR";
+case SRC_HSICPHY_RCR:
+return "SRC_HSICPHY_RCR";
+case SRC_USBOPHY1_RCR:
+return "SRC_USBOPHY1_RCR";
+case SRC_USBOPHY2_RCR:
+return "SRC_USBOPHY2_RCR";
+case SRC_PCIEPHY_RCR:
+return "SRC_PCIEPHY_RCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%u ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx7_src = {
+.name = TYPE_IMX7_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx7_src_reset(DeviceState *dev)
+{
+IMX7SRCState *s = IMX7_SRC(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+
+/* Set reset values */
+s->regs[SRC_SCR] = 0xA0;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static uint64_t imx7_src_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t value = 0;
+IMX7SRCState *s = (IMX7SRCSta

[PATCH v3 0/5] Complete i.MX6UL and i.MX7 processor for bare metal application.

2023-08-02 Thread Jean-Christophe Dubois
This patch adds a few unimplemented TZ devices (TZASC and CSU) to
i.MX6UL and i.MX7 processors to avoid bare metal application to
experiment "bus error" when acccessing these devices.

It also adds some internal memory segments (OCRAM) to the i.MX7 to
allow bare metal application to use them.

Last, it adds the SRC device to the i.MX7 processor to allow bare
metal application to start the secondary Cortex-A7 core.

Note: When running Linux inside Qemu, the secondary core is started
by calling PSCI API and Qemu is emulating PSCI without needing access
to the SRC device. This is why Linux is using the 2 cores in Qemu
even if the SRC is not implemented. This is not the case when running
bare metal application (like u-boot itself) that do not rely on the
PSCI service being available.

Changes since v2:
* use GiB, MiB, KiB constant defined in qemu/units.h after code review

Changes since v1:
* split the i.MX6UL patch into a refactor patch and an addon patch.
* Split the i.MX7 patch into a refactor patch and an addon patch.
* Fix SRC code after few comments in code review.

Jean-Christophe Dubois (5):
  Refactor i.MX6UL processor code
  Add i.MX6UL TZ missing devices.
  Refactor i.MX7 processor code
  Add i.MX7 missing TZ devices and memory regions
  Add i.MX7 SRC device implementation

 hw/arm/fsl-imx6ul.c | 161 -
 hw/arm/fsl-imx7.c   | 205 -
 hw/misc/imx7_src.c  | 276 
 hw/misc/meson.build |   1 +
 hw/misc/trace-events|   4 +
 include/hw/arm/fsl-imx6ul.h | 150 ++--
 include/hw/arm/fsl-imx7.h   | 349 +++-
 include/hw/misc/imx7_src.h  |  66 +++
 8 files changed, 1028 insertions(+), 184 deletions(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

-- 
2.34.1




[PATCH v3 4/5] Add i.MX7 missing TZ devices and memory regions

2023-08-02 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add various memory segments
  - OCRAM
  - OCRAM EPDC
  - OCRAM PXP
  - OCRAM S
  - ROM
  - CAAM

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 63 +++
 include/hw/arm/fsl-imx7.h |  7 +
 2 files changed, 70 insertions(+)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 3bb0da6850..7ca105fd24 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -666,6 +666,69 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
 FSL_IMX7_PCIE_PHY_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
+FSL_IMX7_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
+FSL_IMX7_TZASC_SIZE);
+
+/*
+ * OCRAM memory
+ */
+memory_region_init_ram(>ocram, NULL, "imx7.ocram",
+   FSL_IMX7_OCRAM_MEM_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
+>ocram);
+
+/*
+ * OCRAM EPDC memory
+ */
+memory_region_init_ram(>ocram_epdc, NULL, "imx7.ocram_epdc",
+   FSL_IMX7_OCRAM_EPDC_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
+>ocram_epdc);
+
+/*
+ * OCRAM PXP memory
+ */
+memory_region_init_ram(>ocram_pxp, NULL, "imx7.ocram_pxp",
+   FSL_IMX7_OCRAM_PXP_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
+>ocram_pxp);
+
+/*
+ * OCRAM_S memory
+ */
+memory_region_init_ram(>ocram_s, NULL, "imx7.ocram_s",
+   FSL_IMX7_OCRAM_S_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
+>ocram_s);
+
+/*
+ * ROM memory
+ */
+memory_region_init_rom(>rom, OBJECT(dev), "imx7.rom",
+   FSL_IMX7_ROM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
+>rom);
+
+/*
+ * CAAM memory
+ */
+memory_region_init_rom(>caam, OBJECT(dev), "imx7.caam",
+   FSL_IMX7_CAAM_MEM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
+>caam);
 }
 
 static Property fsl_imx7_properties[] = {
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 9a7cc4e366..629c385987 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -84,6 +84,13 @@ struct FslIMX7State {
 IMX7GPRState   gpr;
 ChipideaState  usb[FSL_IMX7_NUM_USBS];
 DesignwarePCIEHost pcie;
+MemoryRegion   rom;
+MemoryRegion   caam;
+MemoryRegion   ocram;
+MemoryRegion   ocram_epdc;
+MemoryRegion   ocram_pxp;
+MemoryRegion   ocram_s;
+
 uint32_t   phy_num[FSL_IMX7_NUM_ETHS];
 bool   phy_connected[FSL_IMX7_NUM_ETHS];
 };
-- 
2.34.1




[PATCH v3 1/5] Refactor i.MX6UL processor code

2023-08-02 Thread Jean-Christophe Dubois
* Add Addr and size definition for all i.MX6UL devices in i.MX6UL header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM (add missing PWM instances)
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 149 +++
 include/hw/arm/fsl-imx6ul.h | 150 +---
 2 files changed, 240 insertions(+), 59 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 2189dcbb72..910316b628 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -69,7 +69,7 @@ static void fsl_imx6ul_init(Object *obj)
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
 /*
- * GPIOs 1 to 5
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -77,7 +77,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -85,7 +85,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 snprintf(name, NAME_SIZE, "epit%d", i + 1);
@@ -93,7 +93,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * eCSPI
+ * eCSPIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
@@ -101,7 +101,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * I2C
+ * I2Cs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
@@ -109,7 +109,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -117,25 +117,31 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
 object_initialize_child(obj, name, >eth[i], TYPE_IMX_ENET);
 }
 
-/* USB */
+/*
+ * USB PHYs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
 snprintf(name, NAME_SIZE, "usbphy%d", i);
 object_initialize_child(obj, name, >usbphy[i], TYPE_IMX_USBPHY);
 }
+
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -143,7 +149,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -189,10 +195,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX6UL_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
@@ -217,7 +223,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
@@ -242,7 +248,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * GPIO
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
@@ -286,15 +292,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 /*
  * IOMUXC and IOMUXC_GPR
  */
-for (i = 0; i < 1; i++) {
-static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
-FSL_IMX6UL_IOMUXC_ADDR,
-FSL_IMX6UL_IOMUXC_GPR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
-}
+create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
+FSL_IMX6UL_IOMUXC_SIZE);
+create_unimplemented_device("iomuxc_gpr"

[PATCH v2 3/5] Refactor i.MX7 processor code

2023-07-29 Thread Jean-Christophe Dubois
 Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 134 ++-
 include/hw/arm/fsl-imx7.h | 339 --
 2 files changed, 349 insertions(+), 124 deletions(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 9e41d4b677..3bb0da6850 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -36,6 +36,9 @@ static void fsl_imx7_init(Object *obj)
 char name[NAME_SIZE];
 int i;
 
+/*
+ * CPUs
+ */
 for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
 snprintf(name, NAME_SIZE, "cpu%d", i);
 object_initialize_child(obj, name, >cpu[i],
@@ -49,7 +52,7 @@ static void fsl_imx7_init(Object *obj)
 TYPE_A15MPCORE_PRIV);
 
 /*
- * GPIOs 1 to 7
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -57,7 +60,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -79,19 +82,24 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * ECSPIs
+ */
 for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
 object_initialize_child(obj, name, >spi[i], TYPE_IMX_SPI);
 }
 
-
+/*
+ * I2Cs
+ */
 for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
 object_initialize_child(obj, name, >i2c[i], TYPE_IMX_I2C);
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -99,7 +107,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
@@ -107,7 +115,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -120,7 +128,7 @@ static void fsl_imx7_init(Object *obj)
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -132,8 +140,14 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
+/*
+ * PCIE
+ */
 object_initialize_child(obj, "pcie", >pcie, TYPE_DESIGNWARE_PCIE_HOST);
 
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
@@ -156,6 +170,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 return;
 }
 
+/*
+ * CPUs
+ */
 for (i = 0; i < smp_cpus; i++) {
 o = OBJECT(>cpu[i]);
 
@@ -206,10 +223,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX7_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
@@ -234,6 +251,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_GPTn_IRQ[i]));
 }
 
+/*
+ * GPIOs
+ */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
 FSL_IMX7_GPIO1_ADDR,
@@ -279,18 +299,14 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * IOMUXC and IOMUXC_LPSR
+ * IOMUXC, IOMUXC_GPR and IOMUXC_LPSR
  */
-for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
-static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
-FSL_IMX7_IOMUXC_ADDR,
-FSL_IMX7_IOMUXC_LPSR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
-

[PATCH v2 4/5] Add i.MX7 missing TZ devices and memory regions

2023-07-29 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add various memory segments
  - OCRAM
  - OCRAM EPDC
  - OCRAM PXP
  - OCRAM S
  - ROM
  - CAAM

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 63 +++
 include/hw/arm/fsl-imx7.h |  7 +
 2 files changed, 70 insertions(+)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 3bb0da6850..7ca105fd24 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -666,6 +666,69 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
 FSL_IMX7_PCIE_PHY_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
+FSL_IMX7_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
+FSL_IMX7_TZASC_SIZE);
+
+/*
+ * OCRAM memory
+ */
+memory_region_init_ram(>ocram, NULL, "imx7.ocram",
+   FSL_IMX7_OCRAM_MEM_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
+>ocram);
+
+/*
+ * OCRAM EPDC memory
+ */
+memory_region_init_ram(>ocram_epdc, NULL, "imx7.ocram_epdc",
+   FSL_IMX7_OCRAM_EPDC_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
+>ocram_epdc);
+
+/*
+ * OCRAM PXP memory
+ */
+memory_region_init_ram(>ocram_pxp, NULL, "imx7.ocram_pxp",
+   FSL_IMX7_OCRAM_PXP_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
+>ocram_pxp);
+
+/*
+ * OCRAM_S memory
+ */
+memory_region_init_ram(>ocram_s, NULL, "imx7.ocram_s",
+   FSL_IMX7_OCRAM_S_SIZE,
+   _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
+>ocram_s);
+
+/*
+ * ROM memory
+ */
+memory_region_init_rom(>rom, OBJECT(dev), "imx7.rom",
+   FSL_IMX7_ROM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
+>rom);
+
+/*
+ * CAAM memory
+ */
+memory_region_init_rom(>caam, OBJECT(dev), "imx7.caam",
+   FSL_IMX7_CAAM_MEM_SIZE, _abort);
+memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
+>caam);
 }
 
 static Property fsl_imx7_properties[] = {
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 306fe3ce66..6138221350 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -83,6 +83,13 @@ struct FslIMX7State {
 IMX7GPRState   gpr;
 ChipideaState  usb[FSL_IMX7_NUM_USBS];
 DesignwarePCIEHost pcie;
+MemoryRegion   rom;
+MemoryRegion   caam;
+MemoryRegion   ocram;
+MemoryRegion   ocram_epdc;
+MemoryRegion   ocram_pxp;
+MemoryRegion   ocram_s;
+
 uint32_t   phy_num[FSL_IMX7_NUM_ETHS];
 bool   phy_connected[FSL_IMX7_NUM_ETHS];
 };
-- 
2.34.1




[PATCH v2 5/5] Add i.MX7 SRC device implementation

2023-07-29 Thread Jean-Christophe Dubois
The SRC device is normaly used to start the secondary CPU.

When running Linux directly, Qemu is emulating a PSCI interface that UBOOT
is installing at boot time and therefore the fact that the SRC device is
unimplemented is hidden as Qemu respond directly to PSCI requets without
using the SRC device.

But if you try to run a more bare metal application (maybe uboot itself),
then it is not possible to start the secondary CPU as the SRC is an
unimplemented device.

This patch adds the ability to start the secondary CPU through the SRC
device so that you can use this feature in bare metal application.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c  |   8 +-
 hw/misc/imx7_src.c | 276 +
 hw/misc/meson.build|   1 +
 hw/misc/trace-events   |   4 +
 include/hw/arm/fsl-imx7.h  |   2 +
 include/hw/misc/imx7_src.h |  66 +
 6 files changed, 356 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 7ca105fd24..e7fe4f808e 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -82,6 +82,11 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * SRC
+ */
+object_initialize_child(obj, "src", >src, TYPE_IMX7_SRC);
+
 /*
  * ECSPIs
  */
@@ -490,7 +495,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 /*
  * SRC
  */
-create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
+sysbus_realize(SYS_BUS_DEVICE(>src), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>src), 0, FSL_IMX7_SRC_ADDR);
 
 /*
  * Watchdogs
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
new file mode 100644
index 00..983251e86f
--- /dev/null
+++ b/hw/misc/imx7_src.c
@@ -0,0 +1,276 @@
+/*
+ * IMX7 System Reset Controller
+ *
+ * Copyright (c) 2023 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_src.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "target/arm/arm-powerctl.h"
+#include "hw/core/cpu.h"
+#include "hw/registerfields.h"
+
+#include "trace.h"
+
+static const char *imx7_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_A7RCR0:
+return "SRC_A7RCR0";
+case SRC_A7RCR1:
+return "SRC_A7RCR1";
+case SRC_M4RCR:
+return "SRC_M4RCR";
+case SRC_ERCR:
+return "SRC_ERCR";
+case SRC_HSICPHY_RCR:
+return "SRC_HSICPHY_RCR";
+case SRC_USBOPHY1_RCR:
+return "SRC_USBOPHY1_RCR";
+case SRC_USBOPHY2_RCR:
+return "SRC_USBOPHY2_RCR";
+case SRC_PCIEPHY_RCR:
+return "SRC_PCIEPHY_RCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%u ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx7_src = {
+.name = TYPE_IMX7_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx7_src_reset(DeviceState *dev)
+{
+IMX7SRCState *s = IMX7_SRC(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+
+/* Set reset values */
+s->regs[SRC_SCR] = 0xA0;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static uint64_t imx7_src_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t value = 0;
+IMX7SRCState *s = (IMX7SRCSta

[PATCH v2 2/5] Add i.MX6UL TZ missing devices.

2023-07-29 Thread Jean-Christophe Dubois
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 910316b628..0811163ddd 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -651,6 +651,18 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
 FSL_IMX6UL_LCDIF_SIZE);
 
+/*
+ * CSU
+ */
+create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
+FSL_IMX6UL_CSU_SIZE);
+
+/*
+ * TZASC
+ */
+create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
+FSL_IMX6UL_TZASC_SIZE);
+
 /*
  * ROM memory
  */
-- 
2.34.1




[PATCH v2 1/5] Refactor i.MX6UL processor code

2023-07-29 Thread Jean-Christophe Dubois
* Add Addr and size definition for all i.MX6UL devices in i.MX6UL header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM (add missing PWM instances)
  - CAN
* Add/rework few comments

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 149 
 include/hw/arm/fsl-imx6ul.h | 149 +---
 2 files changed, 239 insertions(+), 59 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 2189dcbb72..910316b628 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -69,7 +69,7 @@ static void fsl_imx6ul_init(Object *obj)
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
 /*
- * GPIOs 1 to 5
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -77,7 +77,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -85,7 +85,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 snprintf(name, NAME_SIZE, "epit%d", i + 1);
@@ -93,7 +93,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * eCSPI
+ * eCSPIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
@@ -101,7 +101,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * I2C
+ * I2Cs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
@@ -109,7 +109,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -117,25 +117,31 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
 object_initialize_child(obj, name, >eth[i], TYPE_IMX_ENET);
 }
 
-/* USB */
+/*
+ * USB PHYs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
 snprintf(name, NAME_SIZE, "usbphy%d", i);
 object_initialize_child(obj, name, >usbphy[i], TYPE_IMX_USBPHY);
 }
+
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -143,7 +149,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -189,10 +195,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX6UL_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
@@ -217,7 +223,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
@@ -242,7 +248,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * GPIO
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
@@ -286,15 +292,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 /*
  * IOMUXC and IOMUXC_GPR
  */
-for (i = 0; i < 1; i++) {
-static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
-FSL_IMX6UL_IOMUXC_ADDR,
-FSL_IMX6UL_IOMUXC_GPR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
-}
+create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
+FSL_IMX6UL_IOMUXC_SIZE);
+create_unimplemented_device("iomuxc_gpr"

[PATCH v2 0/5] Complete i.MX6UL and i.MX7 processor for bare metal application.

2023-07-29 Thread Jean-Christophe Dubois
This patch adds a few unimplemented TZ devices (TZASC and CSU) to
i.MX6UL and i.MX7 processors to avoid bare metal application to
experiment "bus error" when acccessing these devices.

It also adds some internal memory segments (OCRAM) to the i.MX7 to
allow bare metal application to use them.

Last, it adds the SRC device to the i.MX7 processor to allow bare
metal application to start the secondary Cortex-A7 core.

Note: When running Linux inside Qemu, the secondary core is started
by calling PSCI API and Qemu is emulating PSCI without needing access
to the SRC device. This is why Linux is using the 2 cores in Qemu
even if the SRC is not implemented. This is not the case when running
bare metal application (like u-boot itself) that do not rely on the
PSCI service being available.

Changes since v1:
* split the i.MX6UL patch into a refactor patch and an addon patch.
* Split the i.MX7 patch into a refactor patch and an addon patch.
* Fix SRC code after few comments in code review.

Jean-Christophe Dubois (5):
  Refactor i.MX6UL processor code
  Add i.MX6UL TZ missing devices.
  Refactor i.MX7 processor code
  Add i.MX7 missing TZ devices and memory regions
  Add i.MX7 SRC device implementation

 hw/arm/fsl-imx6ul.c | 161 -
 hw/arm/fsl-imx7.c   | 205 -
 hw/misc/imx7_src.c  | 276 
 hw/misc/meson.build |   1 +
 hw/misc/trace-events|   4 +
 include/hw/arm/fsl-imx6ul.h | 149 +--
 include/hw/arm/fsl-imx7.h   | 348 +++-
 include/hw/misc/imx7_src.h  |  66 +++
 8 files changed, 1026 insertions(+), 184 deletions(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

-- 
2.34.1




[PATCH 2/3] Rework i.MX7 device implementation/instantiation

2023-07-26 Thread Jean-Christophe Dubois
From: jcdubois 

* Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM
  - CAN
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add various memory segments
  - OCRAM
  - OCRAM EPDC
  - OCRAM PXP
  - OCRAM S
  - ROM
  - CAAM
* Add/rework few comments

Signed-off-by: jcdubois 
---
 hw/arm/fsl-imx7.c | 197 +-
 include/hw/arm/fsl-imx7.h | 346 +-
 2 files changed, 419 insertions(+), 124 deletions(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 9e41d4b677..05cdd4831e 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -36,6 +36,9 @@ static void fsl_imx7_init(Object *obj)
 char name[NAME_SIZE];
 int i;
 
+/*
+ * CPUs
+ */
 for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
 snprintf(name, NAME_SIZE, "cpu%d", i);
 object_initialize_child(obj, name, >cpu[i],
@@ -49,7 +52,7 @@ static void fsl_imx7_init(Object *obj)
 TYPE_A15MPCORE_PRIV);
 
 /*
- * GPIOs 1 to 7
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -57,7 +60,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -79,19 +82,24 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * ECSPIs
+ */
 for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
 object_initialize_child(obj, name, >spi[i], TYPE_IMX_SPI);
 }
 
-
+/*
+ * I2Cs
+ */
 for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
 object_initialize_child(obj, name, >i2c[i], TYPE_IMX_I2C);
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -99,7 +107,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
@@ -107,7 +115,7 @@ static void fsl_imx7_init(Object *obj)
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -120,7 +128,7 @@ static void fsl_imx7_init(Object *obj)
 object_initialize_child(obj, "snvs", >snvs, TYPE_IMX7_SNVS);
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -132,8 +140,14 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
+/*
+ * PCIE
+ */
 object_initialize_child(obj, "pcie", >pcie, TYPE_DESIGNWARE_PCIE_HOST);
 
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
@@ -156,6 +170,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 return;
 }
 
+/*
+ * CPUs
+ */
 for (i = 0; i < smp_cpus; i++) {
 o = OBJECT(>cpu[i]);
 
@@ -206,10 +223,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX7_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT1, 2, 3, 4
+ * GPTs
  */
 for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
@@ -234,6 +251,9 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_GPTn_IRQ[i]));
 }
 
+/*
+ * GPIOs
+ */
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
 FSL_IMX7_GPIO1_ADDR,
@@ -279,18 +299,14 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * IOMUXC and IOMUXC_LPSR
+ * IOMUXC, IOMUXC_GPR and IOMUXC_LPSR
  */
-for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
-static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
-FSL_IMX7_IOMUXC_ADDR,
-FSL_IMX7_IOMUXC_LPSR_ADDR,
-};
-
-snprintf(name, 

[PATCH 3/3] Add i.MX7 SRC device implementation

2023-07-26 Thread Jean-Christophe Dubois
From: jcdubois 

The SRC device is normaly used to start the secondary CPU.

When running Linux directly, Qemu is emulating a PSCI interface that UBOOT
is installing at boot time and therefore the fact that the SRC device is
unimplemented is hidden as Qemu respond directly to PSCI requets without
using the SRC device.

But if you try to run a more bare metal application (maybe uboot itself),
then it is not possible to start the secondary CPU as the SRC is an
unimplemented device.

This patch adds the ability to start the secondary CPU through the SRC
device so that you can use this feature in bare metal application.

Signed-off-by: jcdubois 
---
 hw/arm/fsl-imx7.c  |   9 +-
 hw/misc/imx7_src.c | 289 +
 hw/misc/meson.build|   1 +
 include/hw/arm/fsl-imx7.h  |   2 +
 include/hw/misc/imx7_src.h |  68 +
 5 files changed, 368 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 05cdd4831e..db103069e1 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -82,6 +82,11 @@ static void fsl_imx7_init(Object *obj)
  */
 object_initialize_child(obj, "gpcv2", >gpcv2, TYPE_IMX_GPCV2);
 
+/*
+ * SRC
+ */
+object_initialize_child(obj, "src", >src, TYPE_IMX7_SRC);
+
 /*
  * ECSPIs
  */
@@ -90,6 +95,7 @@ static void fsl_imx7_init(Object *obj)
 object_initialize_child(obj, name, >spi[i], TYPE_IMX_SPI);
 }
 
+
 /*
  * I2Cs
  */
@@ -490,7 +496,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 /*
  * SRC
  */
-create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
+sysbus_realize(SYS_BUS_DEVICE(>src), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>src), 0, FSL_IMX7_SRC_ADDR);
 
 /*
  * Watchdogs
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
new file mode 100644
index 00..b1b7d11e8f
--- /dev/null
+++ b/hw/misc/imx7_src.c
@@ -0,0 +1,289 @@
+/*
+ * IMX7 System Reset Controller
+ *
+ * Copyright (c) 2023 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_src.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "target/arm/arm-powerctl.h"
+#include "hw/core/cpu.h"
+
+#define DEBUG_IMX7_SRC 1
+#ifndef DEBUG_IMX7_SRC
+#define DEBUG_IMX7_SRC 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX7_SRC) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX7_SRC, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static const char *imx7_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_A7RCR0:
+return "SRC_A7RCR0";
+case SRC_A7RCR1:
+return "SRC_A7RCR1";
+case SRC_M4RCR:
+return "SRC_M4RCR";
+case SRC_ERCR:
+return "SRC_ERCR";
+case SRC_HSICPHY_RCR:
+return "SRC_HSICPHY_RCR";
+case SRC_USBOPHY1_RCR:
+return "SRC_USBOPHY1_RCR";
+case SRC_USBOPHY2_RCR:
+return "SRC_USBOPHY2_RCR";
+case SRC_PCIEPHY_RCR:
+return "SRC_PCIEPHY_RCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%u ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx7_src = {
+.name = TYPE_IMX7_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static

[PATCH 1/3] Rework i.MX6UL device implementation/instantiation

2023-07-26 Thread Jean-Christophe Dubois
From: jcdubois 

* Add Addr and size definition for all i.MX6UL devices in i.MX6UL header file.
* Use those newly defined named constants whenever possible.
* Standardize the way we init a familly of unimplemented devices
  - SAI
  - PWM (add missing PWM instances)
  - CAN
* Add TZASC as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Add CSU as unimplemented device.
  - Allow bare metal application to access this (unimplemented) device
* Change CAAM specific memory from ROM to RAM.
* Add/rework few comments

Signed-off-by: jcdubois 
---
 hw/arm/fsl-imx6ul.c | 163 +---
 include/hw/arm/fsl-imx6ul.h | 149 +---
 2 files changed, 252 insertions(+), 60 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 2189dcbb72..75aaf2adb4 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -69,7 +69,7 @@ static void fsl_imx6ul_init(Object *obj)
 object_initialize_child(obj, "gpr", >gpr, TYPE_IMX7_GPR);
 
 /*
- * GPIOs 1 to 5
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i);
@@ -77,7 +77,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
@@ -85,7 +85,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 snprintf(name, NAME_SIZE, "epit%d", i + 1);
@@ -93,7 +93,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * eCSPI
+ * eCSPIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
@@ -101,7 +101,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * I2C
+ * I2Cs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
 snprintf(name, NAME_SIZE, "i2c%d", i + 1);
@@ -109,7 +109,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * UART
+ * UARTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
 snprintf(name, NAME_SIZE, "uart%d", i);
@@ -117,25 +117,31 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Ethernet
+ * Ethernets
  */
 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
 snprintf(name, NAME_SIZE, "eth%d", i);
 object_initialize_child(obj, name, >eth[i], TYPE_IMX_ENET);
 }
 
-/* USB */
+/*
+ * USB PHYs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
 snprintf(name, NAME_SIZE, "usbphy%d", i);
 object_initialize_child(obj, name, >usbphy[i], TYPE_IMX_USBPHY);
 }
+
+/*
+ * USBs
+ */
 for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
 snprintf(name, NAME_SIZE, "usb%d", i);
 object_initialize_child(obj, name, >usb[i], TYPE_CHIPIDEA);
 }
 
 /*
- * SDHCI
+ * SDHCIs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
 snprintf(name, NAME_SIZE, "usdhc%d", i);
@@ -143,7 +149,7 @@ static void fsl_imx6ul_init(Object *obj)
 }
 
 /*
- * Watchdog
+ * Watchdogs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
 snprintf(name, NAME_SIZE, "wdt%d", i);
@@ -189,10 +195,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
  * A7MPCORE DAP
  */
 create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
-0x10);
+FSL_IMX6UL_A7MPCORE_DAP_SIZE);
 
 /*
- * GPT 1, 2
+ * GPTs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
@@ -217,7 +223,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * EPIT 1, 2
+ * EPITs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
 static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
@@ -242,7 +248,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 }
 
 /*
- * GPIO
+ * GPIOs
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
 static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
@@ -286,15 +292,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 /*
  * IOMUXC and IOMUXC_GPR
  */
-for (i = 0; i < 1; i++) {
-static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
-FSL_IMX6UL_IOMUXC_ADDR,
-FSL_IMX6UL_IOMUXC_GPR_ADDR,
-};
-
-snprintf(name, NAME_SIZE, "iomuxc%d", i);
-create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
-}
+create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
+FSL_IMX6UL_IOMUXC_SIZE);
+

[PATCH 0/3] Complete i.MX6UL and i.MX7 processor for bare metal application.

2023-07-26 Thread Jean-Christophe Dubois
This patch adds a few unimplemented TZ devices (TZASC and CSU) to
i.MX6UL and i.MX7 processors to avoid bare metal application to
experiment "bus error" when acccessing these devices.

It also adds some internal memory segments (OCRAM) to the i.MX7 to
allow bare metal application to use them.

Last, it adds the SRC device to the i.MX7 processor to allow bare
metal application to start the secondary Cortex-A7 core.

Note: When running Linux inside Qemu, the secondary core is started
by calling PSCI API and Qemu is emulating PSCI without needing access
to the SRC device. This is why Linux is using the 2 cores in Qemu
even if the SRC is not implemented. This is not the case when running
bare metal application (like u-boot itself) that do not rely on the
PSCI service being available.

Jean-Christophe Dubois (3):
  Rework i.MX6UL device implementation/instantiation
  Rework i.MX7 device implementation/instantiation
  Add i.MX7 SRC device implementation

 hw/arm/fsl-imx6ul.c | 163 -
 hw/arm/fsl-imx7.c   | 204 -
 hw/misc/imx7_src.c  | 289 ++
 hw/misc/meson.build |   1 +
 include/hw/arm/fsl-imx6ul.h | 149 +--
 include/hw/arm/fsl-imx7.h   | 348 +++-
 include/hw/misc/imx7_src.h  |  68 +++
 7 files changed, 1038 insertions(+), 184 deletions(-)
 create mode 100644 hw/misc/imx7_src.c
 create mode 100644 include/hw/misc/imx7_src.h

-- 
2.34.1




[PATCH] i.MX7D: Connect IRQs to GPIO devices.

2022-12-26 Thread Jean-Christophe Dubois
IRQs were not associated to the various GPIO devices inside i.MX7D.
This patch brings the i.MX7D on par with i.MX6.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 31 ++-
 include/hw/arm/fsl-imx7.h | 15 +++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index cc6fdb9373..5629ee249d 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -235,8 +235,37 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX7_GPIO7_ADDR,
 };
 
+static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
+FSL_IMX7_GPIO1_LOW_IRQ,
+FSL_IMX7_GPIO2_LOW_IRQ,
+FSL_IMX7_GPIO3_LOW_IRQ,
+FSL_IMX7_GPIO4_LOW_IRQ,
+FSL_IMX7_GPIO5_LOW_IRQ,
+FSL_IMX7_GPIO6_LOW_IRQ,
+FSL_IMX7_GPIO7_LOW_IRQ,
+};
+
+static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
+FSL_IMX7_GPIO1_HIGH_IRQ,
+FSL_IMX7_GPIO2_HIGH_IRQ,
+FSL_IMX7_GPIO3_HIGH_IRQ,
+FSL_IMX7_GPIO4_HIGH_IRQ,
+FSL_IMX7_GPIO5_HIGH_IRQ,
+FSL_IMX7_GPIO6_HIGH_IRQ,
+FSL_IMX7_GPIO7_HIGH_IRQ,
+};
+
 sysbus_realize(SYS_BUS_DEVICE(>gpio[i]), _abort);
-sysbus_mmio_map(SYS_BUS_DEVICE(>gpio[i]), 0, 
FSL_IMX7_GPIOn_ADDR[i]);
+sysbus_mmio_map(SYS_BUS_DEVICE(>gpio[i]), 0,
+FSL_IMX7_GPIOn_ADDR[i]);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>gpio[i]), 0,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+FSL_IMX7_GPIOn_LOW_IRQ[i]));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>gpio[i]), 1,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+FSL_IMX7_GPIOn_HIGH_IRQ[i]));
 }
 
 /*
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 1c5fa6fd67..852eb0d238 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -235,6 +235,21 @@ enum FslIMX7IRQs {
 FSL_IMX7_USB2_IRQ = 42,
 FSL_IMX7_USB3_IRQ = 40,
 
+FSL_IMX7_GPIO1_LOW_IRQ  = 64,
+FSL_IMX7_GPIO1_HIGH_IRQ = 65,
+FSL_IMX7_GPIO2_LOW_IRQ  = 66,
+FSL_IMX7_GPIO2_HIGH_IRQ = 67,
+FSL_IMX7_GPIO3_LOW_IRQ  = 68,
+FSL_IMX7_GPIO3_HIGH_IRQ = 69,
+FSL_IMX7_GPIO4_LOW_IRQ  = 70,
+FSL_IMX7_GPIO4_HIGH_IRQ = 71,
+FSL_IMX7_GPIO5_LOW_IRQ  = 72,
+FSL_IMX7_GPIO5_HIGH_IRQ = 73,
+FSL_IMX7_GPIO6_LOW_IRQ  = 74,
+FSL_IMX7_GPIO6_HIGH_IRQ = 75,
+FSL_IMX7_GPIO7_LOW_IRQ  = 76,
+FSL_IMX7_GPIO7_HIGH_IRQ = 77,
+
 FSL_IMX7_WDOG1_IRQ= 78,
 FSL_IMX7_WDOG2_IRQ= 79,
 FSL_IMX7_WDOG3_IRQ= 10,
-- 
2.34.1




[PATCH] i.MX6UL: Add a specific GPT timer instance for the i.MX6UL

2022-12-20 Thread Jean-Christophe Dubois
The i.MX6UL doesn't support CLK_HIGH ou CLK_HIGH_DIV clock source.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c|  2 +-
 hw/misc/imx6ul_ccm.c   |  6 --
 hw/timer/imx_gpt.c | 25 +
 include/hw/timer/imx_gpt.h |  1 +
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index f189712329..d88d6cc1c5 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -81,7 +81,7 @@ static void fsl_imx6ul_init(Object *obj)
  */
 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
 snprintf(name, NAME_SIZE, "gpt%d", i);
-object_initialize_child(obj, name, >gpt[i], TYPE_IMX7_GPT);
+object_initialize_child(obj, name, >gpt[i], TYPE_IMX6UL_GPT);
 }
 
 /*
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
index a65d031455..e01bb68ac7 100644
--- a/hw/misc/imx6ul_ccm.c
+++ b/hw/misc/imx6ul_ccm.c
@@ -522,12 +522,6 @@ static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 case CLK_32k:
 freq = CKIL_FREQ;
 break;
-case CLK_HIGH:
-freq = CKIH_FREQ;
-break;
-case CLK_HIGH_DIV:
-freq = CKIH_FREQ / 8;
-break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
   TYPE_IMX6UL_CCM, __func__, clock);
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 80b8302639..7222b1b387 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -115,6 +115,17 @@ static const IMXClk imx6_gpt_clocks[] = {
 CLK_HIGH,  /* 111 reference clock */
 };
 
+static const IMXClk imx6ul_gpt_clocks[] = {
+CLK_NONE,  /* 000 No clock source */
+CLK_IPG,   /* 001 ipg_clk, 532MHz*/
+CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
+CLK_EXT,   /* 011 External clock */
+CLK_32k,   /* 100 ipg_clk_32k */
+CLK_NONE,  /* 101 not defined */
+CLK_NONE,  /* 110 not defined */
+CLK_NONE,  /* 111 not defined */
+};
+
 static const IMXClk imx7_gpt_clocks[] = {
 CLK_NONE,  /* 000 No clock source */
 CLK_IPG,   /* 001 ipg_clk, 532MHz*/
@@ -539,6 +550,13 @@ static void imx6_gpt_init(Object *obj)
 s->clocks = imx6_gpt_clocks;
 }
 
+static void imx6ul_gpt_init(Object *obj)
+{
+IMXGPTState *s = IMX_GPT(obj);
+
+s->clocks = imx6ul_gpt_clocks;
+}
+
 static void imx7_gpt_init(Object *obj)
 {
 IMXGPTState *s = IMX_GPT(obj);
@@ -566,6 +584,12 @@ static const TypeInfo imx6_gpt_info = {
 .instance_init = imx6_gpt_init,
 };
 
+static const TypeInfo imx6ul_gpt_info = {
+.name = TYPE_IMX6UL_GPT,
+.parent = TYPE_IMX25_GPT,
+.instance_init = imx6ul_gpt_init,
+};
+
 static const TypeInfo imx7_gpt_info = {
 .name = TYPE_IMX7_GPT,
 .parent = TYPE_IMX25_GPT,
@@ -577,6 +601,7 @@ static void imx_gpt_register_types(void)
 type_register_static(_gpt_info);
 type_register_static(_gpt_info);
 type_register_static(_gpt_info);
+type_register_static(_gpt_info);
 type_register_static(_gpt_info);
 }
 
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
index ff5c8a351a..5a1230da35 100644
--- a/include/hw/timer/imx_gpt.h
+++ b/include/hw/timer/imx_gpt.h
@@ -78,6 +78,7 @@
 #define TYPE_IMX25_GPT "imx25.gpt"
 #define TYPE_IMX31_GPT "imx31.gpt"
 #define TYPE_IMX6_GPT "imx6.gpt"
+#define TYPE_IMX6UL_GPT "imx6ul.gpt"
 #define TYPE_IMX7_GPT "imx7.gpt"
 
 #define TYPE_IMX_GPT TYPE_IMX25_GPT
-- 
2.34.1




[PATCH] i.MX7D: Connect GPT timers to IRQ

2022-12-20 Thread Jean-Christophe Dubois
So far the GPT timers were unable to raise IRQs to the processor.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 10 ++
 include/hw/arm/fsl-imx7.h |  5 +
 2 files changed, 15 insertions(+)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index cc6fdb9373..146bb559bb 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -219,9 +219,19 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX7_GPT4_ADDR,
 };
 
+static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
+FSL_IMX7_GPT1_IRQ,
+FSL_IMX7_GPT2_IRQ,
+FSL_IMX7_GPT3_IRQ,
+FSL_IMX7_GPT4_IRQ,
+};
+
 s->gpt[i].ccm = IMX_CCM(>ccm);
 sysbus_realize(SYS_BUS_DEVICE(>gpt[i]), _abort);
 sysbus_mmio_map(SYS_BUS_DEVICE(>gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>gpt[i]), 0,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+FSL_IMX7_GPTn_IRQ[i]));
 }
 
 for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 1c5fa6fd67..50f19d8db0 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -235,6 +235,11 @@ enum FslIMX7IRQs {
 FSL_IMX7_USB2_IRQ = 42,
 FSL_IMX7_USB3_IRQ = 40,
 
+FSL_IMX7_GPT1_IRQ = 55,
+FSL_IMX7_GPT2_IRQ = 54,
+FSL_IMX7_GPT3_IRQ = 53,
+FSL_IMX7_GPT4_IRQ = 52,
+
 FSL_IMX7_WDOG1_IRQ= 78,
 FSL_IMX7_WDOG2_IRQ= 79,
 FSL_IMX7_WDOG3_IRQ= 10,
-- 
2.34.1




[PATCH] Fix i.MX GPT timers for i.MX6UL and i.MX7 processors

2022-12-20 Thread Jean-Christophe Dubois
This patch series allow GPT timers to be used on Qemu emulated i.MX7.

In particular it allows GPT timer to raise interrupts in i.MX7 processor
and supports some of the fixed frequency clocks.

Note: CCM generated clock sources will be added with a later patch.

This also brings some fixes to the i.MX6UL GPT timer as its clock sources
differ slightly from the i.MX7 version.

Tested by running µCOS application on i.MX7D emulated processor. µCOS
is using the GPT timer as its tick source.

Jean-Christophe Dubois (3):
  i.MX7D: Connect GPT timers to IRQ
  i.MX7D: Compute clock frequency for the fixed frequency clocks.
  i.MX6UL: Add a specific GPT timer instance for the i.MX6UL

 hw/arm/fsl-imx6ul.c|  2 +-
 hw/arm/fsl-imx7.c  | 10 
 hw/misc/imx6ul_ccm.c   |  6 -
 hw/misc/imx7_ccm.c | 49 +++---
 hw/timer/imx_gpt.c | 25 +++
 include/hw/arm/fsl-imx7.h  |  5 
 include/hw/timer/imx_gpt.h |  1 +
 7 files changed, 82 insertions(+), 16 deletions(-)

-- 
2.34.1




[PATCH] i.MX7D: Compute clock frequency for the fixed frequency clocks.

2022-12-20 Thread Jean-Christophe Dubois
CCM derived clocks will have to be added later.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/imx7_ccm.c | 49 +-
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
index 075159e497..f135ec7b7e 100644
--- a/hw/misc/imx7_ccm.c
+++ b/hw/misc/imx7_ccm.c
@@ -16,6 +16,10 @@
 #include "hw/misc/imx7_ccm.h"
 #include "migration/vmstate.h"
 
+#include "trace.h"
+
+#define CKIH_FREQ 2400 /* 24MHz crystal input */
+
 static void imx7_analog_reset(DeviceState *dev)
 {
 IMX7AnalogState *s = IMX7_ANALOG(dev);
@@ -219,16 +223,43 @@ static const VMStateDescription vmstate_imx7_ccm = {
 static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
 {
 /*
- * This function is "consumed" by GPT emulation code, however on
- * i.MX7 each GPT block can have their own clock root. This means
- * that this functions needs somehow to know requester's identity
- * and the way to pass it: be it via additional IMXClk constants
- * or by adding another argument to this method needs to be
- * figured out
+ * This function is "consumed" by GPT emulation code. Some clocks
+ * have fixed frequencies and we can provide requested frequency
+ * easily. However for CCM provided clocks (like IPG) each GPT
+ * timer can have its own clock root.
+ * This means we need additionnal information when calling this
+ * function to know the requester's identity.
  */
-qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
-  TYPE_IMX7_CCM, __func__);
-return 0;
+uint32_t freq = 0;
+
+switch (clock) {
+case CLK_NONE:
+break;
+case CLK_32k:
+freq = CKIL_FREQ;
+break;
+case CLK_HIGH:
+freq = CKIH_FREQ;
+break;
+case CLK_IPG:
+case CLK_IPG_HIGH:
+/*
+ * For now we don't have a way to figure out the device this
+ * function is called for. Until then the IPG derived clocks
+ * are left unimplemented.
+ */
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
+  TYPE_IMX7_CCM, __func__, clock);
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
+  TYPE_IMX7_CCM, __func__, clock);
+break;
+}
+
+trace_ccm_clock_freq(clock, freq);
+
+return freq;
 }
 
 static void imx7_ccm_class_init(ObjectClass *klass, void *data)
-- 
2.34.1




Re: [PATCH for-6.2] Revert "arm: tcg: Adhere to SMCCC 1.3 section 5.2"

2021-11-23 Thread Jean-Christophe DUBOIS

Le 19/11/2021 à 17:34, Peter Maydell a écrit :

This reverts commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4.

This change turns out to cause regressions, for instance on the
imx6ul boards as described here:
https://lore.kernel.org/qemu-devel/c8b89685-7490-328b-51a3-48711c140...@tribudubois.net/

The primary cause of that regression is that the guest code running
at EL3 expects SMCs (not related to PSCI) to do what they would if
our PSCI emulation was not present at all, but after this change
they instead set a value in R0/X0 and continue.

We could fix that by a refactoring that allowed us to only turn on
the PSCI emulation if we weren't booting the guest at EL3, but there
is a more tangled problem with the highbank board, which:
  (1) wants to enable PSCI emulation
  (2) has a bit of guest code that it wants to run at EL3 and
  to perform SMC calls that trap to the monitor vector table:
  this is the boot stub code that is written to memory by
  arm_write_secure_board_setup_dummy_smc() and which the
  highbank board enables by setting bootinfo->secure_board_setup

We can't satisfy both of those and also have the PSCI emulation
handle all SMC instruction executions regardless of function
identifier value.

This is too tricky to try to sort out before 6.2 is released;
revert this commit so we can take the time to get it right in
the 7.0 release.

Signed-off-by: Peter Maydell 
---
Jean-Christophe: could you confirm that reverting this fixes the
regressions you had on the imx boards ?


Hello Peter,

With this patch, things are back to "normal".

Thanks.

JC



  target/arm/psci.c | 35 +--
  1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/target/arm/psci.c b/target/arm/psci.c
index b279c0b9a45..6709e280133 100644
--- a/target/arm/psci.c
+++ b/target/arm/psci.c
@@ -27,13 +27,15 @@
  
  bool arm_is_psci_call(ARMCPU *cpu, int excp_type)

  {
-/*
- * Return true if the exception type matches the configured PSCI conduit.
- * This is called before the SMC/HVC instruction is executed, to decide
- * whether we should treat it as a PSCI call or with the architecturally
+/* Return true if the r0/x0 value indicates a PSCI call and
+ * the exception type matches the configured PSCI conduit. This is
+ * called before the SMC/HVC instruction is executed, to decide whether
+ * we should treat it as a PSCI call or with the architecturally
   * defined behaviour for an SMC or HVC (which might be UNDEF or trap
   * to EL2 or to EL3).
   */
+CPUARMState *env = >env;
+uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
  
  switch (excp_type) {

  case EXCP_HVC:
@@ -50,7 +52,27 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
  return false;
  }
  
-return true;

+switch (param) {
+case QEMU_PSCI_0_2_FN_PSCI_VERSION:
+case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
+case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
+case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
+case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
+case QEMU_PSCI_0_1_FN_CPU_ON:
+case QEMU_PSCI_0_2_FN_CPU_ON:
+case QEMU_PSCI_0_2_FN64_CPU_ON:
+case QEMU_PSCI_0_1_FN_CPU_OFF:
+case QEMU_PSCI_0_2_FN_CPU_OFF:
+case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
+case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
+case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
+case QEMU_PSCI_0_1_FN_MIGRATE:
+case QEMU_PSCI_0_2_FN_MIGRATE:
+return true;
+default:
+return false;
+}
  }
  
  void arm_handle_psci_call(ARMCPU *cpu)

@@ -172,9 +194,10 @@ void arm_handle_psci_call(ARMCPU *cpu)
  break;
  case QEMU_PSCI_0_1_FN_MIGRATE:
  case QEMU_PSCI_0_2_FN_MIGRATE:
-default:
  ret = QEMU_PSCI_RET_NOT_SUPPORTED;
  break;
+default:
+g_assert_not_reached();
  }
  
  err:






Re: Qemu and ARM secure state.

2021-11-09 Thread Jean-Christophe DUBOIS

Le 09/11/2021 à 11:55, Peter Maydell a écrit :

On Mon, 8 Nov 2021 at 22:09, Jean-Christophe DUBOIS  
wrote:

OK, so one problem seems to be that PSCI-via-SMC is enabled on i.MX6UL
when there is no built in PSCI related function on this processor.

According the Linux DTS, i.MX7 (solo and dual) processors have a
somewhat PSCI related "entry-method"
(https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx7s.dtsi).
But it is not clear to me how this is used and this seems a bit strange
as "entry-method" seems to be mostly used on arm64 and there is no other
PSCI related information in the i.MX7 DTS files.

Yeah, PSCI was an interface introduced mostly with aarch64. In the
32-bit world bringing up multiple CPUs was complete anarchy -- the
way the kernel told the secure firmware that it should start up
a secondary core was entirely determined by the firmware, and
the kernel had to have board-specific code to do this. (For the
32-bit imx boards I think this is in arch/arm/mach-imx/src.c.)
For aarch64 we had a clean slate and took the opportunity to insist
that all boards did it the same way, ie using PSCI. (There are other
useful things PSCI allows, but standardising secondary boot is the
one that matters for this discussion.) So if a platform's firmware
implements PSCI, all the dts file has to do is say so, and then
there's no need for board-specific "start secondary CPUs" code.
PSCI does define an aarch32 interface, but there are a lot of
legacy older boards (and new flavours of boards in long-standing
design families) which still do things the old way in aarch32 land.

Typically the top-level "PSCI is available" node is added by the firmware.
(QEMU will do this too when it's emulating PSCI firmware) -- if the
board code enables the psci-conduit it will add an appropriate psci
node in the hw/arm/boot.c code.)


As a matter of fact
previous quad or dual i.MX6 were not supporting PSCI. Instead they were
using a proprietary method through the internal SRC device (and i.MX7
also has a similar internal SRC device). But let's assume Linux on i.mx7
is actually using PSCI to handle processors.

Thinking about it, I guess this might be u-boot that sets an EL3 monitor
software that is able to handle PSCI requests for the Linux kernel. If
this is the case, it make sense that Qemu emulates the PSCI services
normally provided by u-boot to be able to boot linux directly (without
booting a real u-boot prior to linux). All  is well and nice.

Yes, that's the way it works. The EL3 firmware is supposed to provide
PSCI.

For aarch64 the kernel is never entered in EL3 -- it will always run at EL2
or EL1. (This is unlike aarch32, where in some cases you might run the
kernel in secure-SVC, although even there starting the kernel in
NS-SVC or NS-Hyp is more common.)


But then if I want to boot and test the u-boot binary (or any trusted OS
for the matter) on a Qemu emulated i.MX7 (to later boot an hypervisor or
an OS), it would be rather strange that any PSCI related service
requested by the hypervisor/OS  would be handled by Qemu directly and
not by the u-boot code (or any other EL3 code) running on the processor.

Exactly. This is why the board code is supposed to set things
up so that if we are starting the guest code in EL1 or EL2
then we enable the PSCI-via-SMC support, and if we're starting
the guest code in EL3 then we do not.


How is it supposed to work? How can I tell Qemu (dynamically?) if I want
it to provide (or not) the PSCI services (and more generally SMC/HVC
services).

If you want PSCI via SMC or HVC, then set the psci-conduit
property on the CPUs to QEMU_PSCI_CONDUIT_SMC or QEMU_PSCI_CONDUIT_HVC.
If you do not want QEMU to provide PSCI, then leave psci-conduit
at its default (which is QEMU_PSCI_CONDUIT_DISABLED).

How can I tell it that I want to handle all SMC/EL3 services

by myself even if the "psci-conduit" is already set to SMC in Qemu?

It's the imx7 code that's setting psci-conduit, so it should
not do that if it doesn't want that (and also should either
start or not start the secondary cpus powered off, depending
on what the hardware-to-firmware interface is supposed to be.)
This is a bit awkward, because the boards we initially wanted
PSCI for (notably virt) don't have an SoC object, so the code
creating CPUs is in the same source file as the code that knows
whether it's booting a kernel directly or not, and so it just
open-codes the decision logic. With the imx, the CPU creation
is in the source code for the SoC object which is abstracted
away from the board model code. So we'd need to sort out how
to plumb that information into the SoC object (or have the SoC
object's code that creates the CPUs call some function to find out).


Thanks Peter,

So basically the Qemu i.MX7 processor code needs to set psci-conduit to 
SMC because we want to be able to boot the Linux kernel directly 
(without u-boot) with Qemu emulating the PSCI services when 

Re: Qemu and ARM secure state.

2021-11-08 Thread Jean-Christophe DUBOIS

Le 08/11/2021 à 15:50, Peter Maydell a écrit :

On Sat, 6 Nov 2021 at 18:11, Jean-Christophe DUBOIS  
wrote:

One small question/remark:

According to the the "Arm Power State Coordinate Interface" (DEN0022D.b) document 
(chapter 5) PSCI calls can only be issued by "normal world" (EL1 or EL2). Therefore, 
should we be adding a test for the current secure state in the arm_is_psci_call() function? This 
would prevent calling the built-in Qemu PSCI function if SMC is issued  from secure state.

This shouldn't matter, because if the machine model is configured
to execute guest code in EL3 at all then it should not be enabling
QEMU's internal PSCI support. The internal PSCI stuff is only
there as a kind of "emulated firmware" for when we're running
guest code that starts at EL2 (notably, when directly booting
a Linux kernel).

The problem seems to be that fsl_imx6ul_realize() and
fsl_imx7_realize() unconditionally enable PSCI-via-SMC.
The imx7 code also puts all the secondaries into
PSCI-powered-off mode -- this should be checked to
work out what the right thing is if we're not doing
emulated PSCI and instead starting the guest at EL3.


OK, so one problem seems to be that PSCI-via-SMC is enabled on i.MX6UL 
when there is no built in PSCI related function on this processor.


According the Linux DTS, i.MX7 (solo and dual) processors have a 
somewhat PSCI related "entry-method" 
(https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx7s.dtsi). 
But it is not clear to me how this is used and this seems a bit strange 
as "entry-method" seems to be mostly used on arm64 and there is no other 
PSCI related information in the i.MX7 DTS files. As a matter of fact 
previous quad or dual i.MX6 were not supporting PSCI. Instead they were 
using a proprietary method through the internal SRC device (and i.MX7 
also has a similar internal SRC device). But let's assume Linux on i.mx7 
is actually using PSCI to handle processors.


Thinking about it, I guess this might be u-boot that sets an EL3 monitor 
software that is able to handle PSCI requests for the Linux kernel. If 
this is the case, it make sense that Qemu emulates the PSCI services 
normally provided by u-boot to be able to boot linux directly (without 
booting a real u-boot prior to linux). All  is well and nice.


But then if I want to boot and test the u-boot binary (or any trusted OS 
for the matter) on a Qemu emulated i.MX7 (to later boot an hypervisor or 
an OS), it would be rather strange that any PSCI related service 
requested by the hypervisor/OS  would be handled by Qemu directly and 
not by the u-boot code (or any other EL3 code) running on the processor. 
How is it supposed to work? How can I tell Qemu (dynamically?) if I want 
it to provide (or not) the PSCI services (and more generally SMC/HVC 
services). How can I tell it that I want to handle all SMC/EL3 services 
by myself even if the "psci-conduit" is already set to SMC in Qemu?


Am I missing something?

thanks.

JC



-- PMM






Re: Qemu and ARM secure state.

2021-11-08 Thread Jean-Christophe DUBOIS

Le 08/11/2021 à 15:14, Alex Bennée a écrit :

Jean-Christophe DUBOIS  writes:


One small question/remark:

According to the the "Arm Power State Coordinate Interface" (DEN0022D.b) 
document (chapter 5) PSCI calls can only be issued by
"normal world" (EL1 or EL2). Therefore, should we be adding a test for the 
current secure state in the arm_is_psci_call() function? This
would prevent calling the built-in Qemu PSCI function if SMC is issued
from secure state.

All that should be handled in:

   void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)

which should cause things to be trapped if the CPU is in an invalid
state to execute the SMC instruction. If the exception is a valid SMC we
end up in arm_cpu_do_interrupt where we may divert to
arm_handle_psci_call.


The problem I have is that is seems that once the "psci-conduit" is set 
to SMC, all SMC exception would be handled only by the diverted  
arm_handle_psci_call().


It seems there is no way to handle SMC exception in my software once 
"psci-conduit" is set to SMC on a platform.


It used to be that only some PSCI services were diverted and other SMC 
services were handled by the EL3 software if any (and this split was 
actually also a bit awkward).









Re: Qemu and ARM secure state.

2021-11-06 Thread Jean-Christophe DUBOIS

One small question/remark:

According to the the "Arm Power State Coordinate Interface" (DEN0022D.b) 
document (chapter 5) PSCI calls can only be issued by "normal world" 
(EL1 or EL2). Therefore, should we be adding a test for the current 
secure state in the arm_is_psci_call() function? This would prevent 
calling the built-in Qemu PSCI function if SMC is issued  from secure state.


Regards.

JC

Le 06/11/2021 à 14:04, Jean-Christophe DUBOIS a écrit :
So it seems that what is needed is a way to choose on the command line 
if we want to enable the Qemu built-in PSCI implementation (because we 
are booting linux for example) or if we really want a bare metal 
processor (because we are booting a trustedOS like optee).


The "virt" platform allows to dynamically choose one or the other. 
Other platforms seems to need the same feature.


JC

Le 06/11/2021 à 11:04, Jean-Christophe DUBOIS a écrit :

So, I am trying to understand:

Contrary to what I said, In my case the SMC instruction is not really 
a "no-op" as it sets R0 to -1 (0x) to indicate an unknown 
PSCI service (by the Qemu internal PSCI handler).


With the new code introduced by the "arm: tcg: Adhere to SMCCC 1.3 
section 5.2" commit, once a processor/platform configure things to 
have PSCI requests handled by Qemu code (with "psci-conduit" 
attribute set to QEMU_PSCI_CONDUIT_SMC for example), then any 
exception raised by an "SMC" instruction will be only handled by the 
Qemu internal code and will no call the monitor related code in the 
guest/OS application. This seems to be why my SMC monitor handler is 
not called anymore in my case.


As my i.MX6UL is a mono-processor platform I don't really need to set 
the "psci-conduit" attribute (which really makes sense when you have 
a cluster of 2 or more cores I guess). As a matter of fact if I 
remove the "psci-conduit" attribute setting from the i.MX6UL 
processor file, my application is working again on main/latest.


But this still raises the question to know if the current behavior 
for processors with "psci-conduit" set to SMC or HVC is correct. For 
example an i.MX7 based platform (with up to 4 cortex A7 cores) would 
not be able to trigger OS SMC handler as the exception would be 
entirely processed by the Qemu internal code (with CR generally set 
to -1 in R0 to indicate unknown PSCI request).


Is there something I am missing?

Regards

JC

Le 04/11/2021 à 22:11, Jean-Christophe DUBOIS a écrit :

Le 04/11/2021 à 12:11, Peter Maydell a écrit :

On Wed, 3 Nov 2021 at 13:27, Jean-Christophe DUBOIS  
wrote:

I have a little application that is designed to work on the i.MX6UL processor.

I developed it and tested it on the mcimx6ul-evk platform emulated by Qemu.

This application used to work "flawlessly" on Qemu 5.0.50 and is working on 
Qemu 6.0.0 (available as a pre-built package on the latest Ubuntu).

But when I try to run the exact same command line on a Qemu version I compile 
myself from main/latest of github (Qemu 6.1.50), my application fails to start.

So a little background:

My application expects to start in "secure" state and supervisor mode (which is 
the default state of i.MX6UL when booting barebone [without u-boot]).

>From this state the application tries to get to "non secure" / hypervisor mode which imply going to the 
"secure" / monitor state before being able to drop to "non secure" / hypervisor. To do so is runs a "smc 
0" operand (from "secure" / supervisor).

This "smc" instruction is processed "as expected" by Qemu 5.0.50 and Qemu 6.0.0 (getting to 
"secure" / monitor mode) but on Qemu 6.1.50 (latest from github) it is as if the smc operand was a no-op. It 
doesn't trigger any exception and the processor just get to the next instruction after the "smc" instruction. 
So I am a bit puzzled.

Is there something that changed in Qemu (since Qemu 6.0.0) when it comes to the 
"secure" world/state?
Is there some additional command line parameters to use (I search in the 
documentation but without luck) to get secure world behavior ?
Is it necessary to "adapt" the emulated platform (i.MX6UL/mcimx6ul-evk) in some way (it looks like 
the "virt" machine with "secure=on" does work for arm platform)?

Could you try doing a bisect to find the QEMU commit that caused
your guest to stop working ?


OK, I did the bisect and the commit that break the i.MX6UL behavior 
for my program is commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4 
(arm: tcg: Adhere to SMCCC 1.3 section 5.2).


Before it the SMC instruction would trigger a monitor exception.

After it the SMC instruction is acting like a no-op.

Thanks

JC



thanks
-- PMM









Re: Qemu and ARM secure state.

2021-11-06 Thread Jean-Christophe DUBOIS
So it seems that what is needed is a way to choose on the command line 
if we want to enable the Qemu built-in PSCI implementation (because we 
are booting linux for example) or if we really want a bare metal 
processor (because we are booting a trustedOS like optee).


The "virt" platform allows to dynamically choose one or the other. Other 
platforms seems to need the same feature.


JC

Le 06/11/2021 à 11:04, Jean-Christophe DUBOIS a écrit :

So, I am trying to understand:

Contrary to what I said, In my case the SMC instruction is not really 
a "no-op" as it sets R0 to -1 (0x) to indicate an unknown PSCI 
service (by the Qemu internal PSCI handler).


With the new code introduced by the "arm: tcg: Adhere to SMCCC 1.3 
section 5.2" commit, once a processor/platform configure things to 
have PSCI requests handled by Qemu code (with "psci-conduit" attribute 
set to QEMU_PSCI_CONDUIT_SMC for example), then any exception raised 
by an "SMC" instruction will be only handled by the Qemu internal code 
and will no call the monitor related code in the guest/OS application. 
This seems to be why my SMC monitor handler is not called anymore in 
my case.


As my i.MX6UL is a mono-processor platform I don't really need to set 
the "psci-conduit" attribute (which really makes sense when you have a 
cluster of 2 or more cores I guess). As a matter of fact if I remove 
the "psci-conduit" attribute setting from the i.MX6UL processor file, 
my application is working again on main/latest.


But this still raises the question to know if the current behavior for 
processors with "psci-conduit" set to SMC or HVC is correct. For 
example an i.MX7 based platform (with up to 4 cortex A7 cores) would 
not be able to trigger OS SMC handler as the exception would be 
entirely processed by the Qemu internal code (with CR generally set to 
-1 in R0 to indicate unknown PSCI request).


Is there something I am missing?

Regards

JC

Le 04/11/2021 à 22:11, Jean-Christophe DUBOIS a écrit :

Le 04/11/2021 à 12:11, Peter Maydell a écrit :

On Wed, 3 Nov 2021 at 13:27, Jean-Christophe DUBOIS  
wrote:

I have a little application that is designed to work on the i.MX6UL processor.

I developed it and tested it on the mcimx6ul-evk platform emulated by Qemu.

This application used to work "flawlessly" on Qemu 5.0.50 and is working on 
Qemu 6.0.0 (available as a pre-built package on the latest Ubuntu).

But when I try to run the exact same command line on a Qemu version I compile 
myself from main/latest of github (Qemu 6.1.50), my application fails to start.

So a little background:

My application expects to start in "secure" state and supervisor mode (which is 
the default state of i.MX6UL when booting barebone [without u-boot]).

>From this state the application tries to get to "non secure" / hypervisor mode which imply going to the 
"secure" / monitor state before being able to drop to "non secure" / hypervisor. To do so is runs a "smc 
0" operand (from "secure" / supervisor).

This "smc" instruction is processed "as expected" by Qemu 5.0.50 and Qemu 6.0.0 (getting to 
"secure" / monitor mode) but on Qemu 6.1.50 (latest from github) it is as if the smc operand was a no-op. It 
doesn't trigger any exception and the processor just get to the next instruction after the "smc" instruction. 
So I am a bit puzzled.

Is there something that changed in Qemu (since Qemu 6.0.0) when it comes to the 
"secure" world/state?
Is there some additional command line parameters to use (I search in the 
documentation but without luck) to get secure world behavior ?
Is it necessary to "adapt" the emulated platform (i.MX6UL/mcimx6ul-evk) in some way (it looks like 
the "virt" machine with "secure=on" does work for arm platform)?

Could you try doing a bisect to find the QEMU commit that caused
your guest to stop working ?


OK, I did the bisect and the commit that break the i.MX6UL behavior 
for my program is commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4 
(arm: tcg: Adhere to SMCCC 1.3 section 5.2).


Before it the SMC instruction would trigger a monitor exception.

After it the SMC instruction is acting like a no-op.

Thanks

JC



thanks
-- PMM







Re: Qemu and ARM secure state.

2021-11-06 Thread Jean-Christophe DUBOIS

So, I am trying to understand:

Contrary to what I said, In my case the SMC instruction is not really a 
"no-op" as it sets R0 to -1 (0x) to indicate an unknown PSCI 
service (by the Qemu internal PSCI handler).


With the new code introduced by the "arm: tcg: Adhere to SMCCC 1.3 
section 5.2" commit, once a processor/platform configure things to have 
PSCI requests handled by Qemu code (with "psci-conduit" attribute set to 
QEMU_PSCI_CONDUIT_SMC for example), then any exception raised by an 
"SMC" instruction will be only handled by the Qemu internal code and 
will no call the monitor related code in the guest/OS application. This 
seems to be why my SMC monitor handler is not called anymore in my case.


As my i.MX6UL is a mono-processor platform I don't really need to set 
the "psci-conduit" attribute (which really makes sense when you have a 
cluster of 2 or more cores I guess). As a matter of fact if I remove the 
"psci-conduit" attribute setting from the i.MX6UL processor file, my 
application is working again on main/latest.


But this still raises the question to know if the current behavior for 
processors with "psci-conduit" set to SMC or HVC is correct. For example 
an i.MX7 based platform (with up to 4 cortex A7 cores) would not be able 
to trigger OS SMC handler as the exception would be entirely processed 
by the Qemu internal code (with CR generally set to -1 in R0 to indicate 
unknown PSCI request).


Is there something I am missing?

Regards

JC

Le 04/11/2021 à 22:11, Jean-Christophe DUBOIS a écrit :

Le 04/11/2021 à 12:11, Peter Maydell a écrit :

On Wed, 3 Nov 2021 at 13:27, Jean-Christophe DUBOIS  
wrote:

I have a little application that is designed to work on the i.MX6UL processor.

I developed it and tested it on the mcimx6ul-evk platform emulated by Qemu.

This application used to work "flawlessly" on Qemu 5.0.50 and is working on 
Qemu 6.0.0 (available as a pre-built package on the latest Ubuntu).

But when I try to run the exact same command line on a Qemu version I compile 
myself from main/latest of github (Qemu 6.1.50), my application fails to start.

So a little background:

My application expects to start in "secure" state and supervisor mode (which is 
the default state of i.MX6UL when booting barebone [without u-boot]).

>From this state the application tries to get to "non secure" / hypervisor mode which imply going to the 
"secure" / monitor state before being able to drop to "non secure" / hypervisor. To do so is runs a "smc 
0" operand (from "secure" / supervisor).

This "smc" instruction is processed "as expected" by Qemu 5.0.50 and Qemu 6.0.0 (getting to 
"secure" / monitor mode) but on Qemu 6.1.50 (latest from github) it is as if the smc operand was a no-op. It 
doesn't trigger any exception and the processor just get to the next instruction after the "smc" instruction. 
So I am a bit puzzled.

Is there something that changed in Qemu (since Qemu 6.0.0) when it comes to the 
"secure" world/state?
Is there some additional command line parameters to use (I search in the 
documentation but without luck) to get secure world behavior ?
Is it necessary to "adapt" the emulated platform (i.MX6UL/mcimx6ul-evk) in some way (it looks like 
the "virt" machine with "secure=on" does work for arm platform)?

Could you try doing a bisect to find the QEMU commit that caused
your guest to stop working ?


OK, I did the bisect and the commit that break the i.MX6UL behavior 
for my program is commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4 
(arm: tcg: Adhere to SMCCC 1.3 section 5.2).


Before it the SMC instruction would trigger a monitor exception.

After it the SMC instruction is acting like a no-op.

Thanks

JC



thanks
-- PMM





Re: Qemu and ARM secure state.

2021-11-04 Thread Jean-Christophe DUBOIS

Le 04/11/2021 à 12:11, Peter Maydell a écrit :

On Wed, 3 Nov 2021 at 13:27, Jean-Christophe DUBOIS  
wrote:

I have a little application that is designed to work on the i.MX6UL processor.

I developed it and tested it on the mcimx6ul-evk platform emulated by Qemu.

This application used to work "flawlessly" on Qemu 5.0.50 and is working on 
Qemu 6.0.0 (available as a pre-built package on the latest Ubuntu).

But when I try to run the exact same command line on a Qemu version I compile 
myself from main/latest of github (Qemu 6.1.50), my application fails to start.

So a little background:

My application expects to start in "secure" state and supervisor mode (which is 
the default state of i.MX6UL when booting barebone [without u-boot]).

 From this state the application tries to get to "non secure" / hypervisor mode which imply going to the 
"secure" / monitor state before being able to drop to "non secure" / hypervisor. To do so is runs a "smc 
0" operand (from "secure" / supervisor).

This "smc" instruction is processed "as expected" by Qemu 5.0.50 and Qemu 6.0.0 (getting to 
"secure" / monitor mode) but on Qemu 6.1.50 (latest from github) it is as if the smc operand was a no-op. It 
doesn't trigger any exception and the processor just get to the next instruction after the "smc" instruction. 
So I am a bit puzzled.

Is there something that changed in Qemu (since Qemu 6.0.0) when it comes to the 
"secure" world/state?
Is there some additional command line parameters to use (I search in the 
documentation but without luck) to get secure world behavior ?
Is it necessary to "adapt" the emulated platform (i.MX6UL/mcimx6ul-evk) in some way (it looks like 
the "virt" machine with "secure=on" does work for arm platform)?

Could you try doing a bisect to find the QEMU commit that caused
your guest to stop working ?


OK, I did the bisect and the commit that break the i.MX6UL behavior for 
my program is commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4 (arm: tcg: 
Adhere to SMCCC 1.3 section 5.2).


Before it the SMC instruction would trigger a monitor exception.

After it the SMC instruction is acting like a no-op.

Thanks

JC




thanks
-- PMM



Re: [RFC PATCH] contrib/gitdm: Add more individual contributors

2020-10-24 Thread Jean-Christophe DUBOIS

Acked-by Jean-Christophe Dubois 

On 04/10/2020 20:25, Philippe Mathieu-Daudé wrote:

These individual contributors have a number of contributions,
add them to the 'individual' group map.

Cc: Ahmed Karaman 
Cc: Aleksandar Markovic 
Cc: Alistair Francis 
Cc: Artyom Tarasenko 
Cc: David Carlier 
Cc: Finn Thain 
Cc: Guenter Roeck 
Cc: Helge Deller 
Cc: Hervé Poussineau 
Cc: James Hogan 
Cc: Jean-Christophe Dubois 
Cc: Kővágó Zoltán 
Cc: Laurent Vivier 
Cc: Michael Rolnik 
Cc: Niek Linnenbank 
Cc: Paul Burton 
Cc: Paul Zimmerman 
Cc: Stefan Weil 
Cc: Subbaraya Sundeep 
Cc: Sven Schnelle 
Cc: Thomas Huth 
Cc: Volker Rümelin 
Signed-off-by: Philippe Mathieu-Daudé 
---
To the developers Cc'ed: If you agree with your entry, please
reply with a Reviewed-by/Acked-by tag. If you disagree or doesn't
care, please either reply with Nack-by or ignore this patch.
I'll repost in 2 weeks as formal patch (not RFC) with only the
entries acked by their author.
---
  contrib/gitdm/group-map-individuals | 22 ++
  contrib/gitdm/group-map-redhat  |  1 -
  2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/contrib/gitdm/group-map-individuals 
b/contrib/gitdm/group-map-individuals
index cf8a2ce367..b478fd4576 100644
--- a/contrib/gitdm/group-map-individuals
+++ b/contrib/gitdm/group-map-individuals
@@ -16,3 +16,25 @@ aurel...@aurel32.net
  bala...@eik.bme.hu
  e.emanuelegiuse...@gmail.com
  andrew.smir...@gmail.com
+s...@weilnetz.de
+h...@tuxfamily.org
+laur...@vivier.eu
+atar4q...@gmail.com
+hpous...@reactos.org
+del...@gmx.de
+alist...@alistair23.me
+fth...@telegraphics.com.au
+sv...@stackframe.org
+aleksandar.qemu.de...@gmail.com
+jho...@kernel.org
+paulbur...@kernel.org
+vr_q...@t-online.de
+nieklinnenb...@gmail.com
+devne...@gmail.com
+j...@tribudubois.net
+dirty.ice...@gmail.com
+mrol...@gmail.com
+pauld...@gmail.com
+li...@roeck-us.net
+sundeep.l...@gmail.com
+ahmedkhaledkara...@gmail.com
diff --git a/contrib/gitdm/group-map-redhat b/contrib/gitdm/group-map-redhat
index d15db2d35e..4a8ca84b36 100644
--- a/contrib/gitdm/group-map-redhat
+++ b/contrib/gitdm/group-map-redhat
@@ -3,6 +3,5 @@
  #
  
  da...@gibson.dropbear.id.au

-laur...@vivier.eu
  p...@fedoraproject.org
  arm...@pond.sub.org






Re: [PATCH 0/3] Add ability to choose MDIO phy number to i.MX processors

2020-07-04 Thread Jean-Christophe DUBOIS
This patch set is to be applied on top of the patch serie recently 
accepted by Peter on his tree.


I guess I will have to wait a bit that his pull request is accepted in 
mainline before resubmitting my patch.


JC

Le 03/07/2020 à 22:44, no-re...@patchew.org a écrit :

Patchew URL: https://patchew.org/QEMU/cover.1593806826.git@tribudubois.net/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

qemu-system-aarch64: Property '.phy-num' not found
Broken pipe
/tmp/qemu-test/src/tests/qtest/libqtest.c:175: kill_qemu() detected QEMU death 
from signal 6 (Aborted) (core dumped)
ERROR - too few tests run (expected 66, got 0)
make: *** [check-qtest-aarch64] Error 1
make: *** Waiting for unfinished jobs
   TESTiotest-qcow2: 154
Could not access KVM kernel module: No such file or directory
---
 raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=4a2335c3dedc4400bae7b327958dfa5a', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-9e58kfzn/src/docker-src.2020-07-03-16.29.20.28169:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=4a2335c3dedc4400bae7b327958dfa5a
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-9e58kfzn/src'
make: *** [docker-run-test-quick@centos7] Error 2

real14m58.666s
user0m9.169s


The full log is available at
http://patchew.org/logs/cover.1593806826.git@tribudubois.net/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com






[PATCH 1/3] Add the ability to change the FEC PHY MDIO device number on i.MX25 processor

2020-07-03 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx25.c | 7 +++
 include/hw/arm/fsl-imx25.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 7ab5c98fbe1..35874aac00b 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -183,6 +183,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 epit_table[i].irq));
 }
 
+object_property_set_uint(OBJECT(>fec), s->phy_num, "phy-num", );
 qdev_set_nic_properties(DEVICE(>fec), _table[0]);
 
 sysbus_realize(SYS_BUS_DEVICE(>fec), );
@@ -339,10 +340,16 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 >iram_alias);
 }
 
+static Property fsl_imx25_properties[] = {
+DEFINE_PROP_UINT32("fec-phy-num", FslIMX25State, phy_num, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void fsl_imx25_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, fsl_imx25_properties);
 dc->realize = fsl_imx25_realize;
 dc->desc = "i.MX25 SOC";
 /*
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
index 9e228daceae..54ee1bfd780 100644
--- a/include/hw/arm/fsl-imx25.h
+++ b/include/hw/arm/fsl-imx25.h
@@ -65,6 +65,7 @@ typedef struct FslIMX25State {
 MemoryRegion   rom[2];
 MemoryRegion   iram;
 MemoryRegion   iram_alias;
+uint32_t   phy_num;
 } FslIMX25State;
 
 /**
-- 
2.25.1




[PATCH 0/3] Add ability to choose MDIO phy number to i.MX processors

2020-07-03 Thread Jean-Christophe Dubois
This patch set adds the ability to select the Ethernet PHY device number
for the i.MX25 processor, the i.MX6 processor and the i.MX7 processor.

Note: the i.MX6UL processor was addressed in a previous patch.

Jean-Christophe Dubois (3):
  Add the ability to change the FEC PHY MDIO device number on i.MX25
processor
  Add the ability to change the FEC PHY MDIO device number on i.MX6
processor
  Add the ability to change the FEC PHY MDIO devices numbers on i.MX7
processor

 hw/arm/fsl-imx25.c | 7 +++
 hw/arm/fsl-imx6.c  | 7 +++
 hw/arm/fsl-imx7.c  | 9 +
 include/hw/arm/fsl-imx25.h | 1 +
 include/hw/arm/fsl-imx6.h  | 1 +
 include/hw/arm/fsl-imx7.h  | 1 +
 6 files changed, 26 insertions(+)

-- 
2.25.1




[PATCH 3/3] Add the ability to change the FEC PHY MDIO devices numbers on i.MX7 processor

2020-07-03 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 9 +
 include/hw/arm/fsl-imx7.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index b49d895a412..5dbf0e500aa 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -364,6 +364,8 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_ENET2_ADDR,
 };
 
+object_property_set_uint(OBJECT(>eth[i]), s->phy_num[i],
+ "phy-num", _abort);
 object_property_set_uint(OBJECT(>eth[i]), FSL_IMX7_ETH_NUM_TX_RINGS,
  "tx-ring-num", _abort);
 qdev_set_nic_properties(DEVICE(>eth[i]), _table[i]);
@@ -551,10 +553,17 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX7_PCIE_PHY_SIZE);
 }
 
+static Property fsl_imx7_properties[] = {
+DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
+DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void fsl_imx7_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, fsl_imx7_properties);
 dc->realize = fsl_imx7_realize;
 
 /* Reason: Uses serial_hds and nd_table in realize() directly */
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index da977f9ffb4..ad889237077 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -81,6 +81,7 @@ typedef struct FslIMX7State {
 IMX7GPRState   gpr;
 ChipideaState  usb[FSL_IMX7_NUM_USBS];
 DesignwarePCIEHost pcie;
+uint32_t   phy_num[FSL_IMX7_NUM_ETHS];
 } FslIMX7State;
 
 enum FslIMX7MemoryMap {
-- 
2.25.1




[PATCH 2/3] Add the ability to change the FEC PHY MDIO device number on i.MX6 processor

2020-07-03 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6.c | 7 +++
 include/hw/arm/fsl-imx6.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 4ae3c3efc28..0721f333497 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -402,6 +402,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
 spi_table[i].irq));
 }
 
+object_property_set_uint(OBJECT(>eth), s->phy_num, "phy-num", );
 qdev_set_nic_properties(DEVICE(>eth), _table[0]);
 sysbus_realize(SYS_BUS_DEVICE(>eth), );
 if (err) {
@@ -476,10 +477,16 @@ static void fsl_imx6_realize(DeviceState *dev, Error 
**errp)
 >ocram_alias);
 }
 
+static Property fsl_imx6_properties[] = {
+DEFINE_PROP_UINT32("fec-phy-num", FslIMX6State, phy_num, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void fsl_imx6_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, fsl_imx6_properties);
 dc->realize = fsl_imx6_realize;
 dc->desc = "i.MX6 SOC";
 /* Reason: Uses serial_hd() in the realize() function */
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
index 1ebd7513246..162fe99375d 100644
--- a/include/hw/arm/fsl-imx6.h
+++ b/include/hw/arm/fsl-imx6.h
@@ -73,6 +73,7 @@ typedef struct FslIMX6State {
 MemoryRegion   caam;
 MemoryRegion   ocram;
 MemoryRegion   ocram_alias;
+uint32_t   phy_num;
 } FslIMX6State;
 
 
-- 
2.25.1




Re: [PATCH] hw/misc/pca9552: Add missing TypeInfo::class_size field

2020-06-29 Thread Jean-Christophe DUBOIS

Le 29/06/2020 à 09:47, Philippe Mathieu-Daudé a écrit :

When adding the generic PCA955xClass in commit 736132e455, we
forgot to set the class_size field. Fill it now to avoid:

   (gdb) run -machine mcimx6ul-evk -m 128M -display none -serial stdio -kernel 
./OS.elf
   Starting program: ../../qemu/qemu/arm-softmmu/qemu-system-arm -machine 
mcimx6ul-evk -m 128M -display none -serial stdio -kernel ./OS.elf
   double free or corruption (!prev)
   Thread 1 "qemu-system-arm" received signal SIGABRT, Aborted.
   __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
   (gdb) where
   #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
   #1  0x775d8859 in __GI_abort () at abort.c:79
   #2  0x776433ee in __libc_message
   (action=action@entry=do_abort, fmt=fmt@entry=0x7776d285 "%s\n")
   at ../sysdeps/posix/libc_fatal.c:155
   #3  0x7764b47c in malloc_printerr
   (str=str@entry=0x7776f690 "double free or corruption (!prev)")
   at malloc.c:5347
   #4  0x7764d12c in _int_free
   (av=0x7779eb80 , p=0x567a3990, have_lock=) at malloc.c:4317
   #5  0x55c906c3 in type_initialize_interface
   (ti=ti@entry=0x565b8f40, interface_type=0x56597ad0, 
parent_type=0x5662ca10) at qom/object.c:259
   #6  0x55c902da in type_initialize (ti=ti@entry=0x565b8f40)
   at qom/object.c:323
   #7  0x55c90d20 in type_initialize (ti=0x565b8f40)
   at qom/object.c:1028

   $ valgrind --track-origins=yes qemu-system-arm -M mcimx6ul-evk -m 128M 
-display none -serial stdio -kernel ./OS.elf
   ==77479== Memcheck, a memory error detector
   ==77479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
   ==77479== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
   ==77479== Command: qemu-system-arm -M mcimx6ul-evk -m 128M -display none 
-serial stdio -kernel ./OS.elf
   ==77479==
   ==77479== Invalid write of size 2
   ==77479==at 0x6D8322: pca9552_class_init (pca9552.c:424)
   ==77479==by 0x844D1F: type_initialize (object.c:1029)
   ==77479==by 0x844D1F: object_class_foreach_tramp (object.c:1016)
   ==77479==by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)
   ==77479==by 0x8453A4: object_class_foreach (object.c:1038)
   ==77479==by 0x8453A4: object_class_get_list (object.c:1095)
   ==77479==by 0x556194: select_machine (vl.c:2416)
   ==77479==by 0x556194: qemu_init (vl.c:3828)
   ==77479==by 0x40AF9C: main (main.c:48)
   ==77479==  Address 0x583f108 is 0 bytes after a block of size 200 alloc'd
   ==77479==at 0x483DD99: calloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
   ==77479==by 0x4AF8D30: g_malloc0 (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)
   ==77479==by 0x844258: type_initialize.part.0 (object.c:306)
   ==77479==by 0x844D1F: type_initialize (object.c:1029)
   ==77479==by 0x844D1F: object_class_foreach_tramp (object.c:1016)
   ==77479==by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)
   ==77479==by 0x8453A4: object_class_foreach (object.c:1038)
   ==77479==by 0x8453A4: object_class_get_list (object.c:1095)
   ==77479==by 0x556194: select_machine (vl.c:2416)
   ==77479==by 0x556194: qemu_init (vl.c:3828)
   ==77479==by 0x40AF9C: main (main.c:48)

Fixes: 736132e455 ("hw/misc/pca9552: Add generic PCA955xClass")
Reported-by: Jean-Christophe DUBOIS 


Tested-by: Jean-Christophe DUBOIS 


Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/misc/pca9552.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 80caa9ec8f..68b574d084 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -410,6 +410,7 @@ static const TypeInfo pca955x_info = {
  .instance_init = pca955x_initfn,
  .instance_size = sizeof(PCA955xState),
  .class_init= pca955x_class_init,
+.class_size= sizeof(PCA955xClass),
  .abstract  = true,
  };
  






[PATCH 3/3] Select MDIO device 2 and 1 as PHY devices for i.MX6UL EVK board.

2020-06-28 Thread Jean-Christophe Dubois
The i.MX6UL EVK 14x14 board uses:
- PHY 2 for FEC 1
- PHY 1 for FEC 2

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/mcimx6ul-evk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
index 2f845cedfce..9033d3f8f38 100644
--- a/hw/arm/mcimx6ul-evk.c
+++ b/hw/arm/mcimx6ul-evk.c
@@ -40,6 +40,8 @@ static void mcimx6ul_evk_init(MachineState *machine)
 
 s = FSL_IMX6UL(object_new(TYPE_FSL_IMX6UL));
 object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
+object_property_set_uint(OBJECT(s), 2, "fec1-phy-num", _fatal);
+object_property_set_uint(OBJECT(s), 1, "fec2-phy-num", _fatal);
 qdev_realize(DEVICE(s), NULL, _fatal);
 
 memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR,
-- 
2.25.1




[PATCH 2/3] Add the ability to select a different PHY for each i.MX6UL FEC interface

2020-06-28 Thread Jean-Christophe Dubois
Add properties to the i.MX6UL processor to be able to select a
particular PHY on the MDIO bus for each FEC device.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx6ul.c | 10 ++
 include/hw/arm/fsl-imx6ul.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 6446034711e..51b2f256ec8 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -427,6 +427,9 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX6UL_ENET2_TIMER_IRQ,
 };
 
+object_property_set_uint(OBJECT(>eth[i]),
+ s->phy_num[i],
+ "phy-num", _abort);
 object_property_set_uint(OBJECT(>eth[i]),
  FSL_IMX6UL_ETH_NUM_TX_RINGS,
  "tx-ring-num", _abort);
@@ -607,10 +610,17 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
 FSL_IMX6UL_OCRAM_ALIAS_ADDR, >ocram_alias);
 }
 
+static Property fsl_imx6ul_properties[] = {
+DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
+DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, fsl_imx6ul_properties);
 dc->realize = fsl_imx6ul_realize;
 dc->desc = "i.MX6UL SOC";
 /* Reason: Uses serial_hds and nd_table in realize() directly */
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
index 37c89cc5f92..fcbaf3dc861 100644
--- a/include/hw/arm/fsl-imx6ul.h
+++ b/include/hw/arm/fsl-imx6ul.h
@@ -87,6 +87,8 @@ typedef struct FslIMX6ULState {
 MemoryRegion   caam;
 MemoryRegion   ocram;
 MemoryRegion   ocram_alias;
+
+uint32_t   phy_num[FSL_IMX6UL_NUM_ETHS];
 } FslIMX6ULState;
 
 enum FslIMX6ULMemoryMap {
-- 
2.25.1




[PATCH 1/3] Add a phy-num property to the i.MX FEC emulator

2020-06-28 Thread Jean-Christophe Dubois
We need a solution to use an Ethernet PHY that is not the first device
on the MDIO bus (device 0 on MDIO bus).

As an example with the i.MX6UL the NXP SOC has 2 Ethernet devices but
only one MDIO bus on which the 2 related PHY are connected but at unique
addresses.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/net/imx_fec.c | 24 +---
 hw/net/trace-events  |  4 ++--
 include/hw/net/imx_fec.h |  1 +
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index eefedc252de..2c148040414 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -280,12 +280,16 @@ static void imx_phy_reset(IMXFECState *s)
 static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
+uint32_t phy = reg / 32;
 
-if (reg > 31) {
-/* we only advertise one phy */
+if (phy != s->phy_num) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
+  TYPE_IMX_FEC, __func__, phy);
 return 0;
 }
 
+reg %= 32;
+
 switch (reg) {
 case 0: /* Basic Control */
 val = s->phy_control;
@@ -331,20 +335,25 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-trace_imx_phy_read(val, reg);
+trace_imx_phy_read(val, phy, reg);
 
 return val;
 }
 
 static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-trace_imx_phy_write(val, reg);
+uint32_t phy = reg / 32;
 
-if (reg > 31) {
-/* we only advertise one phy */
+if (phy != s->phy_num) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
+  TYPE_IMX_FEC, __func__, phy);
 return;
 }
 
+reg %= 32;
+
+trace_imx_phy_write(val, phy, reg);
+
 switch (reg) {
 case 0: /* Basic Control */
 if (val & 0x8000) {
@@ -926,7 +935,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
extract32(value,
  18, 10)));
 } else {
-/* This a write operation */
+/* This is a write operation */
 imx_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 
16));
 }
 /* raise the interrupt as the PHY operation is done */
@@ -1315,6 +1324,7 @@ static void imx_eth_realize(DeviceState *dev, Error 
**errp)
 static Property imx_eth_properties[] = {
 DEFINE_NIC_PROPERTIES(IMXFECState, conf),
 DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
+DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/net/trace-events b/hw/net/trace-events
index e6875c4c0f6..5db45456d92 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -413,8 +413,8 @@ i82596_set_multicast(uint16_t count) "Added %d multicast 
entries"
 i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
 
 # imx_fec.c
-imx_phy_read(uint32_t val, int reg) "0x%04"PRIx32" <= reg[%d]"
-imx_phy_write(uint32_t val, int reg) "0x%04"PRIx32" => reg[%d]"
+imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
+imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => 
phy[%d].reg[%d]"
 imx_phy_update_link(const char *s) "%s"
 imx_phy_reset(void) ""
 imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 
0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 7b3faa40194..9f03034b893 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -268,6 +268,7 @@ typedef struct IMXFECState {
 uint32_t phy_advertise;
 uint32_t phy_int;
 uint32_t phy_int_mask;
+uint32_t phy_num;
 
 bool is_fec;
 
-- 
2.25.1




[PATCH 0/3] Allow to specify the PHY number to use with a specific i.MX FEC/ENET Ethernet device

2020-06-28 Thread Jean-Christophe Dubois
The PHY device associated to a specific i.MX Ethernet device is not 
necessarily at address 0 on the MDIO bus.

This patch series adds the ability to set the PHY number on the MDIO bus
for any i.MX6UL based board.

Jean-Christophe Dubois (3):
  Add a phy-num property to the i.MX FEC emulator
  Add the ability to select a different PHY for each i.MX6UL FEC
interface
  Select MDIO device 2 and 1 as PHY devices for i.MW6UL EVK board.

 hw/arm/fsl-imx6ul.c | 10 ++
 hw/arm/mcimx6ul-evk.c   |  2 ++
 hw/net/imx_fec.c| 24 +---
 hw/net/trace-events |  4 ++--
 include/hw/arm/fsl-imx6ul.h |  2 ++
 include/hw/net/imx_fec.h|  1 +
 6 files changed, 34 insertions(+), 9 deletions(-)

-- 
2.25.1




Re: Crash when running Qemu.

2020-06-28 Thread Jean-Christophe DUBOIS
I am not sure how it could influence the fact that I experience this bug 
and others not necessarily but for what it is worth, I am using gcc 
10.0.1 to compile Qemu.


I might try to use a previous version to check if it changes the overall 
behavior.


JC

Le 28/06/2020 à 18:32, Jean-Christophe DUBOIS a écrit :
By reverting the recent (june 23) commit series on PCA9552 I can run 
Qemu again.


Here is the git revert command I did.

jcd@jcd-UX305CA:~/Projects/qemu/qemu$ git revert 
8208335b9539e7b5aa4702b36e2f9a8abd704079..586f495b1e78c27e141ff432dd971eb41866fb80


Regards

JC

Le 28/06/2020 à 17:57, Jean-Christophe DUBOIS a écrit :
When ran from valgrind, qemu does not crash but the following output 
is returned.


valgrind --track-origins=yes 
../../qemu/qemu/arm-softmmu/qemu-system-arm -machine mcimx6ul-evk -m 
128M -display none -serial stdio -kernel ./OS.elf

==77479== Memcheck, a memory error detector
==77479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et 
al.
==77479== Using Valgrind-3.15.0 and LibVEX; rerun with -h for 
copyright info
==77479== Command: ../../qemu/qemu/arm-softmmu/qemu-system-arm 
-machine mcimx6ul-evk -m 128M -display none -serial stdio -kernel 
./OS.elf

==77479==
==77479== Invalid write of size 2
==77479==    at 0x6D8322: pca9552_class_init (pca9552.c:424)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Address 0x583f108 is 0 bytes after a block of size 200 
alloc'd
==77479==    at 0x483DD99: calloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==77479==    by 0x4AF8D30: g_malloc0 (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x844258: type_initialize.part.0 (object.c:306)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==
==77479== Conditional jump or move depends on uninitialised value(s)
==77479==    at 0x41D944: tcg_target_init (tcg-target.inc.c:3867)
==77479==    by 0x41D944: tcg_context_init (tcg.c:983)
==77479==    by 0x48E60D: cpu_gen_init (translate-all.c:246)
==77479==    by 0x48E60D: tcg_exec_init (translate-all.c:1152)
==77479==    by 0x46FE7B: tcg_init (tcg-all.c:129)
==77479==    by 0x5E15A5: accel_init_machine (accel.c:55)
==77479==    by 0x55402F: do_configure_accelerator (vl.c:2708)
==77479==    by 0x94F1D1: qemu_opts_foreach (qemu-option.c:1163)
==77479==    by 0x5598B3: configure_accelerators (vl.c:2775)
==77479==    by 0x5598B3: qemu_init (vl.c:4152)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Uninitialised value was created by a stack allocation
==77479==    at 0x4ADFE5F: ??? (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==
==77479== Warning: set address range perms: large range [0x6483000, 
0x46483000) (defined)


===
=   TCPIP INITIALIZATION =
===
Initializing TCPIP...

--- i.MX6UL-EVK BOARD NETWORK CONFIG 



Starting ENET1...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30


Starting ENET2...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30

Network Configuration:
qemu-system-arm: terminating on signal 2
==77479==
==77479== HEAP SUMMARY:
==77479== in use at exit: 8,452,515 bytes in 57,040 blocks
==77479==   total heap usage: 97,248 allocs, 40,208 frees, 21,279,482 
bytes allocated

==77479==
==77479== LEAK SUMMARY:
==77479==    definitely lost: 0 bytes in 0 blocks
==77479==    indirectly lost: 0 bytes in 0 blocks
==77479==  possibly lost: 3,474 bytes in 45 blocks
==77479==    still reachable: 8,449,041 bytes in 56,995 blocks
==77479==   of which reachable via heuristic:
==77479== newarray   : 1,536 bytes in 
16 blocks

==77479== suppressed: 0 bytes in 0 blocks
==77479== Rerun with --leak-check=full to see details of leaked memory
==77479==
==77479== For lists of detected and suppressed errors, rerun with: -s
==77479== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

Le 28/06/2020 à 12:55, Jean-Christophe

Re: Crash when running Qemu.

2020-06-28 Thread Jean-Christophe DUBOIS
By reverting the recent (june 23) commit series on PCA9552 I can run 
Qemu again.


Here is the git revert command I did.

jcd@jcd-UX305CA:~/Projects/qemu/qemu$ git revert 
8208335b9539e7b5aa4702b36e2f9a8abd704079..586f495b1e78c27e141ff432dd971eb41866fb80


Regards

JC

Le 28/06/2020 à 17:57, Jean-Christophe DUBOIS a écrit :
When ran from valgrind, qemu does not crash but the following output 
is returned.


valgrind --track-origins=yes 
../../qemu/qemu/arm-softmmu/qemu-system-arm -machine mcimx6ul-evk -m 
128M -display none -serial stdio -kernel ./OS.elf

==77479== Memcheck, a memory error detector
==77479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==77479== Using Valgrind-3.15.0 and LibVEX; rerun with -h for 
copyright info
==77479== Command: ../../qemu/qemu/arm-softmmu/qemu-system-arm 
-machine mcimx6ul-evk -m 128M -display none -serial stdio -kernel 
./OS.elf

==77479==
==77479== Invalid write of size 2
==77479==    at 0x6D8322: pca9552_class_init (pca9552.c:424)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Address 0x583f108 is 0 bytes after a block of size 200 alloc'd
==77479==    at 0x483DD99: calloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==77479==    by 0x4AF8D30: g_malloc0 (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x844258: type_initialize.part.0 (object.c:306)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==
==77479== Conditional jump or move depends on uninitialised value(s)
==77479==    at 0x41D944: tcg_target_init (tcg-target.inc.c:3867)
==77479==    by 0x41D944: tcg_context_init (tcg.c:983)
==77479==    by 0x48E60D: cpu_gen_init (translate-all.c:246)
==77479==    by 0x48E60D: tcg_exec_init (translate-all.c:1152)
==77479==    by 0x46FE7B: tcg_init (tcg-all.c:129)
==77479==    by 0x5E15A5: accel_init_machine (accel.c:55)
==77479==    by 0x55402F: do_configure_accelerator (vl.c:2708)
==77479==    by 0x94F1D1: qemu_opts_foreach (qemu-option.c:1163)
==77479==    by 0x5598B3: configure_accelerators (vl.c:2775)
==77479==    by 0x5598B3: qemu_init (vl.c:4152)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Uninitialised value was created by a stack allocation
==77479==    at 0x4ADFE5F: ??? (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==
==77479== Warning: set address range perms: large range [0x6483000, 
0x46483000) (defined)


===
=   TCPIP INITIALIZATION =
===
Initializing TCPIP...

--- i.MX6UL-EVK BOARD NETWORK CONFIG 



Starting ENET1...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30


Starting ENET2...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30

Network Configuration:
qemu-system-arm: terminating on signal 2
==77479==
==77479== HEAP SUMMARY:
==77479== in use at exit: 8,452,515 bytes in 57,040 blocks
==77479==   total heap usage: 97,248 allocs, 40,208 frees, 21,279,482 
bytes allocated

==77479==
==77479== LEAK SUMMARY:
==77479==    definitely lost: 0 bytes in 0 blocks
==77479==    indirectly lost: 0 bytes in 0 blocks
==77479==  possibly lost: 3,474 bytes in 45 blocks
==77479==    still reachable: 8,449,041 bytes in 56,995 blocks
==77479==   of which reachable via heuristic:
==77479== newarray   : 1,536 bytes in 
16 blocks

==77479== suppressed: 0 bytes in 0 blocks
==77479== Rerun with --leak-check=full to see details of leaked memory
==77479==
==77479== For lists of detected and suppressed errors, rerun with: -s
==77479== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

Le 28/06/2020 à 12:55, Jean-Christophe DUBOIS a écrit :

Hi,

Since the last pull I did this week end on the qemu git tree (master 
branch) I am unable to "start" qemu anymore (It was working OK from 
git master previously).


Traces are provided bellow.

Am I the only one to get this behavior?

JC

jcd@jcd-UX305CA:~/Projects/µCOS/work$ 
../..

Re: Crash when running Qemu.

2020-06-28 Thread Jean-Christophe DUBOIS
When ran from valgrind, qemu does not crash but the following output is 
returned.


valgrind --track-origins=yes ../../qemu/qemu/arm-softmmu/qemu-system-arm 
-machine mcimx6ul-evk -m 128M -display none -serial stdio -kernel ./OS.elf

==77479== Memcheck, a memory error detector
==77479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==77479== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==77479== Command: ../../qemu/qemu/arm-softmmu/qemu-system-arm -machine 
mcimx6ul-evk -m 128M -display none -serial stdio -kernel ./OS.elf

==77479==
==77479== Invalid write of size 2
==77479==    at 0x6D8322: pca9552_class_init (pca9552.c:424)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Address 0x583f108 is 0 bytes after a block of size 200 alloc'd
==77479==    at 0x483DD99: calloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==77479==    by 0x4AF8D30: g_malloc0 (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x844258: type_initialize.part.0 (object.c:306)
==77479==    by 0x844D1F: type_initialize (object.c:1029)
==77479==    by 0x844D1F: object_class_foreach_tramp (object.c:1016)
==77479==    by 0x4AE1057: g_hash_table_foreach (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==    by 0x8453A4: object_class_foreach (object.c:1038)
==77479==    by 0x8453A4: object_class_get_list (object.c:1095)
==77479==    by 0x556194: select_machine (vl.c:2416)
==77479==    by 0x556194: qemu_init (vl.c:3828)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==
==77479== Conditional jump or move depends on uninitialised value(s)
==77479==    at 0x41D944: tcg_target_init (tcg-target.inc.c:3867)
==77479==    by 0x41D944: tcg_context_init (tcg.c:983)
==77479==    by 0x48E60D: cpu_gen_init (translate-all.c:246)
==77479==    by 0x48E60D: tcg_exec_init (translate-all.c:1152)
==77479==    by 0x46FE7B: tcg_init (tcg-all.c:129)
==77479==    by 0x5E15A5: accel_init_machine (accel.c:55)
==77479==    by 0x55402F: do_configure_accelerator (vl.c:2708)
==77479==    by 0x94F1D1: qemu_opts_foreach (qemu-option.c:1163)
==77479==    by 0x5598B3: configure_accelerators (vl.c:2775)
==77479==    by 0x5598B3: qemu_init (vl.c:4152)
==77479==    by 0x40AF9C: main (main.c:48)
==77479==  Uninitialised value was created by a stack allocation
==77479==    at 0x4ADFE5F: ??? (in 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.2)

==77479==
==77479== Warning: set address range perms: large range [0x6483000, 
0x46483000) (defined)


===
=   TCPIP INITIALIZATION =
===
Initializing TCPIP...

--- i.MX6UL-EVK BOARD NETWORK CONFIG 



Starting ENET1...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30


Starting ENET2...

NetIF_LinkStateWaitUntilUp() failed w/ err = 30

Network Configuration:
qemu-system-arm: terminating on signal 2
==77479==
==77479== HEAP SUMMARY:
==77479== in use at exit: 8,452,515 bytes in 57,040 blocks
==77479==   total heap usage: 97,248 allocs, 40,208 frees, 21,279,482 
bytes allocated

==77479==
==77479== LEAK SUMMARY:
==77479==    definitely lost: 0 bytes in 0 blocks
==77479==    indirectly lost: 0 bytes in 0 blocks
==77479==  possibly lost: 3,474 bytes in 45 blocks
==77479==    still reachable: 8,449,041 bytes in 56,995 blocks
==77479==   of which reachable via heuristic:
==77479== newarray   : 1,536 bytes in 16 
blocks

==77479== suppressed: 0 bytes in 0 blocks
==77479== Rerun with --leak-check=full to see details of leaked memory
==77479==
==77479== For lists of detected and suppressed errors, rerun with: -s
==77479== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

Le 28/06/2020 à 12:55, Jean-Christophe DUBOIS a écrit :

Hi,

Since the last pull I did this week end on the qemu git tree (master 
branch) I am unable to "start" qemu anymore (It was working OK from 
git master previously).


Traces are provided bellow.

Am I the only one to get this behavior?

JC

jcd@jcd-UX305CA:~/Projects/µCOS/work$ 
../../qemu/qemu/arm-softmmu/qemu-system-arm -machine mcimx6ul-evk -m 
128M -display none -serial stdio -kernel ./OS.elf

double free or corruption (!prev)
Abandon (core dumped)

Running the same command from "gdb" provides the following backtrace.

jcd@jcd-UX305CA:~/Projects/µCOS/work$ gdb 
../../qemu/qemu/arm-softmmu/qemu

Crash when running Qemu.

2020-06-28 Thread Jean-Christophe DUBOIS

Hi,

Since the last pull I did this week end on the qemu git tree (master 
branch) I am unable to "start" qemu anymore (It was working OK from git 
master previously).


Traces are provided bellow.

Am I the only one to get this behavior?

JC

jcd@jcd-UX305CA:~/Projects/µCOS/work$ 
../../qemu/qemu/arm-softmmu/qemu-system-arm -machine mcimx6ul-evk -m 
128M -display none -serial stdio -kernel ./OS.elf

double free or corruption (!prev)
Abandon (core dumped)

Running the same command from "gdb" provides the following backtrace.

jcd@jcd-UX305CA:~/Projects/µCOS/work$ gdb 
../../qemu/qemu/arm-softmmu/qemu-system-arm

GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 


This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
    .

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../../qemu/qemu/arm-softmmu/qemu-system-arm...
(gdb) run -machine mcimx6ul-evk -m 128M -display none -serial stdio 
-kernel ./OS.elf
Starting program: ../../qemu/qemu/arm-softmmu/qemu-system-arm -machine 
mcimx6ul-evk -m 128M -display none -serial stdio -kernel ./OS.elf

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7738e700 (LWP 71630)]
double free or corruption (!prev)

Thread 1 "qemu-system-arm" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50    ../sysdeps/unix/sysv/linux/raise.c: Aucun fichier ou dossier de ce 
type.

(gdb) where
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x775d8859 in __GI_abort () at abort.c:79
#2  0x776433ee in __libc_message
    (action=action@entry=do_abort, fmt=fmt@entry=0x7776d285 "%s\n")
    at ../sysdeps/posix/libc_fatal.c:155
#3  0x7764b47c in malloc_printerr
    (str=str@entry=0x7776f690 "double free or corruption (!prev)")
    at malloc.c:5347
#4  0x7764d12c in _int_free
    (av=0x7779eb80 , p=0x567a3990, 
have_lock=) at malloc.c:4317

#5  0x55c906c3 in type_initialize_interface
    (ti=ti@entry=0x565b8f40, interface_type=0x56597ad0, 
parent_type=0x5662ca10) at qom/object.c:259

#6  0x55c902da in type_initialize (ti=ti@entry=0x565b8f40)
    at qom/object.c:323
#7  0x55c90d20 in type_initialize (ti=0x565b8f40)
    at qom/object.c:1028
#8  object_class_foreach_tramp
    (key=, value=0x565b8f40, opaque=0x7fffdc20)
    at qom/object.c:1016
#9  0x77c89058 in g_hash_table_foreach ()
    at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#10 0x55c913a5 in object_class_foreach
    (opaque=0x7fffdc18, include_abstract=false, 
implements_type=, fn=0x55c8f270 
) at qom/object.c:84

#11 object_class_get_list
    (implements_type=implements_type@entry=0x55fd5e0c "machine", 
include_abstract=include_abstract@entry=false) at qom/object.c:1095

#12 0x559a2195 in select_machine ()
    at /home/jcd/Projects/qemu/qemu/softmmu/vl.c:3828
#13 qemu_init (argc=, argv=0x7fffdef8, 
envp=)

    at /home/jcd/Projects/qemu/qemu/softmmu/vl.c:3828
#14 0x55856f9d in main
    (argc=, argv=, envp=)
    at /home/jcd/Projects/qemu/qemu/softmmu/main.c:48
(gdb)




Re: [PATCH v5 3/3] hw/net/imx_fec: improve PHY implementation.

2020-06-18 Thread Jean-Christophe DUBOIS

Le 15/06/2020 à 15:03, Peter Maydell a écrit :

On Thu, 4 Jun 2020 at 13:39, Jean-Christophe Dubois  
wrote:

improve the PHY implementation with more generic code.

This patch remove a lot of harcoded values to replace them with
generic symbols from header files.

Signed-off-by: Jean-Christophe Dubois 
---
  v2: Not present
  v3: Not present
  v4: Not present
  v5: improve PHY implementation.

  hw/net/imx_fec.c | 76 +++-
  include/hw/net/mii.h |  4 +++
  2 files changed, 50 insertions(+), 30 deletions(-)



-case 5: /* Auto-neg Link Partner Ability */
-val = 0x0f71;
+case MII_ANLPAR: /* Auto-neg Link Partner Ability */
+val = / | MII_ANLPAR_10 | MII_ANLPAR_10FD |
+  MII_ANLPAR_TX | MII_ANLPAR_TXFD | MII_ANLPAR_PAUSE |
+  MII_ANLPAR_PAUSEASY;

The old value is 0x0f71, but the new one with the constants
is 0x0de1.


First of I should say that this PHY, first borrowed by the mfc_fec.c 
(coldfire ethernet device) from lan9118 (and now by imx_fec.c) is not 
one used on any real i.MX (i.MX6, i.MX7, i.MX31, i.MX25, ...) based 
board that I know of (this particular PHY is embedded n the lan9118 
ethernet device)


It is there because we were in need of a PHY and this PHY needs to be 
simple and more or less standard.


I might have missed something but I am not really aware of way in Qemu 
to swap PHYs for a given ethernet emulator depending on the emulated board.


So here this PHY was just a blind cut and paste of the lan9118.c PHY 
part to get a reasonable working PHY for the FEC/ENET device.


So here the previous value of this register is not really meaningful. It 
is a mix of standard MII defined bits and LAN911X specific bits (for 
which I don't necessarily have definition ).


Here I decided to restrict the implementation of this rather "virtual" 
PHY to only standard defined bits


actually I think, I should have removed a lot more lan911x specific 
bits/registers to get to a really simple/trivial standard PHY.



-case 30:/* Interrupt mask */
+case MII_SMC911X_IM:/* Interrupt mask */
  val = s->phy_int_mask;
  break;
-case 17:
-case 18:
+case MII_NSR:
+val = 1 << 6;
+break;

The old code didn't have a case for MII_NSR (16).


I am not sure anymore why I added MII_NSR register. It is not present on 
lan9118 ethernet device but it is a standard defined register.



+case MII_LBREMR:
+case MII_REC:
  case 27:
  case 31:



-case 4: /* Auto-neg advertisement */
-s->phy_advertise = (val & 0x2d7f) | 0x80;
+case MII_ANAR: /* Auto-neg advertisement */
+s->phy_advertise = (val & (MII_ANAR_PAUSE_ASYM | MII_ANAR_PAUSE |
+   MII_ANAR_TXFD | MII_ANAR_TX |
+   MII_ANAR_10FD | MII_ANAR_10 | 0x1f)) |
+   MII_ANAR_TX;

The old code does & 0x2d7f; the new code is & 0xdff.

Same reason as the ANLPAR register.

  break;

If some of these are bug fixes, please can you put them in a separate
patch, so that the "use symbolic constants" change can be reviewed
as making no functional changes?

thanks
-- PMM






Re: [PATCH v5 2/3] hw/net/imx_fec: Allow phy not to be the first device on the mii bus.

2020-06-15 Thread Jean-Christophe DUBOIS

Le 15/06/2020 à 14:23, Peter Maydell a écrit :

On Thu, 4 Jun 2020 at 13:39, Jean-Christophe Dubois  
wrote:

Up to now we were allowing only one PHY device and it had to be the
first device on the bus.

The i.MX6UL has 2 Ethernet devices and can therefore have several
PHY devices on the bus (and not necessarilly as device 0).

This patch allows for PHY devices on 2nd, 3rd or any position.

Signed-off-by: Jean-Christophe Dubois 
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index eefedc252de..29e613699ee 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -280,11 +280,9 @@ static void imx_phy_reset(IMXFECState *s)
  static uint32_t imx_phy_read(IMXFECState *s, int reg)
  {
  uint32_t val;
+uint32_t phy = reg / 32;

-if (reg > 31) {
-/* we only advertise one phy */
-return 0;
-}
+reg %= 32;

This change means we now support multiple PHYs...


Yes, on the i.MX6UL there are 2 ENET devices but only one MDIO bus to 
acess the PHYs.


On the i.MX6UL evaluation board, PHY seems to be at offset/adress 1 and 2.

See linux/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi for details.




  switch (reg) {
  case 0: /* Basic Control */
@@ -331,19 +329,18 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
  break;
  }

-trace_imx_phy_read(val, reg);
+trace_imx_phy_read(val, phy, reg);

...but the only change we actually make is to trace the phy number.
Surely if there is more than one phy then each phy needs to have
its own state (phy_control/phy_status/phy_advertise/etc), rather
than all these PHYs all sharing the same state under the hood?


Well there might be several PHYs on the MDIO bus but each PHY is used 
only by one ENET device. There is no plan for one ENET to use either 
PHY. It can only use one.


In Qemu (or at least in the FEC ethernet device emulator) the phy state 
is embedded in the ethernet device state.




It also sounds from your commit message as if there isn't a
large number of PHYs, but only perhaps two. In that case
don't we need to fail attempts to access non-existent PHYs
and only work with the ones which actually exist on any
given board?


As stated on the particular i.MX6UL evaluation board there are 2 phys 
connected to the MDIO bus at adresse 1 and 2.


On another board the PHYs could be at different addresses or we might 
use only one MAC and therefore only one PHY.


So in order to be able to fail on bad PHY access we need to discriminate 
for each board which PHYs are actually present and at what address on 
the MDIO bus. We would also need to know which PHY is connected to which 
MAC.


I might have overlook something but so far there is no clear separate 
PHY and MAC implementation.


Usually the PHY is more or less part of the MAC implementation and there 
are no easy way to instantiate them separately then connect them with 
the required bus (MDIO and MAC).


I guess it might be feasible even if it sounds like overkill most of the 
time (you usually get one MAC connected to one PHY).


Is there such a qemu framework that would allow to connect multiple PHY 
to a single MDIO bus and then each PHY to a specific MAC device? Could 
you point me in the right direction ?




thanks
-- PMM






[PATCH v2] hw/misc/imx6ul_ccm: Implement non writable bits in CCM registers

2020-06-08 Thread Jean-Christophe Dubois
Some bits of the CCM registers are non writable.

This was left undone in the initial commit (all bits of registers were
writable).

This patch adds the required code to protect the non writable bits.

Signed-off-by: Jean-Christophe Dubois 
---

 v2: simplify code after feedback on the first patch.

 hw/misc/imx6ul_ccm.c | 76 
 1 file changed, 63 insertions(+), 13 deletions(-)

diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
index a2fc1d0364a..5e0661dacf7 100644
--- a/hw/misc/imx6ul_ccm.c
+++ b/hw/misc/imx6ul_ccm.c
@@ -19,6 +19,62 @@
 
 #include "trace.h"
 
+static const uint32_t ccm_mask[CCM_MAX] = {
+[CCM_CCR] = 0xf01fef80,
+[CCM_CCDR] = 0xfffe,
+[CCM_CSR] = 0x,
+[CCM_CCSR] = 0xfef2,
+[CCM_CACRR] = 0xfff8,
+[CCM_CBCDR] = 0xc1f8e000,
+[CCM_CBCMR] = 0xfc03cfff,
+[CCM_CSCMR1] = 0x8070,
+[CCM_CSCMR2] = 0xe01ff003,
+[CCM_CSCDR1] = 0xfe00c780,
+[CCM_CS1CDR] = 0xfe00fe00,
+[CCM_CS2CDR] = 0xf8007000,
+[CCM_CDCDR] = 0xf00f,
+[CCM_CHSCCDR] = 0xfffc01ff,
+[CCM_CSCDR2] = 0xfe0001ff,
+[CCM_CSCDR3] = 0xc1ff,
+[CCM_CDHIPR] = 0x,
+[CCM_CTOR] = 0x,
+[CCM_CLPCR] = 0xf39ff01c,
+[CCM_CISR] = 0xfb85ffbe,
+[CCM_CIMR] = 0xfb85ffbf,
+[CCM_CCOSR] = 0xfe00fe00,
+[CCM_CGPR] = 0xfffc3fea,
+[CCM_CCGR0] = 0x,
+[CCM_CCGR1] = 0x,
+[CCM_CCGR2] = 0x,
+[CCM_CCGR3] = 0x,
+[CCM_CCGR4] = 0x,
+[CCM_CCGR5] = 0x,
+[CCM_CCGR6] = 0x,
+[CCM_CMEOR] = 0xaf1f,
+};
+
+static const uint32_t analog_mask[CCM_ANALOG_MAX] = {
+[CCM_ANALOG_PLL_ARM] = 0xfff60f80,
+[CCM_ANALOG_PLL_USB1] = 0xfffe0fbc,
+[CCM_ANALOG_PLL_USB2] = 0xfffe0fbc,
+[CCM_ANALOG_PLL_SYS] = 0xfffa0ffe,
+[CCM_ANALOG_PLL_SYS_SS] = 0x,
+[CCM_ANALOG_PLL_SYS_NUM] = 0xc000,
+[CCM_ANALOG_PLL_SYS_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_AUDIO] = 0xffe20f80,
+[CCM_ANALOG_PLL_AUDIO_NUM] = 0xc000,
+[CCM_ANALOG_PLL_AUDIO_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_VIDEO] = 0xffe20f80,
+[CCM_ANALOG_PLL_VIDEO_NUM] = 0xc000,
+[CCM_ANALOG_PLL_VIDEO_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_ENET] = 0xffc20ff0,
+[CCM_ANALOG_PFD_480] = 0x40404040,
+[CCM_ANALOG_PFD_528] = 0x40404040,
+[PMU_MISC0] = 0x01fe8306,
+[PMU_MISC1] = 0x07fcede0,
+[PMU_MISC2] = 0x005f5f5f,
+};
+
 static const char *imx6ul_ccm_reg_name(uint32_t reg)
 {
 static char unknown[20];
@@ -596,11 +652,8 @@ static void imx6ul_ccm_write(void *opaque, hwaddr offset, 
uint64_t value,
 
 trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
 
-/*
- * We will do a better implementation later. In particular some bits
- * cannot be written to.
- */
-s->ccm[index] = (uint32_t)value;
+s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
+   ((uint32_t)value & ~ccm_mask[index]);
 }
 
 static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
@@ -737,7 +790,7 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, setting bits passed in the value.
  */
-s->analog[index - 1] |= value;
+s->analog[index - 1] |= (value & ~analog_mask[index - 1]);
 break;
 case CCM_ANALOG_PLL_ARM_CLR:
 case CCM_ANALOG_PLL_USB1_CLR:
@@ -762,7 +815,7 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, unsetting bits passed in the value.
  */
-s->analog[index - 2] &= ~value;
+s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]);
 break;
 case CCM_ANALOG_PLL_ARM_TOG:
 case CCM_ANALOG_PLL_USB1_TOG:
@@ -787,14 +840,11 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, toggling bits passed in the value.
  */
-s->analog[index - 3] ^= value;
+s->analog[index - 3] ^= (value & ~analog_mask[index - 3]);
 break;
 default:
-/*
- * We will do a better implementation later. In particular some bits
- * cannot be written to.
- */
-s->analog[index] = value;
+s->analog[index] = (s->analog[index] & analog_mask[index]) |
+   (value & ~analog_mask[index]);
 break;
 }
 }
-- 
2.25.1




[PATCH v5 3/3] hw/net/imx_fec: improve PHY implementation.

2020-06-04 Thread Jean-Christophe Dubois
improve the PHY implementation with more generic code.

This patch remove a lot of harcoded values to replace them with
generic symbols from header files.

Signed-off-by: Jean-Christophe Dubois 
---
 v2: Not present
 v3: Not present
 v4: Not present
 v5: improve PHY implementation.

 hw/net/imx_fec.c | 76 +++-
 include/hw/net/mii.h |  4 +++
 2 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 29e613699ee..bf9583a93f4 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/net/imx_fec.h"
+#include "hw/net/mii.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "sysemu/dma.h"
@@ -231,6 +232,9 @@ static const VMStateDescription vmstate_imx_eth = {
 #define PHY_INT_PARFAULT(1 << 2)
 #define PHY_INT_AUTONEG_PAGE(1 << 1)
 
+#define MII_SMC911X_ISF 29
+#define MII_SMC911X_IM  30
+
 static void imx_eth_update(IMXFECState *s);
 
 /*
@@ -249,11 +253,11 @@ static void imx_phy_update_link(IMXFECState *s)
 /* Autonegotiation status mirrors link status.  */
 if (qemu_get_queue(s->nic)->link_down) {
 trace_imx_phy_update_link("down");
-s->phy_status &= ~0x0024;
+s->phy_status &= ~(MII_BMSR_LINK_ST | MII_BMSR_AN_COMP);
 s->phy_int |= PHY_INT_DOWN;
 } else {
 trace_imx_phy_update_link("up");
-s->phy_status |= 0x0024;
+s->phy_status |= MII_BMSR_LINK_ST | MII_BMSR_AN_COMP;
 s->phy_int |= PHY_INT_ENERGYON;
 s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
 }
@@ -269,9 +273,11 @@ static void imx_phy_reset(IMXFECState *s)
 {
 trace_imx_phy_reset();
 
-s->phy_status = 0x7809;
-s->phy_control = 0x3000;
-s->phy_advertise = 0x01e1;
+s->phy_status = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD |
+MII_BMSR_10T_HD | MII_BMSR_AUTONEG | MII_BMSR_EXTCAP;
+s->phy_control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
+s->phy_advertise = MII_ANAR_CSMACD | MII_ANAR_TX | MII_ANAR_10FD |
+   MII_ANAR_10 | MII_ANAR_TXFD;
 s->phy_int_mask = 0;
 s->phy_int = 0;
 imx_phy_update_link(s);
@@ -285,37 +291,42 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
 reg %= 32;
 
 switch (reg) {
-case 0: /* Basic Control */
+case MII_BMCR: /* Basic Control */
 val = s->phy_control;
 break;
-case 1: /* Basic Status */
+case MII_BMSR: /* Basic Status */
 val = s->phy_status;
 break;
-case 2: /* ID1 */
-val = 0x0007;
+case MII_PHYID1: /* ID1 */
+val = LAN911x_PHYID1;
 break;
-case 3: /* ID2 */
-val = 0xc0d1;
+case MII_PHYID2: /* ID2 */
+val = LAN911x_PHYID2;
 break;
-case 4: /* Auto-neg advertisement */
+case MII_ANAR: /* Auto-neg advertisement */
 val = s->phy_advertise;
 break;
-case 5: /* Auto-neg Link Partner Ability */
-val = 0x0f71;
+case MII_ANLPAR: /* Auto-neg Link Partner Ability */
+val = MII_ANLPAR_CSMACD | MII_ANLPAR_10 | MII_ANLPAR_10FD |
+  MII_ANLPAR_TX | MII_ANLPAR_TXFD | MII_ANLPAR_PAUSE |
+  MII_ANLPAR_PAUSEASY;
 break;
-case 6: /* Auto-neg Expansion */
-val = 1;
+case MII_ANER: /* Auto-neg Expansion */
+val = MII_ANER_NWAY;
 break;
-case 29:/* Interrupt source.  */
+case MII_SMC911X_ISF:/* Interrupt source.  */
 val = s->phy_int;
 s->phy_int = 0;
 imx_phy_update_irq(s);
 break;
-case 30:/* Interrupt mask */
+case MII_SMC911X_IM:/* Interrupt mask */
 val = s->phy_int_mask;
 break;
-case 17:
-case 18:
+case MII_NSR:
+val = 1 << 6;
+break;
+case MII_LBREMR:
+case MII_REC:
 case 27:
 case 31:
 qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
@@ -343,26 +354,31 @@ static void imx_phy_write(IMXFECState *s, int reg, 
uint32_t val)
 trace_imx_phy_write(val, phy, reg);
 
 switch (reg) {
-case 0: /* Basic Control */
-if (val & 0x8000) {
+case MII_BMCR: /* Basic Control */
+if (val & MII_BMCR_RESET) {
 imx_phy_reset(s);
 } else {
-s->phy_control = val & 0x7980;
+s->phy_control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
+MII_BMCR_AUTOEN | MII_BMCR_PDOWN |
+MII_BMCR_FD | MII_BMCR_CTST);
 /* Complete autonegotiation immediately.  */
-

[PATCH v5 2/3] hw/net/imx_fec: Allow phy not to be the first device on the mii bus.

2020-06-04 Thread Jean-Christophe Dubois
Up to now we were allowing only one PHY device and it had to be the
first device on the bus.

The i.MX6UL has 2 Ethernet devices and can therefore have several
PHY devices on the bus (and not necessarilly as device 0).

This patch allows for PHY devices on 2nd, 3rd or any position.

Signed-off-by: Jean-Christophe Dubois 
---
 v2: Not present
 v3: Not present
 v4: Not present
 v5: Allow phy not to be the first device on the mii bus.

 hw/net/imx_fec.c| 19 ---
 hw/net/trace-events |  4 ++--
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index eefedc252de..29e613699ee 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -280,11 +280,9 @@ static void imx_phy_reset(IMXFECState *s)
 static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
+uint32_t phy = reg / 32;
 
-if (reg > 31) {
-/* we only advertise one phy */
-return 0;
-}
+reg %= 32;
 
 switch (reg) {
 case 0: /* Basic Control */
@@ -331,19 +329,18 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-trace_imx_phy_read(val, reg);
+trace_imx_phy_read(val, phy, reg);
 
 return val;
 }
 
 static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-trace_imx_phy_write(val, reg);
+uint32_t phy = reg / 32;
 
-if (reg > 31) {
-/* we only advertise one phy */
-return;
-}
+reg %= 32;
+
+trace_imx_phy_write(val, phy, reg);
 
 switch (reg) {
 case 0: /* Basic Control */
@@ -926,7 +923,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
extract32(value,
  18, 10)));
 } else {
-/* This a write operation */
+/* This is a write operation */
 imx_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 
16));
 }
 /* raise the interrupt as the PHY operation is done */
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 26700dad997..27dfa0ef775 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -410,8 +410,8 @@ i82596_set_multicast(uint16_t count) "Added %d multicast 
entries"
 i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
 
 # imx_fec.c
-imx_phy_read(uint32_t val, int reg) "0x%04"PRIx32" <= reg[%d]"
-imx_phy_write(uint32_t val, int reg) "0x%04"PRIx32" => reg[%d]"
+imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
+imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => 
phy[%d].reg[%d]"
 imx_phy_update_link(const char *s) "%s"
 imx_phy_reset(void) ""
 imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 
0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
-- 
2.25.1




[PATCH v5 0/3] hw/net/imx_fec: improve the imx fec emulator

2020-06-04 Thread Jean-Christophe Dubois
This series of path makes various improvement to the i.MX FEC ethernet
emulator.
  
 * PATCH 1: Convert the Ethernet emulator debug output to trace event
 * PATCH 2: Allow Ethernet PHY to be at any position on the MDIO bus
 * PATCH 3: Improve the i.MX FEC related PHY emulator by using standard
header symbols instead of hardcoded values.

Jean-Christophe Dubois (3):
  hw/net/imx_fec: Convert debug fprintf() to trace events
  hw/net/imx_fec: Allow phy not to be the first device on the mii bus.
  hw/net/imx_fec: improve PHY implementation.

 hw/net/imx_fec.c | 197 +--
 hw/net/trace-events  |  18 
 include/hw/net/mii.h |   4 +
 3 files changed, 119 insertions(+), 100 deletions(-)

-- 
2.25.1




[PATCH v5 1/3] hw/net/imx_fec: Convert debug fprintf() to trace events

2020-06-04 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200530102707.195131-1-...@tribudubois.net>
[PMD: Fixed 32-bit format string using PRIx32/PRIx64]
Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: <20200530102707.195131-1-...@tribudubois.net>
---
 v2: fix coding style issues.
 v3: improve tracing code based on feedback
 * change some tracing function names
 * remove unnecessary cast
 * add register index in addition to name
 v4: fix 32-bit format string using PRIx32/PRIx64
 v5: Nothing

 hw/net/imx_fec.c| 106 +++-
 hw/net/trace-events |  18 
 2 files changed, 63 insertions(+), 61 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 7adcc9df654..eefedc252de 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -31,34 +31,11 @@
 #include "qemu/module.h"
 #include "net/checksum.h"
 #include "net/eth.h"
+#include "trace.h"
 
 /* For crc32 */
 #include 
 
-#ifndef DEBUG_IMX_FEC
-#define DEBUG_IMX_FEC 0
-#endif
-
-#define FEC_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_FEC) { \
-fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
-#ifndef DEBUG_IMX_PHY
-#define DEBUG_IMX_PHY 0
-#endif
-
-#define PHY_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_PHY) { \
-fprintf(stderr, "[%s.phy]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
 #define IMX_MAX_DESC1024
 
 static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
@@ -262,43 +239,45 @@ static void imx_eth_update(IMXFECState *s);
  * For now we don't handle any GPIO/interrupt line, so the OS will
  * have to poll for the PHY status.
  */
-static void phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(IMXFECState *s)
 {
 imx_eth_update(s);
 }
 
-static void phy_update_link(IMXFECState *s)
+static void imx_phy_update_link(IMXFECState *s)
 {
 /* Autonegotiation status mirrors link status.  */
 if (qemu_get_queue(s->nic)->link_down) {
-PHY_PRINTF("link is down\n");
+trace_imx_phy_update_link("down");
 s->phy_status &= ~0x0024;
 s->phy_int |= PHY_INT_DOWN;
 } else {
-PHY_PRINTF("link is up\n");
+trace_imx_phy_update_link("up");
 s->phy_status |= 0x0024;
 s->phy_int |= PHY_INT_ENERGYON;
 s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
 }
-phy_update_irq(s);
+imx_phy_update_irq(s);
 }
 
 static void imx_eth_set_link(NetClientState *nc)
 {
-phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
 }
 
-static void phy_reset(IMXFECState *s)
+static void imx_phy_reset(IMXFECState *s)
 {
+trace_imx_phy_reset();
+
 s->phy_status = 0x7809;
 s->phy_control = 0x3000;
 s->phy_advertise = 0x01e1;
 s->phy_int_mask = 0;
 s->phy_int = 0;
-phy_update_link(s);
+imx_phy_update_link(s);
 }
 
-static uint32_t do_phy_read(IMXFECState *s, int reg)
+static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
 
@@ -332,7 +311,7 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 case 29:/* Interrupt source.  */
 val = s->phy_int;
 s->phy_int = 0;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 30:/* Interrupt mask */
 val = s->phy_int_mask;
@@ -352,14 +331,14 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-PHY_PRINTF("read 0x%04x @ %d\n", val, reg);
+trace_imx_phy_read(val, reg);
 
 return val;
 }
 
-static void do_phy_write(IMXFECState *s, int reg, uint32_t val)
+static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+trace_imx_phy_write(val, reg);
 
 if (reg > 31) {
 /* we only advertise one phy */
@@ -369,7 +348,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 switch (reg) {
 case 0: /* Basic Control */
 if (val & 0x8000) {
-phy_reset(s);
+imx_phy_reset(s);
 } else {
 s->phy_control = val & 0x7980;
 /* Complete autonegotiation immediately.  */
@@ -383,7 +362,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 break;
 case 30:/* Interrupt mask */
 s->phy_int_mask = val & 0xff;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 17:
 case 18:
@@ -402,6 +381,8 @@ static void do_phy_write(IMXFECState *s, int reg, u

[PATCH v3] hw/net/imx_fec.c: Convert debug fprintf() to trace event

2020-05-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

 v2: fix coding style issues.
 v3: improve tracing code based on feedback
 * change some tracing function names
 * remove unnecessary cast
 * add register index in addition to name

 hw/net/imx_fec.c| 106 +++-
 hw/net/trace-events |  18 
 2 files changed, 63 insertions(+), 61 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 7adcc9df654..eefedc252de 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -31,34 +31,11 @@
 #include "qemu/module.h"
 #include "net/checksum.h"
 #include "net/eth.h"
+#include "trace.h"
 
 /* For crc32 */
 #include 
 
-#ifndef DEBUG_IMX_FEC
-#define DEBUG_IMX_FEC 0
-#endif
-
-#define FEC_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_FEC) { \
-fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
-#ifndef DEBUG_IMX_PHY
-#define DEBUG_IMX_PHY 0
-#endif
-
-#define PHY_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_PHY) { \
-fprintf(stderr, "[%s.phy]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
 #define IMX_MAX_DESC1024
 
 static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
@@ -262,43 +239,45 @@ static void imx_eth_update(IMXFECState *s);
  * For now we don't handle any GPIO/interrupt line, so the OS will
  * have to poll for the PHY status.
  */
-static void phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(IMXFECState *s)
 {
 imx_eth_update(s);
 }
 
-static void phy_update_link(IMXFECState *s)
+static void imx_phy_update_link(IMXFECState *s)
 {
 /* Autonegotiation status mirrors link status.  */
 if (qemu_get_queue(s->nic)->link_down) {
-PHY_PRINTF("link is down\n");
+trace_imx_phy_update_link("down");
 s->phy_status &= ~0x0024;
 s->phy_int |= PHY_INT_DOWN;
 } else {
-PHY_PRINTF("link is up\n");
+trace_imx_phy_update_link("up");
 s->phy_status |= 0x0024;
 s->phy_int |= PHY_INT_ENERGYON;
 s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
 }
-phy_update_irq(s);
+imx_phy_update_irq(s);
 }
 
 static void imx_eth_set_link(NetClientState *nc)
 {
-phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
 }
 
-static void phy_reset(IMXFECState *s)
+static void imx_phy_reset(IMXFECState *s)
 {
+trace_imx_phy_reset();
+
 s->phy_status = 0x7809;
 s->phy_control = 0x3000;
 s->phy_advertise = 0x01e1;
 s->phy_int_mask = 0;
 s->phy_int = 0;
-phy_update_link(s);
+imx_phy_update_link(s);
 }
 
-static uint32_t do_phy_read(IMXFECState *s, int reg)
+static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
 
@@ -332,7 +311,7 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 case 29:/* Interrupt source.  */
 val = s->phy_int;
 s->phy_int = 0;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 30:/* Interrupt mask */
 val = s->phy_int_mask;
@@ -352,14 +331,14 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-PHY_PRINTF("read 0x%04x @ %d\n", val, reg);
+trace_imx_phy_read(val, reg);
 
 return val;
 }
 
-static void do_phy_write(IMXFECState *s, int reg, uint32_t val)
+static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+trace_imx_phy_write(val, reg);
 
 if (reg > 31) {
 /* we only advertise one phy */
@@ -369,7 +348,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 switch (reg) {
 case 0: /* Basic Control */
 if (val & 0x8000) {
-phy_reset(s);
+imx_phy_reset(s);
 } else {
 s->phy_control = val & 0x7980;
 /* Complete autonegotiation immediately.  */
@@ -383,7 +362,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 break;
 case 30:/* Interrupt mask */
 s->phy_int_mask = val & 0xff;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 17:
 case 18:
@@ -402,6 +381,8 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
 {
 dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data);
 }
 
 static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
@@ -412,6 +393,9 @@ static void imx_fec_write_bd(IMXFECBufDesc *bd

Re: [PATCH] hw/net/imx_fec.c: Convert debug fprintf() to trace event

2020-05-30 Thread Jean-Christophe DUBOIS

Le 30/05/2020 à 09:49, Philippe Mathieu-Daudé a écrit :

Hi Jean-Christophe,

On 5/29/20 8:00 PM, Jean-Christophe Dubois wrote:

Signed-off-by: Jean-Christophe Dubois 
---
  hw/net/imx_fec.c| 101 ++--
  hw/net/trace-events |  18 
  2 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 7adcc9df654..823dac0603b 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -31,34 +31,11 @@
  #include "qemu/module.h"
  #include "net/checksum.h"
  #include "net/eth.h"
+#include "trace.h"
  
  /* For crc32 */

  #include 
  
-#ifndef DEBUG_IMX_FEC

-#define DEBUG_IMX_FEC 0
-#endif
-
-#define FEC_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_FEC) { \
-fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
-#ifndef DEBUG_IMX_PHY
-#define DEBUG_IMX_PHY 0
-#endif
-
-#define PHY_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_PHY) { \
-fprintf(stderr, "[%s.phy]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
  #define IMX_MAX_DESC1024
  
  static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)

@@ -262,43 +239,45 @@ static void imx_eth_update(IMXFECState *s);
   * For now we don't handle any GPIO/interrupt line, so the OS will
   * have to poll for the PHY status.
   */
-static void phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(IMXFECState *s)
  {
  imx_eth_update(s);
  }
  
-static void phy_update_link(IMXFECState *s)

+static void imx_phy_update_link(IMXFECState *s)
  {
  /* Autonegotiation status mirrors link status.  */
  if (qemu_get_queue(s->nic)->link_down) {
-PHY_PRINTF("link is down\n");
+trace_imx_phy_update_link("down");
  s->phy_status &= ~0x0024;
  s->phy_int |= PHY_INT_DOWN;
  } else {
-PHY_PRINTF("link is up\n");
+trace_imx_phy_update_link("up");
  s->phy_status |= 0x0024;
  s->phy_int |= PHY_INT_ENERGYON;
  s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
  }
-phy_update_irq(s);
+imx_phy_update_irq(s);
  }
  
  static void imx_eth_set_link(NetClientState *nc)

  {
-phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
  }
  
-static void phy_reset(IMXFECState *s)

+static void imx_phy_reset(IMXFECState *s)
  {
+trace_imx_phy_reset();
+
  s->phy_status = 0x7809;
  s->phy_control = 0x3000;
  s->phy_advertise = 0x01e1;
  s->phy_int_mask = 0;
  s->phy_int = 0;
-phy_update_link(s);
+imx_phy_update_link(s);
  }
  
-static uint32_t do_phy_read(IMXFECState *s, int reg)

+static uint32_t imx_phy_read(IMXFECState *s, int reg)
  {
  uint32_t val;
  
@@ -332,7 +311,7 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)

  case 29:/* Interrupt source.  */
  val = s->phy_int;
  s->phy_int = 0;
-phy_update_irq(s);
+imx_phy_update_irq(s);
  break;
  case 30:/* Interrupt mask */
  val = s->phy_int_mask;
@@ -352,14 +331,14 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
  break;
  }
  
-PHY_PRINTF("read 0x%04x @ %d\n", val, reg);

+trace_imx_phy_read(val, reg);
  
  return val;

  }
  
-static void do_phy_write(IMXFECState *s, int reg, uint32_t val)

+static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
  {
-PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+trace_imx_phy_write(val, reg);
  
  if (reg > 31) {

  /* we only advertise one phy */
@@ -369,7 +348,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
  switch (reg) {
  case 0: /* Basic Control */
  if (val & 0x8000) {
-phy_reset(s);
+imx_phy_reset(s);
  } else {
  s->phy_control = val & 0x7980;
  /* Complete autonegotiation immediately.  */
@@ -383,7 +362,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
  break;
  case 30:/* Interrupt mask */
  s->phy_int_mask = val & 0xff;
-phy_update_irq(s);
+imx_phy_update_irq(s);
  break;
  case 17:
  case 18:
@@ -402,6 +381,8 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
  static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
  {
  dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data);
  }
  
  static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)

@@ -412,6 +393,9

[PATCH v2] hw/net/imx_fec.c: Convert debug fprintf() to trace event

2020-05-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

 v2: fix coding style issues.

 hw/net/imx_fec.c| 101 ++--
 hw/net/trace-events |  18 
 2 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 7adcc9df654..853d47deeb6 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -31,34 +31,11 @@
 #include "qemu/module.h"
 #include "net/checksum.h"
 #include "net/eth.h"
+#include "trace.h"
 
 /* For crc32 */
 #include 
 
-#ifndef DEBUG_IMX_FEC
-#define DEBUG_IMX_FEC 0
-#endif
-
-#define FEC_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_FEC) { \
-fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
-#ifndef DEBUG_IMX_PHY
-#define DEBUG_IMX_PHY 0
-#endif
-
-#define PHY_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_PHY) { \
-fprintf(stderr, "[%s.phy]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
 #define IMX_MAX_DESC1024
 
 static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
@@ -262,43 +239,45 @@ static void imx_eth_update(IMXFECState *s);
  * For now we don't handle any GPIO/interrupt line, so the OS will
  * have to poll for the PHY status.
  */
-static void phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(IMXFECState *s)
 {
 imx_eth_update(s);
 }
 
-static void phy_update_link(IMXFECState *s)
+static void imx_phy_update_link(IMXFECState *s)
 {
 /* Autonegotiation status mirrors link status.  */
 if (qemu_get_queue(s->nic)->link_down) {
-PHY_PRINTF("link is down\n");
+trace_imx_phy_update_link("down");
 s->phy_status &= ~0x0024;
 s->phy_int |= PHY_INT_DOWN;
 } else {
-PHY_PRINTF("link is up\n");
+trace_imx_phy_update_link("up");
 s->phy_status |= 0x0024;
 s->phy_int |= PHY_INT_ENERGYON;
 s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
 }
-phy_update_irq(s);
+imx_phy_update_irq(s);
 }
 
 static void imx_eth_set_link(NetClientState *nc)
 {
-phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
 }
 
-static void phy_reset(IMXFECState *s)
+static void imx_phy_reset(IMXFECState *s)
 {
+trace_imx_phy_reset();
+
 s->phy_status = 0x7809;
 s->phy_control = 0x3000;
 s->phy_advertise = 0x01e1;
 s->phy_int_mask = 0;
 s->phy_int = 0;
-phy_update_link(s);
+imx_phy_update_link(s);
 }
 
-static uint32_t do_phy_read(IMXFECState *s, int reg)
+static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
 
@@ -332,7 +311,7 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 case 29:/* Interrupt source.  */
 val = s->phy_int;
 s->phy_int = 0;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 30:/* Interrupt mask */
 val = s->phy_int_mask;
@@ -352,14 +331,14 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-PHY_PRINTF("read 0x%04x @ %d\n", val, reg);
+trace_imx_phy_read(val, reg);
 
 return val;
 }
 
-static void do_phy_write(IMXFECState *s, int reg, uint32_t val)
+static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+trace_imx_phy_write(val, reg);
 
 if (reg > 31) {
 /* we only advertise one phy */
@@ -369,7 +348,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 switch (reg) {
 case 0: /* Basic Control */
 if (val & 0x8000) {
-phy_reset(s);
+imx_phy_reset(s);
 } else {
 s->phy_control = val & 0x7980;
 /* Complete autonegotiation immediately.  */
@@ -383,7 +362,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 break;
 case 30:/* Interrupt mask */
 s->phy_int_mask = val & 0xff;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 17:
 case 18:
@@ -402,6 +381,8 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
 {
 dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data);
 }
 
 static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
@@ -412,6 +393,9 @@ static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t 
addr)
 static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr)
 {
 dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+  

[PATCH] hw/net/imx_fec.c: Convert debug fprintf() to trace event

2020-05-29 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/net/imx_fec.c| 101 ++--
 hw/net/trace-events |  18 
 2 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 7adcc9df654..823dac0603b 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -31,34 +31,11 @@
 #include "qemu/module.h"
 #include "net/checksum.h"
 #include "net/eth.h"
+#include "trace.h"
 
 /* For crc32 */
 #include 
 
-#ifndef DEBUG_IMX_FEC
-#define DEBUG_IMX_FEC 0
-#endif
-
-#define FEC_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_FEC) { \
-fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
-#ifndef DEBUG_IMX_PHY
-#define DEBUG_IMX_PHY 0
-#endif
-
-#define PHY_PRINTF(fmt, args...) \
-do { \
-if (DEBUG_IMX_PHY) { \
-fprintf(stderr, "[%s.phy]%s: " fmt , TYPE_IMX_FEC, \
- __func__, ##args); \
-} \
-} while (0)
-
 #define IMX_MAX_DESC1024
 
 static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
@@ -262,43 +239,45 @@ static void imx_eth_update(IMXFECState *s);
  * For now we don't handle any GPIO/interrupt line, so the OS will
  * have to poll for the PHY status.
  */
-static void phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(IMXFECState *s)
 {
 imx_eth_update(s);
 }
 
-static void phy_update_link(IMXFECState *s)
+static void imx_phy_update_link(IMXFECState *s)
 {
 /* Autonegotiation status mirrors link status.  */
 if (qemu_get_queue(s->nic)->link_down) {
-PHY_PRINTF("link is down\n");
+trace_imx_phy_update_link("down");
 s->phy_status &= ~0x0024;
 s->phy_int |= PHY_INT_DOWN;
 } else {
-PHY_PRINTF("link is up\n");
+trace_imx_phy_update_link("up");
 s->phy_status |= 0x0024;
 s->phy_int |= PHY_INT_ENERGYON;
 s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
 }
-phy_update_irq(s);
+imx_phy_update_irq(s);
 }
 
 static void imx_eth_set_link(NetClientState *nc)
 {
-phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
 }
 
-static void phy_reset(IMXFECState *s)
+static void imx_phy_reset(IMXFECState *s)
 {
+trace_imx_phy_reset();
+
 s->phy_status = 0x7809;
 s->phy_control = 0x3000;
 s->phy_advertise = 0x01e1;
 s->phy_int_mask = 0;
 s->phy_int = 0;
-phy_update_link(s);
+imx_phy_update_link(s);
 }
 
-static uint32_t do_phy_read(IMXFECState *s, int reg)
+static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
 uint32_t val;
 
@@ -332,7 +311,7 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 case 29:/* Interrupt source.  */
 val = s->phy_int;
 s->phy_int = 0;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 30:/* Interrupt mask */
 val = s->phy_int_mask;
@@ -352,14 +331,14 @@ static uint32_t do_phy_read(IMXFECState *s, int reg)
 break;
 }
 
-PHY_PRINTF("read 0x%04x @ %d\n", val, reg);
+trace_imx_phy_read(val, reg);
 
 return val;
 }
 
-static void do_phy_write(IMXFECState *s, int reg, uint32_t val)
+static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 {
-PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+trace_imx_phy_write(val, reg);
 
 if (reg > 31) {
 /* we only advertise one phy */
@@ -369,7 +348,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 switch (reg) {
 case 0: /* Basic Control */
 if (val & 0x8000) {
-phy_reset(s);
+imx_phy_reset(s);
 } else {
 s->phy_control = val & 0x7980;
 /* Complete autonegotiation immediately.  */
@@ -383,7 +362,7 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 break;
 case 30:/* Interrupt mask */
 s->phy_int_mask = val & 0xff;
-phy_update_irq(s);
+imx_phy_update_irq(s);
 break;
 case 17:
 case 18:
@@ -402,6 +381,8 @@ static void do_phy_write(IMXFECState *s, int reg, uint32_t 
val)
 static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
 {
 dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data);
 }
 
 static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
@@ -412,6 +393,9 @@ static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t 
addr)
 static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr)
 {
 dma_memory_read(_space_memory, addr, bd, sizeof(*bd));
+
+trace_imx_enet_read_bd(addr

[PATCH] hw/misc/imx6ul_ccm.c: Implement non writable bits in CCM registers

2020-05-29 Thread Jean-Christophe Dubois
Some bits of the CCM registers are non writable.

This was left undone in the initial commit (all bits of registers were
writable).

This patch add the required code to protect non writable bits.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/imx6ul_ccm.c | 81 +---
 1 file changed, 68 insertions(+), 13 deletions(-)

diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
index a2fc1d0364a..ede845fde8e 100644
--- a/hw/misc/imx6ul_ccm.c
+++ b/hw/misc/imx6ul_ccm.c
@@ -19,6 +19,62 @@
 
 #include "trace.h"
 
+static const uint32_t ccm_mask[CCM_MAX] = {
+[CCM_CCR] = 0xf01fef80,
+[CCM_CCDR] = 0xfffe,
+[CCM_CSR] = 0x,
+[CCM_CCSR] = 0xfef2,
+[CCM_CACRR] = 0xfff8,
+[CCM_CBCDR] = 0xc1f8e000,
+[CCM_CBCMR] = 0xfc03cfff,
+[CCM_CSCMR1] = 0x8070,
+[CCM_CSCMR2] = 0xe01ff003,
+[CCM_CSCDR1] = 0xfe00c780,
+[CCM_CS1CDR] = 0xfe00fe00,
+[CCM_CS2CDR] = 0xf8007000,
+[CCM_CDCDR] = 0xf00f,
+[CCM_CHSCCDR] = 0xfffc01ff,
+[CCM_CSCDR2] = 0xfe0001ff,
+[CCM_CSCDR3] = 0xc1ff,
+[CCM_CDHIPR] = 0x,
+[CCM_CTOR] = 0x,
+[CCM_CLPCR] = 0xf39ff01c,
+[CCM_CISR] = 0xfb85ffbe,
+[CCM_CIMR] = 0xfb85ffbf,
+[CCM_CCOSR] = 0xfe00fe00,
+[CCM_CGPR] = 0xfffc3fea,
+[CCM_CCGR0] = 0x,
+[CCM_CCGR1] = 0x,
+[CCM_CCGR2] = 0x,
+[CCM_CCGR3] = 0x,
+[CCM_CCGR4] = 0x,
+[CCM_CCGR5] = 0x,
+[CCM_CCGR6] = 0x,
+[CCM_CMEOR] = 0xaf1f,
+};
+
+static const uint32_t analog_mask[CCM_ANALOG_MAX] = {
+[CCM_ANALOG_PLL_ARM] = 0xfff60f80,
+[CCM_ANALOG_PLL_USB1] = 0xfffe0fbc,
+[CCM_ANALOG_PLL_USB2] = 0xfffe0fbc,
+[CCM_ANALOG_PLL_SYS] = 0xfffa0ffe,
+[CCM_ANALOG_PLL_SYS_SS] = 0x,
+[CCM_ANALOG_PLL_SYS_NUM] = 0xc000,
+[CCM_ANALOG_PLL_SYS_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_AUDIO] = 0xffe20f80,
+[CCM_ANALOG_PLL_AUDIO_NUM] = 0xc000,
+[CCM_ANALOG_PLL_AUDIO_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_VIDEO] = 0xffe20f80,
+[CCM_ANALOG_PLL_VIDEO_NUM] = 0xc000,
+[CCM_ANALOG_PLL_VIDEO_DENOM] = 0xc000,
+[CCM_ANALOG_PLL_ENET] = 0xffc20ff0,
+[CCM_ANALOG_PFD_480] = 0x40404040,
+[CCM_ANALOG_PFD_528] = 0x40404040,
+[PMU_MISC0] = 0x01fe8306,
+[PMU_MISC1] = 0x07fcede0,
+[PMU_MISC2] = 0x005f5f5f,
+};
+
 static const char *imx6ul_ccm_reg_name(uint32_t reg)
 {
 static char unknown[20];
@@ -596,11 +652,8 @@ static void imx6ul_ccm_write(void *opaque, hwaddr offset, 
uint64_t value,
 
 trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
 
-/*
- * We will do a better implementation later. In particular some bits
- * cannot be written to.
- */
-s->ccm[index] = (uint32_t)value;
+s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
+   ((uint32_t)value & ~ccm_mask[index]);
 }
 
 static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
@@ -737,7 +790,8 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, setting bits passed in the value.
  */
-s->analog[index - 1] |= value;
+s->analog[index - 1] = s->analog[index - 1] |
+   (value & ~analog_mask[index - 1]);
 break;
 case CCM_ANALOG_PLL_ARM_CLR:
 case CCM_ANALOG_PLL_USB1_CLR:
@@ -762,7 +816,8 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, unsetting bits passed in the value.
  */
-s->analog[index - 2] &= ~value;
+s->analog[index - 2] = s->analog[index - 2] &
+   ~(value & ~analog_mask[index - 2]);
 break;
 case CCM_ANALOG_PLL_ARM_TOG:
 case CCM_ANALOG_PLL_USB1_TOG:
@@ -787,14 +842,14 @@ static void imx6ul_analog_write(void *opaque, hwaddr 
offset, uint64_t value,
  * the REG_NAME register. So we change the value of the
  * REG_NAME register, toggling bits passed in the value.
  */
-s->analog[index - 3] ^= value;
+s->analog[index - 3] = (s->analog[index - 3] &
+analog_mask[index - 3]) |
+   ((value ^ s->analog[index - 3]) &
+~analog_mask[index - 3]);
 break;
 default:
-/*
- * We will do a better implementation later. In particular some bits
- * cannot be written to.
- */
-s->analog[index] = value;
+s->analog[index] = (s->analog[index] & analog_mask[index]) |
+   (value & ~analog_mask[index]);
 break;
 }
 }
-- 
2.25.1




[Qemu-devel] [PATCH v3 3/3] i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

2018-07-30 Thread Jean-Christophe Dubois
Tested by booting linux 4.18 (built using imx_v6_v7_defconfig) on the
emulated board.

Signed-off-by: Jean-Christophe Dubois 
---

Changes in V3:
 * None

Changes in V2:
 * use object_initialize_child instead of several funcions

 hw/arm/Makefile.objs  |  2 +-
 hw/arm/mcimx6ul-evk.c | 85 +++
 2 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/mcimx6ul-evk.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index e419ad040b..2902f47b4c 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,4 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
-obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
new file mode 100644
index 00..fb2b015bf6
--- /dev/null
+++ b/hw/arm/mcimx6ul-evk.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * MCIMX6UL_EVK Board System emulation.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a mcimx6ul_evk board, with a Freescale
+ * i.MX6ul SoC
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+#include "sysemu/qtest.h"
+
+typedef struct {
+FslIMX6ULState soc;
+MemoryRegion ram;
+} MCIMX6ULEVK;
+
+static void mcimx6ul_evk_init(MachineState *machine)
+{
+static struct arm_boot_info boot_info;
+MCIMX6ULEVK *s = g_new0(MCIMX6ULEVK, 1);
+int i;
+
+if (machine->ram_size > FSL_IMX6UL_MMDC_SIZE) {
+error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
+ machine->ram_size, FSL_IMX6UL_MMDC_SIZE);
+exit(1);
+}
+
+boot_info = (struct arm_boot_info) {
+.loader_start = FSL_IMX6UL_MMDC_ADDR,
+.board_id = -1,
+.ram_size = machine->ram_size,
+.kernel_filename = machine->kernel_filename,
+.kernel_cmdline = machine->kernel_cmdline,
+.initrd_filename = machine->initrd_filename,
+.nb_cpus = smp_cpus,
+};
+
+object_initialize_child(OBJECT(machine), "soc", >soc,  sizeof(s->soc),
+TYPE_FSL_IMX6UL, _fatal, NULL);
+
+object_property_set_bool(OBJECT(>soc), true, "realized", _fatal);
+
+memory_region_allocate_system_memory(>ram, NULL, "mcimx6ul-evk.ram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(),
+FSL_IMX6UL_MMDC_ADDR, >ram);
+
+for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
+BusState *bus;
+DeviceState *carddev;
+DriveInfo *di;
+BlockBackend *blk;
+
+di = drive_get_next(IF_SD);
+blk = di ? blk_by_legacy_dinfo(di) : NULL;
+bus = qdev_get_child_bus(DEVICE(>soc.usdhc[i]), "sd-bus");
+carddev = qdev_create(bus, TYPE_SD_CARD);
+qdev_prop_set_drive(carddev, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(carddev), true,
+ "realized", _fatal);
+}
+
+if (!qtest_enabled()) {
+arm_load_kernel(>soc.cpu[0], _info);
+}
+}
+
+static void mcimx6ul_evk_machine_init(MachineClass *mc)
+{
+mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
+mc->init = mcimx6ul_evk_init;
+mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
+}
+DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
-- 
2.17.1




[Qemu-devel] [PATCH v3 2/3] i.MX6UL: Add i.MX6UL SOC

2018-07-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes in V3:
 * Fix coding style issue with indent.

Changes in V2:
 * use object_initialize_child instead of several funcions
 * use sysbus_init_child_obj instead for several functions

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 617 
 include/hw/arm/fsl-imx6ul.h | 339 ++
 4 files changed, 958 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 834d45cfaf..311584fd74 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -133,6 +133,7 @@ CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
+CONFIG_FSL_IMX6UL=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index d51fcecaf2..e419ad040b 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,3 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
new file mode 100644
index 00..258f470623
--- /dev/null
+++ b/hw/arm/fsl-imx6ul.c
@@ -0,0 +1,617 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * i.MX6UL SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx7.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 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 "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+#define NAME_SIZE 20
+
+static void fsl_imx6ul_init(Object *obj)
+{
+FslIMX6ULState *s = FSL_IMX6UL(obj);
+char name[NAME_SIZE];
+int i;
+
+for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
+snprintf(name, NAME_SIZE, "cpu%d", i);
+object_initialize_child(obj, name, >cpu[i], sizeof(s->cpu[i]),
+"cortex-a7-" TYPE_ARM_CPU, _abort, NULL);
+}
+
+/*
+ * A7MPCORE
+ */
+sysbus_init_child_obj(obj, "a7mpcore", >a7mpcore, sizeof(s->a7mpcore),
+  TYPE_A15MPCORE_PRIV);
+
+/*
+ * CCM
+ */
+sysbus_init_child_obj(obj, "ccm", >ccm, sizeof(s->ccm), 
TYPE_IMX6UL_CCM);
+
+/*
+ * SRC
+ */
+sysbus_init_child_obj(obj, "src", >src, sizeof(s->src), TYPE_IMX6_SRC);
+
+/*
+ * GPCv2
+ */
+sysbus_init_child_obj(obj, "gpcv2", >gpcv2, sizeof(s->gpcv2),
+  TYPE_IMX_GPCV2);
+
+/*
+ * SNVS
+ */
+sysbus_init_child_obj(obj, "snvs", >snvs, sizeof(s->snvs),
+  TYPE_IMX7_SNVS);
+
+/*
+ * GPR
+ */
+sysbus_init_child_obj(obj, "gpr", >gpr, sizeof(s->gpr),
+  TYPE_IMX7_GPR);
+
+/*
+ * GPIOs 1 to 5
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
+snprintf(name, NAME_SIZE, "gpio%d", i);
+sysbus_init_child_obj(obj, name, >gpio[i], sizeof(s->gpio[i]),
+  TYPE_IMX_GPIO);
+}
+
+/*
+ * GPT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
+snprintf(name, NAME_SIZE, "gpt%d", i);
+sysbus_init_child_obj(obj, name, >gpt[i], sizeof(s->gpt[i]),
+  TYPE_IMX7_GPT);
+}
+
+/*
+ * EPIT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
+snprintf(name, NAME_SIZE, "epit%d", i + 1);
+sysbus_init_child_obj(obj, name, >epit[i], sizeof(s->epit[i]),
+  TYPE_IMX_EPIT);
+}
+
+/*
+ * eCSPI
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
+snprintf(name, NAME_SIZE, "spi%d", i + 1);
+sysbus_init_child_obj(obj, name, >spi[i], sizeof(s->spi[i]),
+  TYPE_IMX_SPI);
+}
+
+/*
+ * I2C
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
+snprintf(name, NAME_SIZE, "i2c%d", i + 1);
+sysbus_init_child_o

[Qemu-devel] [PATCH v3 0/3] i.MX: Add the i.MX6UL SOC and a reference board.

2018-07-30 Thread Jean-Christophe Dubois
This series adds the i.MX6UL SOC from NXP/Freescale and the reference
evaluation board.

This series was tested by booting linux 4.18 (built using imx_v6_v7_defconfig)
on the emulated board (with the appropriate device tree).

Jean-Christophe Dubois (3):
  i.MX6UL: Add i.MX6UL specific CCM device
  i.MX6UL: Add i.MX6UL SOC
  i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 617 ++
 hw/arm/mcimx6ul-evk.c   |  85 +++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx6ul_ccm.c| 890 
 hw/misc/trace-events|   7 +
 include/hw/arm/fsl-imx6ul.h | 339 
 include/hw/misc/imx6ul_ccm.h| 226 
 9 files changed, 2167 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 hw/arm/mcimx6ul-evk.c
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h
 create mode 100644 include/hw/misc/imx6ul_ccm.h

-- 
2.17.1




[Qemu-devel] [PATCH v3 1/3] i.MX6UL: Add i.MX6UL specific CCM device

2018-07-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes in V3:
 * None

Changes in V2:
 * move all CCM "debug" to the "trace" framework for i.MX6UL
 * remove unecessary breaks
 * prevent g_assert_not_reached triggered by guest.
 * Add assert to help static analyzer.
 * use FIELD_EX32 from hw/registerfields.h instead of defining my own.

 hw/misc/Makefile.objs|   1 +
 hw/misc/imx6ul_ccm.c | 890 +++
 hw/misc/trace-events |   7 +
 include/hw/misc/imx6ul_ccm.h | 226 +
 4 files changed, 1124 insertions(+)
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/misc/imx6ul_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 9350900845..51d27b3af1 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6ul_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
new file mode 100644
index 00..32197b2435
--- /dev/null
+++ b/hw/misc/imx6ul_ccm.c
@@ -0,0 +1,890 @@
+/*
+ * IMX6UL Clock Control Module
+ *
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/registerfields.h"
+#include "hw/misc/imx6ul_ccm.h"
+#include "qemu/log.h"
+
+#include "trace.h"
+
+static const char *imx6ul_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_CCR:
+return "CCR";
+case CCM_CCDR:
+return "CCDR";
+case CCM_CSR:
+return "CSR";
+case CCM_CCSR:
+return "CCSR";
+case CCM_CACRR:
+return "CACRR";
+case CCM_CBCDR:
+return "CBCDR";
+case CCM_CBCMR:
+return "CBCMR";
+case CCM_CSCMR1:
+return "CSCMR1";
+case CCM_CSCMR2:
+return "CSCMR2";
+case CCM_CSCDR1:
+return "CSCDR1";
+case CCM_CS1CDR:
+return "CS1CDR";
+case CCM_CS2CDR:
+return "CS2CDR";
+case CCM_CDCDR:
+return "CDCDR";
+case CCM_CHSCCDR:
+return "CHSCCDR";
+case CCM_CSCDR2:
+return "CSCDR2";
+case CCM_CSCDR3:
+return "CSCDR3";
+case CCM_CDHIPR:
+return "CDHIPR";
+case CCM_CTOR:
+return "CTOR";
+case CCM_CLPCR:
+return "CLPCR";
+case CCM_CISR:
+return "CISR";
+case CCM_CIMR:
+return "CIMR";
+case CCM_CCOSR:
+return "CCOSR";
+case CCM_CGPR:
+return "CGPR";
+case CCM_CCGR0:
+return "CCGR0";
+case CCM_CCGR1:
+return "CCGR1";
+case CCM_CCGR2:
+return "CCGR2";
+case CCM_CCGR3:
+return "CCGR3";
+case CCM_CCGR4:
+return "CCGR4";
+case CCM_CCGR5:
+return "CCGR5";
+case CCM_CCGR6:
+return "CCGR6";
+case CCM_CMEOR:
+return "CMEOR";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const char *imx6ul_analog_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_ANALOG_PLL_ARM:
+return "PLL_ARM";
+case CCM_ANALOG_PLL_ARM_SET:
+return "PLL_ARM_SET";
+case CCM_ANALOG_PLL_ARM_CLR:
+return "PLL_ARM_CLR";
+case CCM_ANALOG_PLL_ARM_TOG:
+return "PLL_ARM_TOG";
+case CCM_ANALOG_PLL_USB1:
+return "PLL_USB1";
+case CCM_ANALOG_PLL_USB1_SET:
+return "PLL_USB1_SET";
+case CCM_ANALOG_PLL_USB1_CLR:
+return "PLL_USB1_CLR";
+case CCM_ANALOG_PLL_USB1_TOG:
+return "PLL_USB1_TOG";
+case CCM_ANALOG_PLL_USB2:
+return "PLL_USB2";
+case CCM_ANALOG_PLL_USB2_SET:
+return "PLL_USB2_SET";
+case CCM_ANALOG_PLL_USB2_CLR:
+return "PLL_USB2_CLR";
+case CCM_ANALOG_PLL_USB2_TOG:
+return "PLL_USB2_TOG";
+case CCM_ANALOG_PLL_SYS:
+return "PLL_SYS";
+case CCM_ANALOG_PLL_SYS_SET:
+return "PLL_SYS_SET";
+case CCM_ANALOG_PLL_SYS_CLR:
+return "PLL_SYS_CLR";
+case CCM_ANALOG_PLL_SYS_TOG:
+  

[Qemu-devel] [PATCH v2 1/3] i.MX6UL: Add i.MX6UL specific CCM device

2018-07-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes in V2:
 * move all CCM "debug" to the "trace" framework for i.MX6UL
 * remove unecessary breaks
 * prevent g_assert_not_reached triggered by guest.
 * Add assert to help static analyzer.
 * use FIELD_EX32 from hw/registerfields.h instead of defining my own.

 hw/misc/Makefile.objs|   1 +
 hw/misc/imx6ul_ccm.c | 890 +++
 hw/misc/trace-events |   7 +
 include/hw/misc/imx6ul_ccm.h | 226 +
 4 files changed, 1124 insertions(+)
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/misc/imx6ul_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 9350900845..51d27b3af1 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6ul_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
new file mode 100644
index 00..32197b2435
--- /dev/null
+++ b/hw/misc/imx6ul_ccm.c
@@ -0,0 +1,890 @@
+/*
+ * IMX6UL Clock Control Module
+ *
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/registerfields.h"
+#include "hw/misc/imx6ul_ccm.h"
+#include "qemu/log.h"
+
+#include "trace.h"
+
+static const char *imx6ul_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_CCR:
+return "CCR";
+case CCM_CCDR:
+return "CCDR";
+case CCM_CSR:
+return "CSR";
+case CCM_CCSR:
+return "CCSR";
+case CCM_CACRR:
+return "CACRR";
+case CCM_CBCDR:
+return "CBCDR";
+case CCM_CBCMR:
+return "CBCMR";
+case CCM_CSCMR1:
+return "CSCMR1";
+case CCM_CSCMR2:
+return "CSCMR2";
+case CCM_CSCDR1:
+return "CSCDR1";
+case CCM_CS1CDR:
+return "CS1CDR";
+case CCM_CS2CDR:
+return "CS2CDR";
+case CCM_CDCDR:
+return "CDCDR";
+case CCM_CHSCCDR:
+return "CHSCCDR";
+case CCM_CSCDR2:
+return "CSCDR2";
+case CCM_CSCDR3:
+return "CSCDR3";
+case CCM_CDHIPR:
+return "CDHIPR";
+case CCM_CTOR:
+return "CTOR";
+case CCM_CLPCR:
+return "CLPCR";
+case CCM_CISR:
+return "CISR";
+case CCM_CIMR:
+return "CIMR";
+case CCM_CCOSR:
+return "CCOSR";
+case CCM_CGPR:
+return "CGPR";
+case CCM_CCGR0:
+return "CCGR0";
+case CCM_CCGR1:
+return "CCGR1";
+case CCM_CCGR2:
+return "CCGR2";
+case CCM_CCGR3:
+return "CCGR3";
+case CCM_CCGR4:
+return "CCGR4";
+case CCM_CCGR5:
+return "CCGR5";
+case CCM_CCGR6:
+return "CCGR6";
+case CCM_CMEOR:
+return "CMEOR";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const char *imx6ul_analog_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_ANALOG_PLL_ARM:
+return "PLL_ARM";
+case CCM_ANALOG_PLL_ARM_SET:
+return "PLL_ARM_SET";
+case CCM_ANALOG_PLL_ARM_CLR:
+return "PLL_ARM_CLR";
+case CCM_ANALOG_PLL_ARM_TOG:
+return "PLL_ARM_TOG";
+case CCM_ANALOG_PLL_USB1:
+return "PLL_USB1";
+case CCM_ANALOG_PLL_USB1_SET:
+return "PLL_USB1_SET";
+case CCM_ANALOG_PLL_USB1_CLR:
+return "PLL_USB1_CLR";
+case CCM_ANALOG_PLL_USB1_TOG:
+return "PLL_USB1_TOG";
+case CCM_ANALOG_PLL_USB2:
+return "PLL_USB2";
+case CCM_ANALOG_PLL_USB2_SET:
+return "PLL_USB2_SET";
+case CCM_ANALOG_PLL_USB2_CLR:
+return "PLL_USB2_CLR";
+case CCM_ANALOG_PLL_USB2_TOG:
+return "PLL_USB2_TOG";
+case CCM_ANALOG_PLL_SYS:
+return "PLL_SYS";
+case CCM_ANALOG_PLL_SYS_SET:
+return "PLL_SYS_SET";
+case CCM_ANALOG_PLL_SYS_CLR:
+return "PLL_SYS_CLR";
+case CCM_ANALOG_PLL_SYS_TOG:
+return "PLL_SYS_TOG&

[Qemu-devel] [PATCH v2 0/3] i.MX: Add the i.MX6UL SOC and a reference board.

2018-07-30 Thread Jean-Christophe Dubois
This series adds the i.MX6UL SOC from NXP/Freescale and the reference
evaluation board.

This series was tested by booting linux 4.18 (built using imx_v6_v7_defconfig)
on the emulated board (with the appropriate device tree).

Jean-Christophe Dubois (3):
  i.MX6UL: Add i.MX6UL specific CCM device
  i.MX6UL: Add i.MX6UL SOC
  i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 618 ++
 hw/arm/mcimx6ul-evk.c   |  85 +++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx6ul_ccm.c| 890 
 hw/misc/trace-events|   7 +
 include/hw/arm/fsl-imx6ul.h | 339 
 include/hw/misc/imx6ul_ccm.h| 226 
 9 files changed, 2168 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 hw/arm/mcimx6ul-evk.c
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h
 create mode 100644 include/hw/misc/imx6ul_ccm.h

-- 
2.17.1




[Qemu-devel] [PATCH v2 3/3] i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

2018-07-30 Thread Jean-Christophe Dubois
Tested by booting linux 4.18 (built using imx_v6_v7_defconfig) on the
emulated board.

Signed-off-by: Jean-Christophe Dubois 
---

Changes in V2:
 * use object_initialize_child instead of several funcions

 hw/arm/Makefile.objs  |  2 +-
 hw/arm/mcimx6ul-evk.c | 85 +++
 2 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/mcimx6ul-evk.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index e419ad040b..2902f47b4c 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,4 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
-obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
new file mode 100644
index 00..fb2b015bf6
--- /dev/null
+++ b/hw/arm/mcimx6ul-evk.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * MCIMX6UL_EVK Board System emulation.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a mcimx6ul_evk board, with a Freescale
+ * i.MX6ul SoC
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+#include "sysemu/qtest.h"
+
+typedef struct {
+FslIMX6ULState soc;
+MemoryRegion ram;
+} MCIMX6ULEVK;
+
+static void mcimx6ul_evk_init(MachineState *machine)
+{
+static struct arm_boot_info boot_info;
+MCIMX6ULEVK *s = g_new0(MCIMX6ULEVK, 1);
+int i;
+
+if (machine->ram_size > FSL_IMX6UL_MMDC_SIZE) {
+error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
+ machine->ram_size, FSL_IMX6UL_MMDC_SIZE);
+exit(1);
+}
+
+boot_info = (struct arm_boot_info) {
+.loader_start = FSL_IMX6UL_MMDC_ADDR,
+.board_id = -1,
+.ram_size = machine->ram_size,
+.kernel_filename = machine->kernel_filename,
+.kernel_cmdline = machine->kernel_cmdline,
+.initrd_filename = machine->initrd_filename,
+.nb_cpus = smp_cpus,
+};
+
+object_initialize_child(OBJECT(machine), "soc", >soc,  sizeof(s->soc),
+TYPE_FSL_IMX6UL, _fatal, NULL);
+
+object_property_set_bool(OBJECT(>soc), true, "realized", _fatal);
+
+memory_region_allocate_system_memory(>ram, NULL, "mcimx6ul-evk.ram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(),
+FSL_IMX6UL_MMDC_ADDR, >ram);
+
+for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
+BusState *bus;
+DeviceState *carddev;
+DriveInfo *di;
+BlockBackend *blk;
+
+di = drive_get_next(IF_SD);
+blk = di ? blk_by_legacy_dinfo(di) : NULL;
+bus = qdev_get_child_bus(DEVICE(>soc.usdhc[i]), "sd-bus");
+carddev = qdev_create(bus, TYPE_SD_CARD);
+qdev_prop_set_drive(carddev, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(carddev), true,
+ "realized", _fatal);
+}
+
+if (!qtest_enabled()) {
+arm_load_kernel(>soc.cpu[0], _info);
+}
+}
+
+static void mcimx6ul_evk_machine_init(MachineClass *mc)
+{
+mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
+mc->init = mcimx6ul_evk_init;
+mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
+}
+DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
-- 
2.17.1




[Qemu-devel] [PATCH v2 2/3] i.MX6UL: Add i.MX6UL SOC

2018-07-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes in V2:
 * use object_initialize_child instead of several funcions
 * use sysbus_init_child_obj instead for several functions

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 618 
 include/hw/arm/fsl-imx6ul.h | 339 ++
 4 files changed, 959 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 834d45cfaf..311584fd74 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -133,6 +133,7 @@ CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
+CONFIG_FSL_IMX6UL=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index d51fcecaf2..e419ad040b 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,3 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
new file mode 100644
index 00..e514216d09
--- /dev/null
+++ b/hw/arm/fsl-imx6ul.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * i.MX6UL SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx7.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 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 "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+#define NAME_SIZE 20
+
+static void fsl_imx6ul_init(Object *obj)
+{
+FslIMX6ULState *s = FSL_IMX6UL(obj);
+char name[NAME_SIZE];
+int i;
+
+for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
+snprintf(name, NAME_SIZE, "cpu%d", i);
+object_initialize_child(obj, name, >cpu[i], sizeof(s->cpu[i]),
+"cortex-a7-" TYPE_ARM_CPU, _abort, NULL);
+}
+
+/*
+ * A7MPCORE
+ */
+sysbus_init_child_obj(obj, "a7mpcore", >a7mpcore, sizeof(s->a7mpcore),
+  TYPE_A15MPCORE_PRIV);
+
+/*
+ * CCM
+ */
+sysbus_init_child_obj(obj, "ccm", >ccm, sizeof(s->ccm), 
TYPE_IMX6UL_CCM);
+
+/*
+ * SRC
+ */
+sysbus_init_child_obj(obj, "src", >src, sizeof(s->src), TYPE_IMX6_SRC);
+
+/*
+ * GPCv2
+ */
+sysbus_init_child_obj(obj, "gpcv2", >gpcv2, sizeof(s->gpcv2),
+  TYPE_IMX_GPCV2);
+
+/*
+ * SNVS
+ */
+sysbus_init_child_obj(obj, "snvs", >snvs, sizeof(s->snvs),
+  TYPE_IMX7_SNVS);
+
+/*
+ * GPR
+ */
+sysbus_init_child_obj(obj, "gpr", >gpr, sizeof(s->gpr),
+  TYPE_IMX7_GPR);
+
+/*
+ * GPIOs 1 to 5
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
+   snprintf(name, NAME_SIZE, "gpio%d", i);
+   sysbus_init_child_obj(obj, name, >gpio[i], sizeof(s->gpio[i]),
+ TYPE_IMX_GPIO);
+}
+
+/*
+ * GPT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
+   snprintf(name, NAME_SIZE, "gpt%d", i);
+   sysbus_init_child_obj(obj, name, >gpt[i], sizeof(s->gpt[i]),
+ TYPE_IMX7_GPT);
+}
+
+/*
+ * EPIT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
+   snprintf(name, NAME_SIZE, "epit%d", i + 1);
+   sysbus_init_child_obj(obj, name, >epit[i], sizeof(s->epit[i]),
+ TYPE_IMX_EPIT);
+}
+
+/*
+ * eCSPI
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
+   snprintf(name, NAME_SIZE, "spi%d", i + 1);
+   sysbus_init_child_obj(obj, name, >spi[i], sizeof(s->spi[i]),
+ TYPE_IMX_SPI);
+}
+
+/*
+ * I2C
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
+   snprintf(name, NAME_SIZE, "i2c%d", i + 1);
+   sysbus_init_child_obj(obj, name, >i2c[i], sizeof(s->i2c[i]),
+   

Re: [Qemu-devel] [PATCH 0/3] i.MX: Add the i.MX6UL SOC and a reference board.

2018-07-05 Thread Jean-Christophe DUBOIS

Le 01/07/2018 à 12:44, Peter Maydell a écrit :

On 30 June 2018 at 22:57, Jean-Christophe Dubois  wrote:

This series adds the i.MX6UL SOC from NXP/Freescale and the reference
evaluation board.

This series as tested by booting linux 4.18 (built using imx_v6_v7_defconfig)
on the emulated board (with the appropriate device tree).

Jean-Christophe Dubois (3):
   i.MX6UL: Add i.MX6UL specific CCM device
   i.MX6UL: Add i.MX6UL SOC
   i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

Hi; thanks for this patchset. I've put it on my to-review queue,
but since it's too late to get in for softfreeze for 3.0 I'm
planning to prioritize release-related work so it may take
me a little while to get back to it.

thanks
-- PMM


OK, take your time.

Also for the record, I believe the Qemu FEC/ENET device doesn't work 
with linux 4.18 on the i.MX6Q/DL sabrelite emulation.


JC




Re: [Qemu-devel] [PATCH 0/3] i.mx7d fixes

2018-06-30 Thread Jean-Christophe DUBOIS

Le 28/06/2018 à 17:13, Peter Maydell a écrit :

On 26 June 2018 at 22:59, Jean-Christophe Dubois  wrote:

Small fixes in the i.mx7d code.

Jean-Christophe Dubois (3):
   i.mx7d: Remove unused header files
   i.mx7d: Change SRC unimpleted device name from sdma to src
   i.mx7d: Change IRQ number type from hwaddr to int

  hw/arm/fsl-imx7.c  | 8 
  hw/arm/mcimx7d-sabre.c | 2 --
  2 files changed, 4 insertions(+), 6 deletions(-)

Thanks, applied all to target-arm.next.

Something seems to have gone wrong with posting of this series:
the patches didn't get sent as followups to the cover letter
(missing In-reply-to: headers). You might want to look into that
for future patch postings.

Thank Peter,

Yes, something went wrong (I think this is the piece between the chair 
and the keyboard).


I'll try to be better next time.

JC



-- PMM







[Qemu-devel] [PATCH 3/3] i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

2018-06-30 Thread Jean-Christophe Dubois
Tested by booting linux 4.18 (built using imx_v6_v7_defconfig) on the
emulated board.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/Makefile.objs  |  2 +-
 hw/arm/mcimx6ul-evk.c | 86 +++
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/mcimx6ul-evk.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index e419ad040b..2902f47b4c 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,4 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
-obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
new file mode 100644
index 00..7d1b3c97df
--- /dev/null
+++ b/hw/arm/mcimx6ul-evk.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * MCIMX6UL_EVK Board System emulation.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a mcimx6ul_evk board, with a Freescale
+ * i.MX6ul SoC
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+#include "sysemu/qtest.h"
+
+typedef struct {
+FslIMX6ULState soc;
+MemoryRegion ram;
+} MCIMX6ULEVK;
+
+static void mcimx6ul_evk_init(MachineState *machine)
+{
+static struct arm_boot_info boot_info;
+MCIMX6ULEVK *s = g_new0(MCIMX6ULEVK, 1);
+Object *soc;
+int i;
+
+if (machine->ram_size > FSL_IMX6UL_MMDC_SIZE) {
+error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
+ machine->ram_size, FSL_IMX6UL_MMDC_SIZE);
+exit(1);
+}
+
+boot_info = (struct arm_boot_info) {
+.loader_start = FSL_IMX6UL_MMDC_ADDR,
+.board_id = -1,
+.ram_size = machine->ram_size,
+.kernel_filename = machine->kernel_filename,
+.kernel_cmdline = machine->kernel_cmdline,
+.initrd_filename = machine->initrd_filename,
+.nb_cpus = smp_cpus,
+};
+
+object_initialize(>soc, sizeof(s->soc), TYPE_FSL_IMX6UL);
+soc = OBJECT(>soc);
+object_property_add_child(OBJECT(machine), "soc", soc, _fatal);
+object_property_set_bool(soc, true, "realized", _fatal);
+
+memory_region_allocate_system_memory(>ram, NULL, "mcimx6ul-evk.ram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(),
+FSL_IMX6UL_MMDC_ADDR, >ram);
+
+for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
+BusState *bus;
+DeviceState *carddev;
+DriveInfo *di;
+BlockBackend *blk;
+
+di = drive_get_next(IF_SD);
+blk = di ? blk_by_legacy_dinfo(di) : NULL;
+bus = qdev_get_child_bus(DEVICE(>soc.usdhc[i]), "sd-bus");
+carddev = qdev_create(bus, TYPE_SD_CARD);
+qdev_prop_set_drive(carddev, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(carddev), true,
+ "realized", _fatal);
+}
+
+if (!qtest_enabled()) {
+arm_load_kernel(>soc.cpu[0], _info);
+}
+}
+
+static void mcimx6ul_evk_machine_init(MachineClass *mc)
+{
+mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
+mc->init = mcimx6ul_evk_init;
+mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
+}
+DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
-- 
2.17.1




[Qemu-devel] [PATCH 2/3] i.MX6UL: Add i.MX6UL SOC

2018-06-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 649 
 include/hw/arm/fsl-imx6ul.h | 339 +
 4 files changed, 990 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 834d45cfaf..311584fd74 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -133,6 +133,7 @@ CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
+CONFIG_FSL_IMX6UL=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index d51fcecaf2..e419ad040b 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -36,3 +36,4 @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
 obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
new file mode 100644
index 00..25d6c3f7c2
--- /dev/null
+++ b/hw/arm/fsl-imx6ul.c
@@ -0,0 +1,649 @@
+/*
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * i.MX6UL SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx7.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 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 "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx6ul.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+#define NAME_SIZE 20
+
+static void fsl_imx6ul_init(Object *obj)
+{
+BusState *sysbus = sysbus_get_default();
+FslIMX6ULState *s = FSL_IMX6UL(obj);
+char name[NAME_SIZE];
+int i;
+
+
+for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
+object_initialize(>cpu[i], sizeof(s->cpu[i]),
+  ARM_CPU_TYPE_NAME("cortex-a7"));
+snprintf(name, NAME_SIZE, "cpu%d", i);
+object_property_add_child(obj, name, OBJECT(>cpu[i]),
+  _fatal);
+}
+
+/*
+ * A7MPCORE
+ */
+object_initialize(>a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
+qdev_set_parent_bus(DEVICE(>a7mpcore), sysbus);
+object_property_add_child(obj, "a7mpcore",
+  OBJECT(>a7mpcore), _fatal);
+
+/*
+ * CCM
+ */
+object_initialize(>ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM);
+qdev_set_parent_bus(DEVICE(>ccm), sysbus);
+object_property_add_child(obj, "ccm", OBJECT(>ccm), _fatal);
+
+/*
+ * SRC
+ */
+object_initialize(>src, sizeof(s->src), TYPE_IMX6_SRC);
+qdev_set_parent_bus(DEVICE(>src), sysbus);
+object_property_add_child(obj, "src", OBJECT(>src), _fatal);
+
+/*
+ * GPCv2
+ */
+object_initialize(>gpcv2, sizeof(s->gpcv2), TYPE_IMX_GPCV2);
+qdev_set_parent_bus(DEVICE(>gpcv2), sysbus);
+object_property_add_child(obj, "gpcv2", OBJECT(>gpcv2), _fatal);
+
+/*
+ * GPIOs 1 to 5
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
+object_initialize(>gpio[i], sizeof(s->gpio[i]),
+  TYPE_IMX_GPIO);
+qdev_set_parent_bus(DEVICE(>gpio[i]), sysbus);
+snprintf(name, NAME_SIZE, "gpio%d", i);
+object_property_add_child(obj, name,
+  OBJECT(>gpio[i]), _fatal);
+}
+
+/*
+ * GPT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
+object_initialize(>gpt[i], sizeof(s->gpt[i]), TYPE_IMX7_GPT);
+qdev_set_parent_bus(DEVICE(>gpt[i]), sysbus);
+snprintf(name, NAME_SIZE, "gpt%d", i);
+object_property_add_child(obj, name, OBJECT(>gpt[i]),
+  _fatal);
+}
+
+/*
+ * EPIT 1, 2
+ */
+for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
+object_initialize(>epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
+qdev_set_parent_bus(DEVICE(>epit[i]), sysbus);
+snprintf(name, NAME_SIZE, "epit%d", i + 1);
+object_property_add_child(obj, name, OBJECT(>epit[i]),
+  _fatal);
+}
+
+

[Qemu-devel] [PATCH 0/3] i.MX: Add the i.MX6UL SOC and a reference board.

2018-06-30 Thread Jean-Christophe Dubois
This series adds the i.MX6UL SOC from NXP/Freescale and the reference
evaluation board.

This series as tested by booting linux 4.18 (built using imx_v6_v7_defconfig)
on the emulated board (with the appropriate device tree).

Jean-Christophe Dubois (3):
  i.MX6UL: Add i.MX6UL specific CCM device
  i.MX6UL: Add i.MX6UL SOC
  i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6ul.c | 649 +++
 hw/arm/mcimx6ul-evk.c   |  86 
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx6ul_ccm.c| 887 
 include/hw/arm/fsl-imx6ul.h | 339 
 include/hw/misc/imx6ul_ccm.h| 228 
 8 files changed, 2192 insertions(+)
 create mode 100644 hw/arm/fsl-imx6ul.c
 create mode 100644 hw/arm/mcimx6ul-evk.c
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/arm/fsl-imx6ul.h
 create mode 100644 include/hw/misc/imx6ul_ccm.h

-- 
2.17.1




[Qemu-devel] [PATCH 1/3] i.MX6UL: Add i.MX6UL specific CCM device

2018-06-30 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/Makefile.objs|   1 +
 hw/misc/imx6ul_ccm.c | 887 +++
 include/hw/misc/imx6ul_ccm.h | 228 +
 3 files changed, 1116 insertions(+)
 create mode 100644 hw/misc/imx6ul_ccm.c
 create mode 100644 include/hw/misc/imx6ul_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 9350900845..51d27b3af1 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6ul_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
new file mode 100644
index 00..fc894b087e
--- /dev/null
+++ b/hw/misc/imx6ul_ccm.c
@@ -0,0 +1,887 @@
+/*
+ * IMX6UL Clock Control Module
+ *
+ * Copyright (c) 2018 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx6ul_ccm.h"
+#include "qemu/log.h"
+
+#ifndef DEBUG_IMX6UL_CCM
+#define DEBUG_IMX6UL_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6UL_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6UL_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static const char *imx6ul_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_CCR:
+return "CCR";
+case CCM_CCDR:
+return "CCDR";
+case CCM_CSR:
+return "CSR";
+case CCM_CCSR:
+return "CCSR";
+case CCM_CACRR:
+return "CACRR";
+case CCM_CBCDR:
+return "CBCDR";
+case CCM_CBCMR:
+return "CBCMR";
+case CCM_CSCMR1:
+return "CSCMR1";
+case CCM_CSCMR2:
+return "CSCMR2";
+case CCM_CSCDR1:
+return "CSCDR1";
+case CCM_CS1CDR:
+return "CS1CDR";
+case CCM_CS2CDR:
+return "CS2CDR";
+case CCM_CDCDR:
+return "CDCDR";
+case CCM_CHSCCDR:
+return "CHSCCDR";
+case CCM_CSCDR2:
+return "CSCDR2";
+case CCM_CSCDR3:
+return "CSCDR3";
+case CCM_CDHIPR:
+return "CDHIPR";
+case CCM_CTOR:
+return "CTOR";
+case CCM_CLPCR:
+return "CLPCR";
+case CCM_CISR:
+return "CISR";
+case CCM_CIMR:
+return "CIMR";
+case CCM_CCOSR:
+return "CCOSR";
+case CCM_CGPR:
+return "CGPR";
+case CCM_CCGR0:
+return "CCGR0";
+case CCM_CCGR1:
+return "CCGR1";
+case CCM_CCGR2:
+return "CCGR2";
+case CCM_CCGR3:
+return "CCGR3";
+case CCM_CCGR4:
+return "CCGR4";
+case CCM_CCGR5:
+return "CCGR5";
+case CCM_CCGR6:
+return "CCGR6";
+case CCM_CMEOR:
+return "CMEOR";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const char *imx6ul_analog_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_ANALOG_PLL_ARM:
+return "PLL_ARM";
+case CCM_ANALOG_PLL_ARM_SET:
+return "PLL_ARM_SET";
+case CCM_ANALOG_PLL_ARM_CLR:
+return "PLL_ARM_CLR";
+case CCM_ANALOG_PLL_ARM_TOG:
+return "PLL_ARM_TOG";
+case CCM_ANALOG_PLL_USB1:
+return "PLL_USB1";
+case CCM_ANALOG_PLL_USB1_SET:
+return "PLL_USB1_SET";
+case CCM_ANALOG_PLL_USB1_CLR:
+return "PLL_USB1_CLR";
+case CCM_ANALOG_PLL_USB1_TOG:
+return "PLL_USB1_TOG";
+case CCM_ANALOG_PLL_USB2:
+return "PLL_USB2";
+case CCM_ANALOG_PLL_USB2_SET:
+return "PLL_USB2_SET";
+case CCM_ANALOG_PLL_USB2_CLR:
+return "PLL_USB2_CLR";
+case CCM_ANALOG_PLL_USB2_TOG:
+return "PLL_USB2_TOG";
+case CCM_ANALOG_PLL_SYS:
+return "PLL_SYS";
+case CCM_ANALOG_PLL_SYS_SET:
+return "PLL_SYS_SET";
+case CCM_ANALOG_PLL_SYS_CLR:
+return "PLL_SYS_CLR";
+case CCM_ANALOG_PLL_SYS_TOG:
+return "PLL_SYS_TOG";
+case CCM_ANALOG_PLL_SYS_SS:
+return "PLL_SYS_SS&q

[Qemu-devel] [PATCH 1/3] i.mx7d: Remove unused header files

2018-06-26 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/mcimx7d-sabre.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
index 95fb409d9c..9c5f0e70c3 100644
--- a/hw/arm/mcimx7d-sabre.c
+++ b/hw/arm/mcimx7d-sabre.c
@@ -18,10 +18,8 @@
 #include "hw/arm/fsl-imx7.h"
 #include "hw/boards.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/device_tree.h"
 #include "qemu/error-report.h"
 #include "sysemu/qtest.h"
-#include "net/net.h"
 
 typedef struct {
 FslIMX7State soc;
-- 
2.17.1




[Qemu-devel] [PATCH 3/3] i.mx7d: Change IRQ number type from hwaddr to int

2018-06-26 Thread Jean-Christophe Dubois
The qdev_get_gpio_in() function accept an int as second parameter.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index e15aadb587..44fde03cbe 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -324,7 +324,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_ECSPI4_ADDR,
 };
 
-static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
+static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
 FSL_IMX7_ECSPI1_IRQ,
 FSL_IMX7_ECSPI2_IRQ,
 FSL_IMX7_ECSPI3_IRQ,
@@ -349,7 +349,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_I2C4_ADDR,
 };
 
-static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
+static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
 FSL_IMX7_I2C1_IRQ,
 FSL_IMX7_I2C2_IRQ,
 FSL_IMX7_I2C3_IRQ,
@@ -515,7 +515,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 FSL_IMX7_USB3_ADDR,
 };
 
-static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
+static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
 FSL_IMX7_USB1_IRQ,
 FSL_IMX7_USB2_IRQ,
 FSL_IMX7_USB3_IRQ,
-- 
2.17.1




[Qemu-devel] [PATCH 2/3] i.mx7d: Change SRC unimpleted device name from sdma to src

2018-06-26 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx7.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 26c1d27f7c..e15aadb587 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -459,7 +459,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
 /*
  * SRC
  */
-create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
+create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
 
 /*
  * Watchdog
-- 
2.17.1




[Qemu-devel] [PATCH 0/3] i.mx7d fixes

2018-06-26 Thread Jean-Christophe Dubois
Small fixes in the i.mx7d code.

Jean-Christophe Dubois (3):
  i.mx7d: Remove unused header files
  i.mx7d: Change SRC unimpleted device name from sdma to src
  i.mx7d: Change IRQ number type from hwaddr to int

 hw/arm/fsl-imx7.c  | 8 
 hw/arm/mcimx7d-sabre.c | 2 --
 2 files changed, 4 insertions(+), 6 deletions(-)

-- 
2.17.1




Re: [Qemu-devel] [PATCH v2] i.MX: Fix FEC/ENET receive funtions

2018-01-24 Thread Jean-Christophe DUBOIS
My guess is that with this patch, the "flush" feature that was added by 
Andrey in "imx_fec: Change queue flushing heuristics" (commit b2b012a) 
is not really necessary anymore.


But it does not hurt (it might induce a little bit more processing).

JC

Le 22/01/2018 à 15:59, Peter Maydell a écrit :

On 22 January 2018 at 14:54, Andrey Smirnov <andrew.smir...@gmail.com> wrote:

On Mon, Jan 22, 2018 at 3:48 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:

On 13 January 2018 at 11:34, Jean-Christophe Dubois <j...@tribudubois.net> 
wrote:

The actual imx_eth_enable_rx() function is buggy.

It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().

qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
is going to call imx_eth_enable_rx().

By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
we end up updating the register with an outdated value which might
lead to disabling the receive function in the i.MX FEC/ENET device.

This patch change the place where the register update is done so that the
register value stays up to date and the receive function can keep
running.

Reported-by: Fyleo <fyle...@gmail.com>
Tested-by: Fyleo  <fyle...@gmail.com>
Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---

Andrey, do you have an opinion on this patch, since you've been
looking at i.MX code recently?


The rationale makes sense to me and patch looks like a good cleanup in
general, so FWIW:

Reviewed-by: Andrey Smirnov <andrew.smir...@gmail.com>

I also gave it a spin against my i.MX7 changes with doing basic things
like ping and scp of 1GB file, so I can give my:

Tested-by: Andrey Smirnov <andrew.smir...@gmail.com>

Thanks; I've applied the patch to target-arm.next.

-- PMM






Re: [Qemu-devel] [PATCH] LEON3 IRQMP: Fix IRQ software ack

2018-01-15 Thread Jean-Christophe Dubois

Le 2018-01-15 14:45, Jean-Christophe Dubois a écrit :

Le 2018-01-15 12:09, Fabien Chouteau a écrit :

On 12/01/2018 15:10, Jean-Christophe Dubois wrote:

Le 2018-01-12 11:55, Fabien Chouteau a écrit :

On 11/01/2018 13:35, Jean-Christophe Dubois wrote:

Thanks Fabien,

Now, as a side question, could you tell me which reference LEON3 
platform is implemented by Qemu in leon3_generic?




I think it was the based on the FPGA version of Leon3 I was using at 
the

time. The name leon3_generic comes from my will to make it a
configurable board where users could define the number and the 
location

of the different peripherals, I never had time to work on this.


I see. I am not sure how to bring configurability to Qemu. There is 
the possibility to describe the hw PTF with DTC/DTB or something 
similar. I think some people were working on it for the ARM Qemu 
platform (but I am not sure what happened to this initiative).


Now in the meantime, would it make sense to move leon3_generic to a 
tsim compatible platform?




I don't think so, leon3_generic is compatible with a real hardware 
which

is also interesting for comparison.


What real hardware (gaisler reference platform) is it? Could you point
to the public reference manual for this hardware?

Another possibility is to add a leon3_tsim platform into Qemu to
support the compatibility with the tsim emulator. But the difference
with leon3_generic would be minimal.



This would allow to validate the same software on the 2 simulators 
(obviously it would not be compatible with your specific FPGA version 
for now).




The Leon3 AMBA bus provides a way to discover the peripherals and 
their

address, so any system should be capable of supporting different
peripheral layouts.

Here's an example of AMBA discovery code from a very old project of 
mine

(don't judge me on this :) :
https://github.com/Fabien-Chouteau/kabitbol/blob/master/src/amba.c

There was a couple of patches submitted some times ago to add Leon3 
AMBA

support in QEMU, I think it's time to bring them back...


What you are talking about here is the possibility for the software
running inside Qemu to probe/discover the hardware. For such feature
Qemu should implement what is required for this AMBA discovery. But it
does not solve how you decide at run time at what addresses are the
various AMBA devices (how you decide to emulate a tsim platform or
another one).

Note: For now I am not so much interested in the AMBA discovery as the
type of software platform I am thinking about is embedded where the
hardware is well known ahead of time. This discovery capability would
make sense for more generic OS like linux or such. We cannot require
all embedded OS to implement the AMBA discovery process.


For the configurability of Qemu, I was thinking of using something 
similar to the Qemu provided by Xilinx 
(http://www.wiki.xilinx.com/QEMU). Basically, you provide a DTB file as 
a Qemu command line argument and Qemu will build the various devices 
(including addresses and interrupts) based on the content of this file. 
Then when running an OS, it can provide the DTB file (for example to 
Linux) that match exactly the emulated platform.


This should allow to build "any" variation of the platform and to add 
devices as you need them. This makes sense for Xilinx (their customer 
are building custom platforms) and it would also make sense for LEON as 
the CPU core is usually integrated inside a custom SOC/FPGA.


JC



Re: [Qemu-devel] [PATCH] LEON3 IRQMP: Fix IRQ software ack

2018-01-15 Thread Jean-Christophe Dubois

Le 2018-01-15 12:09, Fabien Chouteau a écrit :

On 12/01/2018 15:10, Jean-Christophe Dubois wrote:

Le 2018-01-12 11:55, Fabien Chouteau a écrit :

On 11/01/2018 13:35, Jean-Christophe Dubois wrote:

Thanks Fabien,

Now, as a side question, could you tell me which reference LEON3 
platform is implemented by Qemu in leon3_generic?




I think it was the based on the FPGA version of Leon3 I was using at 
the

time. The name leon3_generic comes from my will to make it a
configurable board where users could define the number and the 
location

of the different peripherals, I never had time to work on this.


I see. I am not sure how to bring configurability to Qemu. There is 
the possibility to describe the hw PTF with DTC/DTB or something 
similar. I think some people were working on it for the ARM Qemu 
platform (but I am not sure what happened to this initiative).


Now in the meantime, would it make sense to move leon3_generic to a 
tsim compatible platform?




I don't think so, leon3_generic is compatible with a real hardware 
which

is also interesting for comparison.


What real hardware (gaisler reference platform) is it? Could you point 
to the public reference manual for this hardware?


Another possibility is to add a leon3_tsim platform into Qemu to support 
the compatibility with the tsim emulator. But the difference with 
leon3_generic would be minimal.




This would allow to validate the same software on the 2 simulators 
(obviously it would not be compatible with your specific FPGA version 
for now).




The Leon3 AMBA bus provides a way to discover the peripherals and their
address, so any system should be capable of supporting different
peripheral layouts.

Here's an example of AMBA discovery code from a very old project of 
mine

(don't judge me on this :) :
https://github.com/Fabien-Chouteau/kabitbol/blob/master/src/amba.c

There was a couple of patches submitted some times ago to add Leon3 
AMBA

support in QEMU, I think it's time to bring them back...


What you are talking about here is the possibility for the software 
running inside Qemu to probe/discover the hardware. For such feature 
Qemu should implement what is required for this AMBA discovery. But it 
does not solve how you decide at run time at what addresses are the 
various AMBA devices (how you decide to emulate a tsim platform or 
another one).


Note: For now I am not so much interested in the AMBA discovery as the 
type of software platform I am thinking about is embedded where the 
hardware is well known ahead of time. This discovery capability would 
make sense for more generic OS like linux or such. We cannot require all 
embedded OS to implement the AMBA discovery process.





[Qemu-devel] [PATCH v2] i.MX: Fix FEC/ENET receive funtions

2018-01-13 Thread Jean-Christophe Dubois
The actual imx_eth_enable_rx() function is buggy.

It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().

qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
is going to call imx_eth_enable_rx().

By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
we end up updating the register with an outdated value which might
lead to disabling the receive function in the i.MX FEC/ENET device.

This patch change the place where the register update is done so that the
register value stays up to date and the receive function can keep
running.

Reported-by: Fyleo <fyle...@gmail.com>
Tested-by: Fyleo  <fyle...@gmail.com>
Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---
Change since v1:
1. Rebase the patch on the updated master branch

 hw/net/imx_fec.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 4fb48f62ba..9506f9b69f 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -595,19 +595,16 @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
 static void imx_eth_enable_rx(IMXFECState *s, bool flush)
 {
 IMXFECBufDesc bd;
-bool rx_ring_full;
 
 imx_fec_read_bd(, s->rx_descriptor);
 
-rx_ring_full = !(bd.flags & ENET_BD_E);
+s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
 
-if (rx_ring_full) {
+if (!s->regs[ENET_RDAR]) {
 FEC_PRINTF("RX buffer full\n");
 } else if (flush) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
-
-s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
 }
 
 static void imx_eth_reset(DeviceState *d)
@@ -866,7 +863,6 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
 case ENET_RDAR:
 if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
 if (!s->regs[index]) {
-s->regs[index] = ENET_RDAR_RDAR;
 imx_eth_enable_rx(s, true);
 }
 } else {
-- 
2.14.1




Re: [Qemu-devel] [PATCH] i.MX: Fix FEC/ENET receive funtions

2018-01-12 Thread Jean-Christophe Dubois

Le 2018-01-12 18:08, Peter Maydell a écrit :
On 10 January 2018 at 20:38, Jean-Christophe Dubois 
<j...@tribudubois.net> wrote:

The actual imx_eth_enable_rx() function is buggy.

It updates s->regs[ENET_RDAR] after calling 
qemu_flush_queued_packets().


qemu_flush_queued_packets() is going to call imx_XXX_receive() which 
itself

is going to call imx_eth_enable_rx().

By updating s->regs[ENET_RDAR] after calling 
qemu_flush_queued_packets()

we end up updating the register with an outdated value which might
lead to disabling the receive function in the i.MX FEC/ENET device.

This patch change the place where the register update is done so that 
the

register value stays up to date and the receive function can keep
running.

Reported-by: Fyleo <fyle...@gmail.com>
Tested-by: Fyleo <fyle...@gmail.com>
Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>


Could you have a look at current QEMU master, please? I think that
commit b2b012afdd9c has probably fixed this bug. (At any rate it
has changed that code so that your patch won't apply.)


It seems the patch (imx_fec: Refactor imx_eth_enable_rx()) only renamed 
a variable (from tmp to rx_ring_full) without changing the logic. So I 
don't expect the bug to be fixed in mainline.


I'll rebase and resubmit my patch.

JC




thanks
-- PMM





Re: [Qemu-devel] [PATCH] LEON3 IRQMP: Fix IRQ software ack

2018-01-12 Thread Jean-Christophe Dubois

Le 2018-01-12 11:55, Fabien Chouteau a écrit :

On 11/01/2018 13:35, Jean-Christophe Dubois wrote:

Thanks Fabien,

Now, as a side question, could you tell me which reference LEON3 
platform is implemented by Qemu in leon3_generic?




I think it was the based on the FPGA version of Leon3 I was using at 
the

time. The name leon3_generic comes from my will to make it a
configurable board where users could define the number and the location
of the different peripherals, I never had time to work on this.


I see. I am not sure how to bring configurability to Qemu. There is the 
possibility to describe the hw PTF with DTC/DTB or something similar. I 
think some people were working on it for the ARM Qemu platform (but I am 
not sure what happened to this initiative).


Now in the meantime, would it make sense to move leon3_generic to a tsim 
compatible platform?


This would allow to validate the same software on the 2 simulators 
(obviously it would not be compatible with your specific FPGA version 
for now).


JC




Re: [Qemu-devel] [PATCH] LEON3 IRQMP: Fix IRQ software ack

2018-01-11 Thread Jean-Christophe Dubois

Thanks Fabien,

Now, as a side question, could you tell me which reference LEON3 
platform is implemented by Qemu in leon3_generic?


It doesn't seem to match the one emulated by tsim.

Thanks.

JC

Le 2018-01-11 12:48, Fabien Chouteau a écrit :

On 10/01/2018 21:43, Jean-Christophe Dubois wrote:

With the LEON3 IRQ controller IRQs can be acknoledged 2 ways:
* Explicitely by software writing to the CLEAR_OFFSET register
* Implicitely when the procesor is done running the trap handler 
attached

  to the IRQ.



Thanks Jean-Christophe,

I tested the patch with our software and it works.

Reviewed-by: Fabien Chouteau <chout...@adacore.com>





[Qemu-devel] [PATCH] LEON3 IRQMP: Fix IRQ software ack

2018-01-10 Thread Jean-Christophe Dubois
With the LEON3 IRQ controller IRQs can be acknoledged 2 ways:
* Explicitely by software writing to the CLEAR_OFFSET register
* Implicitely when the procesor is done running the trap handler attached
  to the IRQ.

The actual IRQMP code only allows the implicit processor triggered IRQ ack.
If software write explicitely to the CLEAR_OFFSET register, this will clear
the pending bit in the register value but this will not lower the onloing
raised IRQ with the processor. The IRQ will be kept raised to the LEON
processor until the related trap handler is run and the processor implicitely
ack the interrupt. So with the actual IRQMP code trap hadler have to be run
even if the software has already done its job by clearing the pending bit.

This feature has been tested on another LEON3 simulator (tsim_leon3 from
Gaisler) and it turns out that the Qemu implementation is not equivalent to
the tsim one. In tsim, if software does clear a pending interrupt before
the related interrupt handler is triggered the said interrupt handler will
not be called.

This patch bring the Qemu IRQMP implementation in line with the tsim
implementation by allowing IRQ to be acknoledged by software only.

Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---
 hw/intc/grlib_irqmp.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index 94659ee256..d6f9cb3692 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -106,6 +106,15 @@ static void grlib_irqmp_check_irqs(IRQMPState *state)
 }
 }
 
+static void grlib_irqmp_ack_mask(IRQMPState *state, uint32_t mask)
+{
+/* Clear registers */
+state->pending  &= ~mask;
+state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
+
+grlib_irqmp_check_irqs(state);
+}
+
 void grlib_irqmp_ack(DeviceState *dev, int intno)
 {
 IRQMP*irqmp = GRLIB_IRQMP(dev);
@@ -120,11 +129,7 @@ void grlib_irqmp_ack(DeviceState *dev, int intno)
 
 trace_grlib_irqmp_ack(intno);
 
-/* Clear registers */
-state->pending  &= ~mask;
-state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
-
-grlib_irqmp_check_irqs(state);
+grlib_irqmp_ack_mask(state, mask);
 }
 
 void grlib_irqmp_set_irq(void *opaque, int irq, int level)
@@ -251,7 +256,7 @@ static void grlib_irqmp_write(void *opaque, hwaddr addr,
 
 case CLEAR_OFFSET:
 value &= ~1; /* clean up the value */
-state->pending &= ~value;
+grlib_irqmp_ack_mask(state, value);
 return;
 
 case MP_STATUS_OFFSET:
-- 
2.14.1




[Qemu-devel] [PATCH] i.MX: Fix FEC/ENET receive funtions

2018-01-10 Thread Jean-Christophe Dubois
The actual imx_eth_enable_rx() function is buggy.

It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().

qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
is going to call imx_eth_enable_rx().

By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
we end up updating the register with an outdated value which might
lead to disabling the receive function in the i.MX FEC/ENET device.

This patch change the place where the register update is done so that the
register value stays up to date and the receive function can keep
running.

Reported-by: Fyleo <fyle...@gmail.com>
Tested-by: Fyleo <fyle...@gmail.com>
Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---
 hw/net/imx_fec.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 90e6ee35ba..04a5cf12f1 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -536,19 +536,16 @@ static void imx_eth_do_tx(IMXFECState *s)
 static void imx_eth_enable_rx(IMXFECState *s)
 {
 IMXFECBufDesc bd;
-bool tmp;
 
 imx_fec_read_bd(, s->rx_descriptor);
 
-tmp = ((bd.flags & ENET_BD_E) != 0);
+s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
 
-if (!tmp) {
+if (!s->regs[ENET_RDAR]) {
 FEC_PRINTF("RX buffer full\n");
-} else if (!s->regs[ENET_RDAR]) {
+} else {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
-
-s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
 }
 
 static void imx_eth_reset(DeviceState *d)
@@ -806,7 +803,6 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
 case ENET_RDAR:
 if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
 if (!s->regs[index]) {
-s->regs[index] = ENET_RDAR_RDAR;
 imx_eth_enable_rx(s);
 }
 } else {
-- 
2.14.1




Re: [Qemu-devel] [SPARC] question on LEON IRQMP interrupt controller.

2018-01-08 Thread Jean-Christophe DUBOIS

Le 08/01/2018 à 20:56, Mark Cave-Ayland a écrit :
Thanks for the patch! I'm afraid I don't really have any experience 
with LEON as my focus is sun4m/sun4u, however I'm happy to take 
patches Acked/Reviewed by Fabien as the current LEON maintainer


I am waiting for Fabien feedback after my experiment with tsim.


if they don't cause any regressions in my own tests.


Of course.

JC




ATB,

Mark. 






Re: [Qemu-devel] [SPARC] question on LEON IRQMP interrupt controller.

2018-01-06 Thread Jean-Christophe DUBOIS

Hi,

So after trying my code on tsim, I can confirm that the software is 
indeed able to clear/ack the interrupt without requiring the ack from 
the processor.


Things are a bit strange with tsim as the simulator doesn't seem to 
respect time delay when the processor is in sleep/idle mode and jump 
straight to the next timer expiration/interrupt (incrementing the 
required clock cycles in the process) ...


And as the evaluation version of tsim stops the program after 2^32 clock 
cycles the program could not run more than 86 seconds (with the LEON 
clock @ 50 MHz).


But still the interrupts are acknowledged by software only without 
requiring the trap handler to run or the processor to ack the interrupt 
on a hardware way.


So I believe that my proposed modification is correct.

On a related note, tsim is using different interrupts (than Qemu) for 
timer and all. So what is the reference LEON3 platform that Qemu is 
emulating with leon3_generic?


JC

Le 03/01/2018 à 10:23, j...@tribudubois.net a écrit :

Le 2018-01-02 19:58, Fabien Chouteau a écrit :

Hello Jean-Christophe,

I'm the original author of this patch and I add in copy my colleague
Frederic.

On 02/01/2018 12:13, Jean-Christophe DUBOIS wrote:

I am wondering if the IRQMP code in hw/intc/grlib_irqmp.c is correct
when it comes to acknowledging interrupts.

With the actual code an interrupt can be lowered/acked only by an
"ack" from the processor which means that the trap handler related to
this external interrupt needs to be run for the ack to happen.

In particular this means that the interrupt cannot be acked only by
software. Even if the software clears the "pending" interrupts (by
writing to the CLEAR_OFFSET register before the interrupt handler is
run) this does not clear the interrupt to the processor (which is kept
asserted until the handler is run and the interrupt acked by the
processor). Do you know if this is indeed the intended behavior (I
understand that for most operating system the interrupt handler will
be run at last and this does not make a difference)?

I would expect that clearing interrupt through software (by writing to
the CLEAR_OFFSET register) would have the same effect as the processor
acknowledgment (and could avoid to run the interrupt handler if things
have already been taken care of by software).

Unfortunately the documentation I got (on the web) on the IRQMP is not
very clear on the topic.



I don't remember all the details of this CPU on top of my head, I worked
on this years ago.

If you have access to a real board the best would be to compare the
behavior of the CPU on it.


Unfortunately I don't have a real board (yet).


There's also a cycle accurate simulator of
Leon3, you can download an evaluation version here:
http://www.gaisler.com/index.php/downloads/simulators


OK, I will try the tsim simulator from Gaisler as a reference.




Anyway you can find below the patch I'd like to provide for IRQMP.



Can you explain the reason for this change? Why can't you use the
current interrupt handling?


I am working on a cooperative multitasking kernel (with no 
preemption). So the kernel is not handling interrupt related traps 
(actually the kernel is not handling the interrupt controller). All 
interrupts are masked at all time for all application or kernel so no 
interrupt trap handler is ever going to trigger (except for IRQ 15 
which is not maskable).


When the tasks have nothing to do the kernel goes to sleep using ASR19 
on LEON. So the system is awaken by next interrupt and the kernel will 
schedule the task handling the interrupt controller.


On LEON, I can go to sleep until the first interrupt. Once the first 
interrupt has been raised the LEON will never be able to get to 
sleep/idle again through ASR19 (it exists immediately) even if the 
interrupt controller handling task clears the interrupt (writing to 
CLEAR_OFFSET register). And this is because, in the actual Qemu 
implementation, the interrupt can only be acknowledged in the 
interrupt controller by the CPU through the triggering of the related 
trap handler.


So I am wondering if this is indeed the expected behavior in real 
hardware/life (interrupts can only be acked by processor and not by 
software).


Note: On a related subject I am wondering if the system (put in 
idle/sleep through ASR19) would woke up on interrupt if the interrupts 
are all masked through PSR (PIL) (it does wake up in Qemu for now). I 
will also test this on tsim before trying it on real hardware someday.




Regards,









[Qemu-devel] [SPARC] question on LEON IRQMP interrupt controller.

2018-01-02 Thread Jean-Christophe DUBOIS

Hi Mark, Artyom,

I am wondering if the IRQMP code in hw/intc/grlib_irqmp.c is correct 
when it comes to acknowledging interrupts.


With the actual code an interrupt can be lowered/acked only by an "ack" 
from the processor which means that the trap handler related to this 
external interrupt needs to be run for the ack to happen.


In particular this means that the interrupt cannot be acked only by 
software. Even if the software clears the "pending" interrupts (by 
writing to the CLEAR_OFFSET register before the interrupt handler is 
run) this does not clear the interrupt to the processor (which is kept 
asserted until the handler is run and the interrupt acked by the 
processor). Do you know if this is indeed the intended behavior (I 
understand that for most operating system the interrupt handler will be 
run at last and this does not make a difference)?


I would expect that clearing interrupt through software (by writing to 
the CLEAR_OFFSET register) would have the same effect as the processor 
acknowledgment (and could avoid to run the interrupt handler if things 
have already been taken care of by software).


Unfortunately the documentation I got (on the web) on the IRQMP is not 
very clear on the topic.


Anyway you can find below the patch I'd like to provide for IRQMP.

Thanks

JC

diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index 94659ee256..d6f9cb3692 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -106,6 +106,15 @@ static void grlib_irqmp_check_irqs(IRQMPState *state)
 }
 }

+static void grlib_irqmp_ack_mask(IRQMPState *state, uint32_t mask)
+{
+    /* Clear registers */
+    state->pending  &= ~mask;
+    state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
+
+    grlib_irqmp_check_irqs(state);
+}
+
 void grlib_irqmp_ack(DeviceState *dev, int intno)
 {
 IRQMP    *irqmp = GRLIB_IRQMP(dev);
@@ -120,11 +129,7 @@ void grlib_irqmp_ack(DeviceState *dev, int intno)

 trace_grlib_irqmp_ack(intno);

-    /* Clear registers */
-    state->pending  &= ~mask;
-    state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
-
-    grlib_irqmp_check_irqs(state);
+    grlib_irqmp_ack_mask(state, mask);
 }

 void grlib_irqmp_set_irq(void *opaque, int irq, int level)
@@ -251,7 +256,7 @@ static void grlib_irqmp_write(void *opaque, hwaddr addr,

 case CLEAR_OFFSET:
 value &= ~1; /* clean up the value */
-    state->pending &= ~value;
+    grlib_irqmp_ack_mask(state, value);
 return;

 case MP_STATUS_OFFSET:





Re: [Qemu-devel] [PATCH] Remove MemoryRegionSection check code from sparc_cpu_get_phys_page_debug()

2017-12-06 Thread Jean-Christophe DUBOIS

Le 04/12/2017 à 21:45, Mark Cave-Ayland a écrit :

On 27/11/17 20:19, Jean-Christophe DUBOIS wrote:


Hello Mark,

Did you get any second opinion on this?

Also do you need me to resend the patch with the SPARC keyword in the 
patch subject line?


Hi Jean-Christophe,

Apologies for the delay as I've been fairly busy with my day job. I 
believe Artyom is away at the moment which is why I haven't written a 
reply, but AFAICT there are 2 options:


1) Remove the MemoryRegion check (as per your patch)

2) Change dump_mmu() to call cpu_sparc_get_phys_page() directly

I'm mildly leaning towards 1) since there doesn't seem to be 
equivalent code in other architectures, however the tree is currently 
in freeze for the upcoming 2.11 release so that's where most people's 
free time is currently being spent.


Once I can confirm the correct approach, I'm keen to get this into the 
2.12 tree early so there is plenty of time to spot any regressions 
during the next development cycle.



OK, thanks for the feedback.

JC



ATB,

Mark.







Re: [Qemu-devel] [SPARC] Accessing devices through MMU mapped memory region

2017-11-27 Thread Jean-Christophe DUBOIS
Surprisingly the GCC compiler transformed my 32 bits access into 4 x 8 
bits access in my application code.


So this is not a Qemu issue but I need to find why the compiler is not 
generating the code I was expecting.


Sorry for the noise.

JC

Le 27/11/2017 à 21:16, Jean-Christophe DUBOIS a écrit :

Hi,

I am using Qemu to emulate a Leon3 based board.

In the software I am running on top of Qemu, I am mapping devices to a 
virtual address using MMU table.


Now I am experimenting some issues when I am trying to access some 
device (here the UART port at 0x8100) through the MMU mapping 
(with NOCACHE attribute for this page).


in my (user space) software I am doing something like:

   #define MY_VIRTUAL_ADDRESS 0x40808100 /* mapped to 0x8100
   physical address through MMU */

   #define UART_CTRL_REG_OFFSET 0x8

   #define UART_CTRL_TE 0x0002

   *(volatile uint32_t *)(MY_VIRTUAL_ADDRESS + UART_CTRL_REG_OFFSET) =
   UART_CTRL_TE;

But when the write is propagated by Qemu to the serial device, I am 
getting 4 x 8bits (1 byte) write access (0x8, 0x9, 0xa, 0xb) instead 
of a single 32 bits (4 bytes) access.


The Qemu driver emulator for the serial device is unhappy about this 
as it would not handle byte access for addresses 0x9, 0xa, 0xb which 
are then tagged as unsupported access.


I am wondering if I am missing something and if there is a reason for 
my single 32 bits access to be transformed by Qemu in 4 single byte 
access.


I believe it is expected to be able to get single atomic 32 bits 
read/write to the device.


Would you have any hint/advice for me?

JC








Re: [Qemu-devel] [PATCH] Remove MemoryRegionSection check code from sparc_cpu_get_phys_page_debug()

2017-11-27 Thread Jean-Christophe DUBOIS

Hello Mark,

Did you get any second opinion on this?

Also do you need me to resend the patch with the SPARC keyword in the 
patch subject line?


Regards

JC

Le 23/11/2017 à 20:49, Mark Cave-Ayland a écrit :

On 22/11/17 06:32, Jean-Christophe Dubois wrote:


This code is preventing the MMU debug code from displaying virtual
mappings of IO devices (anything that is not located in the RAM).

Before this patch, Qemu would output 0x (-1) as the
physical address corresponding to a IO device virtual address.

With this patch the intended physical adresse is displayed.

Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---
  target/sparc/mmu_helper.c | 6 --
  1 file changed, 6 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index d5b6c1e48c..f2d2250e7a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -857,18 +857,12 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
  CPUSPARCState *env = >env;
  hwaddr phys_addr;
  int mmu_idx = cpu_mmu_index(env, false);
-MemoryRegionSection section;
  
  if (cpu_sparc_get_phys_page(env, _addr, addr, 2, mmu_idx) != 0) {

  if (cpu_sparc_get_phys_page(env, _addr, addr, 0, mmu_idx) != 0) {
  return -1;
  }
  }
-section = memory_region_find(get_system_memory(), phys_addr, 1);
-memory_region_unref(section.mr);
-if (!int128_nz(section.size)) {
-return -1;
-}
  return phys_addr;
  }
  #endif

Hi Jean-Christophe,

Thanks for looking into this and providing the patch. I asked on IRC to
see if anyone could explain what this code was trying to do and Peter
suggested that it could be related to when cpu_get_phys_page_debug()
used to have to be more resilient to bad conditions such as missing
mappings.

Tracing through the git log I see it was introduced as part of commit
cc4aa830 "sparc: avoid cpu_get_physical_page_desc()":

diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 8cdc224..bdff1c3 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -19,6 +19,7 @@

  #include "cpu.h"
  #include "trace.h"
+#include "exec-memory.h"

  /* Sparc MMU emulation */

@@ -839,13 +840,15 @@ target_phys_addr_t
cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
  {
  target_phys_addr_t phys_addr;
  int mmu_idx = cpu_mmu_index(env);
+MemoryRegionSection section;

  if (cpu_sparc_get_phys_page(env, _addr, addr, 2, mmu_idx) != 0) {
  if (cpu_sparc_get_phys_page(env, _addr, addr, 0, mmu_idx)
!= 0) {
  return -1;
  }
  }
-if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) {
+section = memory_region_find(get_system_memory(), phys_addr, 1);
+if (!section.size) {
  return -1;
  }
  return phys_addr;

and cpu_get_physical_page_desc() used to look like this:

/* XXX: temporary until new memory mapping API */
uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
{
 PhysPageDesc *p;

 p = phys_page_find(addr >> TARGET_PAGE_BITS);
 if (!p)
 return IO_MEM_UNASSIGNED;
 return p->phys_offset;
}

i.e. IO_MEM_UNASSIGNED indicates there is no physical mapping for this
virtual address.

Now I've had a look at some of the other *_get_phys_page_debug()
functions and I don't see any similar logic (and in fact the git log for
PPC details the simplification of the ppc_*_get_phys_page_debug()
functions by removing permission checks etc.) so I'm inclined to think
that commit cc4aa830 did the wrong thing by restricting lookups to the
system memory address space and the patch is correct.

I'd like a second opinion if possible before queuing this patch as I'm
not overly familiar with this area of the code (and what the exact
behaviour for debug MMIO accesses should be), but otherwise it looks
good - the only part missing is a "sparc: " prefix to the subject line.


ATB,

Mark.







[Qemu-devel] [SPARC] Accessing devices through MMU mapped memory region

2017-11-27 Thread Jean-Christophe DUBOIS

Hi,

I am using Qemu to emulate a Leon3 based board.

In the software I am running on top of Qemu, I am mapping devices to a 
virtual address using MMU table.


Now I am experimenting some issues when I am trying to access some 
device (here the UART port at 0x8100) through the MMU mapping (with 
NOCACHE attribute for this page).


in my (user space) software I am doing something like:

   #define MY_VIRTUAL_ADDRESS 0x40808100 /* mapped to 0x8100
   physical address through MMU */

   #define UART_CTRL_REG_OFFSET 0x8

   #define UART_CTRL_TE 0x0002

   *(volatile uint32_t *)(MY_VIRTUAL_ADDRESS + UART_CTRL_REG_OFFSET) =
   UART_CTRL_TE;

But when the write is propagated by Qemu to the serial device, I am 
getting 4 x 8bits (1 byte) write access (0x8, 0x9, 0xa, 0xb) instead of 
a single 32 bits (4 bytes) access.


The Qemu driver emulator for the serial device is unhappy about this as 
it would not handle byte access for addresses 0x9, 0xa, 0xb which are 
then tagged as unsupported access.


I am wondering if I am missing something and if there is a reason for my 
single 32 bits access to be transformed by Qemu in 4 single byte access.


I believe it is expected to be able to get single atomic 32 bits 
read/write to the device.


Would you have any hint/advice for me?

JC




[Qemu-devel] [PATCH] Remove MemoryRegionSection check code from sparc_cpu_get_phys_page_debug()

2017-11-21 Thread Jean-Christophe Dubois
This code is preventing the MMU debug code from displaying virtual
mappings of IO devices (anything that is not located in the RAM).

Before this patch, Qemu would output 0x (-1) as the
physical address corresponding to a IO device virtual address.

With this patch the intended physical adresse is displayed.

Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
---
 target/sparc/mmu_helper.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index d5b6c1e48c..f2d2250e7a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -857,18 +857,12 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 CPUSPARCState *env = >env;
 hwaddr phys_addr;
 int mmu_idx = cpu_mmu_index(env, false);
-MemoryRegionSection section;
 
 if (cpu_sparc_get_phys_page(env, _addr, addr, 2, mmu_idx) != 0) {
 if (cpu_sparc_get_phys_page(env, _addr, addr, 0, mmu_idx) != 0) {
 return -1;
 }
 }
-section = memory_region_find(get_system_memory(), phys_addr, 1);
-memory_region_unref(section.mr);
-if (!int128_nz(section.size)) {
-return -1;
-}
 return phys_addr;
 }
 #endif
-- 
2.14.1




[Qemu-devel] [SPARC] Qemu failed to display MMU mapping for non memory area.

2017-11-19 Thread Jean-Christophe DUBOIS

Hello,

I am using Qemu to emulate a Leon3 based board.

In the software I am running on Qemu, I configured the virtual memory 
through MMU programming.


In particular, I mapped the built-in UART to a 4K page.

To check that my MMU table was OK I switched on (at compile time) the 
DEBUG_MMU facility in the target/sparc/ldst_helper.c file.


Then anytime I changed the MMU setting (through software) I got a 
display of it. A typical debug from Qemu console is as follow:


MMU: mmu change reg[2]: 0x0001 -> 0x0002
Root ptr: 40003000, ctx: 2
VA: 4000, PA: 4000 PDE: 04000401
 VA: 4000, PA: 4000 PDE: 04000421
  VA: 4000, PA: 4000 PTE: 04ba
  VA: 40001000, PA: 40001000 PTE: 0400019a
  VA: 40002000, PA: 40002000 PTE: 0400029a
  VA: 40006000, PA: 40006000 PTE: 0400069e
  VA: 40007000, PA: 40007000 PTE: 0400079a
  VA: 40008000, PA: 40008000 PTE: 0400089e
 VA: 4080, PA: 4000d000 PDE: 04000411
  VA: 4080, PA: 4000d000 PTE: 04000db2
  VA: 40802000, PA: 4000e000 PTE: 04000e82
  VA: 40804000, PA: 40013000 PTE: 04001386
  VA: 40806000, PA: 40017000 PTE: 04001786
  VA: 40808000, PA:  PTE: 0806
  VA: 4080a000, PA: 4001a000 PTE: 04001a82
  VA: 4080c000, PA: 40019000 PTE: 04001982
  VA: 4080e000, PA: 4001c000 PTE: 04001c82
  VA: 4081, PA: 4001b000 PTE: 04001b82

As you can see Qemu (debug) is unable to find the physical address 
associated to 0x40808000 (which should be 0x8000 where the UART lives).


Note: This also has on impact on the ability to explore the memory 
through GDB. Trying to access 0x40808100 (mapped to 0x8100) through 
gdb (connected to Qemu) is impossible.


(gdb) x 0x40808100
0x40808100:    Cannot access memory at address 0x40808100
(gdb)

I traced the problem down to the sparc_cpu_get_phys_page_debug() 
function in the target/sparc/mmu_helper.c file.


By commenting out the last part of the function, the MMU mapping debug 
in Qemu is functional again.


hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    SPARCCPU *cpu = SPARC_CPU(cs);
    CPUSPARCState *env = >env;
    hwaddr phys_addr;
    int mmu_idx = cpu_mmu_index(env, false);
    //MemoryRegionSection section;

    if (cpu_sparc_get_phys_page(env, _addr, addr, 2, mmu_idx) != 0) {
    if (cpu_sparc_get_phys_page(env, _addr, addr, 0, mmu_idx) 
!= 0) {

    return -1;
    }
    }
    /*
    section = memory_region_find(get_system_memory(), phys_addr, 1);
    memory_region_unref(section.mr);
    if (!int128_nz(section.size)) {
    printf("%s: failed to int128_nz()\n", __func__);
    return -1;
    }
    */
    return phys_addr;
}

Root ptr: 40003000, ctx: 2
VA: 4000, PA: 4000 PDE: 04000401
 VA: 4000, PA: 4000 PDE: 04000421
  VA: 4000, PA: 4000 PTE: 04ba
  VA: 40001000, PA: 40001000 PTE: 0400019a
  VA: 40002000, PA: 40002000 PTE: 0400029a
  VA: 40006000, PA: 40006000 PTE: 0400069e
  VA: 40007000, PA: 40007000 PTE: 0400079a
  VA: 40008000, PA: 40008000 PTE: 0400089e
 VA: 4080, PA: 4000d000 PDE: 04000411
  VA: 4080, PA: 4000d000 PTE: 04000db2
  VA: 40802000, PA: 4000e000 PTE: 04000e82
  VA: 40804000, PA: 40013000 PTE: 04001386
  VA: 40806000, PA: 40017000 PTE: 04001786
  VA: 40808000, PA: 8000 PTE: 0806
  VA: 4080a000, PA: 4001a000 PTE: 04001a82
  VA: 4080c000, PA: 40019000 PTE: 04001982
  VA: 4080e000, PA: 4001c000 PTE: 04001c82
  VA: 4081, PA: 4001b000 PTE: 04001b82

Moreover, the GDB memory display is also working again with this change.

(gdb) x 0x40808100
0x40808100:    0x
(gdb)
0x40808104:    0x0006
(gdb)
0x40808108:    0x0002

I am not sure the proposed change is correct because GDB would then 
display memory result for memory area where there is no device mapped. 
For example accessing 0x40808000 would return 0 when there is no device 
mapped from 0x8000 to 0x80FF.


(gdb) x 0x40808000
0x40808000:    0x
(gdb)
0x40808004:    0x
(gdb)
0x40808008:    0x

You feed back would be appreciated.

Regards.

JC





  1   2   3   4   5   6   7   >