Re: [PATCH v3] spapr: Fail CAS if option vector table cannot be parsed

2020-01-18 Thread David Gibson
On Fri, Jan 17, 2020 at 10:15:52AM +0100, Greg Kurz wrote:
> Most of the option vector helpers have assertions to check their
> arguments aren't null. The guest can provide an arbitrary address
> for the CAS structure that would result in such null arguments.
> Fail CAS with H_PARAMETER and print a warning instead of aborting
> QEMU.
> 
> Signed-off-by: Greg Kurz 
> Reviewed-by: Philippe Mathieu-Daudé 

Applied to ppc-for-5.0, thanks.

> ---
> v3: - drop ov_table check
> v2: - print warnings
> ---
>  hw/ppc/spapr_hcall.c |8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index f1799b1b707d..ffb14641f9d3 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1703,7 +1703,15 @@ static target_ulong 
> h_client_architecture_support(PowerPCCPU *cpu,
>  ov_table = addr;
>  
>  ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
> +if (!ov1_guest) {
> +warn_report("guest didn't provide option vector 1");
> +return H_PARAMETER;
> +}
>  ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
> +if (!ov5_guest) {
> +warn_report("guest didn't provide option vector 5");
> +return H_PARAMETER;
> +}
>  if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
>  error_report("guest requested hash and radix MMU, which is 
> invalid.");
>  exit(EXIT_FAILURE);
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH 6/6] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330

2020-01-18 Thread Guenter Roeck

On 1/18/20 12:02 PM, Peter Maydell wrote:

On Sat, 18 Jan 2020 at 15:08, Guenter Roeck  wrote:

Do only the pointers have to be in Exynos4210State, or the entire
data structures ? In the armsse code it looks like it is the complete
data structures.


Either works. Embedding the entire data structure is the more
"modern" approach, but we don't generally go to the effort of
converting from the older style to the newer.


Also, it seems to me that this means that not only pl330 and uart states
are affected, but everything created with qdev_create(). If so, the entire
file needs a serious rework, not just its pl330 / uart initialization.
Am I missing something ?


Yeah, all that stuff is broken, but don't feel you need to fix it.
You just brought the pl330 pointers to my attention specifically
by declaring locals in this patch, at which point it's just
as easy to put those pointers in the state struct where they
should be.



I'd rather try to fix it all if I am at it; otherwise it feels kind
of incomplete. Would you be ok with addressing this separately after
the current patch series is accepted ?

Thanks,
Guenter



RE: [PATCH RFC 12/12] migration/rdma: only register the virt-ram block for MultiRDMA

2020-01-18 Thread fengzhimin
OK, I will modify it.

Due to the mach-virt.ram is sent by the multiRDMA channels instead of the main 
channel, it don't to register on the main channel.
It takes a long time to register the mach-virt.ram for VM with large capacity 
memory, so we shall try our best not to register it.

Thanks for your review.

Zhimin Feng

-Original Message-
From: Dr. David Alan Gilbert [mailto:dgilb...@redhat.com] 
Sent: Saturday, January 18, 2020 2:52 AM
To: fengzhimin 
Cc: quint...@redhat.com; arm...@redhat.com; ebl...@redhat.com; 
qemu-devel@nongnu.org; Zhanghailiang ; 
jemmy858...@gmail.com
Subject: Re: [PATCH RFC 12/12] migration/rdma: only register the virt-ram block 
for MultiRDMA

* Zhimin Feng (fengzhim...@huawei.com) wrote:
> From: fengzhimin 
> 
> The virt-ram block is sent by MultiRDMA, so we only register it for 
> MultiRDMA channels and main channel don't register the virt-ram block.
> 
> Signed-off-by: fengzhimin 

You can't specialise on the name of the RAMBlock like that.
'mach-virt.ram' is the name specific to just the main ram on just aarch's 
machine type;  for example the name on x86 is completely different and if you 
use NUMA or hotplug etc it would also be different on aarch.

Is there a downside to also registering the mach-virt.ram on the main channel?

Dave

> ---
>  migration/rdma.c | 140 
> +--
>  1 file changed, 112 insertions(+), 28 deletions(-)
> 
> diff --git a/migration/rdma.c b/migration/rdma.c index 
> 0a150099e2..1477fd509b 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -618,7 +618,9 @@ const char *print_wrid(int wrid);  static int 
> qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,
> uint8_t *data, RDMAControlHeader *resp,
> int *resp_idx,
> -   int (*callback)(RDMAContext *rdma));
> +   int (*callback)(RDMAContext *rdma,
> +   uint8_t id),
> +   uint8_t id);
>  
>  static inline uint64_t ram_chunk_index(const uint8_t *start,
> const uint8_t *host) @@ 
> -1198,24 +1200,81 @@ static int qemu_rdma_alloc_qp(RDMAContext *rdma)
>  return 0;
>  }
>  
> -static int qemu_rdma_reg_whole_ram_blocks(RDMAContext *rdma)
> +/*
> + * Parameters:
> + *@id == UNUSED_ID :
> + *This means that we register memory for the main RDMA channel,
> + *the main RDMA channel don't register the mach-virt.ram block
> + *when we use multiRDMA method to migrate.
> + *
> + *@id == 0 or id == 1 or ... :
> + *This means that we register memory for the multiRDMA channels,
> + *the multiRDMA channels only register memory for the mach-virt.ram
> + *block when we use multiRDAM method to migrate.
> + */
> +static int qemu_rdma_reg_whole_ram_blocks(RDMAContext *rdma, uint8_t 
> +id)
>  {
>  int i;
>  RDMALocalBlocks *local = &rdma->local_ram_blocks;
>  
> -for (i = 0; i < local->nb_blocks; i++) {
> -local->block[i].mr =
> -ibv_reg_mr(rdma->pd,
> -local->block[i].local_host_addr,
> -local->block[i].length,
> -IBV_ACCESS_LOCAL_WRITE |
> -IBV_ACCESS_REMOTE_WRITE
> -);
> -if (!local->block[i].mr) {
> -perror("Failed to register local dest ram block!\n");
> -break;
> +if (migrate_use_multiRDMA()) {
> +if (id == UNUSED_ID) {
> +for (i = 0; i < local->nb_blocks; i++) {
> +/* main RDMA channel don't register the mach-virt.ram block 
> */
> +if (strcmp(local->block[i].block_name, "mach-virt.ram") == 
> 0) {
> +continue;
> +}
> +
> +local->block[i].mr =
> +ibv_reg_mr(rdma->pd,
> +local->block[i].local_host_addr,
> +local->block[i].length,
> +IBV_ACCESS_LOCAL_WRITE |
> +IBV_ACCESS_REMOTE_WRITE
> +);
> +if (!local->block[i].mr) {
> +perror("Failed to register local dest ram block!\n");
> +break;
> +}
> +rdma->total_registrations++;
> +}
> +} else {
> +for (i = 0; i < local->nb_blocks; i++) {
> +/*
> + * The multiRDAM channels only register
> + * the mach-virt.ram block
> + */
> +if (strcmp(local->block[i].block_name, "mach-virt.ram") == 
> 0) {
> +local->block[i].mr =
> +ibv_reg_mr(rdma->pd,
> +local->block[i].local_host_addr,
> +local->block[i].length,
> +

[PATCH] riscv: Fix defination of csr operations

2020-01-18 Thread Ian Jiang
There is a mistake in defining CSR operations for pmpcfg registers.
This patch fixes the bug.

Signed-off-by: Ian Jiang 
---
 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index da02f9f0b1..e07b5267be 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -948,7 +948,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_SATP] ={ smode, read_satp,write_satp
   },

 /* Physical Memory Protection */
-[CSR_PMPCFG0  ... CSR_PMPADDR9] =  { pmp,   read_pmpcfg,  write_pmpcfg
  },
+[CSR_PMPCFG0  ... CSR_PMPCFG3] =  { pmp,   read_pmpcfg,  write_pmpcfg
  },
 [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp,   read_pmpaddr,
write_pmpaddr  },

 /* Performance Counters */
-- 
2.17.1


[PATCH v4 19/20] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

This test boots U-Boot then NetBSD (stored on a SD card) on
a OrangePi PC board.

As it requires ~1.3GB of storage, it is disabled by default.

U-Boot is built by the Debian project [1], and the SD card image
is provided by the NetBSD organization [2].

Once the compressed SD card image is downloaded (304MB) and
extracted, this test is fast:

  $ AVOCADO_ALLOW_LARGE_STORAGE=yes \
avocado --show=app,console run -t machine:orangepi-pc \
  tests/acceptance/boot_linux_console.py
  console: U-Boot SPL 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +)
  console: DRAM: 1024 MiB
  console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) Allwinner 
Technology
  console: CPU:   Allwinner H3 (SUN8I )
  console: scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
  console: scanning bus usb@1c1d000 for devices... 1 USB Device(s) found
  console: scanning usb for storage devices... 0 Storage Device(s) found
  console: Hit any key to stop autoboot:  0
  console: => setenv bootargs root=ld0a
  console: => setenv kernel netbsd-GENERIC.ub
  console: => setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb
  console: => boot
  console: ## Booting kernel from Legacy Image at 4200 ...
  console: Image Name:   NetBSD/earmv7hf 9.0_RC1
  console: Image Type:   ARM Linux Kernel Image (no loading done) (uncompressed)
  console: XIP Kernel Image (no loading done)
  console: Loading Device Tree to 49ff6000, end 49fffe01 ... OK
  console: Starting kernel ...
  console: [   1.000] NetBSD/evbarm (fdt) booting ...
  console: [   1.000] NetBSD 9.0_RC1 (GENERIC) #0: Wed Nov 27 16:14:52 UTC 
2019
  console: [   1.000] simplebus0 at armfdt0: Xunlong Orange Pi PC
  console: [   1.000] cpu0 at cpus0: Cortex-A7 r0p5 (Cortex V7A core)
  console: [   1.000] cpu0: DC enabled IC enabled WB enabled LABT branch 
prediction enabled
  console: [   1.000] cpu0: 32KB/64B 2-way L1 VIPT Instruction cache
  console: [   1.000] cpu0: 32KB/64B 2-way write-back-locking-C L1 PIPT 
Data cache
  console: [   1.000] cpu0: 2304KB/64B 16-way write-through L2 PIPT Unified 
cache
  console: [   1.000] vfp0 at cpu0: NEON MPE (VFP 3.0+), rounding, NaN 
propagation, denormals
  ...
  console: [   2.8171937] sdmmc0: SD card status: 4-bit, C0
  console: [   2.8234040] ld0 at sdmmc0: 
<0xaa:0x5859:QEMU!:0x01:0xdeadbeef:0x062>
  console: [   2.8743967] ld0: 1290 MB, 655 cyl, 64 head, 63 sec, 512 
bytes/sect x 2642944 sectors
  console: [   3.1588850] ld0: 4-bit width, High-Speed/SDR25, 50.000 MHz
  console: [   4.9942260] WARNING: 4 errors while detecting hardware; check 
system log.
  console: [   5.0142912] boot device: ld0
  console: [   5.0551260] root on ld0a dumps on ld0b
  console: [   5.2175484] root file system type: ffs
  console: [   5.2858559] kern.module.path=/stand/evbarm/9.0/modules
  console: Tue Jan 18 18:15:15 UTC 2050
  console: Starting root file system check:
  PASS (35.96 s)
  RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
  JOB TIME   : 36.09 s

Note, this test only took ~65 seconds to run on Travis-CI, see: [3].

This test is based on a description from Niek Linnenbank from [4].

[1] 
https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot
[2] https://wiki.netbsd.org/ports/evbarm/allwinner/
[3] https://travis-ci.org/philmd/qemu/jobs/638823612#L3778
[4] https://www.mail-archive.com/qemu-devel@nongnu.org/msg669347.html

Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Niek Linnenbank 
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/boot_linux_console.py | 63 ++
 1 file changed, 63 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 399d5062db..b883d7778f 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -16,6 +16,7 @@ import shutil
 from avocado import skipUnless
 from avocado_qemu import Test
 from avocado_qemu import exec_command_and_wait_for_pattern
+from avocado_qemu import interrupt_interactive_console_until_pattern
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import process
 from avocado.utils import archive
@@ -632,6 +633,68 @@ class BootLinuxConsole(Test):
   'to ')
 self.wait_for_console_pattern('Starting Load Kernel Modules...')
 
+@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
+def test_arm_orangepi_uboot_netbsd9(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+# This test download a 304MB compressed image and expand it to 1.3GB...
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20200108T145233Z/pool/main/u/u-boot/'
+   'u-boot-sunxi_2020.01%2Bdfsg-1_armhf.deb')
+deb_hash = 'f67f404a80753ca3d1258f13e38f2b060e13db99

[PATCH v4 09/20] hw/arm/allwinner-h3: add EMAC ethernet device

2020-01-18 Thread Niek Linnenbank
The Allwinner Sun8i System on Chip family includes an Ethernet MAC (EMAC)
which provides 10M/100M/1000M Ethernet connectivity. This commit
adds support for the Allwinner EMAC from the Sun8i family (H2+, H3, A33, etc),
including emulation for the following functionality:

 * DMA transfers
 * MII interface
 * Transmit CRC calculation

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h |   3 +
 include/hw/net/allwinner-sun8i-emac.h |  99 +++
 hw/arm/allwinner-h3.c |  16 +-
 hw/arm/orangepi.c |   3 +
 hw/net/allwinner-sun8i-emac.c | 871 ++
 hw/arm/Kconfig|   1 +
 hw/net/Kconfig|   3 +
 hw/net/Makefile.objs  |   1 +
 hw/net/trace-events   |  10 +
 9 files changed, 1006 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/net/allwinner-sun8i-emac.h
 create mode 100644 hw/net/allwinner-sun8i-emac.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index d71a4917ab..f9b9a02373 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -44,6 +44,7 @@
 #include "hw/misc/allwinner-h3-sysctrl.h"
 #include "hw/misc/allwinner-sid.h"
 #include "hw/sd/allwinner-sdhost.h"
+#include "hw/net/allwinner-sun8i-emac.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -77,6 +78,7 @@ enum {
 AW_H3_UART1,
 AW_H3_UART2,
 AW_H3_UART3,
+AW_H3_EMAC,
 AW_H3_GIC_DIST,
 AW_H3_GIC_CPU,
 AW_H3_GIC_HYP,
@@ -120,6 +122,7 @@ typedef struct AwH3State {
 AwH3SysCtrlState sysctrl;
 AwSidState sid;
 AwSdHostState mmc0;
+AwSun8iEmacState emac;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/net/allwinner-sun8i-emac.h 
b/include/hw/net/allwinner-sun8i-emac.h
new file mode 100644
index 00..eda034e96b
--- /dev/null
+++ b/include/hw/net/allwinner-sun8i-emac.h
@@ -0,0 +1,99 @@
+/*
+ * Allwinner Sun8i Ethernet MAC emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_NET_ALLWINNER_SUN8I_EMAC_H
+#define HW_NET_ALLWINNER_SUN8I_EMAC_H
+
+#include "qom/object.h"
+#include "net/net.h"
+#include "hw/sysbus.h"
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_SUN8I_EMAC "allwinner-sun8i-emac"
+#define AW_SUN8I_EMAC(obj) \
+OBJECT_CHECK(AwSun8iEmacState, (obj), TYPE_AW_SUN8I_EMAC)
+
+/** @} */
+
+/**
+ * Allwinner Sun8i EMAC object instance state
+ */
+typedef struct AwSun8iEmacState {
+/*< private >*/
+SysBusDevice  parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Interrupt output signal to notify CPU */
+qemu_irq irq;
+
+/** Generic Network Interface Controller (NIC) for networking API */
+NICState *nic;
+
+/** Generic Network Interface Controller (NIC) configuration */
+NICConf  conf;
+
+/**
+ * @name Media Independent Interface (MII)
+ * @{
+ */
+
+uint8_t  mii_phy_addr;  /**< PHY address */
+uint32_t mii_cr;/**< Control */
+uint32_t mii_st;/**< Status */
+uint32_t mii_adv;   /**< Advertised Abilities */
+
+/** @} */
+
+/**
+ * @name Hardware Registers
+ * @{
+ */
+
+uint32_t basic_ctl0;/**< Basic Control 0 */
+uint32_t basic_ctl1;/**< Basic Control 1 */
+uint32_t int_en;/**< Interrupt Enable */
+uint32_t int_sta;   /**< Interrupt Status */
+uint32_t frm_flt;   /**< Receive Frame Filter */
+
+uint32_t rx_ctl0;   /**< Receive Control 0 */
+uint32_t rx_ctl1;   /**< Receive Control 1 */
+uint32_t rx_desc_head;  /**< Receive Descriptor List Address */
+uint32_t rx_desc_curr;  /**< Current Receive Descriptor Address */
+
+uint32_t tx_ctl0;   /**< Transmit Control 0 */
+uint32_t tx_ctl1;   /**< Transmit Control 1 */
+uint32_t tx_desc_head;  /**< Transmit Descriptor List Address */
+uint32_t tx_desc_curr;  /**< Current Transmit Descriptor Address */
+uint32_t tx_flowctl;/**< Transmit Flow Control */
+
+uint32_t mii_cmd;   /**< Management Interface Command */
+uint32_t mii_data;  /**< Management Interface

[PATCH v4 18/20] Acceptance tests: Add interrupt_interactive_console_until_pattern()

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

We need a function to interrupt interactive consoles.

Example: Interrupt U-Boot to set different environment values.

Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Niek Linnenbank 
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/avocado_qemu/__init__.py | 32 +--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 0a50fcf2be..d4358eb431 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -56,13 +56,15 @@ def pick_default_qemu_bin(arch=None):
 
 
 def _console_interaction(test, success_message, failure_message,
- send_string):
+ send_string, keep_sending=False):
+assert not keep_sending or send_string
 console = test.vm.console_socket.makefile()
 console_logger = logging.getLogger('console')
 while True:
 if send_string:
 test.vm.console_socket.sendall(send_string.encode())
-send_string = None # send only once
+if not keep_sending:
+send_string = None # send only once
 msg = console.readline().strip()
 if not msg:
 continue
@@ -74,6 +76,32 @@ def _console_interaction(test, success_message, 
failure_message,
 fail = 'Failure message found in console: %s' % failure_message
 test.fail(fail)
 
+def interrupt_interactive_console_until_pattern(test, success_message,
+failure_message=None,
+interrupt_string='\r'):
+"""
+Keep sending a string to interrupt a console prompt, while logging the
+console output. Typical use case is to break a boot loader prompt, such:
+
+Press a key within 5 seconds to interrupt boot process.
+5
+4
+3
+2
+1
+Booting default image...
+
+:param test: an Avocado test containing a VM that will have its console
+ read and probed for a success or failure message
+:type test: :class:`avocado_qemu.Test`
+:param success_message: if this message appears, test succeeds
+:param failure_message: if this message appears, test fails
+:param interrupt_string: a string to send to the console before trying
+ to read a new line
+"""
+_console_interaction(test, success_message, failure_message,
+ interrupt_string, True)
+
 def wait_for_console_pattern(test, success_message, failure_message=None):
 """
 Waits for messages to appear on the console, while logging the content
-- 
2.17.1




[PATCH v4 17/20] Acceptance tests: Extract _console_interaction()

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

Since we are going to re-use the code shared between
wait_for_console_pattern() and exec_command_and_wait_for_pattern(),
extract the common part into a local function.

Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Niek Linnenbank 
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/avocado_qemu/__init__.py | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 6618ea67c1..0a50fcf2be 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -55,19 +55,14 @@ def pick_default_qemu_bin(arch=None):
 return qemu_bin_from_src_dir_path
 
 
-def wait_for_console_pattern(test, success_message, failure_message=None):
-"""
-Waits for messages to appear on the console, while logging the content
-
-:param test: an Avocado test containing a VM that will have its console
- read and probed for a success or failure message
-:type test: :class:`avocado_qemu.Test`
-:param success_message: if this message appears, test succeeds
-:param failure_message: if this message appears, test fails
-"""
+def _console_interaction(test, success_message, failure_message,
+ send_string):
 console = test.vm.console_socket.makefile()
 console_logger = logging.getLogger('console')
 while True:
+if send_string:
+test.vm.console_socket.sendall(send_string.encode())
+send_string = None # send only once
 msg = console.readline().strip()
 if not msg:
 continue
@@ -79,6 +74,17 @@ def wait_for_console_pattern(test, success_message, 
failure_message=None):
 fail = 'Failure message found in console: %s' % failure_message
 test.fail(fail)
 
+def wait_for_console_pattern(test, success_message, failure_message=None):
+"""
+Waits for messages to appear on the console, while logging the content
+
+:param test: an Avocado test containing a VM that will have its console
+ read and probed for a success or failure message
+:type test: :class:`avocado_qemu.Test`
+:param success_message: if this message appears, test succeeds
+:param failure_message: if this message appears, test fails
+"""
+_console_interaction(test, success_message, failure_message, None)
 
 def exec_command_and_wait_for_pattern(test, command,
   success_message, failure_message=None):
@@ -94,10 +100,7 @@ def exec_command_and_wait_for_pattern(test, command,
 :param success_message: if this message appears, test succeeds
 :param failure_message: if this message appears, test fails
 """
-command += '\r'
-test.vm.console_socket.sendall(command.encode())
-wait_for_console_pattern(test, success_message, failure_message)
-
+_console_interaction(test, success_message, failure_message, command + 
'\r')
 
 class Test(avocado.Test):
 def _get_unique_tag_val(self, tag_name):
-- 
2.17.1




[PATCH v4 08/20] hw/arm/allwinner: add SD/MMC host controller

2020-01-18 Thread Niek Linnenbank
The Allwinner System on Chip families sun4i and above contain
an integrated storage controller for Secure Digital (SD) and
Multi Media Card (MMC) interfaces. This commit adds support
for the Allwinner SD/MMC storage controller with the following
emulated features:

 * DMA transfers
 * Direct FIFO I/O
 * Short/Long format command responses
 * Auto-Stop command (CMD12)
 * Insert & remove card detection

The following boards are extended with the SD host controller:

 * Cubieboard (hw/arm/cubieboard.c)
 * Orange Pi PC (hw/arm/orangepi.c)

Signed-off-by: Niek Linnenbank 
Tested-by: Philippe Mathieu-Daudé 
---
 include/hw/arm/allwinner-a10.h   |   2 +
 include/hw/arm/allwinner-h3.h|   3 +
 include/hw/sd/allwinner-sdhost.h | 135 +
 hw/arm/allwinner-a10.c   |  11 +
 hw/arm/allwinner-h3.c|  15 +-
 hw/arm/cubieboard.c  |  15 +
 hw/arm/orangepi.c|  16 +
 hw/sd/allwinner-sdhost.c | 848 +++
 hw/sd/Makefile.objs  |   1 +
 hw/sd/trace-events   |   7 +
 10 files changed, 1052 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/sd/allwinner-sdhost.h
 create mode 100644 hw/sd/allwinner-sdhost.c

diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index 40d0b1d9c0..d009616eef 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -7,6 +7,7 @@
 #include "hw/timer/allwinner-a10-pit.h"
 #include "hw/intc/allwinner-a10-pic.h"
 #include "hw/net/allwinner_emac.h"
+#include "hw/sd/allwinner-sdhost.h"
 #include "hw/ide/ahci.h"
 
 #include "target/arm/cpu.h"
@@ -27,6 +28,7 @@ typedef struct AwA10State {
 AwA10PICState intc;
 AwEmacState emac;
 AllwinnerAHCIState sata;
+AwSdHostState mmc0;
 MemoryRegion sram_a;
 } AwA10State;
 
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 85416d9d64..d71a4917ab 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -43,6 +43,7 @@
 #include "hw/misc/allwinner-cpucfg.h"
 #include "hw/misc/allwinner-h3-sysctrl.h"
 #include "hw/misc/allwinner-sid.h"
+#include "hw/sd/allwinner-sdhost.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -60,6 +61,7 @@ enum {
 AW_H3_SRAM_A2,
 AW_H3_SRAM_C,
 AW_H3_SYSCTRL,
+AW_H3_MMC0,
 AW_H3_SID,
 AW_H3_EHCI0,
 AW_H3_OHCI0,
@@ -117,6 +119,7 @@ typedef struct AwH3State {
 AwCpuCfgState cpucfg;
 AwH3SysCtrlState sysctrl;
 AwSidState sid;
+AwSdHostState mmc0;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/sd/allwinner-sdhost.h b/include/hw/sd/allwinner-sdhost.h
new file mode 100644
index 00..d94606a853
--- /dev/null
+++ b/include/hw/sd/allwinner-sdhost.h
@@ -0,0 +1,135 @@
+/*
+ * Allwinner (sun4i and above) SD Host Controller emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_SD_ALLWINNER_SDHOST_H
+#define HW_SD_ALLWINNER_SDHOST_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "hw/sd/sd.h"
+
+/**
+ * Object model types
+ * @{
+ */
+
+/** Generic Allwinner SD Host Controller (abstract) */
+#define TYPE_AW_SDHOST "allwinner-sdhost"
+
+/** Allwinner sun4i family (A10, A12) */
+#define TYPE_AW_SDHOST_SUN4I TYPE_AW_SDHOST "-sun4i"
+
+/** Allwinner sun5i family and newer (A13, H2+, H3, etc) */
+#define TYPE_AW_SDHOST_SUN5I TYPE_AW_SDHOST "-sun5i"
+
+/** @} */
+
+/**
+ * Object model macros
+ * @{
+ */
+
+#define AW_SDHOST(obj) \
+OBJECT_CHECK(AwSdHostState, (obj), TYPE_AW_SDHOST)
+#define AW_SDHOST_CLASS(klass) \
+ OBJECT_CLASS_CHECK(AwSdHostClass, (klass), TYPE_AW_SDHOST)
+#define AW_SDHOST_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(AwSdHostClass, (obj), TYPE_AW_SDHOST)
+
+/** @} */
+
+/**
+ * Allwinner SD Host Controller object instance state.
+ */
+typedef struct AwSdHostState {
+/*< private >*/
+SysBusDevice busdev;
+/*< public >*/
+
+/** Secure Digital (SD) bus, which connects to SD card (if present) */
+SDBus sdbus;
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Interrupt output signal to notify CPU */
+qemu_irq irq;
+
+/** Number of bytes left in current DMA transfer */
+uint32_t transfer_cnt;
+
+/**
+ * @name Hardware Registers
+ * @{
+ */
+
+uint32

[PATCH v4 12/20] hw/arm/allwinner: add RTC device support

2020-01-18 Thread Niek Linnenbank
Allwinner System-on-Chips usually contain a Real Time Clock (RTC)
for non-volatile system date and time keeping. This commit adds a generic
Allwinner RTC device that supports the RTC devices found in Allwinner SoC
family sun4i (A10), sun7i (A20) and sun6i and newer (A31, H2+, H3, etc).
The following RTC functionality and features are implemented:

 * Year-Month-Day read/write
 * Hour-Minute-Second read/write
 * General Purpose storage

The following boards are extended with the RTC device:

 * Cubieboard (hw/arm/cubieboard.c)
 * Orange Pi PC (hw/arm/orangepi.c)

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-a10.h |   2 +
 include/hw/arm/allwinner-h3.h  |   3 +
 include/hw/rtc/allwinner-rtc.h | 128 +++
 hw/arm/allwinner-a10.c |   8 +
 hw/arm/allwinner-h3.c  |   9 +-
 hw/rtc/allwinner-rtc.c | 386 +
 hw/rtc/Makefile.objs   |   1 +
 hw/rtc/trace-events|   4 +
 8 files changed, 540 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/rtc/allwinner-rtc.h
 create mode 100644 hw/rtc/allwinner-rtc.c

diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index d009616eef..fc979985e6 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -9,6 +9,7 @@
 #include "hw/net/allwinner_emac.h"
 #include "hw/sd/allwinner-sdhost.h"
 #include "hw/ide/ahci.h"
+#include "hw/rtc/allwinner-rtc.h"
 
 #include "target/arm/cpu.h"
 
@@ -29,6 +30,7 @@ typedef struct AwA10State {
 AwEmacState emac;
 AllwinnerAHCIState sata;
 AwSdHostState mmc0;
+AwRtcState rtc;
 MemoryRegion sram_a;
 } AwA10State;
 
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 8bcfc4a164..fd6077c23b 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -46,6 +46,7 @@
 #include "hw/misc/allwinner-sid.h"
 #include "hw/sd/allwinner-sdhost.h"
 #include "hw/net/allwinner-sun8i-emac.h"
+#include "hw/rtc/allwinner-rtc.h"
 #include "target/arm/cpu.h"
 #include "sysemu/block-backend.h"
 
@@ -88,6 +89,7 @@ enum {
 AW_H3_GIC_CPU,
 AW_H3_GIC_HYP,
 AW_H3_GIC_VCPU,
+AW_H3_RTC,
 AW_H3_CPUCFG,
 AW_H3_SDRAM
 };
@@ -129,6 +131,7 @@ typedef struct AwH3State {
 AwSidState sid;
 AwSdHostState mmc0;
 AwSun8iEmacState emac;
+AwRtcState rtc;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/rtc/allwinner-rtc.h b/include/hw/rtc/allwinner-rtc.h
new file mode 100644
index 00..ce5f883396
--- /dev/null
+++ b/include/hw/rtc/allwinner-rtc.h
@@ -0,0 +1,128 @@
+/*
+ * Allwinner Real Time Clock emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_RTC_H
+#define HW_MISC_ALLWINNER_RTC_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+
+/**
+ * Constants
+ * @{
+ */
+
+/** Highest register address used by RTC device */
+#define AW_RTC_REGS_MAXADDR (0x200)
+
+/** Total number of known registers */
+#define AW_RTC_REGS_NUM (AW_RTC_REGS_MAXADDR / sizeof(uint32_t))
+
+/** @} */
+
+/**
+ * Object model types
+ * @{
+ */
+
+/** Generic Allwinner RTC device (abstract) */
+#define TYPE_AW_RTC  "allwinner-rtc"
+
+/** Allwinner RTC sun4i family (A10, A12) */
+#define TYPE_AW_RTC_SUN4ITYPE_AW_RTC "-sun4i"
+
+/** Allwinner RTC sun6i family and newer (A31, H2+, H3, etc) */
+#define TYPE_AW_RTC_SUN6ITYPE_AW_RTC "-sun6i"
+
+/** Allwinner RTC sun7i family (A20) */
+#define TYPE_AW_RTC_SUN7ITYPE_AW_RTC "-sun7i"
+
+/** @} */
+
+/**
+ * Object model macros
+ * @{
+ */
+
+#define AW_RTC(obj) \
+OBJECT_CHECK(AwRtcState, (obj), TYPE_AW_RTC)
+#define AW_RTC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(AwRtcClass, (klass), TYPE_AW_RTC)
+#define AW_RTC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(AwRtcClass, (obj), TYPE_AW_RTC)
+
+/** @} */
+
+/**
+ * Allwinner RTC per-object instance state.
+ */
+typedef struct AwRtcState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Array of hardware registers */
+uint32_t regs[AW_RTC_REGS_NUM];
+
+} AwRtcState;
+
+/**
+ * Allwinner RTC class-level struct.
+ *
+ * This struct is filled by each sunxi device specific code
+ * such that t

[PATCH v4 11/20] hw/arm/allwinner-h3: add SDRAM controller device

2020-01-18 Thread Niek Linnenbank
In the Allwinner H3 SoC the SDRAM controller is responsible
for interfacing with the external Synchronous Dynamic Random
Access Memory (SDRAM). Types of memory that the SDRAM controller
supports are DDR2/DDR3 and capacities of up to 2GiB. This commit
adds emulation support of the Allwinner H3 SDRAM controller.

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h|   5 +
 include/hw/misc/allwinner-h3-dramc.h | 106 
 hw/arm/allwinner-h3.c|  19 +-
 hw/arm/orangepi.c|   6 +
 hw/misc/allwinner-h3-dramc.c | 358 +++
 hw/misc/Makefile.objs|   1 +
 hw/misc/trace-events |  10 +
 7 files changed, 502 insertions(+), 3 deletions(-)
 create mode 100644 include/hw/misc/allwinner-h3-dramc.h
 create mode 100644 hw/misc/allwinner-h3-dramc.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index f5e16266cd..8bcfc4a164 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -41,6 +41,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/allwinner-h3-ccu.h"
 #include "hw/misc/allwinner-cpucfg.h"
+#include "hw/misc/allwinner-h3-dramc.h"
 #include "hw/misc/allwinner-h3-sysctrl.h"
 #include "hw/misc/allwinner-sid.h"
 #include "hw/sd/allwinner-sdhost.h"
@@ -80,6 +81,9 @@ enum {
 AW_H3_UART2,
 AW_H3_UART3,
 AW_H3_EMAC,
+AW_H3_DRAMCOM,
+AW_H3_DRAMCTL,
+AW_H3_DRAMPHY,
 AW_H3_GIC_DIST,
 AW_H3_GIC_CPU,
 AW_H3_GIC_HYP,
@@ -120,6 +124,7 @@ typedef struct AwH3State {
 AwA10PITState timer;
 AwH3ClockCtlState ccu;
 AwCpuCfgState cpucfg;
+AwH3DramCtlState dramc;
 AwH3SysCtrlState sysctrl;
 AwSidState sid;
 AwSdHostState mmc0;
diff --git a/include/hw/misc/allwinner-h3-dramc.h 
b/include/hw/misc/allwinner-h3-dramc.h
new file mode 100644
index 00..bacdf236b7
--- /dev/null
+++ b/include/hw/misc/allwinner-h3-dramc.h
@@ -0,0 +1,106 @@
+/*
+ * Allwinner H3 SDRAM Controller emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_H3_DRAMC_H
+#define HW_MISC_ALLWINNER_H3_DRAMC_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+
+/**
+ * Constants
+ * @{
+ */
+
+/** Highest register address used by DRAMCOM module */
+#define AW_H3_DRAMCOM_REGS_MAXADDR  (0x804)
+
+/** Total number of known DRAMCOM registers */
+#define AW_H3_DRAMCOM_REGS_NUM  (AW_H3_DRAMCOM_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** Highest register address used by DRAMCTL module */
+#define AW_H3_DRAMCTL_REGS_MAXADDR  (0x88c)
+
+/** Total number of known DRAMCTL registers */
+#define AW_H3_DRAMCTL_REGS_NUM  (AW_H3_DRAMCTL_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** Highest register address used by DRAMPHY module */
+#define AW_H3_DRAMPHY_REGS_MAXADDR  (0x4)
+
+/** Total number of known DRAMPHY registers */
+#define AW_H3_DRAMPHY_REGS_NUM  (AW_H3_DRAMPHY_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** @} */
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_H3_DRAMC "allwinner-h3-dramc"
+#define AW_H3_DRAMC(obj) \
+OBJECT_CHECK(AwH3DramCtlState, (obj), TYPE_AW_H3_DRAMC)
+
+/** @} */
+
+/**
+ * Allwinner H3 SDRAM Controller object instance state.
+ */
+typedef struct AwH3DramCtlState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Physical base address for start of RAM */
+hwaddr ram_addr;
+
+/** Total RAM size in megabytes */
+uint32_t ram_size;
+
+/**
+ * @name Memory Regions
+ * @{
+ */
+
+MemoryRegion row_mirror;   /**< Simulates rows for RAM size detection 
*/
+MemoryRegion row_mirror_alias; /**< Alias of the row which is mirrored */
+MemoryRegion dramcom_iomem;/**< DRAMCOM module I/O registers */
+MemoryRegion dramctl_iomem;/**< DRAMCTL module I/O registers */
+MemoryRegion dramphy_iomem;/**< DRAMPHY module I/O registers */
+
+/** @} */
+
+/**
+ * @name Hardware Registers
+ * @{
+ */
+
+uint32_t dramcom[AW_H3_DRAMCOM_REGS_NUM]; /**< Array of DRAMCOM registers 
*/
+uint32_t dramctl[AW_H3_DRAMCTL_REGS_NUM]; /**< Array of DRAMCTL registers 
*/
+uint32_t dramphy[AW_H3_DRAMPH

[PATCH v4 15/20] tests/boot_linux_console: Add a SD card test for the OrangePi PC board

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

The kernel image and DeviceTree blob are built by the Armbian
project (based on Debian):
https://www.armbian.com/orange-pi-pc/

The SD image is from the kernelci.org project:
https://kernelci.org/faq/#the-code

If ARM is a target being built, "make check-acceptance" will
automatically include this test by the use of the "arch:arm" tags.

Alternatively, this test can be run using:

  $ avocado --show=console run -t machine:orangepi-pc 
tests/acceptance/boot_linux_console.py
  console: Uncompressing Linux... done, booting the kernel.
  console: Booting Linux on physical CPU 0x0
  console: Linux version 4.20.7-sunxi (r...@armbian.com) (gcc version 7.2.1 
20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
  console: CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=50c5387d
  [...]
  console: sunxi-wdt 1c20ca0.watchdog: Watchdog enabled (timeout=16 sec, 
nowayout=0)
  console: sunxi-mmc 1c0f000.mmc: Linked as a consumer to regulator.2
  console: sunxi-mmc 1c0f000.mmc: Got CD GPIO
  console: ledtrig-cpu: registered to indicate activity on CPUs
  console: hidraw: raw HID events driver (C) Jiri Kosina
  console: usbcore: registered new interface driver usbhid
  console: usbhid: USB HID core driver
  console: Initializing XFRM netlink socket
  console: sunxi-mmc 1c0f000.mmc: initialized, max. request size: 16384 KB
  console: NET: Registered protocol family 10
  console: mmc0: host does not support reading read-only switch, assuming 
write-enable
  console: mmc0: Problem switching card into high-speed mode!
  console: mmc0: new SD card at address 4567
  console: mmcblk0: mmc0:4567 QEMU! 60.0 MiB
  [...]
  console: EXT4-fs (mmcblk0): mounting ext2 file system using the ext4 subsystem
  console: EXT4-fs (mmcblk0): mounted filesystem without journal. Opts: (null)
  console: VFS: Mounted root (ext2 filesystem) on device 179:0.
  console: Run /sbin/init as init process
  console: EXT4-fs (mmcblk0): re-mounted. Opts: 
block_validity,barrier,user_xattr,acl
  console: Starting syslogd: OK
  console: Starting klogd: OK
  console: Populating /dev using udev: udevd[203]: starting version 3.2.7
  console: /bin/sh: can't access tty; job control turned off
  console: cat /proc/partitions
  console: / # cat /proc/partitions
  console: major minor  #blocks  name
  console: 10   4096 ram0
  console: 11   4096 ram1
  console: 12   4096 ram2
  console: 13   4096 ram3
  console: 1790  61440 mmcblk0
  console: reboot
  console: / # reboot
  console: umount: devtmpfs busy - remounted read-only
  console: EXT4-fs (mmcblk0): re-mounted. Opts: (null)
  console: The system is going down NOW!
  console: Sent SIGTERM to all processes
  console: Sent SIGKILL to all processes
  console: Requesting system reboot
  console: reboot: Restarting system
  JOB TIME   : 68.64 s

Signed-off-by: Philippe Mathieu-Daudé 
[NL: rename in commit message Raspbian to Armbian, remove vm.set_machine()]
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/boot_linux_console.py | 41 ++
 1 file changed, 41 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 463aa65f4d..50294e1675 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -550,6 +550,47 @@ class BootLinuxConsole(Test):
 exec_command_and_wait_for_pattern(self, 'reboot',
 'reboot: Restarting system')
 
+def test_arm_orangepi_sd(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+deb_url = ('https://apt.armbian.com/pool/main/l/'
+   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
+deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinuz-4.20.7-sunxi')
+dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
+dtb_path = self.extract_from_deb(deb_path, dtb_path)
+rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
+  'kci-2019.02/armel/base/rootfs.ext2.xz')
+rootfs_hash = '692510cb625efda31640d1de0a8d60e26040f061'
+rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
+rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
+archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0,115200 '
+   'root=/dev/mmcblk0 rootwait rw '
+   'panic=-1 noreboot')
+self.vm.add_args('-kernel', kernel_path,
+ 

[PATCH v4 14/20] tests/boot_linux_console: Add initrd test for the Orange Pi PC board

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

This test boots a Linux kernel on a OrangePi PC board and verify
the serial output is working.

The kernel image and DeviceTree blob are built by the Armbian
project (based on Debian):
https://www.armbian.com/orange-pi-pc/

The cpio image used comes from the linux-build-test project:
https://github.com/groeck/linux-build-test

If ARM is a target being built, "make check-acceptance" will
automatically include this test by the use of the "arch:arm" tags.

Alternatively, this test can be run using:

  $ avocado --show=console run -t machine:orangepi-pc 
tests/acceptance/boot_linux_console.py
  console: Uncompressing Linux... done, booting the kernel.
  console: Booting Linux on physical CPU 0x0
  console: Linux version 4.20.7-sunxi (r...@armbian.com) (gcc version 7.2.1 
20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
  console: CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=50c5387d
  console: CPU: div instructions available: patching division code
  console: CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction 
cache
  console: OF: fdt: Machine model: Xunlong Orange Pi PC
  [...]
  console: Trying to unpack rootfs image as initramfs...
  console: Freeing initrd memory: 3256K
  console: Freeing unused kernel memory: 1024K
  console: Run /init as init process
  console: mount: mounting devtmpfs on /dev failed: Device or resource busy
  console: Starting logging: OK
  console: Initializing random number generator... random: dd: uninitialized 
urandom read (512 bytes read)
  console: done.
  console: Starting network: OK
  console: Found console ttyS0
  console: Linux version 4.20.7-sunxi (r...@armbian.com) (gcc version 7.2.1 
20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
  console: Boot successful.
  console: cat /proc/cpuinfo
  console: / # cat /proc/cpuinfo
  console: processor  : 0
  console: model name : ARMv7 Processor rev 5 (v7l)
  console: BogoMIPS   : 125.00
  console: Features   : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 
idiva idivt vfpd32 lpae evtstrm
  console: CPU implementer: 0x41
  console: CPU architecture: 7
  console: CPU variant: 0x0
  console: CPU part   : 0xc07
  console: CPU revision   : 5
  [...]
  console: processor  : 3
  console: model name : ARMv7 Processor rev 5 (v7l)
  console: BogoMIPS   : 125.00
  console: Features   : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 
idiva idivt vfpd32 lpae evtstrm
  console: CPU implementer: 0x41
  console: CPU architecture: 7
  console: CPU variant: 0x0
  console: CPU part   : 0xc07
  console: CPU revision   : 5
  console: Hardware   : Allwinner sun8i Family
  console: Revision   : 
  console: Serial : 
  console: cat /proc/iomem
  console: / # cat /proc/iomem
  console: 0100-010f : clock@100
  console: 01c0-01c00fff : system-control@1c0
  console: 01c02000-01c02fff : dma-controller@1c02000
  [...]
  console: reboot
  console: / # reboot
  console: / # Found console ttyS0
  console: Stopping network: OK
  console: hrtimer: interrupt took 21852064 ns
  console: Saving random seed... random: dd: uninitialized urandom read (512 
bytes read)
  console: done.
  console: Stopping logging: OK
  console: umount: devtmpfs busy - remounted read-only
  console: umount: can't unmount /: Invalid argument
  console: The system is going down NOW!
  console: Sent SIGTERM to all processes
  console: Sent SIGKILL to all processes
  console: Requesting system reboot
  console: reboot: Restarting system
  PASS (48.32 s)
  JOB TIME   : 49.16 s

Signed-off-by: Philippe Mathieu-Daudé 
[NL: rename in commit message Raspbian to Armbian, remove vm.set_machine()]
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/boot_linux_console.py | 40 ++
 1 file changed, 40 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 7b4e400511..463aa65f4d 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -510,6 +510,46 @@ class BootLinuxConsole(Test):
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
 
+def test_arm_orangepi_initrd(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+deb_url = ('https://apt.armbian.com/pool/main/l/'
+   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
+deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinuz-4.20.7-sunxi')
+dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
+dtb_path = self.extract_

[PATCH v4 16/20] tests/boot_linux_console: Add a SLOW test booting Ubuntu on OrangePi PC

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

This test boots Ubuntu Bionic on a OrangePi PC board.

As it requires 1GB of storage, and is slow, this test is disabled
on automatic CI testing.

It is useful for workstation testing. Currently Avocado timeouts too
quickly, so we can't run userland commands.

The kernel image and DeviceTree blob are built by the Armbian
project (based on Debian):
https://www.armbian.com/orange-pi-pc/

The Ubuntu image is downloaded from:
https://dl.armbian.com/orangepipc/Bionic_current

This test can be run using:

  $ AVOCADO_ALLOW_LARGE_STORAGE=yes \
avocado --show=app,console run -t machine:orangepi-pc \
  tests/acceptance/boot_linux_console.py
  console: U-Boot SPL 2019.04-armbian (Nov 18 2019 - 23:08:35 +0100)
  console: DRAM: 1024 MiB
  console: Failed to set core voltage! Can't set CPU frequency
  console: Trying to boot from MMC1
  console: U-Boot 2019.04-armbian (Nov 18 2019 - 23:08:35 +0100) Allwinner 
Technology
  console: CPU:   Allwinner H3 (SUN8I )
  console: Model: Xunlong Orange Pi PC
  console: DRAM:  1 GiB
  console: MMC:   mmc@1c0f000: 0
  [...]
  console: Uncompressing Linux... done, booting the kernel.
  console: Booting Linux on physical CPU 0x0
  console: Linux version 5.3.9-sunxi (root@builder) (gcc version 8.3.0 (GNU 
Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36))) #19.11.3 
SMP Mon Nov 18 18:49:43 CET 2019
  console: CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=50c5387d
  console: CPU: div instructions available: patching division code
  console: CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction 
cache
  console: OF: fdt: Machine model: Xunlong Orange Pi PC
  [...]
  console: EXT4-fs (mmcblk0p1): mounted filesystem with writeback data mode. 
Opts: (null)
  console: done.
  console: Begin: Running /scripts/local-bottom ... done.
  console: Begin: Running /scripts/init-bottom ... done.
  console: systemd[1]: systemd 237 running in system mode. (...)
  console: systemd[1]: Detected architecture arm.
  console: Welcome to Ubuntu 18.04.3 LTS!
  console: systemd[1]: Set hostname to .

Signed-off-by: Philippe Mathieu-Daudé 
[NL: rename in commit message Raspbian to Armbian, remove vm.set_machine()]
[NL: changed test to boot from SD card via BootROM]
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/boot_linux_console.py | 41 ++
 1 file changed, 41 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 50294e1675..399d5062db 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -591,6 +591,47 @@ class BootLinuxConsole(Test):
 exec_command_and_wait_for_pattern(self, 'reboot',
 'reboot: Restarting system')
 
+@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
+def test_arm_orangepi_bionic(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+
+# This test download a 196MB compressed image and expand it to 932MB...
+image_url = ('https://dl.armbian.com/orangepipc/archive/'
+ 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
+image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
+image_path_7z = self.fetch_asset(image_url, asset_hash=image_hash)
+image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
+image_path = os.path.join(self.workdir, image_name)
+process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
+
+self.vm.set_console()
+self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
+ '-nic', 'user',
+ '-no-reboot')
+self.vm.launch()
+
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0,115200 '
+   'loglevel=7 '
+   'nosmp '
+   'systemd.default_timeout_start_sec=9000 '
+   'systemd.mask=armbian-zram-config.service '
+   'systemd.mask=armbian-ramlog.service')
+
+self.wait_for_console_pattern('U-Boot SPL')
+self.wait_for_console_pattern('Autoboot in ')
+exec_command_and_wait_for_pattern(self, ' ', '=>')
+exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
+kernel_command_line + "'", 
'=>')
+exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+
+self.wait_for_console_pattern('systemd[1]: Set hostname ' +
+  'to ')
+self.wait_for_console_pattern('Starting Load Kernel Modules...')
+
 def test_s390x_s390_ccw_virtio(self):
 """
 :avocado: tags=arch:s390x
-- 
2.17.1




[PATCH v4 10/20] hw/arm/allwinner-h3: add Boot ROM support

2020-01-18 Thread Niek Linnenbank
A real Allwinner H3 SoC contains a Boot ROM which is the
first code that runs right after the SoC is powered on.
The Boot ROM is responsible for loading user code (e.g. a bootloader)
from any of the supported external devices and writing the downloaded
code to internal SRAM. After loading the SoC begins executing the code
written to SRAM.

This commits adds emulation of the Boot ROM firmware setup functionality
by loading user code from SD card in the A1 SRAM. While the A1 SRAM is
64KiB, we limit the size to 32KiB because the real H3 Boot ROM also rejects
sizes larger than 32KiB. For reference, this behaviour is documented
by the Linux Sunxi project wiki at:

  https://linux-sunxi.org/BROM#U-Boot_SPL_limitations

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h | 23 +++
 hw/arm/allwinner-h3.c | 28 
 hw/arm/orangepi.c |  5 +
 3 files changed, 56 insertions(+)

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index f9b9a02373..f5e16266cd 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -46,6 +46,7 @@
 #include "hw/sd/allwinner-sdhost.h"
 #include "hw/net/allwinner-sun8i-emac.h"
 #include "target/arm/cpu.h"
+#include "sysemu/block-backend.h"
 
 /**
  * Allwinner H3 device list
@@ -129,4 +130,26 @@ typedef struct AwH3State {
 MemoryRegion sram_c;
 } AwH3State;
 
+/**
+ * Emulate Boot ROM firmware setup functionality.
+ *
+ * A real Allwinner H3 SoC contains a Boot ROM
+ * which is the first code that runs right after
+ * the SoC is powered on. The Boot ROM is responsible
+ * for loading user code (e.g. a bootloader) from any
+ * of the supported external devices and writing the
+ * downloaded code to internal SRAM. After loading the SoC
+ * begins executing the code written to SRAM.
+ *
+ * This function emulates the Boot ROM by copying 32 KiB
+ * of data from the given block device and writes it to
+ * the start of the first internal SRAM memory.
+ *
+ * @s: Allwinner H3 state object pointer
+ * @blk: Block backend device object pointer
+ * @errp: Error object pointer for raising errors
+ */
+void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk,
+Error **errp);
+
 #endif /* HW_ARM_ALLWINNER_H3_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index 1085223812..3d0470825a 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -29,6 +29,7 @@
 #include "hw/char/serial.h"
 #include "hw/misc/unimp.h"
 #include "hw/usb/hcd-ehci.h"
+#include "hw/loader.h"
 #include "sysemu/sysemu.h"
 #include "hw/arm/allwinner-h3.h"
 
@@ -170,6 +171,33 @@ enum {
 AW_H3_GIC_NUM_SPI   = 128
 };
 
+void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk, Error **errp)
+{
+uint8_t *buffer;
+int64_t rom_size = 32 * KiB;
+
+int64_t blk_size = blk_getlength(blk);
+if (blk_size <= 0) {
+error_setg(errp, "%s: failed to get BlockBackend size", __func__);
+return;
+}
+
+if (rom_size > blk_size) {
+rom_size = blk_size;
+}
+
+buffer = g_new0(uint8_t, rom_size);
+if (blk_pread(blk, 8 * KiB, buffer, rom_size) < 0) {
+error_setg(errp, "%s: failed to read BlockBackend data", __func__);
+return;
+}
+
+rom_add_blob("allwinner-h3.bootrom", buffer, rom_size,
+  rom_size, s->memmap[AW_H3_SRAM_A1],
+  NULL, NULL, NULL, NULL, false);
+g_free(buffer);
+}
+
 static void allwinner_h3_init(Object *obj)
 {
 AwH3State *s = AW_H3(obj);
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
index 25bf85f8fc..9d4c79885e 100644
--- a/hw/arm/orangepi.c
+++ b/hw/arm/orangepi.c
@@ -95,6 +95,11 @@ static void orangepi_init(MachineState *machine)
 memory_region_add_subregion(get_system_memory(), 
s->h3->memmap[AW_H3_SDRAM],
 &s->sdram);
 
+/* Load target kernel or start using BootROM */
+if (!machine->kernel_filename && blk_is_available(blk)) {
+/* Use Boot ROM to copy data from SD card to SRAM */
+allwinner_h3_bootrom_setup(s->h3, blk, &error_fatal);
+}
 orangepi_binfo.loader_start = s->h3->memmap[AW_H3_SDRAM];
 orangepi_binfo.ram_size = machine->ram_size;
 arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo);
-- 
2.17.1




[PATCH v4 13/20] tests/boot_linux_console: Add a quick test for the OrangePi PC board

2020-01-18 Thread Niek Linnenbank
From: Philippe Mathieu-Daudé 

This test boots a Linux kernel on a OrangePi PC board and verify
the serial output is working.

The kernel image and DeviceTree blob are built by the Armbian
project (based on Debian):
https://www.armbian.com/orange-pi-pc/

If ARM is a target being built, "make check-acceptance" will
automatically include this test by the use of the "arch:arm" tags.

Alternatively, this test can be run using:

  $ make check-venv
  $ ./tests/venv/bin/avocado --show=console,app run -t machine:orangepi-pc 
tests/acceptance/boot_linux_console.py
  JOB ID : 2e4d15eceb13c33672af406f08171e6e9de1414a
  JOB LOG: ~/job-results/job-2019-12-17T05.46-2e4d15e/job.log
  (1/1) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
  console: Uncompressing Linux... done, booting the kernel.
  console: Booting Linux on physical CPU 0x0
  console: Linux version 4.20.7-sunxi (r...@armbian.com) (gcc version 7.2.1 
20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
  console: CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=50c5387d
  console: CPU: div instructions available: patching division code
  console: CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction 
cache
  console: OF: fdt: Machine model: Xunlong Orange Pi PC
  console: Memory policy: Data cache writealloc
  console: OF: reserved mem: failed to allocate memory for node 'cma@4a00'
  console: cma: Failed to reserve 128 MiB
  console: psci: probing for conduit method from DT.
  console: psci: PSCIv0.2 detected in firmware.
  console: psci: Using standard PSCI v0.2 function IDs
  console: psci: Trusted OS migration not required
  console: random: get_random_bytes called from start_kernel+0x8d/0x3c2 with 
crng_init=0
  console: percpu: Embedded 18 pages/cpu @(ptrval) s41228 r8192 d24308 u73728
  console: Built 1 zonelists, mobility grouping on.  Total pages: 32480
  console: Kernel command line: printk.time=0 console=ttyS0,115200
  PASS (8.59 s)
  JOB TIME   : 8.81 s

Signed-off-by: Philippe Mathieu-Daudé 
[NL: rename in commit message Raspbian to Armbian, remove vm.set_machine()]
Signed-off-by: Niek Linnenbank 
---
 tests/acceptance/boot_linux_console.py | 25 +
 1 file changed, 25 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index e40b84651b..7b4e400511 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -485,6 +485,31 @@ class BootLinuxConsole(Test):
 exec_command_and_wait_for_pattern(self, 'reboot',
 'reboot: Restarting system')
 
+def test_arm_orangepi(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+deb_url = ('https://apt.armbian.com/pool/main/l/'
+   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
+deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinuz-4.20.7-sunxi')
+dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
+dtb_path = self.extract_from_deb(deb_path, dtb_path)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0,115200n8 '
+   'earlycon=uart,mmio32,0x1c28000')
+self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-append', kernel_command_line)
+self.vm.launch()
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+self.wait_for_console_pattern(console_pattern)
+
 def test_s390x_s390_ccw_virtio(self):
 """
 :avocado: tags=arch:s390x
-- 
2.17.1




[PATCH v4 07/20] hw/arm/allwinner: add Security Identifier device

2020-01-18 Thread Niek Linnenbank
The Security Identifier device found in various Allwinner System on Chip
designs gives applications a per-board unique identifier. This commit
adds support for the Allwinner Security Identifier using a 128-bit
UUID value as input.

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h   |   3 +
 include/hw/misc/allwinner-sid.h |  60 +++
 hw/arm/allwinner-h3.c   |  11 ++-
 hw/arm/orangepi.c   |   4 +
 hw/misc/allwinner-sid.c | 170 
 hw/misc/Makefile.objs   |   1 +
 hw/misc/trace-events|   4 +
 7 files changed, 252 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/allwinner-sid.h
 create mode 100644 hw/misc/allwinner-sid.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index dc729176ab..85416d9d64 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -42,6 +42,7 @@
 #include "hw/misc/allwinner-h3-ccu.h"
 #include "hw/misc/allwinner-cpucfg.h"
 #include "hw/misc/allwinner-h3-sysctrl.h"
+#include "hw/misc/allwinner-sid.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -59,6 +60,7 @@ enum {
 AW_H3_SRAM_A2,
 AW_H3_SRAM_C,
 AW_H3_SYSCTRL,
+AW_H3_SID,
 AW_H3_EHCI0,
 AW_H3_OHCI0,
 AW_H3_EHCI1,
@@ -114,6 +116,7 @@ typedef struct AwH3State {
 AwH3ClockCtlState ccu;
 AwCpuCfgState cpucfg;
 AwH3SysCtrlState sysctrl;
+AwSidState sid;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/misc/allwinner-sid.h b/include/hw/misc/allwinner-sid.h
new file mode 100644
index 00..4c1fa4762b
--- /dev/null
+++ b/include/hw/misc/allwinner-sid.h
@@ -0,0 +1,60 @@
+/*
+ * Allwinner Security ID emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_SID_H
+#define HW_MISC_ALLWINNER_SID_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "qemu/uuid.h"
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_SID"allwinner-sid"
+#define AW_SID(obj) \
+OBJECT_CHECK(AwSidState, (obj), TYPE_AW_SID)
+
+/** @} */
+
+/**
+ * Allwinner Security ID object instance state
+ */
+typedef struct AwSidState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Control register defines how and what to read */
+uint32_t control;
+
+/** RdKey register contains the data retrieved by the device */
+uint32_t rdkey;
+
+/** Stores the emulated device identifier */
+QemuUUID identifier;
+
+} AwSidState;
+
+#endif /* HW_MISC_ALLWINNER_SID_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index daa2d3c819..919fba6cf6 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -38,6 +38,7 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_SRAM_A2]= 0x00044000,
 [AW_H3_SRAM_C] = 0x0001,
 [AW_H3_SYSCTRL]= 0x01c0,
+[AW_H3_SID]= 0x01c14000,
 [AW_H3_EHCI0]  = 0x01c1a000,
 [AW_H3_OHCI0]  = 0x01c1a400,
 [AW_H3_EHCI1]  = 0x01c1b000,
@@ -78,7 +79,6 @@ struct AwH3Unimplemented {
 { "mmc0",  0x01c0f000, 4 * KiB },
 { "mmc1",  0x01c1, 4 * KiB },
 { "mmc2",  0x01c11000, 4 * KiB },
-{ "sid",   0x01c14000, 1 * KiB },
 { "crypto",0x01c15000, 4 * KiB },
 { "msgbox",0x01c17000, 4 * KiB },
 { "spinlock",  0x01c18000, 4 * KiB },
@@ -198,6 +198,11 @@ static void allwinner_h3_init(Object *obj)
 
 sysbus_init_child_obj(obj, "cpucfg", &s->cpucfg, sizeof(s->cpucfg),
   TYPE_AW_CPUCFG);
+
+sysbus_init_child_obj(obj, "sid", &s->sid, sizeof(s->sid),
+  TYPE_AW_SID);
+object_property_add_alias(obj, "identifier", OBJECT(&s->sid),
+  "identifier", &error_abort);
 }
 
 static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@@ -315,6 +320,10 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 qdev_init_nofail(DEVICE(&s->cpucfg));
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->cpucfg), 0, s->memmap[AW_H3_CPUCFG]);
 
+/* Security Identifier */
+qdev_init_nofail(DEVICE(&s->sid));
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->sid), 0, s->memmap[AW_H3_SID]);
+
 /* Univ

[PATCH v4 20/20] docs: add Orange Pi PC document

2020-01-18 Thread Niek Linnenbank
The Xunlong Orange Pi PC machine is a functional ARM machine
based on the Allwinner H3 System-on-Chip. It supports mainline
Linux, U-Boot, NetBSD and is covered by acceptance tests.

This commit adds a documentation text file with a description
of the machine and instructions for the user.

Signed-off-by: Niek Linnenbank 
---
 docs/orangepi.rst | 199 ++
 MAINTAINERS   |   1 +
 2 files changed, 200 insertions(+)
 create mode 100644 docs/orangepi.rst

diff --git a/docs/orangepi.rst b/docs/orangepi.rst
new file mode 100644
index 00..dbca9abe80
--- /dev/null
+++ b/docs/orangepi.rst
@@ -0,0 +1,199 @@
+=
+Orange Pi PC Machine Type
+=
+
+The Xunlong Orange Pi PC is an Allwinner H3 System on Chip
+based embedded computer with mainline support in both U-Boot
+and Linux. The board comes with a Quad Core Cortex A7 @ 1.3GHz,
+1GiB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and
+various other I/O.
+
+Supported devices
+-
+
+The Orange Pi PC machine supports the following devices:
+
+ * SMP (Quad Core Cortex A7)
+ * Generic Interrupt Controller configuration
+ * SRAM mappings
+ * SDRAM controller
+ * Real Time Clock
+ * Timer device (re-used from Allwinner A10)
+ * UART
+ * SD/MMC storage controller
+ * EMAC ethernet
+ * USB 2.0 interfaces
+ * Clock Control Unit
+ * System Control module
+ * Security Identifier device
+
+Limitations
+---
+
+Currently, Orange Pi PC does *not* support the following features:
+
+- Graphical output via HDMI, GPU and/or the Display Engine
+- Audio output
+- Hardware Watchdog
+
+Also see the 'unimplemented' array in the Allwinner H3 SoC module
+for a complete list of unimplemented I/O devices:
+  ./hw/arm/allwinner-h3.c
+
+Using the Orange Pi PC machine type
+---
+
+Boot options
+
+
+The Orange Pi PC machine can start using the standard -kernel functionality
+for loading a Linux kernel or ELF executable. Additionally, the Orange Pi PC
+machine can also emulate the BootROM which is present on an actual Allwinner H3
+based SoC, which loads the bootloader from a SD card, specified via the -sd 
argument
+to qemu-system-arm.
+
+Running mainline Linux
+~~
+
+Mainline Linux kernels from 4.19 up to latest master are known to work.
+To build a Linux mainline kernel that can be booted by the Orange Pi PC 
machine,
+simply configure the kernel using the sunxi_defconfig configuration:
+
+  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make mrproper
+  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make sunxi_defconfig
+
+To be able to use USB storage, you need to manually enable the corresponding
+configuration item. Start the kconfig configuration tool:
+
+  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make menuconfig
+
+Navigate to the following item, enable it and save your configuration:
+
+  Device Drivers > USB support > USB Mass Storage support
+
+Build the Linux kernel with:
+
+  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make
+
+To boot the newly build linux kernel in QEMU with the Orange Pi PC machine, 
use:
+
+  $ qemu-system-arm -M orangepi-pc -nic user -nographic \
+  -kernel /path/to/linux/arch/arm/boot/zImage \
+  -append 'console=ttyS0,115200' \
+  -dtb /path/to/linux/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb
+
+Orange Pi PC images
+~~~
+
+Note that the mainline kernel does not have a root filesystem. You may provide 
it
+with an official Orange Pi PC image from the official website:
+
+  http://www.orangepi.org/downloadresources/
+
+Another possibility is to run an Armbian image for Orange Pi PC which
+can be downloaded from:
+
+   https://www.armbian.com/orange-pi-pc/
+
+Alternatively, you can also choose to build you own image with buildroot
+using the orangepi_pc_defconfig. Also see https://buildroot.org for more 
information.
+
+You can choose to attach the selected image either as an SD card or as USB 
mass storage.
+For example, to boot using the Orange Pi PC Debian image on SD card, simply 
add the -sd
+argument and provide the proper root= kernel parameter:
+
+  $ qemu-system-arm -M orangepi-pc -nic user -nographic \
+  -kernel /path/to/linux/arch/arm/boot/zImage \
+  -append 'console=ttyS0,115200 root=/dev/mmcblk0p2' \
+  -dtb /path/to/linux/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb \
+  -sd OrangePi_pc_debian_stretch_server_linux5.3.5_v1.0.img
+
+To attach the image as an USB mass storage device to the machine,
+simply append to the command:
+
+  -drive if=none,id=stick,file=myimage.img \
+  -device usb-storage,bus=usb-bus.0,drive=stick
+
+Instead of providing a custom Linux kernel via the -kernel command you may also
+choose to let the Orange Pi PC machine load the bootloader from SD card, just 
like
+a real board would do using the BootROM. Simply pass the selected image via 
the -sd
+argument and remove the -kernel, -append, -dbt and -initrd a

[PATCH v4 06/20] hw/arm/allwinner: add CPU Configuration module

2020-01-18 Thread Niek Linnenbank
Various Allwinner System on Chip designs contain multiple processors
that can be configured and reset using the generic CPU Configuration
module interface. This commit adds support for the Allwinner CPU
configuration interface which emulates the following features:

 * CPU reset
 * CPU status

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h  |   3 +
 include/hw/misc/allwinner-cpucfg.h |  52 ++
 hw/arm/allwinner-h3.c  |   9 +-
 hw/misc/allwinner-cpucfg.c | 269 +
 hw/misc/Makefile.objs  |   1 +
 hw/misc/trace-events   |   5 +
 6 files changed, 338 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/allwinner-cpucfg.h
 create mode 100644 hw/misc/allwinner-cpucfg.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 43500c4262..dc729176ab 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -40,6 +40,7 @@
 #include "hw/timer/allwinner-a10-pit.h"
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/allwinner-h3-ccu.h"
+#include "hw/misc/allwinner-cpucfg.h"
 #include "hw/misc/allwinner-h3-sysctrl.h"
 #include "target/arm/cpu.h"
 
@@ -76,6 +77,7 @@ enum {
 AW_H3_GIC_CPU,
 AW_H3_GIC_HYP,
 AW_H3_GIC_VCPU,
+AW_H3_CPUCFG,
 AW_H3_SDRAM
 };
 
@@ -110,6 +112,7 @@ typedef struct AwH3State {
 const hwaddr *memmap;
 AwA10PITState timer;
 AwH3ClockCtlState ccu;
+AwCpuCfgState cpucfg;
 AwH3SysCtrlState sysctrl;
 GICState gic;
 MemoryRegion sram_a1;
diff --git a/include/hw/misc/allwinner-cpucfg.h 
b/include/hw/misc/allwinner-cpucfg.h
new file mode 100644
index 00..2c3693a8be
--- /dev/null
+++ b/include/hw/misc/allwinner-cpucfg.h
@@ -0,0 +1,52 @@
+/*
+ * Allwinner CPU Configuration Module emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_CPUCFG_H
+#define HW_MISC_ALLWINNER_CPUCFG_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_CPUCFG   "allwinner-cpucfg"
+#define AW_CPUCFG(obj) \
+OBJECT_CHECK(AwCpuCfgState, (obj), TYPE_AW_CPUCFG)
+
+/** @} */
+
+/**
+ * Allwinner CPU Configuration Module instance state
+ */
+typedef struct AwCpuCfgState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+MemoryRegion iomem;
+uint32_t gen_ctrl;
+uint32_t super_standby;
+uint32_t entry_addr;
+
+} AwCpuCfgState;
+
+#endif /* HW_MISC_ALLWINNER_CPUCFG_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index 600cfa2c11..daa2d3c819 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -56,6 +56,7 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_GIC_CPU]= 0x01c82000,
 [AW_H3_GIC_HYP]= 0x01c84000,
 [AW_H3_GIC_VCPU]   = 0x01c86000,
+[AW_H3_CPUCFG] = 0x01f01c00,
 [AW_H3_SDRAM]  = 0x4000
 };
 
@@ -122,7 +123,6 @@ struct AwH3Unimplemented {
 { "r_wdog",0x01f01000, 1 * KiB },
 { "r_prcm",0x01f01400, 1 * KiB },
 { "r_twd", 0x01f01800, 1 * KiB },
-{ "r_cpucfg",  0x01f01c00, 1 * KiB },
 { "r_cir-rx",  0x01f02000, 1 * KiB },
 { "r_twi", 0x01f02400, 1 * KiB },
 { "r_uart",0x01f02800, 1 * KiB },
@@ -195,6 +195,9 @@ static void allwinner_h3_init(Object *obj)
 
 sysbus_init_child_obj(obj, "sysctrl", &s->sysctrl, sizeof(s->sysctrl),
   TYPE_AW_H3_SYSCTRL);
+
+sysbus_init_child_obj(obj, "cpucfg", &s->cpucfg, sizeof(s->cpucfg),
+  TYPE_AW_CPUCFG);
 }
 
 static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@@ -308,6 +311,10 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 qdev_init_nofail(DEVICE(&s->sysctrl));
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctrl), 0, s->memmap[AW_H3_SYSCTRL]);
 
+/* CPU Configuration */
+qdev_init_nofail(DEVICE(&s->cpucfg));
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->cpucfg), 0, s->memmap[AW_H3_CPUCFG]);
+
 /* Universal Serial Bus */
 sysbus_create_simple(TYPE_AW_H3_EHCI, s->memmap[AW_H3_EHCI0],
  qdev_get_gpio_in(DEVICE(&s->gic),
diff --git a/hw/misc/allwinner-cpucfg.c b/hw/misc/allwinner-cpucfg.c
new file mode 100644
index 00..47254bfafd
--- /dev/null
+++ b/hw/misc/allwinner-cpucfg.c

[PATCH v4 05/20] hw/arm/allwinner-h3: add System Control module

2020-01-18 Thread Niek Linnenbank
The Allwinner H3 System on Chip has an System Control
module that provides system wide generic controls and
device information. This commit adds support for the
Allwinner H3 System Control module.

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h  |   3 +
 include/hw/misc/allwinner-h3-sysctrl.h |  67 
 hw/arm/allwinner-h3.c  |   9 +-
 hw/misc/allwinner-h3-sysctrl.c | 140 +
 hw/misc/Makefile.objs  |   1 +
 5 files changed, 219 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/allwinner-h3-sysctrl.h
 create mode 100644 hw/misc/allwinner-h3-sysctrl.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 4f4dcbcd17..43500c4262 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -40,6 +40,7 @@
 #include "hw/timer/allwinner-a10-pit.h"
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/allwinner-h3-ccu.h"
+#include "hw/misc/allwinner-h3-sysctrl.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -56,6 +57,7 @@ enum {
 AW_H3_SRAM_A1,
 AW_H3_SRAM_A2,
 AW_H3_SRAM_C,
+AW_H3_SYSCTRL,
 AW_H3_EHCI0,
 AW_H3_OHCI0,
 AW_H3_EHCI1,
@@ -108,6 +110,7 @@ typedef struct AwH3State {
 const hwaddr *memmap;
 AwA10PITState timer;
 AwH3ClockCtlState ccu;
+AwH3SysCtrlState sysctrl;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/misc/allwinner-h3-sysctrl.h 
b/include/hw/misc/allwinner-h3-sysctrl.h
new file mode 100644
index 00..af4119e026
--- /dev/null
+++ b/include/hw/misc/allwinner-h3-sysctrl.h
@@ -0,0 +1,67 @@
+/*
+ * Allwinner H3 System Control emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_H3_SYSCTRL_H
+#define HW_MISC_ALLWINNER_H3_SYSCTRL_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+
+/**
+ * @name Constants
+ * @{
+ */
+
+/** Highest register address used by System Control device */
+#define AW_H3_SYSCTRL_REGS_MAXADDR   (0x30)
+
+/** Total number of known registers */
+#define AW_H3_SYSCTRL_REGS_NUM   ((AW_H3_SYSCTRL_REGS_MAXADDR / \
+  sizeof(uint32_t)) + 1)
+
+/** @} */
+
+/**
+ * @name Object model
+ * @{
+ */
+
+#define TYPE_AW_H3_SYSCTRL"allwinner-h3-sysctrl"
+#define AW_H3_SYSCTRL(obj) \
+OBJECT_CHECK(AwH3SysCtrlState, (obj), TYPE_AW_H3_SYSCTRL)
+
+/** @} */
+
+/**
+ * Allwinner H3 System Control object instance state
+ */
+typedef struct AwH3SysCtrlState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Array of hardware registers */
+uint32_t regs[AW_H3_SYSCTRL_REGS_NUM];
+
+} AwH3SysCtrlState;
+
+#endif /* HW_MISC_ALLWINNER_H3_SYSCTRL_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index f360625ee9..600cfa2c11 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -37,6 +37,7 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_SRAM_A1]= 0x,
 [AW_H3_SRAM_A2]= 0x00044000,
 [AW_H3_SRAM_C] = 0x0001,
+[AW_H3_SYSCTRL]= 0x01c0,
 [AW_H3_EHCI0]  = 0x01c1a000,
 [AW_H3_OHCI0]  = 0x01c1a400,
 [AW_H3_EHCI1]  = 0x01c1b000,
@@ -66,7 +67,6 @@ struct AwH3Unimplemented {
 } unimplemented[] = {
 { "d-engine",  0x0100, 4 * MiB },
 { "d-inter",   0x0140, 128 * KiB },
-{ "syscon",0x01c0, 4 * KiB },
 { "dma",   0x01c02000, 4 * KiB },
 { "nfdc",  0x01c03000, 4 * KiB },
 { "ts",0x01c06000, 4 * KiB },
@@ -192,6 +192,9 @@ static void allwinner_h3_init(Object *obj)
 
 sysbus_init_child_obj(obj, "ccu", &s->ccu, sizeof(s->ccu),
   TYPE_AW_H3_CCU);
+
+sysbus_init_child_obj(obj, "sysctrl", &s->sysctrl, sizeof(s->sysctrl),
+  TYPE_AW_H3_SYSCTRL);
 }
 
 static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@@ -301,6 +304,10 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 qdev_init_nofail(DEVICE(&s->ccu));
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccu), 0, s->memmap[AW_H3_CCU]);
 
+/* System Control */
+qdev_init_nofail(DEVICE(&s->sysctrl));
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctrl)

[PATCH v4 02/20] hw/arm: add Xunlong Orange Pi PC machine

2020-01-18 Thread Niek Linnenbank
The Xunlong Orange Pi PC is an Allwinner H3 System on Chip
based embedded computer with mainline support in both U-Boot
and Linux. The board comes with a Quad Core Cortex A7 @ 1.3GHz,
1GiB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and
various other I/O. This commit add support for the Xunlong
Orange Pi PC machine.

Signed-off-by: Niek Linnenbank 
Tested-by: KONRAD Frederic 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/orangepi.c| 93 
 MAINTAINERS  |  1 +
 hw/arm/Makefile.objs |  2 +-
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/orangepi.c

diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
new file mode 100644
index 00..866f5f7cd6
--- /dev/null
+++ b/hw/arm/orangepi.c
@@ -0,0 +1,93 @@
+/*
+ * Orange Pi emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "hw/sysbus.h"
+#include "hw/boards.h"
+#include "hw/qdev-properties.h"
+#include "hw/arm/allwinner-h3.h"
+#include "sysemu/sysemu.h"
+
+static struct arm_boot_info orangepi_binfo = {
+.nb_cpus = AW_H3_NUM_CPUS,
+};
+
+typedef struct OrangePiState {
+AwH3State *h3;
+MemoryRegion sdram;
+} OrangePiState;
+
+static void orangepi_init(MachineState *machine)
+{
+OrangePiState *s = g_new(OrangePiState, 1);
+
+/* BIOS is not supported by this board */
+if (bios_name) {
+error_report("BIOS not supported for this machine");
+exit(1);
+}
+
+/* Only allow Cortex-A7 for this board */
+if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0) {
+error_report("This board can only be used with cortex-a7 CPU");
+exit(1);
+}
+
+s->h3 = AW_H3(object_new(TYPE_AW_H3));
+
+/* Setup timer properties */
+object_property_set_int(OBJECT(s->h3), 32768, "clk0-freq",
+&error_abort);
+object_property_set_int(OBJECT(s->h3), 24 * 1000 * 1000, "clk1-freq",
+&error_abort);
+
+/* Mark H3 object realized */
+object_property_set_bool(OBJECT(s->h3), true, "realized", &error_abort);
+
+/* SDRAM */
+if (machine->ram_size != 1 * GiB) {
+error_report("This machine can only be used with 1GiB of RAM");
+exit(1);
+}
+memory_region_allocate_system_memory(&s->sdram, NULL, "sdram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(), 
s->h3->memmap[AW_H3_SDRAM],
+&s->sdram);
+
+orangepi_binfo.loader_start = s->h3->memmap[AW_H3_SDRAM];
+orangepi_binfo.ram_size = machine->ram_size;
+arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo);
+}
+
+static void orangepi_machine_init(MachineClass *mc)
+{
+mc->desc = "Orange Pi PC";
+mc->init = orangepi_init;
+mc->min_cpus = AW_H3_NUM_CPUS;
+mc->max_cpus = AW_H3_NUM_CPUS;
+mc->default_cpus = AW_H3_NUM_CPUS;
+mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
+mc->default_ram_size = 1 * GiB;
+}
+
+DEFINE_MACHINE("orangepi-pc", orangepi_machine_init)
diff --git a/MAINTAINERS b/MAINTAINERS
index 225582704d..e99797eec9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -487,6 +487,7 @@ L: qemu-...@nongnu.org
 S: Maintained
 F: hw/*/allwinner-h3*
 F: include/hw/*/allwinner-h3*
+F: hw/arm/orangepi.c
 
 ARM PrimeCell and CMSDK devices
 M: Peter Maydell 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ae577e875f..534a6a119e 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -35,7 +35,7 @@ obj-$(CONFIG_DIGIC) += digic.o
 obj-$(CONFIG_OMAP) += omap1.o omap2.o
 obj-$(CONFIG_STRONGARM) += strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
-obj-$(CONFIG_ALLWINNER_H3) += allwinner-h3.o
+obj-$(CONFIG_ALLWINNER_H3) += allwinner-h3.o orangepi.o
 obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
 obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
-- 
2.17.1




[PATCH v4 04/20] hw/arm/allwinner-h3: add USB host controller

2020-01-18 Thread Niek Linnenbank
The Allwinner H3 System on Chip contains multiple USB 2.0 bus
connections which provide software access using the Enhanced
Host Controller Interface (EHCI) and Open Host Controller
Interface (OHCI) interfaces. This commit adds support for
both interfaces in the Allwinner H3 System on Chip.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Gerd Hoffmann 
---
 hw/usb/hcd-ehci.h |  1 +
 include/hw/arm/allwinner-h3.h |  8 ++
 hw/arm/allwinner-h3.c | 52 ---
 hw/usb/hcd-ehci-sysbus.c  | 17 
 4 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 0298238f0b..edb59311c4 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -342,6 +342,7 @@ typedef struct EHCIPCIState {
 #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
 #define TYPE_PLATFORM_EHCI "platform-ehci-usb"
 #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
+#define TYPE_AW_H3_EHCI "aw-h3-ehci-usb"
 #define TYPE_TEGRA2_EHCI "tegra2-ehci-usb"
 #define TYPE_PPC4xx_EHCI "ppc4xx-ehci-usb"
 #define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index abdc20871a..4f4dcbcd17 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -56,6 +56,14 @@ enum {
 AW_H3_SRAM_A1,
 AW_H3_SRAM_A2,
 AW_H3_SRAM_C,
+AW_H3_EHCI0,
+AW_H3_OHCI0,
+AW_H3_EHCI1,
+AW_H3_OHCI1,
+AW_H3_EHCI2,
+AW_H3_OHCI2,
+AW_H3_EHCI3,
+AW_H3_OHCI3,
 AW_H3_CCU,
 AW_H3_PIT,
 AW_H3_UART0,
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index 8df8e3e05e..f360625ee9 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -28,6 +28,7 @@
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
 #include "hw/misc/unimp.h"
+#include "hw/usb/hcd-ehci.h"
 #include "sysemu/sysemu.h"
 #include "hw/arm/allwinner-h3.h"
 
@@ -36,6 +37,14 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_SRAM_A1]= 0x,
 [AW_H3_SRAM_A2]= 0x00044000,
 [AW_H3_SRAM_C] = 0x0001,
+[AW_H3_EHCI0]  = 0x01c1a000,
+[AW_H3_OHCI0]  = 0x01c1a400,
+[AW_H3_EHCI1]  = 0x01c1b000,
+[AW_H3_OHCI1]  = 0x01c1b400,
+[AW_H3_EHCI2]  = 0x01c1c000,
+[AW_H3_OHCI2]  = 0x01c1c400,
+[AW_H3_EHCI3]  = 0x01c1d000,
+[AW_H3_OHCI3]  = 0x01c1d400,
 [AW_H3_CCU]= 0x01c2,
 [AW_H3_PIT]= 0x01c20c00,
 [AW_H3_UART0]  = 0x01c28000,
@@ -73,10 +82,10 @@ struct AwH3Unimplemented {
 { "msgbox",0x01c17000, 4 * KiB },
 { "spinlock",  0x01c18000, 4 * KiB },
 { "usb0-otg",  0x01c19000, 4 * KiB },
-{ "usb0",  0x01c1a000, 4 * KiB },
-{ "usb1",  0x01c1b000, 4 * KiB },
-{ "usb2",  0x01c1c000, 4 * KiB },
-{ "usb3",  0x01c1d000, 4 * KiB },
+{ "usb0-phy",  0x01c1a000, 4 * KiB },
+{ "usb1-phy",  0x01c1b000, 4 * KiB },
+{ "usb2-phy",  0x01c1c000, 4 * KiB },
+{ "usb3-phy",  0x01c1d000, 4 * KiB },
 { "smc",   0x01c1e000, 4 * KiB },
 { "pio",   0x01c20800, 1 * KiB },
 { "owa",   0x01c21000, 1 * KiB },
@@ -144,6 +153,14 @@ enum {
 AW_H3_GIC_SPI_UART3 =  3,
 AW_H3_GIC_SPI_TIMER0= 18,
 AW_H3_GIC_SPI_TIMER1= 19,
+AW_H3_GIC_SPI_EHCI0 = 72,
+AW_H3_GIC_SPI_OHCI0 = 73,
+AW_H3_GIC_SPI_EHCI1 = 74,
+AW_H3_GIC_SPI_OHCI1 = 75,
+AW_H3_GIC_SPI_EHCI2 = 76,
+AW_H3_GIC_SPI_OHCI2 = 77,
+AW_H3_GIC_SPI_EHCI3 = 78,
+AW_H3_GIC_SPI_OHCI3 = 79,
 };
 
 /* Allwinner H3 general constants */
@@ -284,6 +301,33 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 qdev_init_nofail(DEVICE(&s->ccu));
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccu), 0, s->memmap[AW_H3_CCU]);
 
+/* Universal Serial Bus */
+sysbus_create_simple(TYPE_AW_H3_EHCI, s->memmap[AW_H3_EHCI0],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI_EHCI0));
+sysbus_create_simple(TYPE_AW_H3_EHCI, s->memmap[AW_H3_EHCI1],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI_EHCI1));
+sysbus_create_simple(TYPE_AW_H3_EHCI, s->memmap[AW_H3_EHCI2],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI_EHCI2));
+sysbus_create_simple(TYPE_AW_H3_EHCI, s->memmap[AW_H3_EHCI3],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI_EHCI3));
+
+sysbus_create_simple("sysbus-ohci", s->memmap[AW_H3_OHCI0],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI_OHCI0));
+sysbus_create_simple("sysbus-ohci", s->memmap[AW_H3_OHCI1],
+ qdev_get_gpio_in(DEVICE(&s->gic),
+  AW_H3_GIC_SPI

[PATCH v4 01/20] hw/arm: add Allwinner H3 System-on-Chip

2020-01-18 Thread Niek Linnenbank
The Allwinner H3 is a System on Chip containing four ARM Cortex A7
processor cores. Features and specifications include DDR2/DDR3 memory,
SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and
various I/O modules. This commit adds support for the Allwinner H3
System on Chip.

Signed-off-by: Niek Linnenbank 
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/allwinner-h3.h   | 106 +++
 hw/arm/allwinner-h3.c   | 327 
 MAINTAINERS |   7 +
 hw/arm/Kconfig  |   8 +
 hw/arm/Makefile.objs|   1 +
 6 files changed, 450 insertions(+)
 create mode 100644 include/hw/arm/allwinner-h3.h
 create mode 100644 hw/arm/allwinner-h3.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 645e6201bb..36a0e89daa 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -41,3 +41,4 @@ CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
 CONFIG_FSL_IMX6UL=y
 CONFIG_SEMIHOSTING=y
+CONFIG_ALLWINNER_H3=y
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
new file mode 100644
index 00..2aac9b78ec
--- /dev/null
+++ b/include/hw/arm/allwinner-h3.h
@@ -0,0 +1,106 @@
+/*
+ * Allwinner H3 System on Chip emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+/*
+ * The Allwinner H3 is a System on Chip containing four ARM Cortex A7
+ * processor cores. Features and specifications include DDR2/DDR3 memory,
+ * SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and
+ * various I/O modules.
+ *
+ * This implementation is based on the following datasheet:
+ *
+ *   https://linux-sunxi.org/File:Allwinner_H3_Datasheet_V1.2.pdf
+ *
+ * The latest datasheet and more info can be found on the Linux Sunxi wiki:
+ *
+ *   https://linux-sunxi.org/H3
+ */
+
+#ifndef HW_ARM_ALLWINNER_H3_H
+#define HW_ARM_ALLWINNER_H3_H
+
+#include "qom/object.h"
+#include "hw/arm/boot.h"
+#include "hw/timer/allwinner-a10-pit.h"
+#include "hw/intc/arm_gic.h"
+#include "target/arm/cpu.h"
+
+/**
+ * Allwinner H3 device list
+ *
+ * This enumeration is can be used refer to a particular device in the
+ * Allwinner H3 SoC. For example, the physical memory base address for
+ * each device can be found in the AwH3State object in the memmap member
+ * using the device enum value as index.
+ *
+ * @see AwH3State
+ */
+enum {
+AW_H3_SRAM_A1,
+AW_H3_SRAM_A2,
+AW_H3_SRAM_C,
+AW_H3_PIT,
+AW_H3_UART0,
+AW_H3_UART1,
+AW_H3_UART2,
+AW_H3_UART3,
+AW_H3_GIC_DIST,
+AW_H3_GIC_CPU,
+AW_H3_GIC_HYP,
+AW_H3_GIC_VCPU,
+AW_H3_SDRAM
+};
+
+/** Total number of CPU cores in the H3 SoC */
+#define AW_H3_NUM_CPUS  (4)
+
+/**
+ * Allwinner H3 object model
+ * @{
+ */
+
+/** Object type for the Allwinner H3 SoC */
+#define TYPE_AW_H3 "allwinner-h3"
+
+/** Convert input object to Allwinner H3 state object */
+#define AW_H3(obj) OBJECT_CHECK(AwH3State, (obj), TYPE_AW_H3)
+
+/** @} */
+
+/**
+ * Allwinner H3 object
+ *
+ * This struct contains the state of all the devices
+ * which are currently emulated by the H3 SoC code.
+ */
+typedef struct AwH3State {
+/*< private >*/
+DeviceState parent_obj;
+/*< public >*/
+
+ARMCPU cpus[AW_H3_NUM_CPUS];
+const hwaddr *memmap;
+AwA10PITState timer;
+GICState gic;
+MemoryRegion sram_a1;
+MemoryRegion sram_a2;
+MemoryRegion sram_c;
+} AwH3State;
+
+#endif /* HW_ARM_ALLWINNER_H3_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
new file mode 100644
index 00..efe6042af3
--- /dev/null
+++ b/hw/arm/allwinner-h3.c
@@ -0,0 +1,327 @@
+/*
+ * Allwinner H3 System on Chip emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * a

[PATCH v4 00/20] Add Allwinner H3 SoC and Orange Pi PC Machine

2020-01-18 Thread Niek Linnenbank
Dear QEMU developers,

Hereby I would like to contribute the following set of patches to QEMU
which add support for the Allwinner H3 System on Chip and the
Orange Pi PC machine. The following features and devices are supported:

 * SMP (Quad Core Cortex A7)
 * Generic Interrupt Controller configuration
 * SRAM mappings
 * SDRAM controller
 * Real Time Clock
 * Timer device (re-used from Allwinner A10)
 * UART
 * SD/MMC storage controller
 * EMAC ethernet connectivity
 * USB 2.0 interfaces
 * Clock Control Unit
 * System Control module
 * Security Identifier device

Functionality related to graphical output such as HDMI, GPU,
Display Engine and audio are not included. Recently released
mainline Linux kernels (4.19 up to latest master), mainline U-Boot
and NetBSD 9.0-RC1 are known to work.

For full details on how to use the Orange Pi PC machine, see the file
docs/orangepi.rst which is included as a patch in this series.

The contents of this patch series is available on Github at:

  https://github.com/nieklinnenbank/qemu/tree/allwinner-h3-v3

The followings are currently known issues in this series:

  - NetBSD 9.0-RC1 reads out year 2050 from RTC, while Linux works fine
 -> This is due to difference in base year defined by the corresponding 
drivers
  - RTC date & time is not persistent
  - boot0 custom Allwinner bootloader not yet working
  - Watchdog not yet implemented, affects U-Boot 'reset' and shutdown/reboot
 -> This is part of the existing A10 timer that needs to be generalized 
first

Looking forward to your review comments. I will do my best
to update the patches where needed.

= CHANGELOG =
v4:
 * docs/orangepi.rst: correct SDRAM size in board description: 512MB -> 1GiB
 * hw/arm/orangepi.c: correct SDRAM size in commit message: 512MB -> 1GiB
 * hw/arm/orangepi.c: set .nb_cpus in the orangepi_binfo struct static 
initialisation
 * hw/arm/orangepi.c: remove .board_id from orangepi_binfo struct
 * hw/arm/orangepi.c: move BIOS check to top of orangepi_init()
 * hw/arm/orangepi.c: change clk1-freq argument 2400 to 24 * 1000 * 1000 
for readability
 * hw/arm/orangepi.c: rephrase 1GiB check error message
 * include/hw/arm/allwinner-h3.h: improved comments
 * hw/arm/allwinner-h3.c: remove duplicate initialization and declaration of i 
variable
 * hw/arm/allwinner-h3.c: use DEVICE(&s->cpus[i]) instead of qemu_get_cpu()
 * hw/arm/allwinner-h3.c: use qdev API instead of object API in CPU 
initialization part
 * hw/arm/allwinner-h3.c: add note that UARTs are connected to APB2_CLK, for 
future clocktree API
 * hw/arm/allwinner-h3.c: extend commit message for Boot ROM with description 
for the 32KiB size
 * hw/rtc/allwinner-rtc.c: correct usage of AwRtcClass->regmap_size for 
checking r/w offset
 * hw/misc/allwinner-cpucfg.c: remove 64-bit counter, as it is unused by 
Linux/U-Boot/NetBSD
 * hw/misc/allwinner-cpucfg.c: add CPU_EXCEPTION_LEVEL_ON_RESET constant
 * hw/misc/allwinner-cpucfg.c: break instead of return after logging guest 
error, for tracing
 * hw/misc/allwinner-cpucfg.c: reduce duplication in switch/case for 
REG_CPUX_RST_CTRL in write function
 * include/hw/rtc/allwinner-rtc.h: increase AW_RTC_REGS_MAXADDR to 0x200
 * include/hw/rtc/allwinner-rtc.h: change type of AwRtcClass->year_offset to 
int, to match struct tm
 * tests/acceptance/boot_linux_console.py: remove calls to vm.set_machine()
 * tests/acceptance/boot_linux_console.py: added NetBSD test by Philippe
 * docs/orangepi.rst: removed some unneeded words/typos
 * docs/orangepi.rst: remove usage of -j5 for calling make (not all users have 
>= 4 SMP cores)
 * include/hw/*/allwinner*.h: moved #include "qemu/osdep.h" and unneeded 
#includes to .c file

v3: https://lists.gnu.org/archive/html/qemu-devel/2020-01/msg01534.html
https://github.com/nieklinnenbank/qemu/tree/allwinner-h3-v3

v2: https://lists.gnu.org/archive/html/qemu-devel/2019-12/msg03265.html
https://github.com/nieklinnenbank/qemu/tree/allwinner-h3-v2

v1: https://lists.gnu.org/archive/html/qemu-devel/2019-12/msg00320.html
https://github.com/nieklinnenbank/qemu/tree/allwinner-h3-v1

With kind regards,

Niek Linnenbank

Niek Linnenbank (13):
  hw/arm: add Allwinner H3 System-on-Chip
  hw/arm: add Xunlong Orange Pi PC machine
  hw/arm/allwinner-h3: add Clock Control Unit
  hw/arm/allwinner-h3: add USB host controller
  hw/arm/allwinner-h3: add System Control module
  hw/arm/allwinner: add CPU Configuration module
  hw/arm/allwinner: add Security Identifier device
  hw/arm/allwinner: add SD/MMC host controller
  hw/arm/allwinner-h3: add EMAC ethernet device
  hw/arm/allwinner-h3: add Boot ROM support
  hw/arm/allwinner-h3: add SDRAM controller device
  hw/arm/allwinner: add RTC device support
  docs: add Orange Pi PC document

Philippe Mathieu-Daudé (7):
  tests/boot_linux_console: Add a quick test for the OrangePi PC board
  tests/boot_linux_console: Add initrd test for the Orange Pi PC board
  tests/boot_linux_console: Add a SD card test for the Orang

[PATCH v4 03/20] hw/arm/allwinner-h3: add Clock Control Unit

2020-01-18 Thread Niek Linnenbank
The Clock Control Unit is responsible for clock signal generation,
configuration and distribution in the Allwinner H3 System on Chip.
This commit adds support for the Clock Control Unit which emulates
a simple read/write register interface.

Signed-off-by: Niek Linnenbank 
---
 include/hw/arm/allwinner-h3.h  |   3 +
 include/hw/misc/allwinner-h3-ccu.h |  66 
 hw/arm/allwinner-h3.c  |   9 +-
 hw/misc/allwinner-h3-ccu.c | 243 +
 hw/misc/Makefile.objs  |   1 +
 5 files changed, 321 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/allwinner-h3-ccu.h
 create mode 100644 hw/misc/allwinner-h3-ccu.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 2aac9b78ec..abdc20871a 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -39,6 +39,7 @@
 #include "hw/arm/boot.h"
 #include "hw/timer/allwinner-a10-pit.h"
 #include "hw/intc/arm_gic.h"
+#include "hw/misc/allwinner-h3-ccu.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -55,6 +56,7 @@ enum {
 AW_H3_SRAM_A1,
 AW_H3_SRAM_A2,
 AW_H3_SRAM_C,
+AW_H3_CCU,
 AW_H3_PIT,
 AW_H3_UART0,
 AW_H3_UART1,
@@ -97,6 +99,7 @@ typedef struct AwH3State {
 ARMCPU cpus[AW_H3_NUM_CPUS];
 const hwaddr *memmap;
 AwA10PITState timer;
+AwH3ClockCtlState ccu;
 GICState gic;
 MemoryRegion sram_a1;
 MemoryRegion sram_a2;
diff --git a/include/hw/misc/allwinner-h3-ccu.h 
b/include/hw/misc/allwinner-h3-ccu.h
new file mode 100644
index 00..9c8a887782
--- /dev/null
+++ b/include/hw/misc/allwinner-h3-ccu.h
@@ -0,0 +1,66 @@
+/*
+ * Allwinner H3 Clock Control Unit emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_H3_CCU_H
+#define HW_MISC_ALLWINNER_H3_CCU_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+
+/**
+ * @name Constants
+ * @{
+ */
+
+/** Highest register address used by CCU device */
+#define AW_H3_CCU_REGS_MAXADDR  (0x304)
+
+/** Total number of known registers */
+#define AW_H3_CCU_REGS_NUM  (AW_H3_CCU_REGS_MAXADDR / sizeof(uint32_t))
+
+/** @} */
+
+/**
+ * @name Object model
+ * @{
+ */
+
+#define TYPE_AW_H3_CCU"allwinner-h3-ccu"
+#define AW_H3_CCU(obj) \
+OBJECT_CHECK(AwH3ClockCtlState, (obj), TYPE_AW_H3_CCU)
+
+/** @} */
+
+/**
+ * Allwinner H3 CCU object instance state.
+ */
+typedef struct AwH3ClockCtlState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Array of hardware registers */
+uint32_t regs[AW_H3_CCU_REGS_NUM];
+
+} AwH3ClockCtlState;
+
+#endif /* HW_MISC_ALLWINNER_H3_CCU_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index efe6042af3..8df8e3e05e 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -36,6 +36,7 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_SRAM_A1]= 0x,
 [AW_H3_SRAM_A2]= 0x00044000,
 [AW_H3_SRAM_C] = 0x0001,
+[AW_H3_CCU]= 0x01c2,
 [AW_H3_PIT]= 0x01c20c00,
 [AW_H3_UART0]  = 0x01c28000,
 [AW_H3_UART1]  = 0x01c28400,
@@ -77,7 +78,6 @@ struct AwH3Unimplemented {
 { "usb2",  0x01c1c000, 4 * KiB },
 { "usb3",  0x01c1d000, 4 * KiB },
 { "smc",   0x01c1e000, 4 * KiB },
-{ "ccu",   0x01c2, 1 * KiB },
 { "pio",   0x01c20800, 1 * KiB },
 { "owa",   0x01c21000, 1 * KiB },
 { "pwm",   0x01c21400, 1 * KiB },
@@ -172,6 +172,9 @@ static void allwinner_h3_init(Object *obj)
   "clk0-freq", &error_abort);
 object_property_add_alias(obj, "clk1-freq", OBJECT(&s->timer),
   "clk1-freq", &error_abort);
+
+sysbus_init_child_obj(obj, "ccu", &s->ccu, sizeof(s->ccu),
+  TYPE_AW_H3_CCU);
 }
 
 static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@@ -277,6 +280,10 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 memory_region_add_subregion(get_system_memory(), s->memmap[AW_H3_SRAM_C],
 &s->sram_c);
 
+/* Clock Control Unit */
+qdev_init_nofail(DEVICE(&s->ccu));
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccu), 0, s->memmap[AW_H3_CCU]);
+
 /*

Re: [PATCH 4/4] .travis.yml: Allow untrusted code and large files

2020-01-18 Thread Niek Linnenbank
Hi Philippe,

For some reason, I can't apply this patch with git am:

Applying: .travis.yml: Allow untrusted code and large files
error: patch failed: .travis.yml:260
error: .travis.yml: patch does not apply
Patch failed at 0001 .travis.yml: Allow untrusted code and large files
Use 'git am --show-current-patch' to see the failed patch

I didn't change the .travis.yml file. I'm using latest master from commit
7fb38daf256bd1bcbcb5ea556422283d0d55a1b1

Regards,
Niek

On Sat, Jan 18, 2020 at 8:16 PM Philippe Mathieu-Daudé 
wrote:

> As Travis CI runs our tests in a disposable environment, we don't
> care much if the binaries are trusted. The more we test the better.
>
> Also, as of this commmit, the smallest available announced [1] is
> "approx 18GB", plenty of space to run our acceptance tests.
>
> Enable the proper environment variables to allow Avocado download
> from untrusted sources, and to download large files.
>
> Note: As of this commit, all our tests "Ran for 17 min 7 sec"
> before succeeding, see [2].
>
> [1]
> https://docs.travis-ci.com/user/reference/overview/#virtualisation-environment-vs-operating-system
> [2] https://travis-ci.org/philmd/qemu/jobs/638823612#L3817
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  .travis.yml | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/.travis.yml b/.travis.yml
> index 638fba4799..b8b9df65a6 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -260,6 +260,8 @@ matrix:
>
>  # Acceptance (Functional) tests
>  - env:
> +- AVOCADO_ALLOW_LARGE_STORAGE="yes"
> +- AVOCADO_ALLOW_UNTRUSTED_CODE="sure"
>  - CONFIG="--python=/usr/bin/python3
> --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu"
>  - TEST_CMD="make check-acceptance"
>after_failure:
> --
> 2.21.1
>
>

-- 
Niek Linnenbank


Re: [PATCH 2/4] Acceptance tests: Add interrupt_interactive_console_until_pattern()

2020-01-18 Thread Niek Linnenbank
On Sat, Jan 18, 2020 at 8:16 PM Philippe Mathieu-Daudé 
wrote:

> We need a function to interrupt interactive consoles.
>
> Example: Interrupt U-Boot to set different environment values.
>
> Signed-off-by: Philippe Mathieu-Daudé 
>
Tested-by: Niek Linnenbank 

> ---
>  tests/acceptance/avocado_qemu/__init__.py | 32 +--
>  1 file changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/tests/acceptance/avocado_qemu/__init__.py
> b/tests/acceptance/avocado_qemu/__init__.py
> index 0a50fcf2be..d4358eb431 100644
> --- a/tests/acceptance/avocado_qemu/__init__.py
> +++ b/tests/acceptance/avocado_qemu/__init__.py
> @@ -56,13 +56,15 @@ def pick_default_qemu_bin(arch=None):
>
>
>  def _console_interaction(test, success_message, failure_message,
> - send_string):
> + send_string, keep_sending=False):
> +assert not keep_sending or send_string
>  console = test.vm.console_socket.makefile()
>  console_logger = logging.getLogger('console')
>  while True:
>  if send_string:
>  test.vm.console_socket.sendall(send_string.encode())
> -send_string = None # send only once
> +if not keep_sending:
> +send_string = None # send only once
>  msg = console.readline().strip()
>  if not msg:
>  continue
> @@ -74,6 +76,32 @@ def _console_interaction(test, success_message,
> failure_message,
>  fail = 'Failure message found in console: %s' %
> failure_message
>  test.fail(fail)
>
> +def interrupt_interactive_console_until_pattern(test, success_message,
> +failure_message=None,
> +interrupt_string='\r'):
> +"""
> +Keep sending a string to interrupt a console prompt, while logging the
> +console output. Typical use case is to break a boot loader prompt,
> such:
> +
> +Press a key within 5 seconds to interrupt boot process.
> +5
> +4
> +3
> +2
> +1
> +Booting default image...
> +
> +:param test: an Avocado test containing a VM that will have its
> console
> + read and probed for a success or failure message
> +:type test: :class:`avocado_qemu.Test`
> +:param success_message: if this message appears, test succeeds
> +:param failure_message: if this message appears, test fails
> +:param interrupt_string: a string to send to the console before trying
> + to read a new line
> +"""
> +_console_interaction(test, success_message, failure_message,
> + interrupt_string, True)
> +
>  def wait_for_console_pattern(test, success_message, failure_message=None):
>  """
>  Waits for messages to appear on the console, while logging the content
> --
> 2.21.1
>
>

-- 
Niek Linnenbank


Re: [PATCH 1/4] Acceptance tests: Extract _console_interaction()

2020-01-18 Thread Niek Linnenbank
On Sat, Jan 18, 2020 at 8:16 PM Philippe Mathieu-Daudé 
wrote:

> Since we are going to re-use the code shared between
> wait_for_console_pattern() and exec_command_and_wait_for_pattern(),
> extract the common part into a local function.
>
> Signed-off-by: Philippe Mathieu-Daudé 
>
Tested-by: Niek Linnenbank 

> ---
>  tests/acceptance/avocado_qemu/__init__.py | 31 +--
>  1 file changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/tests/acceptance/avocado_qemu/__init__.py
> b/tests/acceptance/avocado_qemu/__init__.py
> index 6618ea67c1..0a50fcf2be 100644
> --- a/tests/acceptance/avocado_qemu/__init__.py
> +++ b/tests/acceptance/avocado_qemu/__init__.py
> @@ -55,19 +55,14 @@ def pick_default_qemu_bin(arch=None):
>  return qemu_bin_from_src_dir_path
>
>
> -def wait_for_console_pattern(test, success_message, failure_message=None):
> -"""
> -Waits for messages to appear on the console, while logging the content
> -
> -:param test: an Avocado test containing a VM that will have its
> console
> - read and probed for a success or failure message
> -:type test: :class:`avocado_qemu.Test`
> -:param success_message: if this message appears, test succeeds
> -:param failure_message: if this message appears, test fails
> -"""
> +def _console_interaction(test, success_message, failure_message,
> + send_string):
>  console = test.vm.console_socket.makefile()
>  console_logger = logging.getLogger('console')
>  while True:
> +if send_string:
> +test.vm.console_socket.sendall(send_string.encode())
> +send_string = None # send only once
>  msg = console.readline().strip()
>  if not msg:
>  continue
> @@ -79,6 +74,17 @@ def wait_for_console_pattern(test, success_message,
> failure_message=None):
>  fail = 'Failure message found in console: %s' %
> failure_message
>  test.fail(fail)
>
> +def wait_for_console_pattern(test, success_message, failure_message=None):
> +"""
> +Waits for messages to appear on the console, while logging the content
> +
> +:param test: an Avocado test containing a VM that will have its
> console
> + read and probed for a success or failure message
> +:type test: :class:`avocado_qemu.Test`
> +:param success_message: if this message appears, test succeeds
> +:param failure_message: if this message appears, test fails
> +"""
> +_console_interaction(test, success_message, failure_message, None)
>
>  def exec_command_and_wait_for_pattern(test, command,
>success_message,
> failure_message=None):
> @@ -94,10 +100,7 @@ def exec_command_and_wait_for_pattern(test, command,
>  :param success_message: if this message appears, test succeeds
>  :param failure_message: if this message appears, test fails
>  """
> -command += '\r'
> -test.vm.console_socket.sendall(command.encode())
> -wait_for_console_pattern(test, success_message, failure_message)
> -
> +_console_interaction(test, success_message, failure_message, command
> + '\r')
>
>  class Test(avocado.Test):
>  def _get_unique_tag_val(self, tag_name):
> --
> 2.21.1
>
>

-- 
Niek Linnenbank


Re: [PATCH 3/4] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC

2020-01-18 Thread Niek Linnenbank
Hi Philippe,

On Sat, Jan 18, 2020 at 8:16 PM Philippe Mathieu-Daudé 
wrote:

> This test boots U-Boot then NetBSD (stored on a SD card) on
> a OrangePi PC board.
>
> As it requires ~1.3GB of storage, it is disabled by default.
>
> U-Boot is built by the Debian project [1], and the SD card image
> is provided by the NetBSD organization [2].
>

Thanks a lot for sending this patch, it very nicely complements the linux
tests to
prove that the ARM/Allwinner-H3 emulation is working properly!

I also see that you have used a pre-compiled binary from Debian to automate
it.
That works very well indeed.


> Once the compressed SD card image is downloaded (304MB) and
> extracted, this test is fast:
>
>   $ AVOCADO_ALLOW_LARGE_STORAGE=yes \
> avocado --show=app,console run -t machine:orangepi-pc \
>   tests/acceptance/boot_linux_console.py
>   console: U-Boot SPL 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +)
>   console: DRAM: 1024 MiB
>   console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) Allwinner
> Technology
>   console: CPU:   Allwinner H3 (SUN8I )
>   console: scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
>   console: scanning bus usb@1c1d000 for devices... 1 USB Device(s) found
>   console: scanning usb for storage devices... 0 Storage Device(s) found
>   console: Hit any key to stop autoboot:  0
>   console: => setenv bootargs root=ld0a
>   console: => setenv kernel netbsd-GENERIC.ub
>   console: => setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb
>   console: => boot
>   console: ## Booting kernel from Legacy Image at 4200 ...
>   console: Image Name:   NetBSD/earmv7hf 9.0_RC1
>   console: Image Type:   ARM Linux Kernel Image (no loading done)
> (uncompressed)
>   console: XIP Kernel Image (no loading done)
>   console: Loading Device Tree to 49ff6000, end 49fffe01 ... OK
>   console: Starting kernel ...
>   console: [   1.000] NetBSD/evbarm (fdt) booting ...
>   console: [   1.000] NetBSD 9.0_RC1 (GENERIC) #0: Wed Nov 27 16:14:52
> UTC 2019
>   console: [   1.000] simplebus0 at armfdt0: Xunlong Orange Pi PC
>   console: [   1.000] cpu0 at cpus0: Cortex-A7 r0p5 (Cortex V7A core)
>   console: [   1.000] cpu0: DC enabled IC enabled WB enabled LABT
> branch prediction enabled
>   console: [   1.000] cpu0: 32KB/64B 2-way L1 VIPT Instruction cache
>   console: [   1.000] cpu0: 32KB/64B 2-way write-back-locking-C L1
> PIPT Data cache
>   console: [   1.000] cpu0: 2304KB/64B 16-way write-through L2 PIPT
> Unified cache
>   console: [   1.000] vfp0 at cpu0: NEON MPE (VFP 3.0+), rounding, NaN
> propagation, denormals
>   ...
>   console: [   2.8171937] sdmmc0: SD card status: 4-bit, C0
>   console: [   2.8234040] ld0 at sdmmc0:
> <0xaa:0x5859:QEMU!:0x01:0xdeadbeef:0x062>
>   console: [   2.8743967] ld0: 1290 MB, 655 cyl, 64 head, 63 sec, 512
> bytes/sect x 2642944 sectors
>   console: [   3.1588850] ld0: 4-bit width, High-Speed/SDR25, 50.000 MHz
>   console: [   4.9942260] WARNING: 4 errors while detecting hardware;
> check system log.
>   console: [   5.0142912] boot device: ld0
>   console: [   5.0551260] root on ld0a dumps on ld0b
>   console: [   5.2175484] root file system type: ffs
>   console: [   5.2858559] kern.module.path=/stand/evbarm/9.0/modules
>   console: Tue Jan 18 18:15:15 UTC 2050
>   console: Starting root file system check:
>   PASS (35.96 s)
>   RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 |
> CANCEL 0
>   JOB TIME   : 36.09 s
>
> Note, this test only took ~65 seconds to run on Travis-CI, see: [3].
>

It is very fast, on my laptop it only took 23 seconds!


>
> This test is based on a description from Niek Linnenbank from [4].
>
> [1]
> https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot
> [2] https://wiki.netbsd.org/ports/evbarm/allwinner/
> [3] https://travis-ci.org/philmd/qemu/jobs/638823612#L3778
> [4] https://www.mail-archive.com/qemu-devel@nongnu.org/msg669347.html
>
> Signed-off-by: Philippe Mathieu-Daudé 
>
Tested-by: Niek Linnenbank 

Regards,
Niek


> ---
>  tests/acceptance/boot_linux_console.py | 63 ++
>  1 file changed, 63 insertions(+)
>
> diff --git a/tests/acceptance/boot_linux_console.py
> b/tests/acceptance/boot_linux_console.py
> index 55d0b8b036..56d3d6e9eb 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -16,6 +16,7 @@ import shutil
>  from avocado import skipUnless
>  from avocado_qemu import Test
>  from avocado_qemu import exec_command_and_wait_for_pattern
> +from avocado_qemu import interrupt_interactive_console_until_pattern
>  from avocado_qemu import wait_for_console_pattern
>  from avocado.utils import process
>  from avocado.utils import archive
> @@ -551,6 +552,68 @@ class BootLinuxConsole(Test):
>'to ')
>  self.wait_for_console_pattern('Starting Load Kernel Modules...')
>
> +@skipUnless(os.getenv

Re: Commit 3e7fb5811b or something in that series breaks build?

2020-01-18 Thread BALATON Zoltan

On Sun, 19 Jan 2020, BALATON Zoltan wrote:

On Sat, 18 Jan 2020, Peter Maydell wrote:

On Sat, 18 Jan 2020 at 22:41, BALATON Zoltan  wrote:

I'm getting errors about missing headers in qapi/* and build fails on
current master.

I've tried bisecting it which lead to commit 3e7fb5811b where I get:

   CC  qapi/qapi-types-audio.o
cc: error: qapi/qapi-types-audio.c: No such file or directory
cc: fatal error: no input files


I haven't looked, but could you try the usual things to check:
* does your tree have 'stale' files deleted by a commit
  (ie listed in 'git status' as now unknown to git) ?
* did you try a reconfigure and build from clean?
  (ideally this should not be required, but it might help
  narrow down the issue)
* could you test whether you see the issue also with an
  out-of-tree build?


Also fails after make distclean with out-of-tree build in the same way. Seems 
that --disable-guest-agent option breaks earlier but even without that option 
I get error later about some rtc chip and build does not finish. I've tried 
with just


configure --target-list=ppc-softmmu --disable-guest-agent

and get the above error right after it built capstone.a and starts building 
qapi/* (without --disable-guest-agent it almost gets to the end but fails 
later). Sometimes I also see these errors:


In file included from qapi/qapi-types-crypto.c:15:0:
qapi/qapi-types-crypto.h:176:33: error: field ‘qcow’ has incomplete type
QCryptoBlockOptionsQCow qcow;
^
qapi/qapi-types-crypto.h:177:33: error: field ‘luks’ has incomplete type
QCryptoBlockOptionsLUKS luks;
^
qapi/qapi-types-crypto.h:193:33: error: field ‘qcow’ has incomplete type
QCryptoBlockOptionsQCow qcow;
^
qapi/qapi-types-crypto.h:236:30: error: field ‘luks’ has incomplete type
QCryptoBlockInfoLUKS luks;
 ^


I've found this:

https://lists.nongnu.org/archive/html/qemu-devel/2020-01/msg03486.html

which does fix the build for me (I happen to have python 3.5.7 still) so I 
guess you can add


Tested-by: BALATON Zoltan 

to that patch.

Regards,
BALATON Zoltan

Re: Commit 3e7fb5811b or something in that series breaks build?

2020-01-18 Thread BALATON Zoltan

On Sat, 18 Jan 2020, Peter Maydell wrote:

On Sat, 18 Jan 2020 at 22:41, BALATON Zoltan  wrote:

I'm getting errors about missing headers in qapi/* and build fails on
current master.

I've tried bisecting it which lead to commit 3e7fb5811b where I get:

   CC  qapi/qapi-types-audio.o
cc: error: qapi/qapi-types-audio.c: No such file or directory
cc: fatal error: no input files


I haven't looked, but could you try the usual things to check:
* does your tree have 'stale' files deleted by a commit
  (ie listed in 'git status' as now unknown to git) ?
* did you try a reconfigure and build from clean?
  (ideally this should not be required, but it might help
  narrow down the issue)
* could you test whether you see the issue also with an
  out-of-tree build?


Also fails after make distclean with out-of-tree build in the same way. 
Seems that --disable-guest-agent option breaks earlier but even without 
that option I get error later about some rtc chip and build does not 
finish. I've tried with just


configure --target-list=ppc-softmmu --disable-guest-agent

and get the above error right after it built capstone.a and starts 
building qapi/* (without --disable-guest-agent it almost gets to the end 
but fails later). Sometimes I also see these errors:


In file included from qapi/qapi-types-crypto.c:15:0:
qapi/qapi-types-crypto.h:176:33: error: field ‘qcow’ has incomplete type
 QCryptoBlockOptionsQCow qcow;
 ^
qapi/qapi-types-crypto.h:177:33: error: field ‘luks’ has incomplete type
 QCryptoBlockOptionsLUKS luks;
 ^
qapi/qapi-types-crypto.h:193:33: error: field ‘qcow’ has incomplete type
 QCryptoBlockOptionsQCow qcow;
 ^
qapi/qapi-types-crypto.h:236:30: error: field ‘luks’ has incomplete type
 QCryptoBlockInfoLUKS luks;
  ^

Regards,
BALATON Zoltan

Re: [PATCH v3 03/17] hw/arm/allwinner-h3: add Clock Control Unit

2020-01-18 Thread Niek Linnenbank
Hi Philippe,

On Sat, Jan 18, 2020 at 4:37 PM Philippe Mathieu-Daudé 
wrote:

> Hi Niek,
>
> On 1/13/20 8:18 PM, Niek Linnenbank wrote:
> > Hi,
> >
> > Just a friendly reminder for review of this patch and the others in this
> > series
> > that don't yet have a reviewed-by tag :-)
>
> You are right to ping the list after a week.
>
> Cc'ing Damien for this particular patch, he might have good advises.
>
>
> Looking at the stats from your cover:
>
>   include/hw/arm/allwinner-h3.h  | 164 +
>   include/hw/misc/allwinner-cpucfg.h |  54 ++
>   include/hw/misc/allwinner-h3-ccu.h |  67 ++
>   include/hw/misc/allwinner-h3-dramc.h   | 107 +++
>   include/hw/misc/allwinner-h3-sysctrl.h |  68 ++
>   include/hw/net/allwinner-sun8i-emac.h  | 103 +++
>   include/hw/rtc/allwinner-rtc.h | 129 
>   include/hw/sd/allwinner-sdhost.h   | 136 
>   hw/arm/allwinner-h3.c  | 477 ++
>   hw/arm/orangepi.c  | 125 
>   hw/misc/allwinner-cpucfg.c | 282 
>   hw/misc/allwinner-h3-ccu.c | 243 +++
>   hw/misc/allwinner-h3-dramc.c   | 358 ++
>   hw/misc/allwinner-h3-sysctrl.c | 140 
>   hw/misc/allwinner-sid.c| 170 +
>   hw/net/allwinner-sun8i-emac.c  | 871 +
>   hw/rtc/allwinner-rtc.c | 386 +++
>   hw/sd/allwinner-sdhost.c   | 848 
>
>   39 files changed, 5267 insertions(+), 2 deletions(-)
>
> This is a LOT of code to process, keep in mind your series touches
> different subsystems with different maintainers. It is hard to know all
> of them in details.
>
> Yes, true indeed. I'll be patient and wait for more feedback when it comes.


> Since your SoC is in the same family than the A10, I've Cc'ed Beniamino
> Galvani. You should Cc him in your v4, hopefully he can help reviewing.
>
> OK good idea. I'll add Beniamino in CC for v4!


> Regarding the System Control Unit and SDRAM Controller, as I don't know
> this SoC so I have to digest the whole datasheet, so it takes me time,
> bare with me (I'm using my hobby time to review your work).
>
> Yes the SDRAM controller is something that needs a good read to understand
it,
especially also in the U-Boot sources which is using it. No hurry there, I
very much
appreciate all the time you already took for reviewing this series. It
encourages me
to continue with it as well. I'm also doing this work in my hobby time.


> The last patch I plan to review in your series is the SD/MMC one:
>   10 files changed, 1053 insertions(+), 2 deletions(-)
>
> It is 1/5th of your series in a single patch, each time I try to look at
> it I get scared. Anyway today I could test NetBSD booting from a SD card
> so I am more confident.
>
>
Thanks for testing that Philippe! Yes the SD/MMC host device is indeed
relatively large compared to the other patches.


> Anyway, don't forget this comment from the New Contribution page:
> https://wiki.qemu.org/Contribute/SubmitAPatch#Return_the_favor
>
>Peer review only works if everyone chips in a bit of review time.
>If everyone submitted more patches than they reviewed, we would
>have a patch backlog. A good goal is to try to review at least
>as many patches from others as what you submit.
>
> With the quality of your patches, even if this is your first
> contribution, it is obvious you now understand various part of QEMU.
> Don't be shy to look at other patches on the list and help the
> community, as the reviewed authors might review you back :)
>
> Thanks for reminding about that. You are right, indeed I should start
reviewing
other patches as well to return the favor and help others.

Regards,
Niek

That said, your series is almost there!

Regards,
>
> Phil.
>
> >
> > Regards,
> > Niek
>
>

-- 
Niek Linnenbank


Re: Commit 3e7fb5811b or something in that series breaks build?

2020-01-18 Thread Peter Maydell
On Sat, 18 Jan 2020 at 22:41, BALATON Zoltan  wrote:
> I'm getting errors about missing headers in qapi/* and build fails on
> current master.
>
> I've tried bisecting it which lead to commit 3e7fb5811b where I get:
>
>CC  qapi/qapi-types-audio.o
> cc: error: qapi/qapi-types-audio.c: No such file or directory
> cc: fatal error: no input files

I haven't looked, but could you try the usual things to check:
 * does your tree have 'stale' files deleted by a commit
   (ie listed in 'git status' as now unknown to git) ?
 * did you try a reconfigure and build from clean?
   (ideally this should not be required, but it might help
   narrow down the issue)
 * could you test whether you see the issue also with an
   out-of-tree build?

thanks
-- PMM



Re: [PATCH v3 13/17] tests/boot_linux_console: Add a quick test for the OrangePi PC board

2020-01-18 Thread Niek Linnenbank
On Sat, Jan 18, 2020 at 12:22 PM Philippe Mathieu-Daudé 
wrote:

> On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> > From: Philippe Mathieu-Daudé 
> >
> > This test boots a Linux kernel on a OrangePi PC board and verify
> > the serial output is working.
> >
> > The kernel image and DeviceTree blob are built by the Armbian
> > project (based on Debian):
> > https://www.armbian.com/orange-pi-pc/
> >
> > If ARM is a target being built, "make check-acceptance" will
> > automatically include this test by the use of the "arch:arm" tags.
> >
> > Alternatively, this test can be run using:
> >
> >$ make check-venv
> >$ ./tests/venv/bin/avocado --show=console,app run -t
> machine:orangepi-pc tests/acceptance/boot_linux_console.py
> >JOB ID : 2e4d15eceb13c33672af406f08171e6e9de1414a
> >JOB LOG: ~/job-results/job-2019-12-17T05.46-2e4d15e/job.log
> >(1/1)
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
> >console: Uncompressing Linux... done, booting the kernel.
> >console: Booting Linux on physical CPU 0x0
> >console: Linux version 4.20.7-sunxi (r...@armbian.com) (gcc version
> 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET
> 2019
> >console: CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7),
> cr=50c5387d
> >console: CPU: div instructions available: patching division code
> >console: CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing
> instruction cache
> >console: OF: fdt: Machine model: Xunlong Orange Pi PC
> >console: Memory policy: Data cache writealloc
> >console: OF: reserved mem: failed to allocate memory for node
> 'cma@4a00'
> >console: cma: Failed to reserve 128 MiB
> >console: psci: probing for conduit method from DT.
> >console: psci: PSCIv0.2 detected in firmware.
> >console: psci: Using standard PSCI v0.2 function IDs
> >console: psci: Trusted OS migration not required
> >console: random: get_random_bytes called from start_kernel+0x8d/0x3c2
> with crng_init=0
> >console: percpu: Embedded 18 pages/cpu @(ptrval) s41228 r8192 d24308
> u73728
> >console: Built 1 zonelists, mobility grouping on.  Total pages: 32480
> >console: Kernel command line: printk.time=0 console=ttyS0,115200
> >PASS (8.59 s)
> >JOB TIME   : 8.81 s
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > [NL: rename in commit message Raspbian to Armbian]
> > Signed-off-by: Niek Linnenbank 
> > ---
> >   tests/acceptance/boot_linux_console.py | 26 ++
> >   1 file changed, 26 insertions(+)
> >
> > diff --git a/tests/acceptance/boot_linux_console.py
> b/tests/acceptance/boot_linux_console.py
> > index 9c6aa2040a..b58308d724 100644
> > --- a/tests/acceptance/boot_linux_console.py
> > +++ b/tests/acceptance/boot_linux_console.py
> > @@ -400,6 +400,32 @@ class BootLinuxConsole(Test):
> >   self.wait_for_console_pattern('Boot successful.')
> >   # TODO user command, for now the uart is stuck
> >
> > +def test_arm_orangepi(self):
> > +"""
> > +:avocado: tags=arch:arm
> > +:avocado: tags=machine:orangepi-pc
> > +"""
> > +deb_url = ('https://apt.armbian.com/pool/main/l/'
> > +
>  'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
> > +deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
> > +deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
> > +kernel_path = self.extract_from_deb(deb_path,
> > +
> '/boot/vmlinuz-4.20.7-sunxi')
> > +dtb_path =
> '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
> > +dtb_path = self.extract_from_deb(deb_path, dtb_path)
> > +
> > +self.vm.set_machine('orangepi-pc')
>
> Please remove the vm.set_machine() calls.
>

OK, I'll also remove them vm.set_machine() calls in the other 3 patches.


>
> > +self.vm.set_console()
> > +kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> > +   'console=ttyS0,115200n8 '
> > +   'earlycon=uart,mmio32,0x1c28000')
> > +self.vm.add_args('-kernel', kernel_path,
> > + '-dtb', dtb_path,
> > + '-append', kernel_command_line)
> > +self.vm.launch()
> > +console_pattern = 'Kernel command line: %s' %
> kernel_command_line
> > +self.wait_for_console_pattern(console_pattern)
> > +
> >   def test_s390x_s390_ccw_virtio(self):
> >   """
> >   :avocado: tags=arch:s390x
> >
>
>

-- 
Niek Linnenbank


Re: [PATCH v3 12/17] hw/arm/allwinner: add RTC device support

2020-01-18 Thread Niek Linnenbank
Hi Philippe,

On Sat, Jan 18, 2020 at 4:05 PM Philippe Mathieu-Daudé 
wrote:

> Hi Niek,
>
> On 1/14/20 11:57 PM, Niek Linnenbank wrote:
> > On Tue, Jan 14, 2020 at 11:52 PM Niek Linnenbank
> > mailto:nieklinnenb...@gmail.com>> wrote:
> >
> > Hi Philippe,
> >
> > On Mon, Jan 13, 2020 at 11:57 PM Philippe Mathieu-Daudé
> > mailto:phi...@redhat.com>> wrote:
> >
> > On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> >  > Allwinner System-on-Chips usually contain a Real Time Clock
> (RTC)
> >  > for non-volatile system date and time keeping. This commit
> > adds a generic
> >  > Allwinner RTC device that supports the RTC devices found in
> > Allwinner SoC
> >  > family sun4i (A10), sun7i (A20) and sun6i and newer (A31,
> > H2+, H3, etc).
> [...]
> >  > +static uint64_t allwinner_rtc_read(void *opaque, hwaddr
> offset,
> >  > +   unsigned size)
> >  > +{
> >  > +AwRtcState *s = AW_RTC(opaque);
> >  > +const AwRtcClass *c = AW_RTC_GET_CLASS(s);
> >  > +uint64_t val = 0;
> >  > +
> >  > +if (offset >= AW_RTC_REGS_MAXADDR) {
> >  > +qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
> > offset 0x%04x\n",
> >  > +  __func__, (uint32_t)offset);
> >  > +return 0;
> >  > +}
> >  > +
> >  > +if (!c->regmap[offset]) {
> >  > +qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
> > register 0x%04x\n",
> >  > +  __func__, (uint32_t)offset);
> >  > +return 0;
> >  > +}
> >  > +
> >  > +switch (c->regmap[offset]) {
> >  > +case REG_LOSC:   /* Low Oscillator Control */
> >  > +val = s->regs[REG_LOSC];
> >  > +s->regs[REG_LOSC] &= ~(REG_LOSC_YMD | REG_LOSC_HMS);
> >  > +break;
> >  > +case REG_YYMMDD: /* RTC Year-Month-Day */
> >  > +case REG_HHMMSS: /* RTC Hour-Minute-Second */
> >  > +case REG_GP0:/* General Purpose Register 0 */
> >  > +case REG_GP1:/* General Purpose Register 1 */
> >  > +case REG_GP2:/* General Purpose Register 2 */
> >  > +case REG_GP3:/* General Purpose Register 3 */
> >  > +val = s->regs[c->regmap[offset]];
> >  > +break;
> >  > +default:
> >  > +if (!c->read(s, offset)) {
> >  > +qemu_log_mask(LOG_UNIMP, "%s: unimplemented
> > register 0x%04x\n",
> >  > +  __func__, (uint32_t)offset);
> >  > +}
> >  > +val = s->regs[c->regmap[offset]];
> >  > +break;
> >  > +}
> >  > +
> >  > +trace_allwinner_rtc_read(offset, val);
> >  > +return val;
> >  > +}
> >  > +
> >  > +static void allwinner_rtc_write(void *opaque, hwaddr offset,
> >  > +uint64_t val, unsigned size)
> >  > +{
> >  > +AwRtcState *s = AW_RTC(opaque);
> >  > +const AwRtcClass *c = AW_RTC_GET_CLASS(s);
> >  > +
> >  > +if (offset >= AW_RTC_REGS_MAXADDR) {
> >  > +qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
> > offset 0x%04x\n",
> >  > +  __func__, (uint32_t)offset);
> >  > +return;
> >  > +}
> >  > +
> >  > +if (!c->regmap[offset]) {
> >  > +qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
> > register 0x%04x\n",
> >  > +  __func__, (uint32_t)offset);
> >  > +return;
> >  > +}
> >  > +
> >  > +trace_allwinner_rtc_write(offset, val);
> >  > +
> >  > +switch (c->regmap[offset]) {
> >  > +case REG_YYMMDD: /* RTC Year-Month-Day */
> >  > +s->regs[REG_YYMMDD] = val;
> >  > +s->regs[REG_LOSC]  |= REG_LOSC_YMD;
> >  > +break;
> >  > +case REG_HHMMSS: /* RTC Hour-Minute-Second */
> >  > +s->regs[REG_HHMMSS] = val;
> >  > +s->regs[REG_LOSC]  |= REG_LOSC_HMS;
> >  > +break;
> >  > +case REG_GP0:/* General Purpose Register 0 */
> >  > +case REG_GP1:/* General Purpose Register 1 */
> >  > +case REG_GP2:/* General Purpose Register 2 */
> >  > +case REG_GP3:/* General Purpose Register 3 */
> >  > +s->regs[c->regmap[offset]] = val;
> >  > +break;
> >  > +default:
> >  > +if (!c->write(s, offset, val)) {
> >

Commit 3e7fb5811b or something in that series breaks build?

2020-01-18 Thread BALATON Zoltan

Hello,

I'm getting errors about missing headers in qapi/* and build fails on 
current master.


I've tried bisecting it which lead to commit 3e7fb5811b where I get:

  CC  qapi/qapi-types-audio.o
cc: error: qapi/qapi-types-audio.c: No such file or directory
cc: fatal error: no input files

(This is with --audio-drv-list=alsa configure option and in-tree build in 
case that matters.)


Reverting that commit alone does not fix build on master I had to revert 
both 3bef3aaec9 and 3e7fb5811b


Regards,
BALATON Zoltan



Re: [PATCH v3 17/17] docs: add Orange Pi PC document

2020-01-18 Thread Niek Linnenbank
Hi Philippe,

On Sat, Jan 18, 2020 at 10:38 AM Philippe Mathieu-Daudé 
wrote:

> On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> > The Xunlong Orange Pi PC machine is a functional ARM machine
> > based on the Allwinner H3 System-on-Chip. It supports mainline
> > Linux, U-Boot, NetBSD and is covered by acceptance tests.
> >
> > This commit adds a documentation text file with a description
> > of the machine and instructions for the user.
> >
> > Signed-off-by: Niek Linnenbank 
> > ---
> >   docs/orangepi.rst | 200 ++
> >   MAINTAINERS   |   1 +
> >   2 files changed, 201 insertions(+)
> >   create mode 100644 docs/orangepi.rst
> >
> > diff --git a/docs/orangepi.rst b/docs/orangepi.rst
> > new file mode 100644
> > index 00..5ac2a7b7cc
> > --- /dev/null
> > +++ b/docs/orangepi.rst
> > @@ -0,0 +1,200 @@
> > +=
> > +Orange Pi PC Machine Type
> > +=
> > +
> > +The Xunlong Orange Pi PC is an Allwinner H3 System on Chip
> > +based embedded computer with mainline support in both U-Boot
> > +and Linux. The board comes with a Quad Core Cortex A7 @ 1.3GHz,
> > +512MB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and
> > +various other I/O.
> > +
> > +Supported devices
> > +-
> > +
> > +The Orange Pi PC machine type supports the following devices:
>
> Maybe drop "type"?
>
> > +
> > + * SMP (Quad Core Cortex A7)
> > + * Generic Interrupt Controller configuration
> > + * SRAM mappings
> > + * SDRAM controller
> > + * Real Time Clock
> > + * Timer device (re-used from Allwinner A10)
> > + * UART
> > + * SD/MMC storage controller
> > + * EMAC ethernet connectivity
>
> Drop "connectivity"?
>
> > + * USB 2.0 interfaces
> > + * Clock Control Unit
> > + * System Control module
> > + * Security Identifier device
> > +
> > +Limitations
> > +---
> > +
> > +Currently, Orange Pi PC does *not* support the following features:
> > +
> > +- Graphical output via HDMI, GPU and/or the Display Engine
> > +- Audio output
> > +- Hardware Watchdog
> > +
> > +Also see the 'unimplemented' array in the Allwinner H3 SoC module
> > +for a complete list of unimplemented I/O devices:
> > +  ./hw/arm/allwinner-h3.c
> > +
> > +Using the Orange Pi PC machine type
> > +---
> > +
> > +Boot options
> > +
> > +
> > +The Orange Pi PC machine can start using the standard -kernel
> functionality
> > +for loading a Linux kernel or ELF executable. Additionally, the Orange
> Pi PC
> > +machine can also emulate the BootROM which is present on an actual
> Allwinner H3
> > +based SoC, which loads the bootloader from SD card, specified via the
> -sd argument
>
> "from a SD card"?
>
> > +to qemu-system-arm.
> > +
> > +Running mainline Linux
> > +~~
> > +
> > +Recently released mainline Linux kernels from 4.19 up to latest master
>
> Drop "Recently released mainline" or only use "Mainline"?
>
> Thanks, I'll correct all comments above.


> > +are known to work. To build a Linux mainline kernel that can be booted
> > +by the Orange Pi PC machine, simply configure the kernel using the
> > +sunxi_defconfig configuration:
> > +
> > +  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make mrproper
> > +  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make sunxi_defconfig
> > +
> > +To be able to use USB storage, you need to manually enable the
> corresponding
> > +configuration item. Start the kconfig configuration tool:
> > +
> > +  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make menuconfig
> > +
> > +Navigate to the following item, enable it and save your configuration:
> > +
> > +  Device Drivers > USB support > USB Mass Storage support
>
> Isn't it simpler to run 'echo CONFIG_USB_STORAGE=y >> .config && make
> oldconfig'?
>

Yes true, that is also a way to enable it. I just wrote it down like this
since using menuconfig
or xconfig is usually the way people are familiar with.


>
> > +
> > +Build the Linux kernel with:
> > +
> > +  $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make -j5
>
> I'm not sure about recommending "-j5" in the doc, not all user have >=4
> SMP system. Maybe we don't care.
>

Thanks, I'll remove the -j5.


>
> > +
> > +To boot the newly build linux kernel in QEMU with the Orange Pi PC
> machine, use:
> > +
> > +  $ qemu-system-arm -M orangepi-pc -nic user -nographic \
> > +  -kernel /path/to/linux/arch/arm/boot/zImage \
> > +  -append 'console=ttyS0,115200' \
> > +  -dtb /path/to/linux/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb
> > +
> > +Orange Pi PC images
> > +~~~
> > +
> > +Note that the mainline kernel does not have a root filesystem. You may
> provide it
> > +with an official Orange Pi PC image from the official website:
> > +
> > +  http://www.orangepi.org/downloadresources/
> > +
> > +Another possibility is to run an Armbian image for Orange Pi PC which
> > +can be downloaded from:
> > +
> > +   https://www.armbian.com/orange-pi-pc/
> > +

Re: [PATCH v3 10/17] hw/arm/allwinner-h3: add Boot ROM support

2020-01-18 Thread Niek Linnenbank
On Sat, Jan 18, 2020 at 10:09 AM Philippe Mathieu-Daudé 
wrote:

> On 1/15/20 12:10 AM, Niek Linnenbank wrote:
> > On Tue, Jan 14, 2020 at 12:28 AM Philippe Mathieu-Daudé
> > mailto:phi...@redhat.com>> wrote:
> >
> > On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> >  > A real Allwinner H3 SoC contains a Boot ROM which is the
> >  > first code that runs right after the SoC is powered on.
> >  > The Boot ROM is responsible for loading user code (e.g. a
> bootloader)
> >  > from any of the supported external devices and writing the
> downloaded
> >  > code to internal SRAM. After loading the SoC begins executing the
> > code
> >  > written to SRAM. This commits adds emulation of the Boot ROM
> firmware
> >  > setup functionality by loading user code from SD card.
> >  >
> >  > Signed-off-by: Niek Linnenbank  > >
> >  > ---
> >  >   include/hw/arm/allwinner-h3.h | 23 +++
> >  >   hw/arm/allwinner-h3.c | 28 
> >  >   hw/arm/orangepi.c |  3 +++
> >  >   3 files changed, 54 insertions(+)
> >  >
> >  > diff --git a/include/hw/arm/allwinner-h3.h
> > b/include/hw/arm/allwinner-h3.h
> >  > index 5d74cca28e..4b66227ac4 100644
> >  > --- a/include/hw/arm/allwinner-h3.h
> >  > +++ b/include/hw/arm/allwinner-h3.h
> >  > @@ -50,6 +50,7 @@
> >  >   #include "hw/sd/allwinner-sdhost.h"
> >  >   #include "hw/net/allwinner-sun8i-emac.h"
> >  >   #include "target/arm/cpu.h"
> >  > +#include "sysemu/block-backend.h"
> >  >
> >  >   /**
> >  >* Allwinner H3 device list
> >  > @@ -130,4 +131,26 @@ typedef struct AwH3State {
> >  >   MemoryRegion sram_c;
> >  >   } AwH3State;
> >  >
> >  > +/**
> >  > + * Emulate Boot ROM firmware setup functionality.
> >  > + *
> >  > + * A real Allwinner H3 SoC contains a Boot ROM
> >  > + * which is the first code that runs right after
> >  > + * the SoC is powered on. The Boot ROM is responsible
> >  > + * for loading user code (e.g. a bootloader) from any
> >  > + * of the supported external devices and writing the
> >  > + * downloaded code to internal SRAM. After loading the SoC
> >  > + * begins executing the code written to SRAM.
> >  > + *
> >  > + * This function emulates the Boot ROM by copying 32 KiB
> >  > + * of data from the given block device and writes it to
> >  > + * the start of the first internal SRAM memory.
> >  > + *
> >  > + * @s: Allwinner H3 state object pointer
> >  > + * @blk: Block backend device object pointer
> >  > + * @errp: Error object pointer for raising errors
> >  > + */
> >  > +void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk,
> >  > +Error **errp);
> >  > +
> >  >   #endif /* HW_ARM_ALLWINNER_H3_H */
> >  > diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
> >  > index e692432b4e..e7b768ad5b 100644
> >  > --- a/hw/arm/allwinner-h3.c
> >  > +++ b/hw/arm/allwinner-h3.c
> >  > @@ -27,6 +27,7 @@
> >  >   #include "hw/char/serial.h"
> >  >   #include "hw/misc/unimp.h"
> >  >   #include "hw/usb/hcd-ehci.h"
> >  > +#include "hw/loader.h"
> >  >   #include "sysemu/sysemu.h"
> >  >   #include "hw/arm/allwinner-h3.h"
> >  >
> >  > @@ -168,6 +169,33 @@ enum {
> >  >   AW_H3_GIC_NUM_SPI   = 128
> >  >   };
> >  >
> >  > +void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk,
> > Error **errp)
> >  > +{
> >  > +uint8_t *buffer;
> >  > +int64_t rom_size = 32 * KiB;
> >
> > Why restrict to 32K? The A1 SRAM is 64K.
> >
> >
> > The reason is that the actual Boot ROM on the H3 also uses 32K:
> > https://linux-sunxi.org/BROM
> >
> > See the 'U-Boot SPL Limitations' table at the end of the page.
> >
> > You can see the comment in the table there regarding the 32 KiB:
> >"Sizes larger than 32 KiB are rejected by the BROM. Exactly 32 KiB is
> > fine, as verified by writing a special pattern at the end of the SPL and
> > checking it in the SRAM."
> > Probably it would not harm to increase it to the full size of the SRAM,
> > but I tried to model
> > the behavior as close to the real hardware as possible.
>
> OK, then please document this difference in the commit description -
> such "While the A1 SRAM is 64K, we limit to 32K because ..." - and add a
> reference to https://linux-sunxi.org/BROM#U-Boot_SPL_limitations
>
> Agreed, I'll add this to the commit message.

-- 
Niek Linnenbank


Re: [PATCH v3 06/17] hw/arm/allwinner: add CPU Configuration module

2020-01-18 Thread Niek Linnenbank
On Sat, Jan 18, 2020 at 10:06 AM Philippe Mathieu-Daudé 
wrote:

> On 1/15/20 12:04 AM, Niek Linnenbank wrote:
> > On Tue, Jan 14, 2020 at 12:14 AM Philippe Mathieu-Daudé
> > mailto:phi...@redhat.com>> wrote:
> >
> > On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> >  > Various Allwinner System on Chip designs contain multiple
> processors
> >  > that can be configured and reset using the generic CPU
> Configuration
> >  > module interface. This commit adds support for the Allwinner CPU
> >  > configuration interface which emulates the following features:
> >  >
> >  >   * CPU reset
> >  >   * CPU status
> >  >   * Shared 64-bit timer
> >  >
> [...]
> >  > +case REG_CPU0_CTRL: /* CPU#0 Control */
> >  > +case REG_CPU1_CTRL: /* CPU#1 Control */
> >  > +case REG_CPU2_CTRL: /* CPU#2 Control */
> >  > +case REG_CPU3_CTRL: /* CPU#3 Control */
> >  > +case REG_CPU0_STATUS:   /* CPU#0 Status */
> >  > +case REG_CPU1_STATUS:   /* CPU#1 Status */
> >  > +case REG_CPU2_STATUS:   /* CPU#2 Status */
> >  > +case REG_CPU3_STATUS:   /* CPU#3 Status */
> >  > +case REG_CLK_GATING:/* CPU Clock Gating */
> >  > +case REG_GEN_CTRL:  /* General Control */
> >  > +s->gen_ctrl = val;
> >  > +break;
> >  > +case REG_SUPER_STANDBY: /* Super Standby Flag */
> >  > +s->super_standby = val;
> >  > +break;
> >  > +case REG_ENTRY_ADDR:/* Reset Entry Address */
> >  > +s->entry_addr = val;
> >  > +break;
> >  > +case REG_DBG_EXTERN:/* Debug External */
> >  > +break;
> >  > +case REG_CNT64_CTRL:/* 64-bit Counter Control */
> >  > +s->counter_ctrl = val;
> >  > +break;
> >  > +case REG_CNT64_LOW: /* 64-bit Counter Low */
> >  > +case REG_CNT64_HIGH:/* 64-bit Counter High */
> >
> > You forgot to set these. Maybe you can add a int64_t cnt64_diff, set
> it
> > here to the difference with qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
> and
> > in the read() function return cnt64_diff +
> > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL).
> >
> > OK I'll need to look into that. Currently this timer is not used by
> > Linux, NetBSD or U-Boot as far
> > as I know. But since it is there, it should be correct indeed.
>
> You might reduce this patch by simply using LOG_UNIMP for these
> registers. Than add the patch when you find some use.
>
> We are more confident when reviewing code when we have a way to test it :)
>
>
True indeed. I'll just remove the 64-bit counter from this patch. Thanks!

Regards,
Niek


-- 
Niek Linnenbank


Re: [PATCH] qom/object: Display more helpful message when an interface is missing

2020-01-18 Thread Paolo Bonzini
On 18/01/20 17:23, Philippe Mathieu-Daudé wrote:
> When adding new devices implementing QOM interfaces, we might
> forgot to add the Kconfig dependency that pulls the required
> objects in when building.
> 
> Since QOM dependencies are resolved at runtime, we don't get any
> link-time failures, and QEMU aborts while starting:
> 
>   $ qemu ...
>   Segmentation fault (core dumped)
> 
>   (gdb) bt
>   #0  0x7ff6e96b1e35 in raise () from /lib64/libc.so.6
>   #1  0x7ff6e969c895 in abort () from /lib64/libc.so.6
>   #2  0x5572bc5051cf in type_initialize (ti=0x5572be6f1200) at 
> qom/object.c:323
>   #3  0x5572bc505074 in type_initialize (ti=0x5572be6f1800) at 
> qom/object.c:301
>   #4  0x5572bc505074 in type_initialize (ti=0x5572be6e48e0) at 
> qom/object.c:301
>   #5  0x5572bc506939 in object_class_by_name (typename=0x5572bc56109a) at 
> qom/object.c:959
>   #6  0x5572bc503dd5 in cpu_class_by_name (typename=0x5572bc56109a, 
> cpu_model=0x5572be6d9930) at hw/core/cpu.c:286
> 
> Since the caller has access to the qdev parent/interface names,
> we can simply display them to avoid starting a debugger:
> 
>   $ qemu ...
>   qemu: missing interface 'fancy-if' for object 'fancy-dev'
>   Aborted (core dumped)
> 
> This commit is similar to e02bdf1cecd2 ("Display more helpful message
> when an object type is missing").
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> Cc: Cornelia Huck 
> Cc: Stefano Garzarella 
> Cc: Daniel P. Berrangé 
> ---
>  qom/object.c | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/qom/object.c b/qom/object.c
> index 0d971ca897..36123fb330 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -317,6 +317,11 @@ static void type_initialize(TypeImpl *ti)
>  
>  for (i = 0; i < ti->num_interfaces; i++) {
>  TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
> +if (!t) {
> +error_report("missing interface '%s' for object '%s'",
> + ti->interfaces[i].typename, parent->name);
> +abort();
> +}
>  for (e = ti->class->interfaces; e; e = e->next) {
>  TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
>  
> 

Queued, thanks.

Paolo




Re: [PATCH 2/2] pvpanic: implement crashloaded event handling

2020-01-18 Thread Paolo Bonzini
On 14/01/20 03:31, zhenwei pi wrote:
> +# @info: information about a panic (since 2.9)

Removed this "since 2.9" and queued both patches, thanks.

Paolo




Re: [PATCH 1/2] pvpanic: introduce crashloaded for pvpanic

2020-01-18 Thread Paolo Bonzini
On 14/01/20 03:31, zhenwei pi wrote:
> Add bit 1 for pvpanic. This bit means that guest hits a panic, but
> guest wants to handle error by itself. Typical case: Linux guest runs
> kdump in panic. It will help us to separate the abnormal reboot from
> normal operation.
> 
> Signed-off-by: zhenwei pi 
> ---
>  docs/specs/pvpanic.txt | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
> index c7bbacc778..bdea68a430 100644
> --- a/docs/specs/pvpanic.txt
> +++ b/docs/specs/pvpanic.txt
> @@ -16,8 +16,12 @@ pvpanic exposes a single I/O port, by default 0x505. On 
> read, the bits
>  recognized by the device are set. Software should ignore bits it doesn't
>  recognize. On write, the bits not recognized by the device are ignored.
>  Software should set only bits both itself and the device recognize.
> -Currently, only bit 0 is recognized, setting it indicates a guest panic
> -has happened.
> +
> +Bit Definition
> +--
> +bit 0: setting it indicates a guest panic has happened.
> +bit 1: named crashloaded. setting it indicates a guest panic and run
> +   kexec to handle error by guest itself.
>  
>  ACPI Interface
>  --
> 

I added this:

@@ -30,13 +31,12 @@ pvpanic device is defined with ACPI ID "QEMU0001". Custom 
methods:
 
 RDPT:   To determine whether guest panic notification is supported.
 Arguments:  None
-Return: Returns a byte, bit 0 set to indicate guest panic
-notification is supported. Other bits are reserved and
-should be ignored.
+Return: Returns a byte, with the same semantics as the I/O port
+interface.
 
 WRPT:   To send a guest panic event
-Arguments:  Arg0 is a byte, with bit 0 set to indicate guest panic has
-happened. Other bits are reserved and should be cleared.
+Arguments:  Arg0 is a byte to be written, with the same semantics as
+the I/O interface.
 Return: None
 
 The ACPI device will automatically refer to the right port in case it


Paolo




Re: [RFC PATCH] qapi: Incorrect attempt to fix building with MC146818RTC=n

2020-01-18 Thread Paolo Bonzini
On 13/01/20 15:01, Markus Armbruster wrote:
> Philippe Mathieu-Daudé  writes:
> 
>> When configured with --without-default-devices and setting
>> MC146818RTC=n, the build fails:
>>
>> LINKx86_64-softmmu/qemu-system-x86_64
>>   /usr/bin/ld: qapi/qapi-commands-misc-target.o: in function 
>> `qmp_marshal_rtc_reset_reinjection':
>>   qapi/qapi-commands-misc-target.c:46: undefined reference to 
>> `qmp_rtc_reset_reinjection'
>>   /usr/bin/ld: qapi/qapi-commands-misc-target.c:46: undefined reference to 
>> `qmp_rtc_reset_reinjection'
>>   collect2: error: ld returned 1 exit status
>>   make[1]: *** [Makefile:206: qemu-system-x86_64] Error 1
>>   make: *** [Makefile:483: x86_64-softmmu/all] Error 2
>>
>> This patch tries to fix this, but this is incorrect because QAPI
>> scripts only provide TARGET definitions, so with MC146818RTC=y we
>> get:
>>
>>   hw/rtc/mc146818rtc.c:113:6: error: no previous prototype for 
>> ‘qmp_rtc_reset_reinjection’ [-Werror=missing-prototypes]
>> 113 | void qmp_rtc_reset_reinjection(Error **errp)
>> |  ^
>>   cc1: all warnings being treated as errors
>>   make[1]: *** [rules.mak:69: hw/rtc/mc146818rtc.o] Error 1
>>
>> Any idea? :)
>>
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  qapi/misc-target.json | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/qapi/misc-target.json b/qapi/misc-target.json
>> index a00fd821eb..8e49c113d1 100644
>> --- a/qapi/misc-target.json
>> +++ b/qapi/misc-target.json
>> @@ -41,7 +41,7 @@
>>  #
>>  ##
>>  { 'command': 'rtc-reset-reinjection',
>> -  'if': 'defined(TARGET_I386)' }
>> +  'if': 'defined(TARGET_I386) && defined(CONFIG_MC146818RTC)' }
>>  
>>  
>>  ##
> 
> The generated qapi-commands-misc-target.h duly has
> 
> #if defined(TARGET_I386) && defined(CONFIG_MC146818RTC)
> void qmp_rtc_reset_reinjection(Error **errp);
> void qmp_marshal_rtc_reset_reinjection(QDict *args, QObject **ret, Error 
> **errp);
> #endif /* defined(TARGET_I386) && defined(CONFIG_MC146818RTC) */
> 
> mc146818rtc.c includes it.  But since it doesn't include
> config-devices.h, CONFIG_MC146818RTC remains undefined, and the
> prototype gets suppressed.
> 
> Crude fix: make mc146818rtc.c #include "config-devices.h".

Can we modify the code generator to leave out the #if from the header,
and only include it in the .c file?  An extra prototype is harmless.

Paolo




Re: [Qemu-devel] What should a virtual board emulate?

2020-01-18 Thread Paolo Bonzini
On 04/01/20 22:16, Philippe Mathieu-Daudé wrote:
> 1/ the Radeon chip is soldered on the motherboard,
> 
> 2/ the default BIOS expects the Radeon chip to be
>    unconditionally present,
> 
> I insist this patch is incorrect for the particular case of the
> Fuloong2e board. I plan to revert it when I post the test.
> 
> BTW I'm not using --nodefault, I'm running default ./configure:
> 
> qemu-system-mips64el -M fulong2e -bios pmon_2e.bin \
> -display none -vga none -serial stdio

But if you're not specifying -nodefaults, why are you specifying a
configuration that your BIOS does not support?  You should just remove
-vga none and leave in -display none.

Paolo




Re: [PATCH 6/6] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330

2020-01-18 Thread Peter Maydell
On Sat, 18 Jan 2020 at 15:08, Guenter Roeck  wrote:
> Do only the pointers have to be in Exynos4210State, or the entire
> data structures ? In the armsse code it looks like it is the complete
> data structures.

Either works. Embedding the entire data structure is the more
"modern" approach, but we don't generally go to the effort of
converting from the older style to the newer.

> Also, it seems to me that this means that not only pl330 and uart states
> are affected, but everything created with qdev_create(). If so, the entire
> file needs a serious rework, not just its pl330 / uart initialization.
> Am I missing something ?

Yeah, all that stuff is broken, but don't feel you need to fix it.
You just brought the pl330 pointers to my attention specifically
by declaring locals in this patch, at which point it's just
as easy to put those pointers in the state struct where they
should be.

thanks
-- PMM



Re: [PATCH 0/6] Fix more GCC9 -O3 warnings

2020-01-18 Thread Paolo Bonzini
On 18/12/19 07:05, Markus Armbruster wrote:
> "Chubb, Peter (Data61, Kensington NSW)" 
> writes:
> 
>>> "Philippe" == Philippe Mathieu-Daudé  writes:
>>
>> Philippe> Fix some trivial warnings when building with -O3.
>>
>> For compatibility with lint and other older checkers, it'd be good to keep
>> this as /* FALLTHROUGH */ (which gcc should accept according to its
>> manual).
> 
> We have hundreds of /* fall through */ comments already.
> 
>> Fixing the comments' placement is a different matter, and should be
>> done.  Seems to me that until gcc started warning for this, noone had
>> actually run a checker, and the comments were just for human info.
>>
>> Peter C
> 

Queued, thanks.

Paolo




[PATCH v41 21/21] target/avr: Update MAINTAINERS file

2020-01-18 Thread Michael Rolnik
Include AVR maintaners in MAINTAINERS file

Signed-off-by: Michael Rolnik 
---
 MAINTAINERS | 21 +
 1 file changed, 21 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 55d3642e6c..c70d77b1ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -163,6 +163,15 @@ S: Maintained
 F: hw/arm/smmu*
 F: include/hw/arm/smmu*
 
+AVR TCG CPUs
+M: Michael Rolnik 
+R: Sarah Harris 
+S: Maintained
+F: target/avr/
+F: tests/acceptance/machine_avr6.py
+F: default-configs/avr-softmmu.mak
+F: gdb-xml/avr-cpu.xml
+
 CRIS TCG CPUs
 M: Edgar E. Iglesias 
 S: Maintained
@@ -481,6 +490,18 @@ F: hw/*/allwinner*
 F: include/hw/*/allwinner*
 F: hw/arm/cubieboard.c
 
+AVR Machines
+M: Michael Rolnik 
+R: Sarah Harris 
+S: Maintained
+F: hw/avr/
+F: hw/char/avr_usart.c
+F: include/hw/char/avr_usart.h
+F: hw/timer/avr_timer16.c
+F: include/hw/timer/avr_timer16.h
+F: hw/misc/avr_mask.c
+F: include/hw/misc/avr_mask.h
+
 ARM PrimeCell and CMSDK devices
 M: Peter Maydell 
 L: qemu-...@nongnu.org
-- 
2.17.2 (Apple Git-113)




Re: [PATCH v3 0/2] cpu: Clarify overloading of reset QOM methods

2020-01-18 Thread Paolo Bonzini
On 16/12/19 16:01, Greg Kurz wrote:
> Each cpu subclass overloads the reset method of its parent class with
> its own. But since it needs to call the parent method as well, it keeps
> a parent_reset pointer to do so. This causes the same not very explicit
> boiler plate to be duplicated all around the place:
> 
> pcc->parent_reset = cc->reset;
> cc->reset = ppc_cpu_reset;
> 
> A similar concern was addressed some time back by Philippe Mathieu-Daudé
> in qdev, with the addition of device_class_set_parent_reset() and friends:
> 
> https://git.qemu.org/?p=qemu.git;a=commit;h=46795cf2e2f6
> https://git.qemu.org/?p=qemu.git;a=commit;h=bf853881690d
> 
> Follow the same approach with cpus.
> 
> Changes in v3:
> - drop 'cpu: Introduce CPUReset callback typedef' patch which isn't needed
>   and makes the code less clear. This changes the declaration of the helper
>   in 'cpu: Introduce cpu_class_set_parent_reset()', but it is minor so I
>   keep the Reviewed-by and Acked-by tags.
> 
> Changes in v2:
> - added Reviewed-by and Acked-by tags
> - rebased on top of https://github.com/cohuck/qemu.git s390-next
>   SHA1 dd6252f035a2
> 
> --
> Greg
> 
> ---
> 
> Greg Kurz (2):
>   cpu: Introduce cpu_class_set_parent_reset()
>   cpu: Use cpu_class_set_parent_reset()
> 
> 
>  hw/core/cpu.c   |8 
>  include/hw/core/cpu.h   |4 
>  target/arm/cpu.c|3 +--
>  target/cris/cpu.c   |3 +--
>  target/i386/cpu.c   |3 +--
>  target/lm32/cpu.c   |3 +--
>  target/m68k/cpu.c   |3 +--
>  target/microblaze/cpu.c |3 +--
>  target/mips/cpu.c   |3 +--
>  target/moxie/cpu.c  |3 +--
>  target/nios2/cpu.c  |3 +--
>  target/openrisc/cpu.c   |3 +--
>  target/ppc/translate_init.inc.c |3 +--
>  target/riscv/cpu.c  |3 +--
>  target/s390x/cpu.c  |3 +--
>  target/sh4/cpu.c|3 +--
>  target/sparc/cpu.c  |3 +--
>  target/tilegx/cpu.c |3 +--
>  target/tricore/cpu.c|3 +--
>  target/xtensa/cpu.c |3 +--
>  20 files changed, 30 insertions(+), 36 deletions(-)
> 

Queued, thanks.

Paolo




[PATCH v41 19/21] target/avr: Add boot serial test

2020-01-18 Thread Michael Rolnik
Print out 'T' through serial port

Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 

tests/Makefile.include
---
 tests/qtest/boot-serial-test.c | 10 ++
 tests/qtest/Makefile.include   |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 05c7f44457..e556f09db8 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -16,6 +16,15 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 
+static const uint8_t bios_avr[] = {
+0x88, 0xe0, /* ldi r24, 0x08   */
+0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */
+0x86, 0xe0, /* ldi r24, 0x06   */
+0x80, 0x93, 0xc2, 0x00, /* sts 0x00C2, r24 ; Set the data bits to 8 */
+0x84, 0xe5, /* ldi r24, 0x54   */
+0x80, 0x93, 0xc6, 0x00, /* sts 0x00C6, r24 ; Output 'T' */
+};
+
 static const uint8_t kernel_mcf5208[] = {
 0x41, 0xf9, 0xfc, 0x06, 0x00, 0x00, /* lea 0xfc06,%a0 */
 0x10, 0x3c, 0x00, 0x54, /* move.b #'T',%d0 */
@@ -103,6 +112,7 @@ typedef struct testdef {
 
 static testdef_t tests[] = {
 { "alpha", "clipper", "", "PCI:" },
+{ "avr", "sample", "", "T", sizeof(bios_avr), NULL, bios_avr },
 { "ppc", "ppce500", "", "U-Boot" },
 { "ppc", "40p", "-vga none -boot d", "Trying cd:," },
 { "ppc", "g3beige", "", "PowerPC,750" },
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e6bb4ab28c..4817b6320f 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -65,6 +65,8 @@ check-qtest-i386-y += numa-test
 
 check-qtest-x86_64-y += $(check-qtest-i386-y)
 
+check-qtest-avr-y += boot-serial-test
+
 check-qtest-alpha-y += boot-serial-test
 check-qtest-alpha-$(CONFIG_VGA) += display-vga-test
 
-- 
2.17.2 (Apple Git-113)




[PATCH v41 18/21] target/avr: Update build system

2020-01-18 Thread Michael Rolnik
Make AVR support buildable

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
---
 configure   |  7 +++
 default-configs/avr-softmmu.mak |  5 +
 target/avr/Makefile.objs| 34 +
 3 files changed, 46 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 target/avr/Makefile.objs

diff --git a/configure b/configure
index 557e4382ea..94e79ca634 100755
--- a/configure
+++ b/configure
@@ -7612,6 +7612,10 @@ case "$target_name" in
 mttcg="yes"
 gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml 
arm-vfp3.xml arm-neon.xml"
   ;;
+  avr)
+gdb_xml_files="avr-cpu.xml"
+target_compiler=$cross_cc_avr
+  ;;
   cris)
   ;;
   hppa)
@@ -7831,6 +7835,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   disas_config "ARM_A64"
 fi
   ;;
+  avr)
+disas_config "AVR"
+  ;;
   cris)
 disas_config "CRIS"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 00..d1e1c28118
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1,5 @@
+# Default configuration for avr-softmmu
+
+# Boards:
+#
+CONFIG_AVR_SAMPLE=y
diff --git a/target/avr/Makefile.objs b/target/avr/Makefile.objs
new file mode 100644
index 00..7523e0c6e2
--- /dev/null
+++ b/target/avr/Makefile.objs
@@ -0,0 +1,34 @@
+#
+#  QEMU AVR CPU
+#
+#  Copyright (c) 2019 Michael Rolnik
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+decode-y = $(SRC_PATH)/target/avr/insn.decode
+
+target/avr/decode_insn.inc.c: $(decode-y) $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn --insnwidth 16 $<, 
\
+ "GEN", $(TARGET_DIR)$@)
+
+target/avr/translate.o: target/avr/decode_insn.inc.c
+
+obj-y += translate.o cpu.o helper.o
+obj-y += gdbstub.o
+obj-y += disas.o
+obj-$(CONFIG_SOFTMMU) += machine.o
-- 
2.17.2 (Apple Git-113)




[PATCH v41 16/21] target/avr: Register AVR support with the rest of QEMU

2020-01-18 Thread Michael Rolnik
Add AVR related definitions into QEMU

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 

include/disas/dis-asm.h
---
 qapi/machine.json  |  3 ++-
 include/disas/dis-asm.h| 19 +++
 include/sysemu/arch_init.h |  1 +
 arch_init.c|  2 ++
 4 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index b3d30bc816..f2dc385167 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -21,11 +21,12 @@
 #is true even for "qemu-system-x86_64".
 #
 # ppcemb: dropped in 3.1
+# avr: since 5.0
 #
 # Since: 3.0
 ##
 { 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
  'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index e9c7dd8eb4..79bbc8b498 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -211,6 +211,25 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1   1
+#define bfd_mach_avr2   2
+#define bfd_mach_avr25  25
+#define bfd_mach_avr3   3
+#define bfd_mach_avr31  31
+#define bfd_mach_avr35  35
+#define bfd_mach_avr4   4
+#define bfd_mach_avr5   5
+#define bfd_mach_avr51  51
+#define bfd_mach_avr6   6
+#define bfd_mach_avrtiny100
+#define bfd_mach_avrxmega1  101
+#define bfd_mach_avrxmega2  102
+#define bfd_mach_avrxmega3  103
+#define bfd_mach_avrxmega4  104
+#define bfd_mach_avrxmega5  105
+#define bfd_mach_avrxmega6  106
+#define bfd_mach_avrxmega7  107
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 62c6fe4cf1..893df26ce2 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,7 @@ enum {
 QEMU_ARCH_NIOS2 = (1 << 17),
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_AVR = (1 << 20),
 };
 
 extern const uint32_t arch_type;
diff --git a/arch_init.c b/arch_init.c
index 705d0b94ad..6a741165b2 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -89,6 +89,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_XTENSA)
 #define QEMU_ARCH QEMU_ARCH_XTENSA
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
-- 
2.17.2 (Apple Git-113)




[PATCH v41 20/21] target/avr: Add Avocado test

2020-01-18 Thread Michael Rolnik
The test is based on
https://github.com/seharris/qemu-avr-tests/tree/master/free-rtos/Demo
demo which. If working correctly, prints 'ABCDEFGHIJKLMNOPQRSTUVWX' out.
it also demostrates that timer and IRQ are working

Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 
---
 tests/acceptance/machine_avr6.py | 53 
 1 file changed, 53 insertions(+)
 create mode 100644 tests/acceptance/machine_avr6.py

diff --git a/tests/acceptance/machine_avr6.py b/tests/acceptance/machine_avr6.py
new file mode 100644
index 00..43501b26a3
--- /dev/null
+++ b/tests/acceptance/machine_avr6.py
@@ -0,0 +1,53 @@
+#
+# QEMU AVR
+#
+# Copyright (c) 2019 Michael Rolnik 
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import time
+
+from avocado_qemu import Test
+
+class AVR6Machine(Test):
+timeout = 5
+
+def test_freertos(self):
+"""
+:avocado: tags=arch:avr
+:avocado: tags=machine:sample
+"""
+"""
+
https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
+constantly prints out 
'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
+"""
+rom_url = 'https://github.com/seharris/qemu-avr-tests'
+rom_sha1= '36c3e67b8755dcf37e06af6730ef5d477b8ed16d'
+rom_url += '/raw/'
+rom_url += rom_sha1
+rom_url += '/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf'
+rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
+rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
+
+self.vm.set_machine('sample')
+self.vm.add_args('-bios', rom_path)
+self.vm.add_args('-nographic')
+self.vm.launch()
+
+time.sleep(2)
+self.vm.shutdown()
+
+self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
+self.vm.get_log())
-- 
2.17.2 (Apple Git-113)




[PATCH v41 11/21] hw/avr: Add limited support for USART peripheral

2020-01-18 Thread Michael Rolnik
These were designed to facilitate testing but should provide enough function to 
be useful in other contexts.
Only a subset of the functions of each peripheral is implemented, mainly due to 
the lack of a standard way to handle electrical connections (like GPIO pins).

Signed-off-by: Sarah Harris 
---
 include/hw/char/avr_usart.h |  93 +++
 hw/char/avr_usart.c | 320 
 hw/char/Kconfig |   3 +
 hw/char/Makefile.objs   |   1 +
 4 files changed, 417 insertions(+)
 create mode 100644 include/hw/char/avr_usart.h
 create mode 100644 hw/char/avr_usart.c

diff --git a/include/hw/char/avr_usart.h b/include/hw/char/avr_usart.h
new file mode 100644
index 00..467e97e8c0
--- /dev/null
+++ b/include/hw/char/avr_usart.h
@@ -0,0 +1,93 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef HW_AVR_USART_H
+#define HW_AVR_USART_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+#include "hw/hw.h"
+
+/* Offsets of registers. */
+#define USART_DR   0x06
+#define USART_CSRA  0x00
+#define USART_CSRB  0x01
+#define USART_CSRC  0x02
+#define USART_BRRH 0x05
+#define USART_BRRL 0x04
+
+/* Relevant bits in regiters. */
+#define USART_CSRA_RXC(1 << 7)
+#define USART_CSRA_TXC(1 << 6)
+#define USART_CSRA_DRE(1 << 5)
+#define USART_CSRA_MPCM   (1 << 0)
+
+#define USART_CSRB_RXCIE  (1 << 7)
+#define USART_CSRB_TXCIE  (1 << 6)
+#define USART_CSRB_DREIE  (1 << 5)
+#define USART_CSRB_RXEN   (1 << 4)
+#define USART_CSRB_TXEN   (1 << 3)
+#define USART_CSRB_CSZ2   (1 << 2)
+#define USART_CSRB_RXB8   (1 << 1)
+#define USART_CSRB_TXB8   (1 << 0)
+
+#define USART_CSRC_MSEL1  (1 << 7)
+#define USART_CSRC_MSEL0  (1 << 6)
+#define USART_CSRC_PM1(1 << 5)
+#define USART_CSRC_PM0(1 << 4)
+#define USART_CSRC_CSZ1   (1 << 2)
+#define USART_CSRC_CSZ0   (1 << 1)
+
+#define TYPE_AVR_USART "avr-usart"
+#define AVR_USART(obj) \
+OBJECT_CHECK(AVRUsartState, (obj), TYPE_AVR_USART)
+
+typedef struct {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion mmio;
+
+CharBackend chr;
+
+bool enabled;
+
+uint8_t data;
+bool data_valid;
+uint8_t char_mask;
+/* Control and Status Registers */
+uint8_t csra;
+uint8_t csrb;
+uint8_t csrc;
+/* Baud Rate Registers (low/high byte) */
+uint8_t brrh;
+uint8_t brrl;
+
+/* Receive Complete */
+qemu_irq rxc_irq;
+/* Transmit Complete */
+qemu_irq txc_irq;
+/* Data Register Empty */
+qemu_irq dre_irq;
+} AVRUsartState;
+
+#endif /* HW_AVR_USART_H */
diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
new file mode 100644
index 00..cb307fe23d
--- /dev/null
+++ b/hw/char/avr_usart.c
@@ -0,0 +1,320 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "hw/char/avr_usart.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+static int avr_usart_can_receive(void *opaque)
+{
+AVRUsartState *usart = opaque;
+
+if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) {
+return 0;
+}
+return 1;
+}
+
+static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size)
+{
+AVRUsartState *usart = opaque;
+assert(size == 1);
+assert(!usart->data_valid);
+usart->data = buffer[0];
+usart->data_valid = true;
+usart->csra |= USART_CSRA_RXC;
+if (usart->csrb & USART_CSRB_RXCIE) {
+qemu_set_irq(usart->rxc_irq, 1);
+}
+}
+
+static void u

[PATCH v41 15/21] target/avr: Add section about AVR into QEMU documentation

2020-01-18 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 qemu-doc.texi | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index 39f950471f..515aacfae9 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1741,6 +1741,7 @@ differences are mentioned in the following sections.
 * Microblaze System emulator::
 * SH4 System emulator::
 * Xtensa System emulator::
+* AVR System emulator::
 @end menu
 
 @node PowerPC System emulator
@@ -2514,6 +2515,56 @@ so should only be used with trusted guest OS.
 
 @c man end
 
+@node AVR System emulator
+@section AVR System emulator
+@cindex system emulation (AVR)
+
+Use the executable @file{qemu-system-avr} to emulates a AVR 8 bit based 
machine having one for the following cores: avr1, avr2, avr25, avr3, avr31, 
avr35, avr4, avr5, avr51, avr6, avrtiny, xmega2, xmega3, xmega4, xmega5, xmega6 
and xmega7.
+
+As for now it does not support any real MCUs. However, it does support a 
"sample" board for educational and testing purposes. This "sample" board hosts 
USART & 16 bit timer devices and it's enought to run FreeRTOS based applicaton 
(like this 
@url{https://github.com/seharris/qemu-avr-tests/blob/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf,,demo})
+
+Following are examples of possible usages, assuming program.elf is compiled 
for AVR cpu
+@itemize
+
+@item Continious non interrupted execution
+@example
+qemu-system-avr -kernel program.elf
+@end example
+
+@item Continious non interrupted execution with serial output into telnet 
window
+@example
+qemu-system-avr -kernel program.elf -serial tcp::5678,server,nowait -nographic
+@end example
+and then in another shell
+@example
+telent localhost 5678
+@end example
+
+@item Continious non interrupted execution with serial output into stdout
+@example
+qemu-system-avr -kernel program.elf -serial stdio
+@end example
+
+@item Debugging wit GDB debugger
+@example
+qemu-system-avr -kernel program.elf -s -S
+@end example
+and then in another shell
+@example
+avr-gdb program.elf
+@end example
+and then within GDB shell
+@example
+target remote :1234
+@end example
+
+@item Print out executed instructions
+@example
+qemu-system-avr -kernel program.elf -d in_asm
+@end example
+
+@end itemize
+
 @node QEMU User space emulator
 @chapter QEMU User space emulator
 
-- 
2.17.2 (Apple Git-113)




[PATCH v41 17/21] target/avr: Add machine none test

2020-01-18 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
---
 tests/qtest/machine-none-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index 5953d31755..3e5c74e73e 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] = {
 /* tested targets list */
 { "arm", "cortex-a15" },
 { "aarch64", "cortex-a57" },
+{ "avr", "avr6-avr-cpu" },
 { "x86_64", "qemu64,apic-id=0" },
 { "i386", "qemu32,apic-id=0" },
 { "alpha", "ev67" },
-- 
2.17.2 (Apple Git-113)




[PATCH v41 13/21] hw/avr: Add dummy mask device

2020-01-18 Thread Michael Rolnik
This is a simple device of just one register, whenver this register is
written it calls qemu_set_irq function for each of 8 bits/IRQs..
It is used to implement AVR Power Reduction

Signed-off-by: Michael Rolnik 
---
 include/hw/misc/avr_mask.h |  47 
 hw/misc/avr_mask.c | 112 +
 hw/misc/Kconfig|   3 +
 hw/misc/Makefile.objs  |   2 +
 4 files changed, 164 insertions(+)
 create mode 100644 include/hw/misc/avr_mask.h
 create mode 100644 hw/misc/avr_mask.c

diff --git a/include/hw/misc/avr_mask.h b/include/hw/misc/avr_mask.h
new file mode 100644
index 00..d3e21972d8
--- /dev/null
+++ b/include/hw/misc/avr_mask.h
@@ -0,0 +1,47 @@
+/*
+ * AVR Power Reduction
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_avr_mask_H
+#define HW_avr_mask_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+#include "hw/hw.h"
+
+
+#define TYPE_AVR_MASK "avr-mask"
+#define AVR_MASK(obj) OBJECT_CHECK(AVRMaskState, (obj), TYPE_AVR_MASK)
+
+typedef struct {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion iomem;
+
+uint8_t val;
+qemu_irq irq[8];
+} AVRMaskState;
+
+#endif /* HW_avr_mask_H */
diff --git a/hw/misc/avr_mask.c b/hw/misc/avr_mask.c
new file mode 100644
index 00..3af82ed9c1
--- /dev/null
+++ b/hw/misc/avr_mask.c
@@ -0,0 +1,112 @@
+/*
+ * AVR Power Reduction
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/avr_mask.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/irq.h"
+
+#define DB_PRINT(fmt, args...) /* Nothing */
+/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)*/
+
+static void avr_mask_reset(DeviceState *dev)
+{
+AVRMaskState *s = AVR_MASK(dev);
+
+s->val = 0x00;
+
+for (int i = 0; i < 8; i++) {
+qemu_set_irq(s->irq[i], 0);
+}
+}
+
+static uint64_t avr_mask_read(void *opaque, hwaddr offset, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+
+return (uint64_t)s->val;
+}
+
+static void avr_mask_write(void *opaque, hwaddr offset,
+  uint64_t val64, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+uint8_t val8 = val64;
+
+DB_PRINT("write %d to offset %d", val8, (uint8_t)offset);
+
+s->val = val8;
+for (int i = 0; i < 8; i++) {
+qemu_set_irq(s->irq[i], (val8 & (1 << i)) != 0);
+}
+}
+
+static const MemoryRegionOps avr_mask_ops = {
+.read = avr_mask_read,
+.write = avr_mask_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {.max_access_size = 1}
+};
+
+static void avr_mask_init(Object *dev)
+{
+AVRMaskState *s = AVR_MASK(dev);
+SysBusD

[PATCH v41 07/21] target/avr: Add instruction translation - Bit and Bit-test Instructions

2020-01-18 Thread Michael Rolnik
This includes:
- LSR, ROR
- ASR
- SWAP
- SBI, CBI
- BST, BLD
- BSET, BCLR

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 241 +
 target/avr/insn.decode |  14 +++
 2 files changed, 255 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 4a62d9312a..58775af17c 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2440,3 +2440,244 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
 
 return true;
 }
+
+/*
+ * Bit and Bit-test Instructions
+ */
+static void gen_rshift_ZNVSf(TCGv R)
+{
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf);
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is
+ *  loaded into the C Flag of the SREG. This operation effectively divides an
+ *  unsigned value by two. The C Flag can be used to round the result.
+ */
+static bool trans_LSR(DisasContext *ctx, arg_LSR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+tcg_gen_shri_tl(Rd, Rd, 1);
+/* update status register */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */
+tcg_gen_movi_tl(cpu_Nf, 0);
+tcg_gen_mov_tl(cpu_Vf, cpu_Cf);
+tcg_gen_mov_tl(cpu_Sf, cpu_Vf);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. The C Flag is shifted into
+ *  bit 7 of Rd. Bit 0 is shifted into the C Flag.  This operation, combined
+ *  with ASR, effectively divides multi-byte signed values by two. Combined 
with
+ *  LSR it effectively divides multi-byte unsigned values by two. The Carry 
Flag
+ *  can be used to round the result.
+ */
+static bool trans_ROR(DisasContext *ctx, arg_ROR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+tcg_gen_shli_tl(t0, cpu_Cf, 7);
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+/* update output register */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0
+ *  is loaded into the C Flag of the SREG. This operation effectively divides a
+ *  signed value by two without changing its sign. The Carry Flag can be used 
to
+ *  round the result.
+ */
+static bool trans_ASR(DisasContext *ctx, arg_ASR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */
+/* update output register */
+tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Swaps high and low nibbles in a register.
+ */
+static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+TCGv t1 = tcg_temp_new_i32();
+
+tcg_gen_andi_tl(t0, Rd, 0x0f);
+tcg_gen_shli_tl(t0, t0, 4);
+tcg_gen_andi_tl(t1, Rd, 0xf0);
+tcg_gen_shri_tl(t1, t1, 4);
+tcg_gen_or_tl(Rd, t0, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Sets a specified bit in an I/O Register. This instruction operates on
+ *  the lower 32 I/O Registers -- addresses 0-31.
+ */
+static bool trans_SBI(DisasContext *ctx, arg_SBI *a)
+{
+TCGv data = tcg_temp_new_i32();
+TCGv port = tcg_const_i32(a->reg);
+
+gen_helper_inb(data, cpu_env, port);
+tcg_gen_ori_tl(data, data, 1 << a->bit);
+gen_helper_outb(cpu_env, port, data);
+
+tcg_temp_free_i32(port);
+tcg_temp_free_i32(data);
+
+return true;
+}
+
+/*
+ *  Clears a specified bit in an I/O Register. This instruction operates on
+ *  the lower 32 I/O Registers -- addresses 0-31.
+ */
+static bool trans_CBI(DisasContext *ctx, arg_CBI *a)
+{
+TCGv data = tcg_temp_new_i32();
+TCGv port = tcg_const_i32(a->reg);
+
+gen_helper_inb(data, cpu_env, port);
+tcg_gen_andi_tl(data, data, ~(1 << a->bit));
+gen_helper_outb(cpu_env, port, data);
+
+tcg_temp_free_i32(data);
+tcg_temp_free_i32(port);
+
+return true;
+}
+
+/*
+ *  Stores bit b from Rd to the T Flag in SREG (Status Register).
+ */
+static bool trans_BST(DisasContext *ctx, arg_BST *a)
+{
+TCGv Rd = cpu_r[a->rd];
+
+tcg_gen_andi_tl(cpu_Tf, Rd, 1 << a->bit);
+tcg_gen_shri_tl(cpu_Tf, cpu_Tf, a->bit);
+
+return true;
+}
+
+/*
+ *  Copies the T Flag in the SREG (Status Register) to bit b in register Rd.
+ */
+static bool trans_BLD(DisasContext *ctx, arg_BLD *a)
+{
+T

[PATCH v41 10/21] target/avr: Add instruction disassembly function

2020-01-18 Thread Michael Rolnik
Provide function disassembles executed instruction when `-d in_asm` is
provided

Example:
`./avr-softmmu/qemu-system-avr -bios free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf 
-d in_asm` will produce something like the following

```
...
IN:
0x014a:  CALL  0x3808

IN: main
0x3808:  CALL  0x4b4

IN: vParTestInitialise
0x04b4:  LDI   r24, 255
0x04b6:  STS   r24, 0
0x04b8:  MULS  r16, r20
0x04ba:  OUT   $1, r24
0x04bc:  LDS   r24, 0
0x04be:  MULS  r16, r20
0x04c0:  OUT   $2, r24
0x04c2:  RET
...
```

Signed-off-by: Michael Rolnik 
Suggested-by: Richard Henderson 
Suggested-by: Philippe Mathieu-Daudé 
Suggested-by: Aleksandar Markovic 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.h   |   1 +
 target/avr/cpu.c   |   2 +-
 target/avr/disas.c | 245 +
 target/avr/translate.c |  12 ++
 4 files changed, 259 insertions(+), 1 deletion(-)
 create mode 100644 target/avr/disas.c

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index b74bcf01ae..af89b6611e 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -160,6 +160,7 @@ bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_print_insn(bfd_vma addr, disassemble_info *info);
 
 static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
 {
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index c74c5106fe..fa51f771c0 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -84,7 +84,7 @@ static void avr_cpu_reset(CPUState *cs)
 static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
 info->mach = bfd_arch_avr;
-info->print_insn = NULL;
+info->print_insn = avr_print_insn;
 }
 
 static void avr_cpu_realizefn(DeviceState *dev, Error **errp)
diff --git a/target/avr/disas.c b/target/avr/disas.c
new file mode 100644
index 00..f3fa3d6bef
--- /dev/null
+++ b/target/avr/disas.c
@@ -0,0 +1,245 @@
+/*
+ * AVR disassembler
+ *
+ * Copyright (c) 2019 Richard Henderson 
+ * Copyright (c) 2019 Michael Rolnik 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+typedef struct {
+disassemble_info *info;
+uint16_t next_word;
+bool next_word_used;
+} DisasContext;
+
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
+
+static uint16_t next_word(DisasContext *ctx)
+{
+ctx->next_word_used = true;
+return ctx->next_word;
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}
+
+
+/* Include the auto-generated decoder.  */
+static bool decode_insn(DisasContext *ctx, uint16_t insn);
+#include "decode_insn.inc.c"
+
+#define output(mnemonic, format, ...) \
+(pctx->info->fprintf_func(pctx->info->stream, "%-9s " format, \
+mnemonic, ##__VA_ARGS__))
+
+int avr_print_insn(bfd_vma addr, disassemble_info *info)
+{
+DisasContext ctx;
+DisasContext *pctx = &ctx;
+bfd_byte buffer[4];
+uint16_t insn;
+int status;
+
+ctx.info = info;
+
+status = info->read_memory_func(addr, buffer, 4, info);
+if (status != 0) {
+info->memory_error_func(status, addr, info);
+return -1;
+}
+insn = bfd_getl16(buffer);
+ctx.next_word = bfd_getl16(buffer + 2);
+ctx.next_word_used = false;
+
+if (!decode_insn(&ctx, insn)) {
+output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]);
+}
+
+return ctx.next_word_used ? 4 : 2;
+}
+
+
+#define INSN(opcode, format, ...)   \
+static bool trans_##opcode(DisasContext *pctx, arg_##opcode * a)\
+{   \
+output(#opcode, format, ##__VA_ARGS

[PATCH v41 12/21] hw/avr: Add limited support for 16 bit timer peripheral

2020-01-18 Thread Michael Rolnik
These were designed to facilitate testing but should provide enough function to 
be useful in other contexts.
Only a subset of the functions of each peripheral is implemented, mainly due to 
the lack of a standard way to handle electrical connections (like GPIO pins).

Signed-off-by: Sarah Harris 
---
 include/hw/timer/avr_timer16.h |  94 +
 hw/timer/avr_timer16.c | 602 +
 hw/timer/Kconfig   |   3 +
 hw/timer/Makefile.objs |   2 +
 4 files changed, 701 insertions(+)
 create mode 100644 include/hw/timer/avr_timer16.h
 create mode 100644 hw/timer/avr_timer16.c

diff --git a/include/hw/timer/avr_timer16.h b/include/hw/timer/avr_timer16.h
new file mode 100644
index 00..4ae0c64a34
--- /dev/null
+++ b/include/hw/timer/avr_timer16.h
@@ -0,0 +1,94 @@
+/*
+ * AVR 16 bit timer
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Ed Robbins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ * Driver for 16 bit timers on 8 bit AVR devices.
+ * Note:
+ * On ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
+ */
+
+#ifndef AVR_TIMER16_H
+#define AVR_TIMER16_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "hw/hw.h"
+
+enum NextInterrupt {
+OVERFLOW,
+COMPA,
+COMPB,
+COMPC,
+CAPT
+};
+
+#define TYPE_AVR_TIMER16 "avr-timer16"
+#define AVR_TIMER16(obj) \
+OBJECT_CHECK(AVRTimer16State, (obj), TYPE_AVR_TIMER16)
+
+typedef struct AVRTimer16State {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion iomem;
+MemoryRegion imsk_iomem;
+MemoryRegion ifr_iomem;
+QEMUTimer *timer;
+qemu_irq capt_irq;
+qemu_irq compa_irq;
+qemu_irq compb_irq;
+qemu_irq compc_irq;
+qemu_irq ovf_irq;
+
+bool enabled;
+
+/* registers */
+uint8_t cra;
+uint8_t crb;
+uint8_t crc;
+uint8_t cntl;
+uint8_t cnth;
+uint8_t icrl;
+uint8_t icrh;
+uint8_t ocral;
+uint8_t ocrah;
+uint8_t ocrbl;
+uint8_t ocrbh;
+uint8_t ocrcl;
+uint8_t ocrch;
+/*
+ * Reads and writes to CNT and ICR utilise a bizarre temporary
+ * register, which we emulate
+ */
+uint8_t rtmp;
+uint8_t imsk;
+uint8_t ifr;
+
+uint8_t id;
+uint64_t cpu_freq_hz;
+uint64_t freq_hz;
+uint64_t period_ns;
+uint64_t reset_time_ns;
+enum NextInterrupt next_interrupt;
+} AVRTimer16State;
+
+#endif /* AVR_TIMER16_H */
diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
new file mode 100644
index 00..aea1bf009e
--- /dev/null
+++ b/hw/timer/avr_timer16.c
@@ -0,0 +1,602 @@
+/*
+ * AVR 16 bit timer
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Ed Robbins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ * Driver for 16 bit timers on 8 bit AVR devices.
+ * Note:
+ * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
+ */
+
+/*
+ * XXX TODO: Power Reduction Register support
+ *   prescaler pause support
+ *   PWM modes, GPIO, output capture pins, input compare pin
+ */
+
+#include "qemu/osdep.h"
+#include "hw/timer/avr_timer16.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+/* Register offsets */
+#define T16_CRA 0x0
+#define T16_CRB 0x1
+#define T16_CRC 0x2
+#define T16_CNTL0x4
+#define T16_CNTH0x5
+#define T16_ICRL0x6
+#define T16_ICRH0x7
+#define T16_OCRAL   0x8
+#define T16_OCRAH   0x9
+#define T16_OCRBL   0xa
+#define T16_OCRBH   0xb
+#define T16_OCRCL   0xc
+#define T16_OCRCH   0xd
+
+/* Field masks */
+#define T16_CRA_WGM01   0x3
+#define T16_CRA_COMC0xc
+#define T16_CRA_COMB0x3

[PATCH v41 05/21] target/avr: Add instruction translation - Branch Instructions

2020-01-18 Thread Michael Rolnik
This includes:
- RJMP, IJMP, EIJMP, JMP
- RCALL, ICALL, EICALL, CALL
- RET, RETI
- CPSE, CP, CPC, CPI
- SBRC, SBRS, SBIC, SBIS
- BRBC, BRBS

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 533 +
 target/avr/insn.decode |  24 ++
 2 files changed, 557 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 00fb3f5350..475f502e72 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -921,3 +921,536 @@ static bool trans_DES(DisasContext *ctx, arg_DES *a)
 
 return true;
 }
+
+/*
+ * Branch Instructions
+ */
+static void gen_jmp_ez(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_jmp_z(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_push_ret(DisasContext *ctx, int ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0xff));
+
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0x00));
+
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+
+TCGv lo = tcg_const_i32((ret & 0xff));
+TCGv hi = tcg_const_i32((ret & 0x00) >> 8);
+
+tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 2);
+tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
+}
+}
+
+static void gen_pop_ret(DisasContext *ctx, TCGv ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+TCGv lo = tcg_temp_new_i32();
+TCGv hi = tcg_temp_new_i32();
+
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 2);
+tcg_gen_qemu_ld_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
+
+tcg_gen_deposit_tl(ret, lo, hi, 8, 16);
+
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
+}
+}
+
+static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+{
+TranslationBlock *tb = ctx->tb;
+
+if (ctx->singlestep == 0) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_i32(cpu_pc, dest);
+tcg_gen_exit_tb(tb, n);
+} else {
+tcg_gen_movi_i32(cpu_pc, dest);
+gen_helper_debug(cpu_env);
+tcg_gen_exit_tb(NULL, 0);
+}
+ctx->bstate = DISAS_NORETURN;
+}
+
+/*
+ *  Relative jump to an address within PC - 2K +1 and PC + 2K (words). For
+ *  AVR microcontrollers with Program memory not exceeding 4K words (8KB) this
+ *  instruction can address the entire memory from every address location. See
+ *  also JMP.
+ */
+static bool trans_RJMP(DisasContext *ctx, arg_RJMP *a)
+{
+int dst = ctx->npc + a->imm;
+
+gen_goto_tb(ctx, 0, dst);
+
+return true;
+}
+
+/*
+ *  Indirect jump to the address pointed to by the Z (16 bits) Pointer
+ *  Register in the Register File. The Z-pointer Register is 16 bits wide and
+ *  allows jump within the lowest 64K words (128KB) section of Program memory.
+ *  This instruction is not available in all devices. Refer to the device
+ *  specific instruction set summary.
+ */
+static bool trans_IJMP(DisasContext *ctx, arg_IJMP *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) {
+return true;
+}
+
+gen_jmp_z(ctx);
+
+return true;
+}
+
+/*
+ *  Indirect jump to the address pointed to by the Z (16 bits) Pointer
+ *  Register in the Register File and the EIND Register in the I/O space. This
+ *  instruction allows for indirect jumps to the entire 4M (words) Program
+ *  memory space. See also IJMP.  This instruction is not available in all
+ *  devices. Refer to the device specific instruction set summary.
+ */
+static bool trans_EIJMP(DisasContext *ctx, arg_EIJMP *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) {
+return true;
+}
+
+gen_jmp_ez(ctx);
+return true;
+}
+
+/*
+ *  Jump t

[PATCH v41 09/21] target/avr: Add instruction translation - CPU main translation function

2020-01-18 Thread Michael Rolnik
Co-developed-by: Richard Henderson 
Co-developed-by: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 234 +
 1 file changed, 234 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 4c680070e2..af88bb2e5a 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2749,3 +2749,237 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
 
 return true;
 }
+
+
+void avr_cpu_tcg_init(void)
+{
+int i;
+
+#define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
+cpu_pc = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc");
+cpu_Cf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf");
+cpu_Zf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf");
+cpu_Nf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf");
+cpu_Vf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf");
+cpu_Sf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf");
+cpu_Hf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf");
+cpu_Tf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf");
+cpu_If = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If");
+cpu_rampD = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "rampD");
+cpu_rampX = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "rampX");
+cpu_rampY = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "rampY");
+cpu_rampZ = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "rampZ");
+cpu_eind = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind");
+cpu_sp = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp");
+cpu_skip = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip");
+
+for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) {
+cpu_r[i] = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]),
+  reg_names[i]);
+}
+#undef AVR_REG_OFFS
+}
+
+static void translate(DisasContext *ctx)
+{
+uint32_t opcode = next_word(ctx);
+
+if (!decode_insn(ctx, opcode)) {
+gen_helper_unsupported(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+}
+}
+
+/* Standardize the cpu_skip condition to NE.  */
+static bool canonicalize_skip(DisasContext *ctx)
+{
+switch (ctx->skip_cond) {
+case TCG_COND_NEVER:
+/* Normal case: cpu_skip is known to be false.  */
+return false;
+
+case TCG_COND_ALWAYS:
+/*
+ * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
+ * The breakpoint is on the instruction being skipped, at the start
+ * of the TranslationBlock.  No need to update.
+ */
+return false;
+
+case TCG_COND_NE:
+if (ctx->skip_var1 == NULL) {
+tcg_gen_mov_tl(cpu_skip, ctx->skip_var0);
+} else {
+tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+break;
+
+default:
+/* Convert to a NE condition vs 0. */
+if (ctx->skip_var1 == NULL) {
+tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0);
+} else {
+tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip,
+   ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+ctx->skip_cond = TCG_COND_NE;
+break;
+}
+if (ctx->free_skip_var0) {
+tcg_temp_free(ctx->skip_var0);
+ctx->free_skip_var0 = false;
+}
+ctx->skip_var0 = cpu_skip;
+return true;
+}
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+CPUAVRState *env = cs->env_ptr;
+DisasContext ctx = {
+.tb = tb,
+.cs = cs,
+.env = env,
+.memidx = 0,
+.bstate = DISAS_NEXT,
+.skip_cond = TCG_COND_NEVER,
+.singlestep = cs->singlestep_enabled,
+};
+target_ulong pc_start = tb->pc / 2;
+int num_insns = 0;
+
+if (tb->flags & TB_FLAGS_FULL_ACCESS) {
+/*
+ * This flag is set by ST/LD instruction we will regenerate it ONLY
+ * with mem/cpu memory access instead of mem access
+ */
+max_insns = 1;
+}
+if (ctx.singlestep) {
+max_insns = 1;
+}
+
+gen_tb_start(tb);
+
+ctx.npc = pc_start;
+if (tb->flags & TB_FLAGS_SKIP) {
+ctx.skip_cond = TCG_COND_ALWAYS;
+ctx.skip_var0 = cpu_skip;
+}
+
+do {
+TCGLabel *skip_label = NULL;
+
+/* translate current instruction */
+tcg_gen_insn_start(ctx.npc);
+num_insns++;
+
+/*
+ * this is due to some strange GDB behavior
+ * let's assume main has address 0x100
+ * b main   - sets breakpoint at address 0x0100 (code)
+ * b *0x100 - sets breakpoint at address 0x00800100 (data)
+ */
+if (unlikely(!ctx.singleste

[PATCH v41 04/21] target/avr: Add instruction translation - Arithmetic and Logic Instructions

2020-01-18 Thread Michael Rolnik
This includes:
- ADD, ADC, ADIW
- SBIW, SUB, SUBI, SBC, SBCI
- AND, ANDI
- OR, ORI, EOR
- COM, NEG
- INC, DEC
- MUL, MULS, MULSU
- FMUL, FMULS, FMULSU
- DES

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 751 +
 target/avr/insn.decode |  93 +
 2 files changed, 844 insertions(+)
 create mode 100644 target/avr/insn.decode

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 241083dc2d..00fb3f5350 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -170,3 +170,754 @@ static bool avr_have_feature(DisasContext *ctx, int 
feature)
 static bool decode_insn(DisasContext *ctx, uint16_t insn);
 #include "decode_insn.inc.c"
 
+/*
+ * Arithmetic Instructions
+ */
+
+static void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+tcg_gen_and_tl(t1, Rd, Rr); /* t1 = Rd & Rr */
+tcg_gen_andc_tl(t2, Rd, R); /* t2 = Rd & ~R */
+tcg_gen_andc_tl(t3, Rr, R); /* t3 = Rr & ~R */
+tcg_gen_or_tl(t1, t1, t2); /* t1 = t1 | t2 | t3 */
+tcg_gen_or_tl(t1, t1, t3);
+tcg_gen_shri_tl(cpu_Cf, t1, 7); /* Cf = t1(7) */
+tcg_gen_shri_tl(cpu_Hf, t1, 3); /* Hf = t1(3) */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+
+static void gen_add_Vf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+/* t1 = Rd & Rr & ~R | ~Rd & ~Rr & R */
+/*= (Rd ^ R) & ~(Rd ^ Rr) */
+tcg_gen_xor_tl(t1, Rd, R);
+tcg_gen_xor_tl(t2, Rd, Rr);
+tcg_gen_andc_tl(t1, t1, t2);
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+
+static void gen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+tcg_gen_not_tl(t1, Rd); /* t1 = ~Rd */
+tcg_gen_and_tl(t2, t1, Rr); /* t2 = ~Rd & Rr */
+tcg_gen_or_tl(t3, t1, Rr); /* t3 = (~Rd | Rr) & R */
+tcg_gen_and_tl(t3, t3, R);
+tcg_gen_or_tl(t2, t2, t3); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */
+tcg_gen_shri_tl(cpu_Cf, t2, 7); /* Cf = t2(7) */
+tcg_gen_shri_tl(cpu_Hf, t2, 3); /* Hf = t2(3) */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+
+static void gen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+/* t1 = Rd & ~Rr & ~R | ~Rd & Rr & R */
+/*= (Rd ^ R) & (Rd ^ R) */
+tcg_gen_xor_tl(t1, Rd, R);
+tcg_gen_xor_tl(t2, Rd, Rr);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+
+static void gen_NSf(TCGv R)
+{
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+
+static void gen_ZNSf(TCGv R)
+{
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+/*
+ *  Adds two registers without the C Flag and places the result in the
+ *  destination register Rd.
+ */
+static bool trans_ADD(DisasContext *ctx, arg_ADD *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv Rr = cpu_r[a->rr];
+TCGv R = tcg_temp_new_i32();
+
+tcg_gen_add_tl(R, Rd, Rr); /* Rd = Rd + Rr */
+tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
+/* update status register */
+gen_add_CHf(R, Rd, Rr);
+gen_add_Vf(R, Rd, Rr);
+gen_ZNSf(R);
+/* update output registers */
+tcg_gen_mov_tl(Rd, R);
+
+tcg_temp_free_i32(R);
+
+return true;
+}
+
+/*
+ *  Adds two registers and the contents of the C Flag and places the result in
+ *  the destination register Rd.
+ */
+static bool trans_ADC(DisasContext *ctx, arg_ADC *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv Rr = cpu_r[a->rr];
+TCGv R = tcg_temp_new_i32();
+
+tcg_gen_add_tl(R, Rd, Rr); /* R = Rd + Rr + Cf */
+tcg_gen_add_tl(R, R, cpu_Cf);
+tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
+/* update status register */
+gen_add_CHf(R, Rd, Rr);
+gen_add_Vf(R, Rd, Rr);
+gen_ZNSf(R);
+/* update output registers */
+tcg_gen_mov_tl(Rd, R);
+
+tcg_temp_free_i32(R);
+
+return true;
+}
+
+/*
+ *  Adds an immediate value (0 - 63) to a register pair and places the result
+ *  in the register pair. This instruction operates on the upper four register
+ *  pairs, and is well suited for operations on the pointer registers.  This
+ *  instruction is not available in all devices. Refer to the device specific
+ *  instruction set summary.
+ */
+static bool trans_ADIW(DisasContext *ctx, arg_ADIW *a)
+{
+if (!avr_have_feat

[PATCH v41 03/21] target/avr: Add instruction translation - Registers definition

2020-01-18 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 172 +
 1 file changed, 172 insertions(+)
 create mode 100644 target/avr/translate.c

diff --git a/target/avr/translate.c b/target/avr/translate.c
new file mode 100644
index 00..241083dc2d
--- /dev/null
+++ b/target/avr/translate.c
@@ -0,0 +1,172 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
+#include "tcg/tcg.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg-op.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/log.h"
+#include "exec/translator.h"
+#include "exec/gen-icount.h"
+
+/*
+ *  Define if you want a BREAK instruction translated to a breakpoint
+ *  Active debugging connection is assumed
+ *  This is for
+ *  https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
+ *  tests
+ */
+#undef BREAKPOINT_ON_BREAK
+
+static TCGv cpu_pc;
+
+static TCGv cpu_Cf;
+static TCGv cpu_Zf;
+static TCGv cpu_Nf;
+static TCGv cpu_Vf;
+static TCGv cpu_Sf;
+static TCGv cpu_Hf;
+static TCGv cpu_Tf;
+static TCGv cpu_If;
+
+static TCGv cpu_rampD;
+static TCGv cpu_rampX;
+static TCGv cpu_rampY;
+static TCGv cpu_rampZ;
+
+static TCGv cpu_r[NUMBER_OF_CPU_REGISTERS];
+static TCGv cpu_eind;
+static TCGv cpu_sp;
+
+static TCGv cpu_skip;
+
+static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = {
+"r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+"r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+#define REG(x) (cpu_r[x])
+
+enum {
+DISAS_EXIT   = DISAS_TARGET_0,  /* We want return to the cpu main loop.  */
+DISAS_LOOKUP = DISAS_TARGET_1,  /* We have a variable condition exit.  */
+DISAS_CHAIN  = DISAS_TARGET_2,  /* We have a single condition exit.  */
+};
+
+typedef struct DisasContext DisasContext;
+
+/* This is the state at translation time. */
+struct DisasContext {
+TranslationBlock *tb;
+
+CPUAVRState *env;
+CPUState *cs;
+
+target_long npc;
+uint32_t opcode;
+
+/* Routine used to access memory */
+int memidx;
+int bstate;
+int singlestep;
+
+/*
+ * some AVR instructions can make the following instruction to be skipped
+ * Let's name those instructions
+ * A   - instruction that can skip the next one
+ * B   - instruction that can be skipped. this depends on execution of 
A
+ * there are two scenarios
+ * 1. A and B belong to the same translation block
+ * 2. A is the last instruction in the translation block and B is the last
+ *
+ * following variables are used to simplify the skipping logic, they are
+ * used in the following manner (sketch)
+ *
+ * TCGLabel *skip_label = NULL;
+ * if (ctx.skip_cond != TCG_COND_NEVER) {
+ * skip_label = gen_new_label();
+ * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
+ * }
+ *
+ * if (free_skip_var0) {
+ * tcg_temp_free(skip_var0);
+ * free_skip_var0 = false;
+ * }
+ *
+ * translate(&ctx);
+ *
+ * if (skip_label) {
+ * gen_set_label(skip_label);
+ * }
+ */
+TCGv skip_var0;
+TCGv skip_var1;
+TCGCond skip_cond;
+bool free_skip_var0;
+};
+
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
+
+static uint16_t next_word(DisasContext *ctx)
+{
+return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}
+
+
+static bool avr_have_feature(DisasContext *ctx, int feature)
+{
+if (!avr_feature(ctx->env, feature)) {
+gen_helper_unsupported(cpu_env);
+

[PATCH v41 08/21] target/avr: Add instruction translation - MCU Control Instructions

2020-01-18 Thread Michael Rolnik
This includes:
- BREAK
- NOP
- SLEEP
- WDR

Signed-off-by: Michael Rolnik 
---
 target/avr/translate.c | 68 ++
 target/avr/insn.decode |  9 ++
 2 files changed, 77 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 58775af17c..4c680070e2 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2681,3 +2681,71 @@ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a)
 
 return true;
 }
+
+/*
+ * MCU Control Instructions
+ */
+
+/*
+ *  The BREAK instruction is used by the On-chip Debug system, and is
+ *  normally not used in the application software. When the BREAK instruction 
is
+ *  executed, the AVR CPU is set in the Stopped Mode. This gives the On-chip
+ *  Debugger access to internal resources.  If any Lock bits are set, or either
+ *  the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BREAK
+ *  instruction as a NOP and will not enter the Stopped mode.  This instruction
+ *  is not available in all devices. Refer to the device specific instruction
+ *  set summary.
+ */
+static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) {
+return true;
+}
+
+#ifdef BREAKPOINT_ON_BREAK
+tcg_gen_movi_tl(cpu_pc, ctx->npc - 1);
+gen_helper_debug(cpu_env);
+ctx->bstate = DISAS_EXIT;
+#else
+/* NOP */
+#endif
+
+return true;
+}
+
+
+/*
+ *  This instruction performs a single cycle No Operation.
+ */
+static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
+{
+
+/* NOP */
+
+return true;
+}
+
+
+/*
+ *  This instruction sets the circuit in sleep mode defined by the MCU
+ *  Control Register.
+ */
+static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
+{
+gen_helper_sleep(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+return true;
+}
+
+
+/*
+ *  This instruction resets the Watchdog Timer. This instruction must be
+ *  executed within a limited time given by the WD prescaler. See the Watchdog
+ *  Timer hardware specification.
+ */
+static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
+{
+gen_helper_wdr(cpu_env);
+
+return true;
+}
diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 4ee55862b2..0e4ec9ddf0 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -172,3 +172,12 @@ BST  101 rd:5 0 bit:3
 BLD  100 rd:5 0 bit:3
 BSET1001 0100 0 bit:3 1000
 BCLR1001 0100 1 bit:3 1000
+
+#
+# MCU Control Instructions
+#
+BREAK   1001 0101 1001 1000
+NOP    
+SLEEP   1001 0101 1000 1000
+WDR 1001 0101 1010 1000
+
-- 
2.17.2 (Apple Git-113)




[PATCH v41 02/21] target/avr: Add instruction helpers

2020-01-18 Thread Michael Rolnik
Stubs for unimplemented instructions and helpers for instructions that need to 
interact with QEMU.
SPM and WDR are unimplemented because they require emulation of complex 
peripherals.
The implementation of SLEEP is very limited due to the lack of peripherals to 
generate wake interrupts.
Memory access instructions are implemented here because some address ranges 
actually refer to CPU registers.

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/helper.h |  29 
 target/avr/helper.c | 347 
 2 files changed, 376 insertions(+)
 create mode 100644 target/avr/helper.h
 create mode 100644 target/avr/helper.c

diff --git a/target/avr/helper.h b/target/avr/helper.h
new file mode 100644
index 00..bf087504a8
--- /dev/null
+++ b/target/avr/helper.h
@@ -0,0 +1,29 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+DEF_HELPER_1(wdr, void, env)
+DEF_HELPER_1(debug, void, env)
+DEF_HELPER_1(break, void, env)
+DEF_HELPER_1(sleep, void, env)
+DEF_HELPER_1(unsupported, void, env)
+DEF_HELPER_3(outb, void, env, i32, i32)
+DEF_HELPER_2(inb, tl, env, i32)
+DEF_HELPER_3(fullwr, void, env, i32, i32)
+DEF_HELPER_2(fullrd, tl, env, i32)
diff --git a/target/avr/helper.c b/target/avr/helper.c
new file mode 100644
index 00..c43a4b7340
--- /dev/null
+++ b/target/avr/helper.c
@@ -0,0 +1,347 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+
+bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+bool ret = false;
+CPUClass *cc = CPU_GET_CLASS(cs);
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index = ctz32(env->intsrc);
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt */
+cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
+return ret;
+}
+
+void avr_cpu_do_interrupt(CPUState *cs)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+uint32_t ret = env->pc_w;
+int vector = 0;
+int size = avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base = 0;
+
+if (cs->exception_index == EXCP_RESET) {
+vector = 0;
+} else if (env->intsrc != 0) {
+vector = ctz32(env->intsrc) + 1;
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+cpu_stb_data(env, env->sp--, (ret & 0xff) >> 16);
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+} else {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+}
+
+env->pc_w = base + vector * size;
+env->sregI = 0; /* clear Global Interrupt Flag */
+
+cs->exception_index = -1;
+}
+
+int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8

[PATCH v41 06/21] target/avr: Add instruction translation - Data Transfer Instructions

2020-01-18 Thread Michael Rolnik
This includes:
- MOV, MOVW
- LDI, LDS LDX LDY LDZ
- LDDY, LDDZ
- STS, STX STY STZ
- STDY, STDZ
- LPM, LPMX
- ELPM, ELPMX
- SPM, SPMX
- IN, OUT
- PUSH, POP
- XCH
- LAS, LAC LAT

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 986 +
 target/avr/insn.decode |  43 ++
 2 files changed, 1029 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 475f502e72..4a62d9312a 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -1454,3 +1454,989 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
 return true;
 }
 
+/*
+ * Data Transfer Instructions
+ */
+
+/*
+ *  in the gen_set_addr & gen_get_addr functions
+ *  H assumed to be in 0x00ff format
+ *  M assumed to be in 0x00ff format
+ *  L assumed to be in 0x00ff format
+ */
+static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+{
+
+tcg_gen_andi_tl(L, addr, 0x00ff);
+
+tcg_gen_andi_tl(M, addr, 0xff00);
+tcg_gen_shri_tl(M, M, 8);
+
+tcg_gen_andi_tl(H, addr, 0x00ff);
+}
+
+static void gen_set_xaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static void gen_set_yaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
+}
+
+static void gen_set_zaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+}
+
+static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
+{
+TCGv addr = tcg_temp_new_i32();
+
+tcg_gen_deposit_tl(addr, M, H, 8, 8);
+tcg_gen_deposit_tl(addr, L, addr, 8, 16);
+
+return addr;
+}
+
+static TCGv gen_get_xaddr(void)
+{
+return gen_get_addr(cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static TCGv gen_get_yaddr(void)
+{
+return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]);
+}
+
+static TCGv gen_get_zaddr(void)
+{
+return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+}
+
+/*
+ *  Load one byte indirect from data space to register and stores an clear
+ *  the bits in data space specified by the register. The instruction can only
+ *  be used towards internal SRAM.  The data location is pointed to by the Z 
(16
+ *  bits) Pointer Register in the Register File. Memory access is limited to 
the
+ *  current data segment of 64KB. To access another data segment in devices 
with
+ *  more than 64KB data space, the RAMPZ in register in the I/O area has to be
+ *  changed.  The Z-pointer Register is left unchanged by the operation. This
+ *  instruction is especially suited for clearing status bits stored in SRAM.
+ */
+static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr)
+{
+if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) {
+gen_helper_fullwr(cpu_env, data, addr);
+} else {
+tcg_gen_qemu_st8(data, addr, MMU_DATA_IDX); /* mem[addr] = data */
+}
+}
+
+static void gen_data_load(DisasContext *ctx, TCGv data, TCGv addr)
+{
+if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) {
+gen_helper_fullrd(data, cpu_env, addr);
+} else {
+tcg_gen_qemu_ld8u(data, addr, MMU_DATA_IDX); /* data = mem[addr] */
+}
+}
+
+/*
+ *  This instruction makes a copy of one register into another. The source
+ *  register Rr is left unchanged, while the destination register Rd is loaded
+ *  with a copy of Rr.
+ */
+static bool trans_MOV(DisasContext *ctx, arg_MOV *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv Rr = cpu_r[a->rr];
+
+tcg_gen_mov_tl(Rd, Rr);
+
+return true;
+}
+
+/*
+ *  This instruction makes a copy of one register pair into another register
+ *  pair. The source register pair Rr+1:Rr is left unchanged, while the
+ *  destination register pair Rd+1:Rd is loaded with a copy of Rr + 1:Rr.  This
+ *  instruction is not available in all devices. Refer to the device specific
+ *  instruction set summary.
+ */
+static bool trans_MOVW(DisasContext *ctx, arg_MOVW *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_MOVW)) {
+return true;
+}
+
+TCGv RdL = cpu_r[a->rd];
+TCGv RdH = cpu_r[a->rd + 1];
+TCGv RrL = cpu_r[a->rr];
+TCGv RrH = cpu_r[a->rr + 1];
+
+tcg_gen_mov_tl(RdH, RrH);
+tcg_gen_mov_tl(RdL, RrL);
+
+return true;
+}
+
+/*
+ * Loads an 8 bit constant directly to register 16 to 31.
+ */
+static bool trans_LDI(DisasContext *ctx, arg_LDI *a)
+{
+TCGv Rd = cpu_r[a->rd];
+int imm = a->imm;
+
+tcg_gen_movi_tl(Rd, imm);
+
+return true;
+}
+
+/*
+ *  Loads one byte from the data space to a register. For parts with SRAM,
+ *  the data space consists of the Register File, I/O memory and internal SRAM
+ *  (and external SRAM if applicable). For parts without SRAM, the data space
+ *  consists of the register file only. The EEPROM has a separate address 
space.
+ *  A 16-bit address must be supplied. Memory access is limited to the current
+ *  data segment of 64KB. The LDS instruction uses the RAMPD Register to access
+ *  memory above 64KB. To access ano

[PATCH v41 14/21] hw/avr: Add example board configuration

2020-01-18 Thread Michael Rolnik
A simple board setup that configures an AVR CPU to run a given firmware image.
This is all that's useful to implement without peripheral emulation as AVR CPUs 
include a lot of on-board peripherals.

NOTE: this is not a real board 
NOTE: it's used for CPU testing

Signed-off-by: Michael Rolnik 
Reviewed-by: Aleksandar Markovic 
Nacked-by: Philippe Mathieu-Daudé 
---
 include/elf.h|   2 +
 include/hw/elf_ops.h |   6 +-
 include/hw/loader.h  |   6 +-
 hw/avr/sample.c  | 295 +++
 hw/core/loader.c |  15 ++-
 hw/riscv/boot.c  |   2 +-
 hw/Kconfig   |   1 +
 hw/avr/Kconfig   |   6 +
 hw/avr/Makefile.objs |   1 +
 9 files changed, 323 insertions(+), 11 deletions(-)
 create mode 100644 hw/avr/sample.c
 create mode 100644 hw/avr/Kconfig
 create mode 100644 hw/avr/Makefile.objs

diff --git a/include/elf.h b/include/elf.h
index 3501e0c8d0..53cdfa23b7 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -202,6 +202,8 @@ typedef struct mips_elf_abiflags_v0 {
 #define EM_MOXIE   223 /* Moxie processor family */
 #define EM_MOXIE_OLD   0xFEED
 
+#define EM_AVR 83 /* AVR 8-bit microcontroller */
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL0
 #define DT_NEEDED  1
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index e07d276df7..70de85fa72 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -316,7 +316,8 @@ static int glue(load_elf, SZ)(const char *name, int fd,
   void *translate_opaque,
   int must_swab, uint64_t *pentry,
   uint64_t *lowaddr, uint64_t *highaddr,
-  int elf_machine, int clear_lsb, int data_swab,
+  uint32_t *pe_flags, int elf_machine,
+  int clear_lsb, int data_swab,
   AddressSpace *as, bool load_rom,
   symbol_fn_t sym_cb)
 {
@@ -594,6 +595,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
 }
 }
 
+if (pe_flags) {
+*pe_flags = (uint32_t)(elf_sword)ehdr.e_flags;
+}
 if (lowaddr)
 *lowaddr = (uint64_t)(elf_sword)low;
 if (highaddr)
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 48a96cd559..22b59e15ba 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -101,6 +101,7 @@ const char *load_elf_strerror(int error);
  * @pentry: Populated with program entry point. Ignored if NULL.
  * @lowaddr: Populated with lowest loaded address. Ignored if NULL.
  * @highaddr: Populated with highest loaded address. Ignored if NULL.
+ * @pe_flags: Populated with e_flags. Ignore if NULL.
  * @bigendian: Expected ELF endianness. 0 for LE otherwise BE
  * @elf_machine: Expected ELF machine type
  * @clear_lsb: Set to mask off LSB of addresses (Some architectures use
@@ -131,8 +132,9 @@ int load_elf_ram_sym(const char *filename,
  uint64_t (*elf_note_fn)(void *, void *, bool),
  uint64_t (*translate_fn)(void *, uint64_t),
  void *translate_opaque, uint64_t *pentry,
- uint64_t *lowaddr, uint64_t *highaddr, int big_endian,
- int elf_machine, int clear_lsb, int data_swab,
+ uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pe_flags,
+ int big_endian, int elf_machine,
+ int clear_lsb, int data_swab,
  AddressSpace *as, bool load_rom, symbol_fn_t sym_cb);
 
 /** load_elf_ram:
diff --git a/hw/avr/sample.c b/hw/avr/sample.c
new file mode 100644
index 00..95094a8d6c
--- /dev/null
+++ b/hw/avr/sample.c
@@ -0,0 +1,295 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ *  NOTE:
+ *  This is not a real AVR board, this is an example!
+ *  The CPU is an approximation of an ATmega2560, but is missing various
+ *  built-in peripherals.
+ *
+ *  This example board loads provided binary file into flash memory and
+ *  executes it from 0x address in the code memory space.
+ *
+ *  Currently used for AVR CPU validation
+ *
+ */
+
+#include 

[PATCH v41 00/21] QEMU AVR 8 bit cores

2020-01-18 Thread Michael Rolnik
This series of patches adds 8bit AVR cores to QEMU.
All instruction, except BREAK/DES/SPM/SPMX, are implemented. Not fully tested 
yet.
However I was able to execute simple code with functions. e.g fibonacci 
calculation.
This series of patches include a non real, sample board.
No fuses support yet. PC is set to 0 at reset.

Following are examples of possible usages, assuming program.elf is compiled for 
AVR cpu
1.  Continious non interrupted execution
run `qemu-system-avr -kernel program.elf` 
2.  Continious non interrupted execution with serial output into telnet window
run `qemu-system-avr -kernel program.elf -serial tcp::5678,server,nowait 
-nographic `
run `telent localhost 5678`
3.  Continious non interrupted execution with serial output into stdout
run `qemu-system-avr -kernel program.elf -serial stdio`
4.  Debugging wit GDB debugger
run `qemu-system-avr -kernel program.elf -s -S`
run `avr-gdb program.elf` and then within GDB shell `target remote :1234`
5.  Print out executed instructions
run `qemu-system-avr -kernel program.elf -d in_asm` 


the patches include the following
1. just a basic 8bit AVR CPU, without instruction decoding or translation
2. CPU features which allow define the following 8bit AVR cores
 avr1
 avr2 avr25
 avr3 avr31 avr35
 avr4
 avr5 avr51
 avr6
 xmega2 xmega4 xmega5 xmega6 xmega7
3. a definition of sample machine with SRAM, FLASH and CPU which allows to 
execute simple code
4. encoding for all AVR instructions
5. interrupt handling
6. helpers for IN, OUT, SLEEP, WBR & unsupported instructions
7. a decoder which given an opcode decides what istruction it is
8. translation of AVR instruction into TCG
9. all features together

changes since v3
1. rampD/X/Y/Z registers are encoded as 0x00ff (instead of 0x00ff) for 
faster address manipulaton
2. ffs changed to ctz32
3. duplicate code removed at avr_cpu_do_interrupt
4. using andc instead of not + and
5. fixing V flag calculation in varios instructions
6. freeing local variables in PUSH
7. tcg_const_local_i32 -> tcg_const_i32
8. using sextract32 instead of my implementation
9. fixing BLD instruction
10.xor(r) instead of 0xff - r at COM
11.fixing MULS/MULSU not to modify inputs' content
12.using SUB for NEG
13.fixing tcg_gen_qemu_ld/st call in XCH

changes since v4
1. target is now defined as big endian in order to optimize push_ret/pop_ret
2. all style warnings are fixed
3. adding cpu_set/get_sreg functions
4. simplifying gen_goto_tb as there is no real paging
5. env->pc -> env->pc_w
6. making flag dump more compact
7. more spacing
8. renaming CODE/DATA_INDEX -> MMU_CODE/DATA_IDX
9. removing avr_set_feature
10. SPL/SPH set bug fix
11. switching stb_phys to cpu_stb_data
12. cleaning up avr_decode
13. saving sreg, rampD/X/Y/Z, eind in HW format (savevm)
14. saving CPU features (savevm)

changes since v5
1. BLD bug fix
2. decoder generator is added

chages since v6
1. using cpu_get_sreg/cpu_set_sreg in 
avr_cpu_gdb_read_register/avr_cpu_gdb_write_register
2. configure the target as little endian because otherwise GDB does not work
3. fixing and testing gen_push_ret/gen_pop_ret

changes since v7
1. folding back v6
2. logging at helper_outb and helper_inb are done for non supported yet 
registers only
3. MAINTAINERS updated

changes since v8
1. removing hw/avr from hw/Makefile.obj as it should not be built for all
2. making linux compilable
3. testing on
a. Mac, Apple LLVM version 7.0.0
b. Ubuntu 12.04, gcc 4.9.2
c. Fedora 23, gcc 5.3.1
4. folding back some patches
5. translation bug fixes for ORI, CPI, XOR instructions
6. propper handling of cpu register writes though memory

changes since v9
1. removing forward declarations of static functions
2. disabling debug prints
3. switching to case range instead of if else if ...
4. LD/ST IN/OUT accessing CPU maintainder registers are not routed to any device
5. commenst about sample board and sample IO device added
6. sample board description is more descriptive now
7. memory_region_allocate_system_memory is used to create RAM
8. now there are helper_fullrd & helper_fullwr when LD/ST try to access 
registers

changes since v10
1. movig back fullwr & fullrd into the commit where outb and inb were introduced
2. changing tlb_fill function signature
3. adding empty line between functions
4. adding newline on the last line of the file
5. using tb->flags to generae full access ST/LD instructions
6. fixing SBRC bug
7. folding back 10th commit
8. whenever a new file is introduced it's added to Makefile.objs

changes since v11
1. updating to v2.7.0-rc
2. removing assignment to env->fullacc from gen_intermediate_code

changes since v12
1. fixing spacing
2. fixing get/put_segment functions
3. removing target-avr/machine.h file
4. VMSTATE_SINGLE_TEST -> VMSTATE_SINGLE
5. comment spelling
6. removing hw/avr/sample_io.c
7. char const* -> const char*
8. proper ram allocation
9. fixing breakpoint functionality.
10.env1 -> env
11.fix

[PATCH 0/4] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC

2020-01-18 Thread Philippe Mathieu-Daudé
This series add a test on the OrangePi PC for:
- SD Card booting
- U-boot & UART
- NetBSD 9

I simply followed Niek description in docs/orangepi.rst:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg669347.html

The sdcard image is big, but the test runs very quick (1min),
even on Travis CI: https://travis-ci.org/philmd/qemu/jobs/638823612#L3778

(11/48) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_uboot_netbsd9:
  PASS (65.17 s)

  $ TMPDIR=/tmp AVOCADO_ALLOW_LARGE_STORAGE=yes avocado --show=app,console run 
-t machine:orangepi-pc tests/acceptance/boot_linux_console.py
  JOB ID : 4e11f0d22d121fd766ab5f0956ec464cf9fce64b
  JOB LOG: 
/home/phil/avocado/job-results/job-2020-01-18T19.14-4e11f0d/job.log
   (1/1) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_uboot_netbsd9:
  console: U-Boot SPL 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +)
  console: DRAM: 1024 MiB
  console: Failed to set core voltage! Can't set CPU frequency
  console: Trying to boot from MMC1
  console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) Allwinner 
Technology
  console: CPU:   Allwinner H3 (SUN8I )
  console: Model: Xunlong Orange Pi Plus / Plus 2
  console: DRAM:  1 GiB
  console: MMC:   Device 'mmc@1c11000': seq 1 is in use by 'mmc@1c1'
  console: mmc@1c0f000: 0, mmc@1c1: 2, mmc@1c11000: 1
  console: Loading Environment from FAT... Warning: HDMI PHY init timeout!
  console: Warning: HDMI PHY init timeout!
  console: In:serial
  console: Out:   serial
  console: Err:   serial
  console: Net:   phy interface7
  console: Could not get PHY for ethernet@1c3: addr 0
  console: No ethernet found.
  console: starting USB...
  console: Bus usb@1c1b000: USB EHCI 1.00
  console: Bus usb@1c1d000: USB EHCI 1.00
  console: scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
  console: scanning bus usb@1c1d000 for devices... 1 USB Device(s) found
  console: scanning usb for storage devices... 0 Storage Device(s) found
  console: Hit any key to stop autoboot:  0
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: =>
  console: => setenv bootargs root=ld0a
  console: => setenv kernel netbsd-GENERIC.ub
  console: => setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb
  console: => setenv bootcmd 'fatload mmc 0:1 ${kernel_addr_r} ${kernel}; 
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}; fdt addr ${fdt_addr_r}; bootm 
${kernel_addr_r} - ${fdt_addr_r}'
  console: => boot
  console: 8850008 bytes read in 2583 ms (3.3 MiB/s)
  console: 28162 bytes read in 34 ms (808.6 KiB/s)
  console: ## Booting kernel from Legacy Image at 4200 ...
  console: Image Name:   NetBSD/earmv7hf 9.0_RC1
  console: Image Type:   ARM Linux Kernel Image (no loading done) (uncompressed)
  console: Data Size:8849944 Bytes = 8.4 MiB
  console: Load Address: 
  console: Entry Point:  
  console: Verifying Checksum ... OK
  console: ## Flattened Device Tree blob at 4300
  console: Booting using the fdt blob at 0x4300
  console: XIP Kernel Image (no loading done)
  console: Loading Device Tree to 49ff6000, end 49fffe01 ... OK
  console: Starting kernel ...
  console: [   1.000] NetBSD/evbarm (fdt) booting ...
  console: [   1.000] [ Kernel symbol table missing! ]
  console: [   1.000] Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 
2002, 2003, 2004, 2005,
  console: [   1.000] 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 
2014, 2015, 2016, 2017,
  console: [   1.000] 2018, 2019 The NetBSD Foundation, Inc.  All 
rights reserved.
  console: [   1.000] Copyright (c) 1982, 1986, 1989, 1991, 1993
  console: [   1.000] The Regents of the University of California.  All 
rights reserved.
  console: [   1.000] NetBSD 9.0_RC1 (GENERIC) #0: Wed Nov 27 16:14:52 UTC 
2019
  console: [   1.000] 
mkre...@mkrepro.netbsd.org:/usr/src/sys/arch/evbarm/compile/GENERIC
  console: [   1.000] total memory = 1024 MB
  console: [   1.000] avail memory = 1003 MB
  console: [   1.000] armfdt0 (root)
  console: [   1.000] simplebus0 at armfdt0: Xunlong Orange Pi PC
  console: [   1.000] simplebus1 at simplebus0
  console: [   1.000] simplebus2 at simplebus0
  console: [   1.000] cpus0 at simplebus0
  console: [   1.000] simplebus3 at simplebus0
  console: [   1.000] cpu0 at cpus0: Cortex-A7 r0p5 (Cortex V7A core)
  console: [   1.000] cpu0: DC enabled IC enabled WB enabled LABT branch 
prediction enabled
  console: [   1.000] cpu0: 32KB/64B 2-way L1 VIPT Instruction cache
  console: [   1.000] cpu0: 32KB/64B 2-way write-back-locking-C L1 PIPT 
Data cache
  console: [   1.000] cpu0: 2304KB/64B 16-way write-through L2 PIPT Unified 
cache
  console: [   1.000] vfp

[PATCH v41 01/21] target/avr: Add outward facing interfaces and core CPU logic

2020-01-18 Thread Michael Rolnik
This includes:
- CPU data structures
- object model classes and functions
- migration functions
- GDB hooks

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu-param.h |  37 ++
 target/avr/cpu-qom.h   |  54 +++
 target/avr/cpu.h   | 258 +
 target/avr/cpu.c   | 826 +
 target/avr/gdbstub.c   |  84 +
 target/avr/machine.c   | 121 ++
 gdb-xml/avr-cpu.xml|  49 +++
 7 files changed, 1429 insertions(+)
 create mode 100644 target/avr/cpu-param.h
 create mode 100644 target/avr/cpu-qom.h
 create mode 100644 target/avr/cpu.h
 create mode 100644 target/avr/cpu.c
 create mode 100644 target/avr/gdbstub.c
 create mode 100644 target/avr/machine.c
 create mode 100644 gdb-xml/avr-cpu.xml

diff --git a/target/avr/cpu-param.h b/target/avr/cpu-param.h
new file mode 100644
index 00..0c29ce4223
--- /dev/null
+++ b/target/avr/cpu-param.h
@@ -0,0 +1,37 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef AVR_CPU_PARAM_H
+#define AVR_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 32
+/*
+ * TARGET_PAGE_BITS cannot be more than 8 bits because
+ * 1.  all IO registers occupy [0x .. 0x00ff] address range, and they
+ * should be implemented as a device and not memory
+ * 2.  SRAM starts at the address 0x0100
+ */
+#define TARGET_PAGE_BITS 8
+#define TARGET_PHYS_ADDR_SPACE_BITS 24
+#define TARGET_VIRT_ADDR_SPACE_BITS 24
+#define NB_MMU_MODES 2
+
+
+#endif
diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h
new file mode 100644
index 00..e28b58c897
--- /dev/null
+++ b/target/avr/cpu-qom.h
@@ -0,0 +1,54 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef QEMU_AVR_QOM_H
+#define QEMU_AVR_QOM_H
+
+#include "hw/core/cpu.h"
+
+#define TYPE_AVR_CPU "avr-cpu"
+
+#define AVR_CPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(AVRCPUClass, (klass), TYPE_AVR_CPU)
+#define AVR_CPU(obj) \
+OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU)
+#define AVR_CPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AVRCPUClass, (obj), TYPE_AVR_CPU)
+
+/**
+ *  AVRCPUClass:
+ *  @parent_realize: The parent class' realize handler.
+ *  @parent_reset: The parent class' reset handler.
+ *  @vr: Version Register value.
+ *
+ *  A AVR CPU model.
+ */
+typedef struct AVRCPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+} AVRCPUClass;
+
+typedef struct AVRCPU AVRCPU;
+
+
+#endif /* !defined (QEMU_AVR_CPU_QOM_H) */
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
new file mode 100644
index 00..b74bcf01ae
--- /dev/null
+++ b/target/avr/cpu.h
@@ -0,0 +1,258 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 

[PATCH 3/4] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC

2020-01-18 Thread Philippe Mathieu-Daudé
This test boots U-Boot then NetBSD (stored on a SD card) on
a OrangePi PC board.

As it requires ~1.3GB of storage, it is disabled by default.

U-Boot is built by the Debian project [1], and the SD card image
is provided by the NetBSD organization [2].

Once the compressed SD card image is downloaded (304MB) and
extracted, this test is fast:

  $ AVOCADO_ALLOW_LARGE_STORAGE=yes \
avocado --show=app,console run -t machine:orangepi-pc \
  tests/acceptance/boot_linux_console.py
  console: U-Boot SPL 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +)
  console: DRAM: 1024 MiB
  console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +) Allwinner 
Technology
  console: CPU:   Allwinner H3 (SUN8I )
  console: scanning bus usb@1c1b000 for devices... 1 USB Device(s) found
  console: scanning bus usb@1c1d000 for devices... 1 USB Device(s) found
  console: scanning usb for storage devices... 0 Storage Device(s) found
  console: Hit any key to stop autoboot:  0
  console: => setenv bootargs root=ld0a
  console: => setenv kernel netbsd-GENERIC.ub
  console: => setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb
  console: => boot
  console: ## Booting kernel from Legacy Image at 4200 ...
  console: Image Name:   NetBSD/earmv7hf 9.0_RC1
  console: Image Type:   ARM Linux Kernel Image (no loading done) (uncompressed)
  console: XIP Kernel Image (no loading done)
  console: Loading Device Tree to 49ff6000, end 49fffe01 ... OK
  console: Starting kernel ...
  console: [   1.000] NetBSD/evbarm (fdt) booting ...
  console: [   1.000] NetBSD 9.0_RC1 (GENERIC) #0: Wed Nov 27 16:14:52 UTC 
2019
  console: [   1.000] simplebus0 at armfdt0: Xunlong Orange Pi PC
  console: [   1.000] cpu0 at cpus0: Cortex-A7 r0p5 (Cortex V7A core)
  console: [   1.000] cpu0: DC enabled IC enabled WB enabled LABT branch 
prediction enabled
  console: [   1.000] cpu0: 32KB/64B 2-way L1 VIPT Instruction cache
  console: [   1.000] cpu0: 32KB/64B 2-way write-back-locking-C L1 PIPT 
Data cache
  console: [   1.000] cpu0: 2304KB/64B 16-way write-through L2 PIPT Unified 
cache
  console: [   1.000] vfp0 at cpu0: NEON MPE (VFP 3.0+), rounding, NaN 
propagation, denormals
  ...
  console: [   2.8171937] sdmmc0: SD card status: 4-bit, C0
  console: [   2.8234040] ld0 at sdmmc0: 
<0xaa:0x5859:QEMU!:0x01:0xdeadbeef:0x062>
  console: [   2.8743967] ld0: 1290 MB, 655 cyl, 64 head, 63 sec, 512 
bytes/sect x 2642944 sectors
  console: [   3.1588850] ld0: 4-bit width, High-Speed/SDR25, 50.000 MHz
  console: [   4.9942260] WARNING: 4 errors while detecting hardware; check 
system log.
  console: [   5.0142912] boot device: ld0
  console: [   5.0551260] root on ld0a dumps on ld0b
  console: [   5.2175484] root file system type: ffs
  console: [   5.2858559] kern.module.path=/stand/evbarm/9.0/modules
  console: Tue Jan 18 18:15:15 UTC 2050
  console: Starting root file system check:
  PASS (35.96 s)
  RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
  JOB TIME   : 36.09 s

Note, this test only took ~65 seconds to run on Travis-CI, see: [3].

This test is based on a description from Niek Linnenbank from [4].

[1] 
https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot
[2] https://wiki.netbsd.org/ports/evbarm/allwinner/
[3] https://travis-ci.org/philmd/qemu/jobs/638823612#L3778
[4] https://www.mail-archive.com/qemu-devel@nongnu.org/msg669347.html

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/boot_linux_console.py | 63 ++
 1 file changed, 63 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 55d0b8b036..56d3d6e9eb 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -16,6 +16,7 @@ import shutil
 from avocado import skipUnless
 from avocado_qemu import Test
 from avocado_qemu import exec_command_and_wait_for_pattern
+from avocado_qemu import interrupt_interactive_console_until_pattern
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import process
 from avocado.utils import archive
@@ -551,6 +552,68 @@ class BootLinuxConsole(Test):
   'to ')
 self.wait_for_console_pattern('Starting Load Kernel Modules...')
 
+@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
+def test_arm_orangepi_uboot_netbsd9(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+"""
+# This test download a 304MB compressed image and expand it to 1.3GB...
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20200108T145233Z/pool/main/u/u-boot/'
+   'u-boot-sunxi_2020.01%2Bdfsg-1_armhf.deb')
+deb_hash = 'f67f404a80753ca3d1258f13e38f2b060e13db99'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+# We use the 

[PATCH 2/4] Acceptance tests: Add interrupt_interactive_console_until_pattern()

2020-01-18 Thread Philippe Mathieu-Daudé
We need a function to interrupt interactive consoles.

Example: Interrupt U-Boot to set different environment values.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 32 +--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 0a50fcf2be..d4358eb431 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -56,13 +56,15 @@ def pick_default_qemu_bin(arch=None):
 
 
 def _console_interaction(test, success_message, failure_message,
- send_string):
+ send_string, keep_sending=False):
+assert not keep_sending or send_string
 console = test.vm.console_socket.makefile()
 console_logger = logging.getLogger('console')
 while True:
 if send_string:
 test.vm.console_socket.sendall(send_string.encode())
-send_string = None # send only once
+if not keep_sending:
+send_string = None # send only once
 msg = console.readline().strip()
 if not msg:
 continue
@@ -74,6 +76,32 @@ def _console_interaction(test, success_message, 
failure_message,
 fail = 'Failure message found in console: %s' % failure_message
 test.fail(fail)
 
+def interrupt_interactive_console_until_pattern(test, success_message,
+failure_message=None,
+interrupt_string='\r'):
+"""
+Keep sending a string to interrupt a console prompt, while logging the
+console output. Typical use case is to break a boot loader prompt, such:
+
+Press a key within 5 seconds to interrupt boot process.
+5
+4
+3
+2
+1
+Booting default image...
+
+:param test: an Avocado test containing a VM that will have its console
+ read and probed for a success or failure message
+:type test: :class:`avocado_qemu.Test`
+:param success_message: if this message appears, test succeeds
+:param failure_message: if this message appears, test fails
+:param interrupt_string: a string to send to the console before trying
+ to read a new line
+"""
+_console_interaction(test, success_message, failure_message,
+ interrupt_string, True)
+
 def wait_for_console_pattern(test, success_message, failure_message=None):
 """
 Waits for messages to appear on the console, while logging the content
-- 
2.21.1




[PATCH 1/4] Acceptance tests: Extract _console_interaction()

2020-01-18 Thread Philippe Mathieu-Daudé
Since we are going to re-use the code shared between
wait_for_console_pattern() and exec_command_and_wait_for_pattern(),
extract the common part into a local function.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/avocado_qemu/__init__.py | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 6618ea67c1..0a50fcf2be 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -55,19 +55,14 @@ def pick_default_qemu_bin(arch=None):
 return qemu_bin_from_src_dir_path
 
 
-def wait_for_console_pattern(test, success_message, failure_message=None):
-"""
-Waits for messages to appear on the console, while logging the content
-
-:param test: an Avocado test containing a VM that will have its console
- read and probed for a success or failure message
-:type test: :class:`avocado_qemu.Test`
-:param success_message: if this message appears, test succeeds
-:param failure_message: if this message appears, test fails
-"""
+def _console_interaction(test, success_message, failure_message,
+ send_string):
 console = test.vm.console_socket.makefile()
 console_logger = logging.getLogger('console')
 while True:
+if send_string:
+test.vm.console_socket.sendall(send_string.encode())
+send_string = None # send only once
 msg = console.readline().strip()
 if not msg:
 continue
@@ -79,6 +74,17 @@ def wait_for_console_pattern(test, success_message, 
failure_message=None):
 fail = 'Failure message found in console: %s' % failure_message
 test.fail(fail)
 
+def wait_for_console_pattern(test, success_message, failure_message=None):
+"""
+Waits for messages to appear on the console, while logging the content
+
+:param test: an Avocado test containing a VM that will have its console
+ read and probed for a success or failure message
+:type test: :class:`avocado_qemu.Test`
+:param success_message: if this message appears, test succeeds
+:param failure_message: if this message appears, test fails
+"""
+_console_interaction(test, success_message, failure_message, None)
 
 def exec_command_and_wait_for_pattern(test, command,
   success_message, failure_message=None):
@@ -94,10 +100,7 @@ def exec_command_and_wait_for_pattern(test, command,
 :param success_message: if this message appears, test succeeds
 :param failure_message: if this message appears, test fails
 """
-command += '\r'
-test.vm.console_socket.sendall(command.encode())
-wait_for_console_pattern(test, success_message, failure_message)
-
+_console_interaction(test, success_message, failure_message, command + 
'\r')
 
 class Test(avocado.Test):
 def _get_unique_tag_val(self, tag_name):
-- 
2.21.1




[PATCH 4/4] .travis.yml: Allow untrusted code and large files

2020-01-18 Thread Philippe Mathieu-Daudé
As Travis CI runs our tests in a disposable environment, we don't
care much if the binaries are trusted. The more we test the better.

Also, as of this commmit, the smallest available announced [1] is
"approx 18GB", plenty of space to run our acceptance tests.

Enable the proper environment variables to allow Avocado download
from untrusted sources, and to download large files.

Note: As of this commit, all our tests "Ran for 17 min 7 sec"
before succeeding, see [2].

[1] 
https://docs.travis-ci.com/user/reference/overview/#virtualisation-environment-vs-operating-system
[2] https://travis-ci.org/philmd/qemu/jobs/638823612#L3817

Signed-off-by: Philippe Mathieu-Daudé 
---
 .travis.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 638fba4799..b8b9df65a6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -260,6 +260,8 @@ matrix:
 
 # Acceptance (Functional) tests
 - env:
+- AVOCADO_ALLOW_LARGE_STORAGE="yes"
+- AVOCADO_ALLOW_UNTRUSTED_CODE="sure"
 - CONFIG="--python=/usr/bin/python3 
--target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu"
 - TEST_CMD="make check-acceptance"
   after_failure:
-- 
2.21.1




[PATCH v3 5/5] qcow2: Use BDRV_SECTOR_SIZE instead of the hardcoded value

2020-01-18 Thread Alberto Garcia
This replaces all remaining instances in the qcow2 code.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index a6b0d4ee1d..6cc13e388c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3273,7 +3273,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, 
Error **errp)
 
 /* Validate options and set default values */
 if (!QEMU_IS_ALIGNED(qcow2_opts->size, BDRV_SECTOR_SIZE)) {
-error_setg(errp, "Image size must be a multiple of 512 bytes");
+error_setg(errp, "Image size must be a multiple of %u bytes",
+   (unsigned) BDRV_SECTOR_SIZE);
 ret = -EINVAL;
 goto out;
 }
@@ -3947,8 +3948,9 @@ static int coroutine_fn 
qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
 return -ENOTSUP;
 }
 
-if (offset & 511) {
-error_setg(errp, "The new size must be a multiple of 512");
+if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
+error_setg(errp, "The new size must be a multiple of %u",
+   (unsigned) BDRV_SECTOR_SIZE);
 return -EINVAL;
 }
 
-- 
2.20.1




[PATCH v3 1/5] qcow2: Don't round the L1 table allocation up to the sector size

2020-01-18 Thread Alberto Garcia
The L1 table is read from disk using the byte-based bdrv_pread() and
is never accessed beyond its last element, so there's no need to
allocate more memory than that.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2-cluster.c  | 5 ++---
 block/qcow2-refcount.c | 2 +-
 block/qcow2-snapshot.c | 3 +--
 block/qcow2.c  | 2 +-
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 8982b7b762..932fc48919 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -124,12 +124,11 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t 
min_size,
 #endif
 
 new_l1_size2 = sizeof(uint64_t) * new_l1_size;
-new_l1_table = qemu_try_blockalign(bs->file->bs,
-   ROUND_UP(new_l1_size2, 512));
+new_l1_table = qemu_try_blockalign(bs->file->bs, new_l1_size2);
 if (new_l1_table == NULL) {
 return -ENOMEM;
 }
-memset(new_l1_table, 0, ROUND_UP(new_l1_size2, 512));
+memset(new_l1_table, 0, new_l1_size2);
 
 if (s->l1_size) {
 memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index f67ac6b2d8..c963bc8de1 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1262,7 +1262,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
  * l1_table_offset when it is the current s->l1_table_offset! Be careful
  * when changing this! */
 if (l1_table_offset != s->l1_table_offset) {
-l1_table = g_try_malloc0(ROUND_UP(l1_size2, 512));
+l1_table = g_try_malloc0(l1_size2);
 if (l1_size2 && l1_table == NULL) {
 ret = -ENOMEM;
 goto fail;
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 5ab64da1ec..82c32d4c9b 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -1024,8 +1024,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
 return ret;
 }
 new_l1_bytes = sn->l1_size * sizeof(uint64_t);
-new_l1_table = qemu_try_blockalign(bs->file->bs,
-   ROUND_UP(new_l1_bytes, 512));
+new_l1_table = qemu_try_blockalign(bs->file->bs, new_l1_bytes);
 if (new_l1_table == NULL) {
 return -ENOMEM;
 }
diff --git a/block/qcow2.c b/block/qcow2.c
index cef9d72b3a..ba71a815b6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1492,7 +1492,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState 
*bs, QDict *options,
 
 if (s->l1_size > 0) {
 s->l1_table = qemu_try_blockalign(bs->file->bs,
-ROUND_UP(s->l1_size * sizeof(uint64_t), 512));
+  s->l1_size * sizeof(uint64_t));
 if (s->l1_table == NULL) {
 error_setg(errp, "Could not allocate L1 table");
 ret = -ENOMEM;
-- 
2.20.1




[PATCH v3 3/5] qcow2: Use bs->bl.request_alignment when updating an L1 entry

2020-01-18 Thread Alberto Garcia
When updating an L1 entry the qcow2 driver writes a (512-byte) sector
worth of data to avoid a read-modify-write cycle. Instead of always
writing 512 bytes we should follow the alignment requirements of the
storage backend.

(the only exception is when the alignment is larger than the cluster
size because then we could be overwriting data after the L1 table)

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 932fc48919..f1b5535b04 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -216,26 +216,31 @@ static int l2_load(BlockDriverState *bs, uint64_t offset,
 }
 
 /*
- * Writes one sector of the L1 table to the disk (can't update single entries
- * and we really don't want bdrv_pread to perform a read-modify-write)
+ * Writes an L1 entry to disk (note that depending on the alignment
+ * requirements this function may write more that just one entry in
+ * order to prevent bdrv_pwrite from performing a read-modify-write)
  */
-#define L1_ENTRIES_PER_SECTOR (512 / 8)
 int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
 {
 BDRVQcow2State *s = bs->opaque;
-uint64_t buf[L1_ENTRIES_PER_SECTOR] = { 0 };
 int l1_start_index;
 int i, ret;
+int bufsize = MAX(sizeof(uint64_t),
+  MIN(bs->file->bs->bl.request_alignment, 
s->cluster_size));
+int nentries = bufsize / sizeof(uint64_t);
+g_autofree uint64_t *buf = g_try_new0(uint64_t, nentries);
 
-l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
-for (i = 0; i < L1_ENTRIES_PER_SECTOR && l1_start_index + i < s->l1_size;
- i++)
-{
+if (buf == NULL) {
+return -ENOMEM;
+}
+
+l1_start_index = QEMU_ALIGN_DOWN(l1_index, nentries);
+for (i = 0; i < MIN(nentries, s->l1_size - l1_start_index); i++) {
 buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
 }
 
 ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
-s->l1_table_offset + 8 * l1_start_index, sizeof(buf), false);
+s->l1_table_offset + 8 * l1_start_index, bufsize, false);
 if (ret < 0) {
 return ret;
 }
@@ -243,7 +248,7 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
 BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
 ret = bdrv_pwrite_sync(bs->file,
s->l1_table_offset + 8 * l1_start_index,
-   buf, sizeof(buf));
+   buf, bufsize);
 if (ret < 0) {
 return ret;
 }
-- 
2.20.1




[PATCH v3 2/5] qcow2: Tighten cluster_offset alignment assertions

2020-01-18 Thread Alberto Garcia
qcow2_alloc_cluster_offset() and qcow2_get_cluster_offset() always
return offsets that are cluster-aligned so don't just check that they
are sector-aligned.

The check in qcow2_co_preadv_task() is also replaced by an assertion
for the same reason.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index ba71a815b6..100393fd3b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2168,10 +2168,7 @@ static coroutine_fn int 
qcow2_co_preadv_task(BlockDriverState *bs,
   offset, bytes, qiov, qiov_offset);
 
 case QCOW2_CLUSTER_NORMAL:
-if ((file_cluster_offset & 511) != 0) {
-return -EIO;
-}
-
+assert(offset_into_cluster(s, file_cluster_offset) == 0);
 if (bs->encrypted) {
 return qcow2_co_preadv_encrypted(bs, file_cluster_offset,
  offset, bytes, qiov, qiov_offset);
@@ -2507,7 +2504,7 @@ static coroutine_fn int qcow2_co_pwritev_part(
 goto out_locked;
 }
 
-assert((cluster_offset & 511) == 0);
+assert(offset_into_cluster(s, cluster_offset) == 0);
 
 ret = qcow2_pre_write_overlap_check(bs, 0,
 cluster_offset + offset_in_cluster,
@@ -3897,7 +3894,7 @@ qcow2_co_copy_range_to(BlockDriverState *bs,
 goto fail;
 }
 
-assert((cluster_offset & 511) == 0);
+assert(offset_into_cluster(s, cluster_offset) == 0);
 
 ret = qcow2_pre_write_overlap_check(bs, 0,
 cluster_offset + offset_in_cluster, cur_bytes, true);
-- 
2.20.1




[PATCH v3 0/5] Misc BDRV_SECTOR_SIZE updates

2020-01-18 Thread Alberto Garcia
This series gets rid of all the remaining instances of hardcoded
sector sizes in the qcow2 code and adds a check for images whose
virtual size is not a multiple of the sector size.

See the individual patches for details.

Berto

v3:
- Patch 2: Use offset_into_cluster() instead of QEMU_IS_ALIGNED
- Patch 3: Rewrite qcow2_write_l1_entry() to use bl.request_alignment [Kevin]
- Patch 4: Remove alignment check in qcow2_co_copy_range_from()

v2: https://lists.gnu.org/archive/html/qemu-block/2020-01/msg00169.html
- Modify output of iotest 080 to make it easier to understand [Nir]
- Use the QEMU_IS_ALIGNED() macro instead of the modulus operator [Nir]
- Tighten some assertions [Kevin]

v1: https://lists.gnu.org/archive/html/qemu-block/2020-01/msg00139.html

Alberto Garcia (5):
  qcow2: Don't round the L1 table allocation up to the sector size
  qcow2: Tighten cluster_offset alignment assertions
  qcow2: Use bs->bl.request_alignment when updating an L1 entry
  qcow2: Don't require aligned offsets in qcow2_co_copy_range_from()
  qcow2: Use BDRV_SECTOR_SIZE instead of the hardcoded value

 block/qcow2-cluster.c  | 30 +-
 block/qcow2-refcount.c |  2 +-
 block/qcow2-snapshot.c |  3 +--
 block/qcow2.c  | 23 +--
 4 files changed, 28 insertions(+), 30 deletions(-)

-- 
2.20.1




[PATCH v3 4/5] qcow2: Don't require aligned offsets in qcow2_co_copy_range_from()

2020-01-18 Thread Alberto Garcia
qemu-img's convert_co_copy_range() operates at the sector level and
block_copy() operates at the cluster level so this condition is always
true, but it is not necessary to restrict this here, so let's leave it
to the driver implementation return an error if there is any.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 100393fd3b..a6b0d4ee1d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3829,10 +3829,6 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
 case QCOW2_CLUSTER_NORMAL:
 child = s->data_file;
 copy_offset += offset_into_cluster(s, src_offset);
-if ((copy_offset & 511) != 0) {
-ret = -EIO;
-goto out;
-}
 break;
 
 default:
-- 
2.20.1




Re: [PATCH v2 4/4] qcow2: Use BDRV_SECTOR_SIZE instead of the hardcoded value

2020-01-18 Thread Alberto Garcia
On Tue 14 Jan 2020 03:15:48 PM CET, Max Reitz  wrote:
>> @@ -3836,7 +3837,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
>>  case QCOW2_CLUSTER_NORMAL:
>>  child = s->data_file;
>>  copy_offset += offset_into_cluster(s, src_offset);
>> -if ((copy_offset & 511) != 0) {
>> +if (!QEMU_IS_ALIGNED(copy_offset, BDRV_SECTOR_SIZE)) {
>
> Hm.  I don’t get this one.

Ok, this came with Fam's "qemu-img convert with copy offloading" series:

   https://lists.gnu.org/archive/html/qemu-block/2018-06/msg00015.html

and qemu-img uses sectors here:

   blk_co_copy_range(..., sector_num << BDRV_SECTOR_BITS,
 n << BDRV_SECTOR_BITS, ...)

so I guess that's why the check is there. Again, I think this should be
bl.request_alignment, because as far as I can tell copy_file_range()
works just fine unless O_DIRECT is used.

Berto



[PATCH v2 5/7] hw/char/exynos4210_uart: Implement Rx FIFO level triggers and timeouts

2020-01-18 Thread Guenter Roeck
The driver already implements a receive FIFO, but it does not
handle receive FIFO trigger levels and timeout. Implement the
missing functionality.

Signed-off-by: Guenter Roeck 
---
v2: Call exynos4210_uart_rx_timeout_set() from new post_load function
to set the receive timeout timer.
Add timer to vmstate_exynos4210_uart.

 hw/char/exynos4210_uart.c | 122 ++
 hw/char/trace-events  |   3 +-
 2 files changed, 99 insertions(+), 26 deletions(-)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 5d48701b6d..63ea9663f2 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -24,6 +24,7 @@
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
+#include "qemu/timer.h"
 #include "chardev/char-fe.h"
 #include "chardev/char-serial.h"
 
@@ -118,6 +119,7 @@ static const Exynos4210UartReg exynos4210_uart_regs[] = {
 #define ULCON_STOP_BIT_SHIFT  1
 
 /* UART Tx/Rx Status */
+#define UTRSTAT_Rx_TIMEOUT  0x8
 #define UTRSTAT_TRANSMITTER_EMPTY   0x4
 #define UTRSTAT_Tx_BUFFER_EMPTY 0x2
 #define UTRSTAT_Rx_BUFFER_DATA_READY0x1
@@ -147,6 +149,9 @@ typedef struct Exynos4210UartState {
 Exynos4210UartFIFO   rx;
 Exynos4210UartFIFO   tx;
 
+QEMUTimer *fifo_timeout_timer;
+uint64_t wordtime;/* word time in ns */
+
 CharBackend   chr;
 qemu_irq  irq;
 
@@ -209,15 +214,12 @@ static void fifo_reset(Exynos4210UartFIFO *q)
 q->rp = 0;
 }
 
-static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const 
Exynos4210UartState *s)
+static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel,
+   uint32_t reg)
 {
-uint32_t level = 0;
-uint32_t reg;
+uint32_t level;
 
-reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
-UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
-
-switch (s->channel) {
+switch (channel) {
 case 0:
 level = reg * 32;
 break;
@@ -231,12 +233,34 @@ static uint32_t 
exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
 break;
 default:
 level = 0;
-trace_exynos_uart_channel_error(s->channel);
+trace_exynos_uart_channel_error(channel);
+break;
 }
-
 return level;
 }
 
+static uint32_t
+exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
+{
+uint32_t reg;
+
+reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
+UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
+
+return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
+}
+
+static uint32_t
+exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
+{
+uint32_t reg;
+
+reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >>
+UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1;
+
+return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
+}
+
 static void exynos4210_uart_update_irq(Exynos4210UartState *s)
 {
 /*
@@ -244,13 +268,25 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
  * transmit FIFO is smaller than the trigger level.
  */
 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
-
 uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
 UFSTAT_Tx_FIFO_COUNT_SHIFT;
 
 if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
 s->reg[I_(UINTSP)] |= UINTSP_TXD;
 }
+
+/*
+ * Rx interrupt if trigger level is reached or if rx timeout
+ * interrupt is disabled and there is data in the receive buffer
+ */
+count = fifo_elements_number(&s->rx);
+if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
+count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
+timer_del(s->fifo_timeout_timer);
+}
+} else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
 }
 
 s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)];
@@ -264,6 +300,21 @@ static void exynos4210_uart_update_irq(Exynos4210UartState 
*s)
 }
 }
 
+static void exynos4210_uart_timeout_int(void *opaque)
+{
+Exynos4210UartState *s = opaque;
+
+trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)],
+ s->reg[I_(UINTSP)]);
+
+if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) ||
+(s->reg[I_(UCON)] & (1 << 11))) {
+s->reg[I_(UINTSP)] |= UINTSP_RXD;
+s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
+exynos4210_uart_update_irq(s);
+}
+}
+
 static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
 {
 int speed, parity, data_bits, stop_bits;
@@ -302,10 +353,24 @@ static void 
exynos4210_uart_update_parameters(Exynos4210UartState *s)
 ssp.data_bits = data_bits;
 ssp.stop_bits = stop_bits;
 
+s->wordtime = NANOSECONDS_PER_SECOND *

[PATCH v2 6/7] hw/char/exynos4210_uart: Add receive DMA support

2020-01-18 Thread Guenter Roeck
To support receive DMA, we need to inform the DMA controller if receive data
is available. Otherwise the DMA controller keeps requesting data, causing
receive errors.

Implement this using an interrupt line. The instantiating code then needs
to connect the interrupt with the matching DMA controller GPIO pin.

Reviewed-by: Peter Maydell 
Signed-off-by: Guenter Roeck 
---
v2: Added Reviewed-by: tag

 hw/char/exynos4210_uart.c | 24 
 hw/char/trace-events  |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 63ea9663f2..6fe38fad3e 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -154,6 +154,7 @@ typedef struct Exynos4210UartState {
 
 CharBackend   chr;
 qemu_irq  irq;
+qemu_irq  dmairq;
 
 uint32_t channel;
 
@@ -261,6 +262,24 @@ exynos4210_uart_Rx_FIFO_trigger_level(const 
Exynos4210UartState *s)
 return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
 }
 
+/*
+ * Update Rx DMA busy signal if Rx DMA is enabled. For simplicity,
+ * mark DMA as busy if DMA is enabled and the receive buffer is empty.
+ */
+static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s)
+{
+bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02;
+uint32_t count = fifo_elements_number(&s->rx);
+
+if (rx_dma_enabled && !count) {
+qemu_irq_raise(s->dmairq);
+trace_exynos_uart_dmabusy(s->channel);
+} else {
+qemu_irq_lower(s->dmairq);
+trace_exynos_uart_dmaready(s->channel);
+}
+}
+
 static void exynos4210_uart_update_irq(Exynos4210UartState *s)
 {
 /*
@@ -282,10 +301,12 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
 count = fifo_elements_number(&s->rx);
 if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
 count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
+exynos4210_uart_update_dmabusy(s);
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 timer_del(s->fifo_timeout_timer);
 }
 } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
+exynos4210_uart_update_dmabusy(s);
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 }
 
@@ -311,6 +332,7 @@ static void exynos4210_uart_timeout_int(void *opaque)
 (s->reg[I_(UCON)] & (1 << 11))) {
 s->reg[I_(UINTSP)] |= UINTSP_RXD;
 s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
+exynos4210_uart_update_dmabusy(s);
 exynos4210_uart_update_irq(s);
 }
 }
@@ -499,6 +521,7 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr 
offset,
 s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
 res = s->reg[I_(URXH)];
 }
+exynos4210_uart_update_dmabusy(s);
 trace_exynos_uart_read(s->channel, offset,
exynos4210_uart_regname(offset), res);
 return res;
@@ -666,6 +689,7 @@ static void exynos4210_uart_init(Object *obj)
 sysbus_init_mmio(dev, &s->iomem);
 
 sysbus_init_irq(dev, &s->irq);
+sysbus_init_irq(dev, &s->dmairq);
 }
 
 static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/trace-events b/hw/char/trace-events
index cb73fee6a9..6f938301d9 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -79,6 +79,8 @@ nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) 
"addr 0x%" PRIx64
 nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" 
PRIx64 " value 0x%" PRIx64 " size %u"
 
 # exynos4210_uart.c
+exynos_uart_dmabusy(uint32_t channel) "UART%d: DMA busy (Rx buffer empty)"
+exynos_uart_dmaready(uint32_t channel) "UART%d: DMA ready"
 exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 
0x%08"PRIx32
 exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
 exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int 
data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: 
%d, stop bits: %d wordtime: %"PRId64"ns"
-- 
2.17.1




[PATCH v2 3/7] hw/char/exynos4210_uart: Convert to support tracing

2020-01-18 Thread Guenter Roeck
Replace debug code with tracing to aid debugging.

Reviewed-by: Peter Maydell 
Signed-off-by: Guenter Roeck 
---
v2: Added Reviewed-by: tag

 hw/char/exynos4210_uart.c | 96 ---
 hw/char/trace-events  | 17 +++
 2 files changed, 47 insertions(+), 66 deletions(-)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index d6b6b62366..fb7a3ebd09 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -31,45 +31,7 @@
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
 
-#undef DEBUG_UART
-#undef DEBUG_UART_EXTEND
-#undef DEBUG_IRQ
-#undef DEBUG_Rx_DATA
-#undef DEBUG_Tx_DATA
-
-#define DEBUG_UART0
-#define DEBUG_UART_EXTEND 0
-#define DEBUG_IRQ 0
-#define DEBUG_Rx_DATA 0
-#define DEBUG_Tx_DATA 0
-
-#if DEBUG_UART
-#define  PRINT_DEBUG(fmt, args...)  \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
-
-#if DEBUG_UART_EXTEND
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
-#else
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do {} while (0)
-#endif /* EXTEND */
-
-#else
-#define  PRINT_DEBUG(fmt, args...)  \
-do {} while (0)
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-do {} while (0)
-#endif
-
-#define  PRINT_ERROR(fmt, args...) \
-do { \
-fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-} while (0)
+#include "trace.h"
 
 /*
  *  Offsets for UART registers relative to SFR base address
@@ -193,8 +155,7 @@ typedef struct Exynos4210UartState {
 } Exynos4210UartState;
 
 
-#if DEBUG_UART
-/* Used only for debugging inside PRINT_DEBUG_... macros */
+/* Used only for tracing */
 static const char *exynos4210_uart_regname(hwaddr  offset)
 {
 
@@ -208,7 +169,6 @@ static const char *exynos4210_uart_regname(hwaddr  offset)
 
 return NULL;
 }
-#endif
 
 
 static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch)
@@ -271,7 +231,7 @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const 
Exynos4210UartState
 break;
 default:
 level = 0;
-PRINT_ERROR("Wrong UART channel number: %d\n", s->channel);
+trace_exynos_uart_channel_error(s->channel);
 }
 
 return level;
@@ -297,14 +257,10 @@ static void 
exynos4210_uart_update_irq(Exynos4210UartState *s)
 
 if (s->reg[I_(UINTP)]) {
 qemu_irq_raise(s->irq);
-
-#if DEBUG_IRQ
-fprintf(stderr, "UART%d: IRQ has been raised: %08x\n",
-s->channel, s->reg[I_(UINTP)]);
-#endif
-
+trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]);
 } else {
 qemu_irq_lower(s->irq);
+trace_exynos_uart_irq_lowered(s->channel);
 }
 }
 
@@ -348,7 +304,7 @@ static void 
exynos4210_uart_update_parameters(Exynos4210UartState *s)
 
 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 
-PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
+trace_exynos_uart_update_params(
 s->channel, speed, parity, data_bits, stop_bits);
 }
 
@@ -358,8 +314,8 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 Exynos4210UartState *s = (Exynos4210UartState *)opaque;
 uint8_t ch;
 
-PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel,
-offset, exynos4210_uart_regname(offset), (long long unsigned int)val);
+trace_exynos_uart_write(s->channel, offset,
+exynos4210_uart_regname(offset), val);
 
 switch (offset) {
 case ULCON:
@@ -373,12 +329,12 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 if (val & UFCON_Rx_FIFO_RESET) {
 fifo_reset(&s->rx);
 s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET;
-PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel);
+trace_exynos_uart_rx_fifo_reset(s->channel);
 }
 if (val & UFCON_Tx_FIFO_RESET) {
 fifo_reset(&s->tx);
 s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET;
-PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel);
+trace_exynos_uart_tx_fifo_reset(s->channel);
 }
 break;
 
@@ -390,9 +346,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 /* XXX this blocks entire thread. Rewrite to use
  * qemu_chr_fe_write and background I/O callbacks */
 qemu_chr_fe_write_all(&s->chr, &ch, 1);
-#if DEBUG_Tx_DATA
-fprintf(stderr, "%c", ch);
-#endif
+trace_exynos_uart_tx(s->channel, ch);
 s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY |
 UTRSTAT_Tx_BUFFER_EMPTY;
 s->reg[I_(UINTSP)]  |= UINTSP_TXD;
@@ -403,8 +357,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr 
offset,
 case UINTP:
 s->reg[I_(UINTP)]

[PATCH v2 7/7] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330

2020-01-18 Thread Guenter Roeck
The Exynos4210 serial driver uses an interrupt line to signal if receive
data is available. Connect that interrupt with the DMA controller's
'peripheral busy' gpio pin to stop the DMA if there is no more receive
data available. Without this patch, receive DMA runs wild and fills the
entire receive DMA buffer with invalid data. 

Signed-off-by: Guenter Roeck 
---
v2: Context changes; improved description
This patch has an outstanding review comment, suggesting that
uart and pl330 device states should be kept in Exynos4210State.
I did not address this comment for a number of reasons.
It looks like the problem is hypothetical, the problem may
apply to all devices created in exynos4210_realize(), and I am
not sure I understand what would need to be done to fix
the problem for good (ie for all devices created in the same
function which have the same problem). Overall, I think that
handling this situation would be better left for a separate patch.

 hw/arm/exynos4210.c | 42 +-
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 76c0e2a3e8..6b050bb5c9 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -166,8 +166,8 @@ static uint64_t exynos4210_calc_affinity(int cpu)
 return (0x9 << ARM_AFF1_SHIFT) | cpu;
 }
 
-static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
- int nreq, int nevents, int width)
+static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
+ qemu_irq irq, int nreq, int nevents, int 
width)
 {
 SysBusDevice *busdev;
 DeviceState *dev;
@@ -196,6 +196,7 @@ static void pl330_create(uint32_t base, qemu_or_irq 
*orgate, qemu_irq irq,
 sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
 }
 qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
+return dev;
 }
 
 static void exynos4210_realize(DeviceState *socdev, Error **errp)
@@ -204,7 +205,7 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 MemoryRegion *system_mem = get_system_memory();
 qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
 SysBusDevice *busdev;
-DeviceState *dev;
+DeviceState *dev, *uart[4], *pl330[3];
 int i, n;
 
 for (n = 0; n < EXYNOS4210_NCPUS; n++) {
@@ -390,19 +391,19 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 
 
 /*** UARTs ***/
-exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
0)]);
 
-exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
1)]);
 
-exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
2)]);
 
-exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
   s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 
3)]);
 
@@ -450,12 +451,27 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 s->irq_table[exynos4210_get_irq(28, 3)]);
 
 /*** DMA controllers ***/
-pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
- s->irq_table[exynos4210_get_irq(21, 0)], 32, 30, 32);
-pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
- s->irq_table[exynos4210_get_irq(21, 1)], 32, 30, 32);
-pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
- s->irq_table[exynos4210_get_irq(20, 1)], 1, 30, 64);
+pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
+&s->pl330_irq_orgate[0],
+s->irq_table[exynos4210_get_irq(21, 0)],
+32, 30, 32);
+pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
+&s->pl330_irq_orgate[1],
+s->irq_table[exynos4210_get_irq(21, 1)],
+32, 30, 32);
+pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
+&s->pl330_irq_orgate[2],
+s->irq_table[exynos4210_get_irq(20, 1)],
+1, 30, 64);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
+   qd

[PATCH v2 2/7] hw/arm/exynos4210: Fix DMA initialization

2020-01-18 Thread Guenter Roeck
First parameter to exynos4210_get_irq() is not the SPI port number,
but the interrupt group number. Interrupt groups are 20 for mdma
and 21 for pdma. Interrupts are not inverted. Controllers support 32
events (pdma) or 31 events (mdma). Events must all be routed to a single
interrupt line. Set other parameters as documented in Exynos4210 datasheet,
section 8 (DMA controller).

Reduce the number of DMA events to 30 for both pdma and mdma. QEMU's OR
interrupt gates are currently limited to less than 32, and we would need
33 gates to support 32 event interrupts plus the abort interrupt.
Operationally this should not make a difference since they are all
routed to a single interrupt line anyway.

Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
Signed-off-by: Guenter Roeck 
---
v2: Use interrupt combiner instead of connecting all events to a
single interrupt. Limit number of events per DMA channel
to 31 to meet qemu interrupt combiner limitations.
[Not sure if "assert(s->num_lines < MAX_OR_LINES);" should be
 "assert(s->num_lines <= MAX_OR_LINES);"]
Introduce exynos4210_init() to handle interrupt combiner
initialization.

 hw/arm/exynos4210.c | 51 +++--
 include/hw/arm/exynos4210.h |  4 +++
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 77fbe1baab..91586fe265 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -166,17 +166,36 @@ static uint64_t exynos4210_calc_affinity(int cpu)
 return (0x9 << ARM_AFF1_SHIFT) | cpu;
 }
 
-static void pl330_create(uint32_t base, qemu_irq irq, int nreq)
+static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
+ int nreq, int nevents, int width)
 {
 SysBusDevice *busdev;
 DeviceState *dev;
+int i;
 
 dev = qdev_create(NULL, "pl330");
+qdev_prop_set_uint8(dev, "num_events", nevents);
+qdev_prop_set_uint8(dev, "num_chnls",  8);
 qdev_prop_set_uint8(dev, "num_periph_req",  nreq);
+
+qdev_prop_set_uint8(dev, "wr_cap", 4);
+qdev_prop_set_uint8(dev, "wr_q_dep", 8);
+qdev_prop_set_uint8(dev, "rd_cap", 4);
+qdev_prop_set_uint8(dev, "rd_q_dep", 8);
+qdev_prop_set_uint8(dev, "data_width", width);
+qdev_prop_set_uint16(dev, "data_buffer_dep", width);
 qdev_init_nofail(dev);
 busdev = SYS_BUS_DEVICE(dev);
 sysbus_mmio_map(busdev, 0, base);
-sysbus_connect_irq(busdev, 0, irq);
+
+object_property_set_int(OBJECT(orgate), nevents + 1, "num-lines",
+&error_abort);
+object_property_set_bool(OBJECT(orgate), true, "realized", &error_abort);
+
+for (i = 0; i < nevents + 1; i++) {
+sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
+}
+qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
 }
 
 static void exynos4210_realize(DeviceState *socdev, Error **errp)
@@ -431,12 +450,27 @@ static void exynos4210_realize(DeviceState *socdev, Error 
**errp)
 s->irq_table[exynos4210_get_irq(28, 3)]);
 
 /*** DMA controllers ***/
-pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32);
-pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32);
-pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1);
+pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
+ s->irq_table[exynos4210_get_irq(21, 0)], 32, 30, 32);
+pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
+ s->irq_table[exynos4210_get_irq(21, 1)], 32, 30, 32);
+pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
+ s->irq_table[exynos4210_get_irq(20, 1)], 1, 30, 64);
+}
+
+static void exynos4210_init(Object *obj)
+{
+Exynos4210State *s = EXYNOS4210_SOC(obj);
+int i;
+
+for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
+char *name = g_strdup_printf("pl330-irq-orgate%d", i);
+qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
+
+object_initialize_child(obj, name, orgate, sizeof(*orgate),
+TYPE_OR_IRQ, &error_abort, NULL);
+g_free(name);
+}
 }
 
 static void exynos4210_class_init(ObjectClass *klass, void *data)
@@ -450,6 +484,7 @@ static const TypeInfo exynos4210_info = {
 .name = TYPE_EXYNOS4210_SOC,
 .parent = TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(Exynos4210State),
+.instance_init = exynos4210_init,
 .class_init = exynos4210_class_init,
 };
 
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index f0f23b0e9b..55260394af 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -24,6 +24,7 @@
 #ifndef EXYNOS4210_H
 #define EXYNOS4210_H
 
+#include "hw

[PATCH v2 4/7] hw/char/exynos4210_uart: Implement post_load function

2020-01-18 Thread Guenter Roeck
After restoring a VM, serial parameters need to be updated to reflect
restored register values. Implement a post_load function to handle this
situation.

Signed-off-by: Guenter Roeck 
---
v4: Additional patch to implement post-load functionality
in exynos uart driver. Required for next patch in series.

 hw/char/exynos4210_uart.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index fb7a3ebd09..5d48701b6d 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -522,10 +522,20 @@ static void exynos4210_uart_reset(DeviceState *dev)
 trace_exynos_uart_rxsize(s->channel, s->rx.size);
 }
 
+static int exynos4210_uart_post_load(void *opaque, int version_id)
+{
+Exynos4210UartState *s = (Exynos4210UartState *)opaque;
+
+exynos4210_uart_update_parameters(s);
+
+return 0;
+}
+
 static const VMStateDescription vmstate_exynos4210_uart_fifo = {
 .name = "exynos4210.uart.fifo",
 .version_id = 1,
 .minimum_version_id = 1,
+.post_load = exynos4210_uart_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(sp, Exynos4210UartFIFO),
 VMSTATE_UINT32(rp, Exynos4210UartFIFO),
-- 
2.17.1




[PATCH v2 1/7] dma/pl330: Convert to support tracing

2020-01-18 Thread Guenter Roeck
Replace debug logging code with tracing.

Signed-off-by: Guenter Roeck 
---
v2: Make call to pl330_hexdump() conditional

 hw/dma/pl330.c  | 88 -
 hw/dma/trace-events | 24 +
 2 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index f2bb2d9ac1..64519971ef 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -25,19 +25,12 @@
 #include "sysemu/dma.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "trace.h"
 
 #ifndef PL330_ERR_DEBUG
 #define PL330_ERR_DEBUG 0
 #endif
 
-#define DB_PRINT_L(lvl, fmt, args...) do {\
-if (PL330_ERR_DEBUG >= lvl) {\
-fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
-} \
-} while (0)
-
-#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
-
 #define PL330_PERIPH_NUM32
 #define PL330_MAX_BURST_LEN 128
 #define PL330_INSN_MAXSIZE  6
@@ -319,6 +312,26 @@ typedef struct PL330InsnDesc {
 void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len);
 } PL330InsnDesc;
 
+static void pl330_hexdump(uint8_t *buf, size_t size)
+{
+unsigned int b, i, len;
+char tmpbuf[80];
+
+for (b = 0; b < size; b += 16) {
+len = size - b;
+if (len > 16) {
+len = 16;
+}
+tmpbuf[0] = '\0';
+for (i = 0; i < len; i++) {
+if ((i % 4) == 0) {
+strcat(tmpbuf, " ");
+}
+sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]);
+}
+trace_pl330_hexdump(b, tmpbuf);
+}
+}
 
 /* MFIFO Implementation
  *
@@ -582,7 +595,7 @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, 
uint8_t tag)
 
 static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
 {
-DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags);
+trace_pl330_fault(ch, flags);
 ch->fault_type |= flags;
 if (ch->state == pl330_chan_fault) {
 return;
@@ -590,7 +603,7 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t 
flags)
 ch->state = pl330_chan_fault;
 ch->parent->num_faulting++;
 if (ch->parent->num_faulting == 1) {
-DB_PRINT("abort interrupt raised\n");
+trace_pl330_fault_abort();
 qemu_irq_raise(ch->parent->irq_abort);
 }
 }
@@ -648,7 +661,7 @@ static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
 return;
 }
 }
-DB_PRINT("DMA ending!\n");
+trace_pl330_dmaend();
 pl330_fifo_tagged_remove(&s->fifo, ch->tag);
 pl330_queue_remove_tagged(&s->read_queue, ch->tag);
 pl330_queue_remove_tagged(&s->write_queue, ch->tag);
@@ -683,7 +696,7 @@ static void pl330_dmago(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 uint32_t pc;
 PL330Chan *s;
 
-DB_PRINT("\n");
+trace_pl330_dmago();
 
 if (!ch->is_manager) {
 pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
@@ -740,9 +753,7 @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src,
 size, num, inc, 0, ch->tag);
 if (!ch->stall) {
-DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
- " num:%" PRId32 " %c\n",
- ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
+trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
 ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
 }
 }
@@ -782,7 +793,7 @@ static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 ch->fault_type = 0;
 ch->parent->num_faulting--;
 if (ch->parent->num_faulting == 0) {
-DB_PRINT("abort interrupt lowered\n");
+trace_pl330_dmakill();
 qemu_irq_lower(ch->parent->irq_abort);
 }
 }
@@ -800,6 +811,8 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
 uint8_t bs = opcode & 3;
 uint8_t lc = (opcode & 4) >> 2;
 
+trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag);
+
 if (bs == 2) {
 pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
 return;
@@ -813,12 +826,12 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
 if (nf) {
 ch->lc[lc]--;
 }
-DB_PRINT("loop reiteration\n");
+trace_pl330_dmalpiter();
 ch->pc -= args[0];
 ch->pc -= len + 1;
 /* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */
 } else {
-DB_PRINT("loop fallthrough\n");
+trace_pl330_dmalpfallthrough();
 }
 }
 
@@ -886,10 +899,10 @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, 
uint8_t *args, int len)
 }
 if (ch->parent->inten & (1 << ev_id)) {
 ch->parent->int_status |= (1 << ev_id);
-DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id);
+trace_pl330_dmasev_evirq(ev_id);
 qemu_irq_raise(ch->parent->irq[ev_id])

[PATCH v2 0/7] Fix Exynos4210 DMA support

2020-01-18 Thread Guenter Roeck
Commit 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
introduced DMA support for Exynos4210. Unfortunately, it never really
worked. DMA interrupt line and polarity was wrong, and the serial port
needs extra code to support DMA. This patch series fixes the problem.

The series also converts pl330 and exynos4210_uart code to support tracing.
While not strictly necessary, this was very useful for debugging,
and it seemed too valuable to drop it from the final series. Similar,
improved support for receive FIFO handling is not strictly necessary
to fix DMA handling, but I initially thought that it was and added the
code. Like tracing support it seemed too valuable to drop it.

The series was tested with qemu's smdkc210 and nuri emulations and with
exynos4210-smdkv310.dtb. Without the series, the emulation does not react
to serial line input, and serial line output stalls when using DMA. With
this series in place, serial line input is handled correctly, serial
output does not stall, and DMA interrupts are observed and handled.

v2: Addressed all feedback comments but one (see last patch of series).
Please see individual patches for details.



[PATCH] qom/object: Display more helpful message when an interface is missing

2020-01-18 Thread Philippe Mathieu-Daudé
When adding new devices implementing QOM interfaces, we might
forgot to add the Kconfig dependency that pulls the required
objects in when building.

Since QOM dependencies are resolved at runtime, we don't get any
link-time failures, and QEMU aborts while starting:

  $ qemu ...
  Segmentation fault (core dumped)

  (gdb) bt
  #0  0x7ff6e96b1e35 in raise () from /lib64/libc.so.6
  #1  0x7ff6e969c895 in abort () from /lib64/libc.so.6
  #2  0x5572bc5051cf in type_initialize (ti=0x5572be6f1200) at 
qom/object.c:323
  #3  0x5572bc505074 in type_initialize (ti=0x5572be6f1800) at 
qom/object.c:301
  #4  0x5572bc505074 in type_initialize (ti=0x5572be6e48e0) at 
qom/object.c:301
  #5  0x5572bc506939 in object_class_by_name (typename=0x5572bc56109a) at 
qom/object.c:959
  #6  0x5572bc503dd5 in cpu_class_by_name (typename=0x5572bc56109a, 
cpu_model=0x5572be6d9930) at hw/core/cpu.c:286

Since the caller has access to the qdev parent/interface names,
we can simply display them to avoid starting a debugger:

  $ qemu ...
  qemu: missing interface 'fancy-if' for object 'fancy-dev'
  Aborted (core dumped)

This commit is similar to e02bdf1cecd2 ("Display more helpful message
when an object type is missing").

Signed-off-by: Philippe Mathieu-Daudé 
---
Cc: Cornelia Huck 
Cc: Stefano Garzarella 
Cc: Daniel P. Berrangé 
---
 qom/object.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/qom/object.c b/qom/object.c
index 0d971ca897..36123fb330 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -317,6 +317,11 @@ static void type_initialize(TypeImpl *ti)
 
 for (i = 0; i < ti->num_interfaces; i++) {
 TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
+if (!t) {
+error_report("missing interface '%s' for object '%s'",
+ ti->interfaces[i].typename, parent->name);
+abort();
+}
 for (e = ti->class->interfaces; e; e = e->next) {
 TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
 
-- 
2.21.1




Re: [PATCH 037/104] virtiofsd: passthrough_ll: add fallback for racy ops

2020-01-18 Thread Masayoshi Mizuma
On Thu, Dec 12, 2019 at 04:37:57PM +, Dr. David Alan Gilbert (git) wrote:
> From: Miklos Szeredi 
> 
> We have two operations that cannot be done race-free on a symlink in
> certain cases: utimes and link.
> 
> Add racy fallback for these if the race-free method doesn't work.  We do
> our best to avoid races even in this case:
> 
>   - get absolute path by reading /proc/self/fd/NN symlink
> 
>   - lookup parent directory: after this we are safe against renames in
> ancestors
> 
>   - lookup name in parent directory, and verify that we got to the original
> inode,  if not retry the whole thing
> 
> Both utimes(2) and link(2) hold i_lock on the inode across the operation,
> so a racing rename/delete by this fuse instance is not possible, only from
> other entities changing the filesystem.
> 
> If the "norace" option is given, then disable the racy fallbacks.
> 
> Signed-off-by: Miklos Szeredi 
> ---
>  tools/virtiofsd/passthrough_ll.c | 159 +++
>  1 file changed, 142 insertions(+), 17 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index 93e74cce21..1faae2753f 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -98,6 +98,7 @@ enum {
>  struct lo_data {
>  pthread_mutex_t mutex;
>  int debug;
> +int norace;
>  int writeback;
>  int flock;
>  int xattr;
> @@ -124,10 +125,15 @@ static const struct fuse_opt lo_opts[] = {
>  { "cache=never", offsetof(struct lo_data, cache), CACHE_NEVER },
>  { "cache=auto", offsetof(struct lo_data, cache), CACHE_NORMAL },
>  { "cache=always", offsetof(struct lo_data, cache), CACHE_ALWAYS },
> -
> +{ "norace", offsetof(struct lo_data, norace), 1 },
>  FUSE_OPT_END
>  };
>  
> +static void unref_inode(struct lo_data *lo, struct lo_inode *inode, uint64_t 
> n);
> +
> +static struct lo_inode *lo_find(struct lo_data *lo, struct stat *st);
> +
> +
>  static struct lo_data *lo_data(fuse_req_t req)
>  {
>  return (struct lo_data *)fuse_req_userdata(req);
> @@ -347,23 +353,127 @@ static void lo_getattr(fuse_req_t req, fuse_ino_t ino,
>  fuse_reply_attr(req, &buf, lo->timeout);
>  }
>  > -static int utimensat_empty_nofollow(struct lo_inode *inode,
> -const struct timespec *tv)
> +static int lo_parent_and_name(struct lo_data *lo, struct lo_inode *inode,
> +  char path[PATH_MAX], struct lo_inode **parent)
>  {
> -int res;
>  char procname[64];
> +char *last;
> +struct stat stat;
> +struct lo_inode *p;
> +int retries = 2;
> +int res;
> +
> +retry:
> +sprintf(procname, "/proc/self/fd/%i", inode->fd);
> +
> +res = readlink(procname, path, PATH_MAX);
> +if (res < 0) {

> +fuse_log(FUSE_LOG_WARNING, "lo_parent_and_name: readlink failed: 
> %m\n");

I think it's better to use __func__ macro in case the function name is
changed in the future.

   fuse_log(FUSE_LOG_WARNING, "%s: readlink failed: %m\n", __func__);

> +goto fail_noretry;
> +}
> +
> +if (res >= PATH_MAX) {

> +fuse_log(FUSE_LOG_WARNING, "lo_parent_and_name: readlink 
> overflowed\n");

   fuse_log(FUSE_LOG_WARNING, "%s: readlink overflowed\n", __func__);

> +goto fail_noretry;
> +}
> +path[res] = '\0';
> +
> +last = strrchr(path, '/');
> +if (last == NULL) {
> +/* Shouldn't happen */

> +fuse_log(
> +FUSE_LOG_WARNING,
> +"lo_parent_and_name: INTERNAL ERROR: bad path read from proc\n");

   fuse_log(
   FUSE_LOG_WARNING,
"%s: INTERNAL ERROR: bad path read from proc\n", __func__);

> +goto fail_noretry;
> +}
> +if (last == path) {
> +p = &lo->root;
> +pthread_mutex_lock(&lo->mutex);
> +p->refcount++;
> +pthread_mutex_unlock(&lo->mutex);
> +} else {
> +*last = '\0';
> +res = fstatat(AT_FDCWD, last == path ? "/" : path, &stat, 0);
> +if (res == -1) {
> +if (!retries) {

> +fuse_log(FUSE_LOG_WARNING,
> + "lo_parent_and_name: failed to stat parent: %m\n");

   fuse_log(FUSE_LOG_WARNING,
"%s: failed to stat parent: %m\n", __func__);

> +}
> +goto fail;
> +}
> +p = lo_find(lo, &stat);
> +if (p == NULL) {
> +if (!retries) {

> +fuse_log(FUSE_LOG_WARNING,
> + "lo_parent_and_name: failed to find parent\n");

   fuse_log(FUSE_LOG_WARNING,
 "%s: failed to find parent\n", __func__);

> +}
> +goto fail;
> +}
> +}
> +last++;
> +res = fstatat(p->fd, last, &stat, AT_SYMLINK_NOFOLLOW);
> +if (res == -1) {
> +if (!retries) {

> +fuse_log(FUSE_LOG_WARNIN

Re: [PATCH v3 08/17] hw/arm/allwinner: add SD/MMC host controller

2020-01-18 Thread Philippe Mathieu-Daudé

On 1/8/20 9:00 PM, Niek Linnenbank wrote:

The Allwinner System on Chip families sun4i and above contain
an integrated storage controller for Secure Digital (SD) and
Multi Media Card (MMC) interfaces. This commit adds support
for the Allwinner SD/MMC storage controller with the following
emulated features:

  * DMA transfers
  * Direct FIFO I/O
  * Short/Long format command responses
  * Auto-Stop command (CMD12)
  * Insert & remove card detection

The following boards are extended with the SD host controller:

  * Cubieboard (hw/arm/cubieboard.c)
  * Orange Pi PC (hw/arm/orangepi.c)

Signed-off-by: Niek Linnenbank 
---
  include/hw/arm/allwinner-a10.h   |   4 +-
  include/hw/arm/allwinner-h3.h|   3 +
  include/hw/sd/allwinner-sdhost.h | 136 +
  hw/arm/allwinner-a10.c   |  10 +
  hw/arm/allwinner-h3.c|  15 +-
  hw/arm/cubieboard.c  |  15 +
  hw/arm/orangepi.c|  16 +
  hw/sd/allwinner-sdhost.c | 848 +++
  hw/sd/Makefile.objs  |   1 +
  hw/sd/trace-events   |   7 +
  10 files changed, 1053 insertions(+), 2 deletions(-)
  create mode 100644 include/hw/sd/allwinner-sdhost.h
  create mode 100644 hw/sd/allwinner-sdhost.c


So far:
Tested-by: Philippe Mathieu-Daudé 




Re: [PATCH v3 03/17] hw/arm/allwinner-h3: add Clock Control Unit

2020-01-18 Thread Philippe Mathieu-Daudé

Hi Niek,

On 1/13/20 8:18 PM, Niek Linnenbank wrote:

Hi,

Just a friendly reminder for review of this patch and the others in this 
series

that don't yet have a reviewed-by tag :-)


You are right to ping the list after a week.

Cc'ing Damien for this particular patch, he might have good advises.


Looking at the stats from your cover:

 include/hw/arm/allwinner-h3.h  | 164 +
 include/hw/misc/allwinner-cpucfg.h |  54 ++
 include/hw/misc/allwinner-h3-ccu.h |  67 ++
 include/hw/misc/allwinner-h3-dramc.h   | 107 +++
 include/hw/misc/allwinner-h3-sysctrl.h |  68 ++
 include/hw/net/allwinner-sun8i-emac.h  | 103 +++
 include/hw/rtc/allwinner-rtc.h | 129 
 include/hw/sd/allwinner-sdhost.h   | 136 
 hw/arm/allwinner-h3.c  | 477 ++
 hw/arm/orangepi.c  | 125 
 hw/misc/allwinner-cpucfg.c | 282 
 hw/misc/allwinner-h3-ccu.c | 243 +++
 hw/misc/allwinner-h3-dramc.c   | 358 ++
 hw/misc/allwinner-h3-sysctrl.c | 140 
 hw/misc/allwinner-sid.c| 170 +
 hw/net/allwinner-sun8i-emac.c  | 871 +
 hw/rtc/allwinner-rtc.c | 386 +++
 hw/sd/allwinner-sdhost.c   | 848 

 39 files changed, 5267 insertions(+), 2 deletions(-)

This is a LOT of code to process, keep in mind your series touches 
different subsystems with different maintainers. It is hard to know all 
of them in details.


Since your SoC is in the same family than the A10, I've Cc'ed Beniamino 
Galvani. You should Cc him in your v4, hopefully he can help reviewing.


Regarding the System Control Unit and SDRAM Controller, as I don't know 
this SoC so I have to digest the whole datasheet, so it takes me time, 
bare with me (I'm using my hobby time to review your work).


The last patch I plan to review in your series is the SD/MMC one:
 10 files changed, 1053 insertions(+), 2 deletions(-)

It is 1/5th of your series in a single patch, each time I try to look at 
it I get scared. Anyway today I could test NetBSD booting from a SD card 
so I am more confident.


Anyway, don't forget this comment from the New Contribution page:
https://wiki.qemu.org/Contribute/SubmitAPatch#Return_the_favor

  Peer review only works if everyone chips in a bit of review time.
  If everyone submitted more patches than they reviewed, we would
  have a patch backlog. A good goal is to try to review at least
  as many patches from others as what you submit.

With the quality of your patches, even if this is your first 
contribution, it is obvious you now understand various part of QEMU.
Don't be shy to look at other patches on the list and help the 
community, as the reviewed authors might review you back :)


That said, your series is almost there!

Regards,

Phil.



Regards,
Niek





Re: [PATCH v3 07/17] hw/arm/allwinner: add Security Identifier device

2020-01-18 Thread Philippe Mathieu-Daudé

Cc'ing Corey/David for good advices about using UUID.

On 1/8/20 9:00 PM, Niek Linnenbank wrote:

The Security Identifier device found in various Allwinner System on Chip
designs gives applications a per-board unique identifier. This commit
adds support for the Allwinner Security Identifier using a 128-bit
UUID value as input.

Signed-off-by: Niek Linnenbank 
---
  include/hw/arm/allwinner-h3.h   |   3 +
  include/hw/misc/allwinner-sid.h |  61 
  hw/arm/allwinner-h3.c   |  11 ++-
  hw/arm/orangepi.c   |   4 +
  hw/misc/allwinner-sid.c | 170 
  hw/misc/Makefile.objs   |   1 +
  hw/misc/trace-events|   4 +
  7 files changed, 253 insertions(+), 1 deletion(-)
  create mode 100644 include/hw/misc/allwinner-sid.h
  create mode 100644 hw/misc/allwinner-sid.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 5a25a92eae..9ed365507c 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -46,6 +46,7 @@
  #include "hw/misc/allwinner-h3-ccu.h"
  #include "hw/misc/allwinner-cpucfg.h"
  #include "hw/misc/allwinner-h3-sysctrl.h"
+#include "hw/misc/allwinner-sid.h"
  #include "target/arm/cpu.h"
  
  /**

@@ -63,6 +64,7 @@ enum {
  AW_H3_SRAM_A2,
  AW_H3_SRAM_C,
  AW_H3_SYSCTRL,
+AW_H3_SID,
  AW_H3_EHCI0,
  AW_H3_OHCI0,
  AW_H3_EHCI1,
@@ -115,6 +117,7 @@ typedef struct AwH3State {
  AwH3ClockCtlState ccu;
  AwCpuCfgState cpucfg;
  AwH3SysCtrlState sysctrl;
+AwSidState sid;
  GICState gic;
  MemoryRegion sram_a1;
  MemoryRegion sram_a2;
diff --git a/include/hw/misc/allwinner-sid.h b/include/hw/misc/allwinner-sid.h
new file mode 100644
index 00..41189967e2
--- /dev/null
+++ b/include/hw/misc/allwinner-sid.h
@@ -0,0 +1,61 @@
+/*
+ * Allwinner Security ID emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_SID_H
+#define HW_MISC_ALLWINNER_SID_H
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "qemu/uuid.h"
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_SID"allwinner-sid"
+#define AW_SID(obj) \
+OBJECT_CHECK(AwSidState, (obj), TYPE_AW_SID)
+
+/** @} */
+
+/**
+ * Allwinner Security ID object instance state
+ */
+typedef struct AwSidState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Control register defines how and what to read */
+uint32_t control;
+
+/** RdKey register contains the data retrieved by the device */
+uint32_t rdkey;
+
+/** Stores the emulated device identifier */
+QemuUUID identifier;
+
+} AwSidState;
+
+#endif /* HW_MISC_ALLWINNER_SID_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index e9ad6d23df..af7317e86a 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -36,6 +36,7 @@ const hwaddr allwinner_h3_memmap[] = {
  [AW_H3_SRAM_A2]= 0x00044000,
  [AW_H3_SRAM_C] = 0x0001,
  [AW_H3_SYSCTRL]= 0x01c0,
+[AW_H3_SID]= 0x01c14000,
  [AW_H3_EHCI0]  = 0x01c1a000,
  [AW_H3_OHCI0]  = 0x01c1a400,
  [AW_H3_EHCI1]  = 0x01c1b000,
@@ -76,7 +77,6 @@ struct AwH3Unimplemented {
  { "mmc0",  0x01c0f000, 4 * KiB },
  { "mmc1",  0x01c1, 4 * KiB },
  { "mmc2",  0x01c11000, 4 * KiB },
-{ "sid",   0x01c14000, 1 * KiB },
  { "crypto",0x01c15000, 4 * KiB },
  { "msgbox",0x01c17000, 4 * KiB },
  { "spinlock",  0x01c18000, 4 * KiB },
@@ -196,6 +196,11 @@ static void allwinner_h3_init(Object *obj)
  
  sysbus_init_child_obj(obj, "cpucfg", &s->cpucfg, sizeof(s->cpucfg),

TYPE_AW_CPUCFG);
+
+sysbus_init_child_obj(obj, "sid", &s->sid, sizeof(s->sid),
+  TYPE_AW_SID);
+object_property_add_alias(obj, "identifier", OBJECT(&s->sid),
+  "identifier", &error_abort);
  }
  
  static void allwinner_h3_realize(DeviceState *dev, Error **errp)

@@ -316,6 +321,10 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
  qdev_init_nofail(DEVICE(&s->cpucfg));
  sysbus_mmio_map(SYS_BUS_DEVICE(&s->cpucfg), 0, s->memmap

Re: [PATCH v3 11/17] hw/arm/allwinner-h3: add SDRAM controller device

2020-01-18 Thread Philippe Mathieu-Daudé

Cc'ing Igor and Alex for this one.

On 1/8/20 9:00 PM, Niek Linnenbank wrote:

In the Allwinner H3 SoC the SDRAM controller is responsible
for interfacing with the external Synchronous Dynamic Random
Access Memory (SDRAM). Types of memory that the SDRAM controller
supports are DDR2/DDR3 and capacities of up to 2GiB. This commit
adds emulation support of the Allwinner H3 SDRAM controller.

Signed-off-by: Niek Linnenbank 
---
  include/hw/arm/allwinner-h3.h|   5 +
  include/hw/misc/allwinner-h3-dramc.h | 107 
  hw/arm/allwinner-h3.c|  19 +-
  hw/arm/orangepi.c|   6 +
  hw/misc/allwinner-h3-dramc.c | 358 +++
  hw/misc/Makefile.objs|   1 +
  hw/misc/trace-events |  10 +
  7 files changed, 503 insertions(+), 3 deletions(-)
  create mode 100644 include/hw/misc/allwinner-h3-dramc.h
  create mode 100644 hw/misc/allwinner-h3-dramc.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 4b66227ac4..d1b3d7ca67 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -45,6 +45,7 @@
  #include "hw/intc/arm_gic.h"
  #include "hw/misc/allwinner-h3-ccu.h"
  #include "hw/misc/allwinner-cpucfg.h"
+#include "hw/misc/allwinner-h3-dramc.h"
  #include "hw/misc/allwinner-h3-sysctrl.h"
  #include "hw/misc/allwinner-sid.h"
  #include "hw/sd/allwinner-sdhost.h"
@@ -84,6 +85,9 @@ enum {
  AW_H3_UART2,
  AW_H3_UART3,
  AW_H3_EMAC,
+AW_H3_DRAMCOM,
+AW_H3_DRAMCTL,
+AW_H3_DRAMPHY,
  AW_H3_GIC_DIST,
  AW_H3_GIC_CPU,
  AW_H3_GIC_HYP,
@@ -121,6 +125,7 @@ typedef struct AwH3State {
  AwA10PITState timer;
  AwH3ClockCtlState ccu;
  AwCpuCfgState cpucfg;
+AwH3DramCtlState dramc;
  AwH3SysCtrlState sysctrl;
  AwSidState sid;
  AwSdHostState mmc0;
diff --git a/include/hw/misc/allwinner-h3-dramc.h 
b/include/hw/misc/allwinner-h3-dramc.h
new file mode 100644
index 00..70ab331081
--- /dev/null
+++ b/include/hw/misc/allwinner-h3-dramc.h
@@ -0,0 +1,107 @@
+/*
+ * Allwinner H3 SDRAM Controller emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_MISC_ALLWINNER_H3_DRAMC_H
+#define HW_MISC_ALLWINNER_H3_DRAMC_H
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+
+/**
+ * Constants
+ * @{
+ */
+
+/** Highest register address used by DRAMCOM module */
+#define AW_H3_DRAMCOM_REGS_MAXADDR  (0x804)
+
+/** Total number of known DRAMCOM registers */
+#define AW_H3_DRAMCOM_REGS_NUM  (AW_H3_DRAMCOM_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** Highest register address used by DRAMCTL module */
+#define AW_H3_DRAMCTL_REGS_MAXADDR  (0x88c)
+
+/** Total number of known DRAMCTL registers */
+#define AW_H3_DRAMCTL_REGS_NUM  (AW_H3_DRAMCTL_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** Highest register address used by DRAMPHY module */
+#define AW_H3_DRAMPHY_REGS_MAXADDR  (0x4)
+
+/** Total number of known DRAMPHY registers */
+#define AW_H3_DRAMPHY_REGS_NUM  (AW_H3_DRAMPHY_REGS_MAXADDR / \
+ sizeof(uint32_t))
+
+/** @} */
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_H3_DRAMC "allwinner-h3-dramc"
+#define AW_H3_DRAMC(obj) \
+OBJECT_CHECK(AwH3DramCtlState, (obj), TYPE_AW_H3_DRAMC)
+
+/** @} */
+
+/**
+ * Allwinner H3 SDRAM Controller object instance state.
+ */
+typedef struct AwH3DramCtlState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+/** Physical base address for start of RAM */
+hwaddr ram_addr;
+
+/** Total RAM size in megabytes */
+uint32_t ram_size;
+
+/**
+ * @name Memory Regions
+ * @{
+ */
+
+MemoryRegion row_mirror;   /**< Simulates rows for RAM size detection 
*/
+MemoryRegion row_mirror_alias; /**< Alias of the row which is mirrored */
+MemoryRegion dramcom_iomem;/**< DRAMCOM module I/O registers */
+MemoryRegion dramctl_iomem;/**< DRAMCTL module I/O registers */
+MemoryRegion dramphy_iomem;/**< DRAMPHY module I/O registers */
+
+/** @} */
+
+/**
+ * @name Hardware Registers
+ * @{
+ */
+
+uint32_t dramcom[AW_H3_DRAMCOM_REGS_NUM]; /**< Array of DRAMCO

Re: [PATCH v3 09/17] hw/arm/allwinner-h3: add EMAC ethernet device

2020-01-18 Thread Philippe Mathieu-Daudé

Cc'ing the maintainers, please Cc them on v4.

On 1/8/20 9:00 PM, Niek Linnenbank wrote:

The Allwinner Sun8i System on Chip family includes an Ethernet MAC (EMAC)
which provides 10M/100M/1000M Ethernet connectivity. This commit
adds support for the Allwinner EMAC from the Sun8i family (H2+, H3, A33, etc),
including emulation for the following functionality:

  * DMA transfers
  * MII interface
  * Transmit CRC calculation

Signed-off-by: Niek Linnenbank 
---
  include/hw/arm/allwinner-h3.h |   3 +
  include/hw/net/allwinner-sun8i-emac.h | 103 +++
  hw/arm/allwinner-h3.c |  16 +-
  hw/arm/orangepi.c |   3 +
  hw/net/allwinner-sun8i-emac.c | 871 ++
  hw/arm/Kconfig|   1 +
  hw/net/Kconfig|   3 +
  hw/net/Makefile.objs  |   1 +
  hw/net/trace-events   |  10 +
  9 files changed, 1010 insertions(+), 1 deletion(-)
  create mode 100644 include/hw/net/allwinner-sun8i-emac.h
  create mode 100644 hw/net/allwinner-sun8i-emac.c

diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index 0ae830e461..5d74cca28e 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -48,6 +48,7 @@
  #include "hw/misc/allwinner-h3-sysctrl.h"
  #include "hw/misc/allwinner-sid.h"
  #include "hw/sd/allwinner-sdhost.h"
+#include "hw/net/allwinner-sun8i-emac.h"
  #include "target/arm/cpu.h"
  
  /**

@@ -81,6 +82,7 @@ enum {
  AW_H3_UART1,
  AW_H3_UART2,
  AW_H3_UART3,
+AW_H3_EMAC,
  AW_H3_GIC_DIST,
  AW_H3_GIC_CPU,
  AW_H3_GIC_HYP,
@@ -121,6 +123,7 @@ typedef struct AwH3State {
  AwH3SysCtrlState sysctrl;
  AwSidState sid;
  AwSdHostState mmc0;
+AwSun8iEmacState emac;
  GICState gic;
  MemoryRegion sram_a1;
  MemoryRegion sram_a2;
diff --git a/include/hw/net/allwinner-sun8i-emac.h 
b/include/hw/net/allwinner-sun8i-emac.h
new file mode 100644
index 00..d96b564677
--- /dev/null
+++ b/include/hw/net/allwinner-sun8i-emac.h
@@ -0,0 +1,103 @@
+/*
+ * Allwinner Sun8i Ethernet MAC emulation
+ *
+ * Copyright (C) 2019 Niek Linnenbank 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef HW_NET_ALLWINNER_SUN8I_EMAC_H
+#define HW_NET_ALLWINNER_SUN8I_EMAC_H
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "qemu/units.h"
+#include "net/net.h"
+#include "qemu/fifo8.h"
+#include "hw/net/mii.h"
+#include "hw/sysbus.h"
+
+/**
+ * Object model
+ * @{
+ */
+
+#define TYPE_AW_SUN8I_EMAC "allwinner-sun8i-emac"
+#define AW_SUN8I_EMAC(obj) \
+OBJECT_CHECK(AwSun8iEmacState, (obj), TYPE_AW_SUN8I_EMAC)
+
+/** @} */
+
+/**
+ * Allwinner Sun8i EMAC object instance state
+ */
+typedef struct AwSun8iEmacState {
+/*< private >*/
+SysBusDevice  parent_obj;
+/*< public >*/
+
+/** Maps I/O registers in physical memory */
+MemoryRegion iomem;
+
+/** Interrupt output signal to notify CPU */
+qemu_irq irq;
+
+/** Generic Network Interface Controller (NIC) for networking API */
+NICState *nic;
+
+/** Generic Network Interface Controller (NIC) configuration */
+NICConf  conf;
+
+/**
+ * @name Media Independent Interface (MII)
+ * @{
+ */
+
+uint8_t  mii_phy_addr;  /**< PHY address */
+uint32_t mii_cr;/**< Control */
+uint32_t mii_st;/**< Status */
+uint32_t mii_adv;   /**< Advertised Abilities */
+
+/** @} */
+
+/**
+ * @name Hardware Registers
+ * @{
+ */
+
+uint32_t basic_ctl0;/**< Basic Control 0 */
+uint32_t basic_ctl1;/**< Basic Control 1 */
+uint32_t int_en;/**< Interrupt Enable */
+uint32_t int_sta;   /**< Interrupt Status */
+uint32_t frm_flt;   /**< Receive Frame Filter */
+
+uint32_t rx_ctl0;   /**< Receive Control 0 */
+uint32_t rx_ctl1;   /**< Receive Control 1 */
+uint32_t rx_desc_head;  /**< Receive Descriptor List Address */
+uint32_t rx_desc_curr;  /**< Current Receive Descriptor Address */
+
+uint32_t tx_ctl0;   /**< Transmit Control 0 */
+uint32_t tx_ctl1;   /**< Transmit Control 1 */
+uint32_t tx_desc_head;  /**< Transmit Descriptor List Address */
+uint32_t tx_desc_curr;  /**< Curren

Re: [PATCH 6/6] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330

2020-01-18 Thread Guenter Roeck

On 1/17/20 10:44 AM, Peter Maydell wrote:

On Fri, 17 Jan 2020 at 18:29, Guenter Roeck  wrote:

[ ... ]

Rather than having the uart and pl330 pointers be locals,
they should be fields in Exynos4210State. (Otherwise technically
we leak them, though this is unnoticeable in practice because there's
no way to destroy an Exynos4210State.)


Out of curiosity: Is that a new leak because they are now tied together,
or is it an existing leak ? I don't find many DeviceState entries
in xxxState structures, so find it difficult to determine if/when/why
there is such a leak.


Yes, it's an existing leak, though it's more of a conceptual leak


Do only the pointers have to be in Exynos4210State, or the entire
data structures ? In the armsse code it looks like it is the complete
data structures.

Also, it seems to me that this means that not only pl330 and uart states
are affected, but everything created with qdev_create(). If so, the entire
file needs a serious rework, not just its pl330 / uart initialization.
Am I missing something ?

Thanks,
Guenter



Re: [PATCH v3 12/17] hw/arm/allwinner: add RTC device support

2020-01-18 Thread Philippe Mathieu-Daudé

Hi Niek,

On 1/14/20 11:57 PM, Niek Linnenbank wrote:
On Tue, Jan 14, 2020 at 11:52 PM Niek Linnenbank 
mailto:nieklinnenb...@gmail.com>> wrote:


Hi Philippe,

On Mon, Jan 13, 2020 at 11:57 PM Philippe Mathieu-Daudé
mailto:phi...@redhat.com>> wrote:

On 1/8/20 9:00 PM, Niek Linnenbank wrote:
 > Allwinner System-on-Chips usually contain a Real Time Clock (RTC)
 > for non-volatile system date and time keeping. This commit
adds a generic
 > Allwinner RTC device that supports the RTC devices found in
Allwinner SoC
 > family sun4i (A10), sun7i (A20) and sun6i and newer (A31,
H2+, H3, etc).

[...]

 > +static uint64_t allwinner_rtc_read(void *opaque, hwaddr offset,
 > +                                   unsigned size)
 > +{
 > +    AwRtcState *s = AW_RTC(opaque);
 > +    const AwRtcClass *c = AW_RTC_GET_CLASS(s);
 > +    uint64_t val = 0;
 > +
 > +    if (offset >= AW_RTC_REGS_MAXADDR) {
 > +        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
offset 0x%04x\n",
 > +                      __func__, (uint32_t)offset);
 > +        return 0;
 > +    }
 > +
 > +    if (!c->regmap[offset]) {
 > +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
register 0x%04x\n",
 > +                          __func__, (uint32_t)offset);
 > +        return 0;
 > +    }
 > +
 > +    switch (c->regmap[offset]) {
 > +    case REG_LOSC:       /* Low Oscillator Control */
 > +        val = s->regs[REG_LOSC];
 > +        s->regs[REG_LOSC] &= ~(REG_LOSC_YMD | REG_LOSC_HMS);
 > +        break;
 > +    case REG_YYMMDD:     /* RTC Year-Month-Day */
 > +    case REG_HHMMSS:     /* RTC Hour-Minute-Second */
 > +    case REG_GP0:        /* General Purpose Register 0 */
 > +    case REG_GP1:        /* General Purpose Register 1 */
 > +    case REG_GP2:        /* General Purpose Register 2 */
 > +    case REG_GP3:        /* General Purpose Register 3 */
 > +        val = s->regs[c->regmap[offset]];
 > +        break;
 > +    default:
 > +        if (!c->read(s, offset)) {
 > +            qemu_log_mask(LOG_UNIMP, "%s: unimplemented
register 0x%04x\n",
 > +                          __func__, (uint32_t)offset);
 > +        }
 > +        val = s->regs[c->regmap[offset]];
 > +        break;
 > +    }
 > +
 > +    trace_allwinner_rtc_read(offset, val);
 > +    return val;
 > +}
 > +
 > +static void allwinner_rtc_write(void *opaque, hwaddr offset,
 > +                                uint64_t val, unsigned size)
 > +{
 > +    AwRtcState *s = AW_RTC(opaque);
 > +    const AwRtcClass *c = AW_RTC_GET_CLASS(s);
 > +
 > +    if (offset >= AW_RTC_REGS_MAXADDR) {
 > +        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
offset 0x%04x\n",
 > +                      __func__, (uint32_t)offset);
 > +        return;
 > +    }
 > +
 > +    if (!c->regmap[offset]) {
 > +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
register 0x%04x\n",
 > +                          __func__, (uint32_t)offset);
 > +        return;
 > +    }
 > +
 > +    trace_allwinner_rtc_write(offset, val);
 > +
 > +    switch (c->regmap[offset]) {
 > +    case REG_YYMMDD:     /* RTC Year-Month-Day */
 > +        s->regs[REG_YYMMDD] = val;
 > +        s->regs[REG_LOSC]  |= REG_LOSC_YMD;
 > +        break;
 > +    case REG_HHMMSS:     /* RTC Hour-Minute-Second */
 > +        s->regs[REG_HHMMSS] = val;
 > +        s->regs[REG_LOSC]  |= REG_LOSC_HMS;
 > +        break;
 > +    case REG_GP0:        /* General Purpose Register 0 */
 > +    case REG_GP1:        /* General Purpose Register 1 */
 > +    case REG_GP2:        /* General Purpose Register 2 */
 > +    case REG_GP3:        /* General Purpose Register 3 */
 > +        s->regs[c->regmap[offset]] = val;
 > +        break;
 > +    default:
 > +        if (!c->write(s, offset, val)) {
 > +            qemu_log_mask(LOG_UNIMP, "%s: unimplemented
register 0x%04x\n",
 > +                          __func__, (uint32_t)offset);
 > +        }
 > +        break;
 > +    }
 > +}
 > +
 > +static const MemoryRegionOps allwinner_rtc_ops = {
 > +    .read = allwinner_rtc_read,
 > +    .write = allwinner_rtc_write,
 > +    .endianness = DEVICE_NATIVE_ENDIAN,
 > +    .valid = {
   

[PATCH v2] mailmap: Add more entries to sanitize 'git log' output

2020-01-18 Thread Philippe Mathieu-Daudé
Most of these developers have the Signed-off-by tag properly
written, but not the author/committer name. Fix this.
Also we incorrectly wrote Arei Gonglei name, update and reorder.

The committer name/email is displayed when using:

  $ git log --format=fuller

(which can be set in git-config setting format.pretty=fuller).

Example of commits with miswritten committer email:
  3b08098b40 76349f5ba8 eb83c2030a 572992eefa 0d4abda8f7

Note: git-log does not use this file by default until you specify
the --use-mailmap flag:

  $ git log --use-mailmap

Reviewed-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
v2:
- Added Marek Dolata (commit 5a07192a0)
- Describe git-log --format=fuller
- Added Markus R-b
---
 .mailmap | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/.mailmap b/.mailmap
index 3816e4effe..cf981a3ec0 100644
--- a/.mailmap
+++ b/.mailmap
@@ -56,6 +56,10 @@ Aaron Lindsay 
 Alexey Gerasimenko 
 Alex Ivanov 
 Andreas Färber 
+Andreas Färber 
+Andreas Färber  
+Arei Gonglei 
+Arei Gonglei  
 Bandan Das 
 Benjamin MARSILI 
 Benoît Canet 
@@ -67,27 +71,36 @@ Brad Smith 
 Brijesh Singh 
 Brilly Wu 
 Cédric Vincent 
+Chai Wen 
+Chaojian Hu 
 CheneyLin 
+Chen Fan 
 Chen Gang 
 Chen Gang 
 Chen Gang 
 Chen Wei-Ren 
 Christophe Lyon 
+Christoph Hellwig 
 Collin L. Walling 
 Daniel P. Berrangé 
+Disheng Su 
+Dunrong Huang 
 Eduardo Otubo 
 Fabrice Desclaux 
 Fernando Luis Vázquez Cao 
 Fernando Luis Vázquez Cao 
 Gautham R. Shenoy 
 Gautham R. Shenoy 
-Gonglei (Arei) 
 Guang Wang 
 Hailiang Zhang 
 Hervé Poussineau 
+Hiroyuki Obinata 
 Jakub Jermář 
 Jakub Jermář 
+Jay Zhou 
 Jean-Christophe Dubois 
+Jean-Christophe Dubois  
+Jia Lina 
 Jindřich Makovička 
 John Arbuckle 
 Juha Riihimäki 
@@ -96,9 +109,11 @@ Jun Li 
 Laurent Vivier 
 Leandro Lupori 
 Li Guang 
+Lili Huang 
 Liming Wang 
 linzhecheng 
 Liran Schour 
+Li Tianqing 
 Liu Yu 
 Liu Yu 
 Li Zhang 
@@ -110,13 +125,17 @@ Luc Michel 
 Luc Michel 
 Marc Marí 
 Marc Marí 
+Marek Dolata 
 Michael Avdienko 
 Michael S. Tsirkin 
+Michael S. Tsirkin  
+Michael Tokarev  
 Munkyu Im 
 Nicholas Bellinger 
 Nicholas Thomas 
 Nikunj A Dadhania 
 Orit Wasserman 
+Pan Nengyuan 
 Paolo Bonzini 
 Pavel Dovgaluk 
 Pavel Dovgaluk 
@@ -124,15 +143,23 @@ Pavel Dovgaluk 
 Peter Crosthwaite 
 Peter Crosthwaite 
 Peter Crosthwaite 
+Peter Maydell  
 Prasad J Pandit 
 Prasad J Pandit 
 Qiao Nuohan 
 Reimar Döffinger 
 Remy Noel 
+Richard Henderson  
 Roger Pau Monné 
 Shin'ichiro Kawasaki 
 Shin'ichiro Kawasaki 
+Siwei Zhuang 
+Sochin Jiang 
 Sochin Jiang 
+Stefan Berger  
+Stefan Weil  
+Stefan Weil  
+Stefan Weil  
 Takashi Yoshii 
 Thomas Huth 
 Thomas Knych 
@@ -150,6 +177,7 @@ Wenshuang Ma 
 Xiaoqiang Zhao 
 Xinhua Cao 
 Xiong Zhang 
+Ying Fang 
 Yin Yin 
 yuchenlin 
 YunQiang Su 
-- 
2.21.1




Re: [PATCH v2 0/6] buildsys: Build faster (mostly tools and linux-user)

2020-01-18 Thread Philippe Mathieu-Daudé

On 1/18/20 3:06 PM, Philippe Mathieu-Daudé wrote:

In some configuration (linux-user, tools) we can ignore building
various objects (and the libfdt).

Tested with all the combinations of --[enable|disable]-tools,
--[enable|disable]-user and --[enable|disable]-system using the
following commands (suggested by Laurent Vivier in v1):

   $ mkdir build
   $ cd build
   $ for user in enable disable; do \
 for tools in enable disable; do \
 for system in enable disable; do \
 rm -fr build-$user-$system-$tools && \
 mkdir build-$user-$system-$tools && \
 (cd build-$user-$system-$tools && \
  ../../configure \
  --${user}-user \
  --${system}-system \
  --${tools}-tools \
  --disable-docs \
 ); \
 done; \
 done; \
 done

Then building each of the 8 subdirectories on x86_64 and aarch64
hosts, running 'make check', and only on x86_64:
'make run-tcg-tests-x86_64-linux-user'.

All CI green:
https://gitlab.com/philmd/qemu/pipelines/110420332
https://travis-ci.org/philmd/qemu/builds/638781159
https://app.shippable.com/github/philmd/qemu/runs/587/summary/console

Since v1:
- no code change, improved commit description, added review tags
- added 2 new patches touching hw/core/ (remove reset.o from linux-user)

$ git backport-diff -u v1
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/6:[] [--] 'configure: Do not build libfdt if not required'
002/6:[] [--] 'Makefile: Clarify all the codebase requires qom/ objects'
003/6:[] [--] 'Makefile: Restrict system emulation and tools objects'
004/6:[] [--] 'Makefile: Remove unhelpful comment'
005/6:[down] 'hw/core: Restrict reset handlers API to system-mode'
006/6:[down] 'hw/core/Makefile: Group generic objects versus system-mode 
objects'

Supersedes: <20200109153939.27173-1-phi...@redhat.com>


  ^ testing latest patchew feature, v2 has different subject name
than v1, but patchew successfully linked them :)

See "Diff against v1" in v2:
https://patchew.org/QEMU/20200118140619.26333-1-phi...@redhat.com/

https://patchew.org/QEMU/20200109153939.27173-1-phi...@redhat.com/diff/20200118140619.26333-1-phi...@redhat.com/

Thanks Kevin & Paolo for this feature :)




  1   2   >