Re: [PATCH v10 6/9] KVM: Unmap existing mappings when change the memory attributes

2022-12-18 Thread Chao Peng
On Tue, Dec 13, 2022 at 11:51:25PM +, Huang, Kai wrote:
> On Fri, 2022-12-02 at 14:13 +0800, Chao Peng wrote:
> >  
> > -   /* flags is currently not used. */
> > +   /* 'flags' is currently not used. */
> >     if (attrs->flags)
> >     return -EINVAL;
> 
> Unintended code change.

Yeah!

Chao



Re: [PATCH v10 1/9] mm: Introduce memfd_restricted system call to create restricted user memory

2022-12-18 Thread Chao Peng
On Tue, Dec 13, 2022 at 11:49:13PM +, Huang, Kai wrote:
> > 
> > memfd_restricted() itself is implemented as a shim layer on top of real
> > memory file systems (currently tmpfs). Pages in restrictedmem are marked
> > as unmovable and unevictable, this is required for current confidential
> > usage. But in future this might be changed.
> > 
> > 
> I didn't dig full histroy, but I interpret this as we don't support page
> migration and swapping for restricted memfd for now.  IMHO "page marked as
> unmovable" can be confused with PageMovable(), which is a different thing from
> this series.  It's better to just say something like "those pages cannot be
> migrated and swapped".

Yes, if that helps some clarification.

> 
> [...]
> 
> > +
> > +   /*
> > +* These pages are currently unmovable so don't place them into movable
> > +* pageblocks (e.g. CMA and ZONE_MOVABLE).
> > +*/
> > +   mapping = memfd->f_mapping;
> > +   mapping_set_unevictable(mapping);
> > +   mapping_set_gfp_mask(mapping,
> > +mapping_gfp_mask(mapping) & ~__GFP_MOVABLE);
> 
> But, IIUC removing __GFP_MOVABLE flag here only makes page allocation from 
> non-
> movable zones, but doesn't necessarily prevent page from being migrated.  My
> first glance is you need to implement either a_ops->migrate_folio() or just
> get_page() after faulting in the page to prevent.

The current api restrictedmem_get_page() already does this, after the
caller calling it, it holds a reference to the page. The caller then
decides when to call put_page() appropriately.

> 
> So I think the comment also needs improvement -- IMHO we can just call out
> currently those pages cannot be migrated and swapped, which is clearer (and 
> the
> latter justifies mapping_set_unevictable() clearly).

Good to me.

Thanks,
Chao
> 
> 



Re: [PATCH] i386: SGX: remove deprecated member of SGXInfo

2022-12-18 Thread Yang Zhong
On Sun, Dec 18, 2022 at 01:06:49AM +0100, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini 
> ---
>  docs/about/deprecated.rst   | 13 -
>  docs/about/removed-features.rst | 13 +
>  hw/i386/sgx.c   | 15 ++-
>  qapi/misc-target.json   | 12 ++--
>  4 files changed, 21 insertions(+), 32 deletions(-)
> 

   Tested-by: Yang Zhong 

   By the way, there is another sgx bug, please help review, thanks!
   https://lists.nongnu.org/archive/html/qemu-devel/2022-10/msg04825.html

   Yang
> 
> 



[PATCH v14 5/8] config: add check to block layer

2022-12-18 Thread Sam Li
Putting zoned/non-zoned BlockDrivers on top of each other is not
allowed.

Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Dmitry Fomichev 
---
 block.c  | 19 +++
 block/file-posix.c   | 12 
 block/raw-format.c   |  1 +
 include/block/block_int-common.h |  5 +
 4 files changed, 37 insertions(+)

diff --git a/block.c b/block.c
index 9c2ac757e4..09abea9da7 100644
--- a/block.c
+++ b/block.c
@@ -7912,6 +7912,25 @@ void bdrv_add_child(BlockDriverState *parent_bs, 
BlockDriverState *child_bs,
 return;
 }
 
+/*
+ * Non-zoned block drivers do not follow zoned storage constraints
+ * (i.e. sequential writes to zones). Refuse mixing zoned and non-zoned
+ * drivers in a graph.
+ */
+if (!parent_bs->drv->supports_zoned_children &&
+child_bs->bl.zoned == BLK_Z_HM) {
+/*
+ * The host-aware model allows zoned storage constraints and random
+ * write. Allow mixing host-aware and non-zoned drivers. Using
+ * host-aware device as a regular device.
+ */
+error_setg(errp, "Cannot add a %s child to a %s parent",
+   child_bs->bl.zoned == BLK_Z_HM ? "zoned" : "non-zoned",
+   parent_bs->drv->supports_zoned_children ?
+   "support zoned children" : "not support zoned children");
+return;
+}
+
 if (!QLIST_EMPTY(&child_bs->parents)) {
 error_setg(errp, "The node %s already has a parent",
child_bs->node_name);
diff --git a/block/file-posix.c b/block/file-posix.c
index 269c5b508a..091a95c1a9 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -775,6 +775,18 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 goto fail;
 }
 }
+#ifdef CONFIG_BLKZONED
+/*
+ * The kernel page cache does not reliably work for writes to SWR zones
+ * of zoned block device because it can not guarantee the order of writes.
+ */
+if ((strcmp(bs->drv->format_name, "zoned_host_device") == 0) &&
+(!(s->open_flags & O_DIRECT))) {
+error_setg(errp, "driver=zoned_host_device was specified, but it "
+   "requires cache.direct=on, which was not specified.");
+return -EINVAL; /* No host kernel page cache */
+}
+#endif
 
 if (S_ISBLK(st.st_mode)) {
 #ifdef __linux__
diff --git a/block/raw-format.c b/block/raw-format.c
index 8e42fa83ed..2fcc2ad7f6 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -617,6 +617,7 @@ static void raw_child_perm(BlockDriverState *bs, BdrvChild 
*c,
 BlockDriver bdrv_raw = {
 .format_name  = "raw",
 .instance_size= sizeof(BDRVRawState),
+.supports_zoned_children = true,
 .bdrv_probe   = &raw_probe,
 .bdrv_reopen_prepare  = &raw_reopen_prepare,
 .bdrv_reopen_commit   = &raw_reopen_commit,
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index dc6ee8006c..77eb0a2a8b 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -141,6 +141,11 @@ struct BlockDriver {
  */
 bool is_format;
 
+/*
+ * Set to true if the BlockDriver supports zoned children.
+ */
+bool supports_zoned_children;
+
 /*
  * Drivers not implementing bdrv_parse_filename nor bdrv_open should have
  * this field set to true, except ones that are defined only by their
-- 
2.38.1




[PATCH v14 4/8] raw-format: add zone operations to pass through requests

2022-12-18 Thread Sam Li
raw-format driver usually sits on top of file-posix driver. It needs to
pass through requests of zone commands.

Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Damien Le Moal 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Dmitry Fomichev 
---
 block/raw-format.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/block/raw-format.c b/block/raw-format.c
index 28905b09ee..8e42fa83ed 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -316,6 +316,17 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState 
*bs,
 return bdrv_co_pdiscard(bs->file, offset, bytes);
 }
 
+static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t 
offset,
+   unsigned int *nr_zones,
+   BlockZoneDescriptor *zones) {
+return bdrv_co_zone_report(bs->file->bs, offset, nr_zones, zones);
+}
+
+static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
+ int64_t offset, int64_t len) {
+return bdrv_co_zone_mgmt(bs->file->bs, op, offset, len);
+}
+
 static int64_t raw_getlength(BlockDriverState *bs)
 {
 int64_t len;
@@ -617,6 +628,8 @@ BlockDriver bdrv_raw = {
 .bdrv_co_pwritev  = &raw_co_pwritev,
 .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
 .bdrv_co_pdiscard = &raw_co_pdiscard,
+.bdrv_co_zone_report  = &raw_co_zone_report,
+.bdrv_co_zone_mgmt  = &raw_co_zone_mgmt,
 .bdrv_co_block_status = &raw_co_block_status,
 .bdrv_co_copy_range_from = &raw_co_copy_range_from,
 .bdrv_co_copy_range_to  = &raw_co_copy_range_to,
-- 
2.38.1




[PATCH v14 3/8] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-12-18 Thread Sam Li
Add a new zoned_host_device BlockDriver. The zoned_host_device option
accepts only zoned host block devices. By adding zone management
operations in this new BlockDriver, users can use the new block
layer APIs including Report Zone and four zone management operations
(open, close, finish, reset, reset_all).

Qemu-io uses the new APIs to perform zoned storage commands of the device:
zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs),
zone_finish(zf).

For example, to test zone_report, use following command:
$ ./build/qemu-io --image-opts -n driver=zoned_host_device, filename=/dev/nullb0
-c "zrp offset nr_zones"

Signed-off-by: Sam Li 
Reviewed-by: Hannes Reinecke 
---
 block/block-backend.c | 147 
 block/file-posix.c| 364 ++
 block/io.c|  41 
 include/block/block-io.h  |   7 +
 include/block/block_int-common.h  |  21 ++
 include/block/raw-aio.h   |   6 +-
 include/sysemu/block-backend-io.h |  18 ++
 meson.build   |   4 +
 qapi/block-core.json  |   8 +-
 qemu-io-cmds.c| 149 
 10 files changed, 762 insertions(+), 3 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index ba7bf1d6bc..a4847b9131 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1451,6 +1451,15 @@ typedef struct BlkRwCo {
 void *iobuf;
 int ret;
 BdrvRequestFlags flags;
+union {
+struct {
+unsigned int *nr_zones;
+BlockZoneDescriptor *zones;
+} zone_report;
+struct {
+unsigned long op;
+} zone_mgmt;
+};
 } BlkRwCo;
 
 int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
@@ -1795,6 +1804,144 @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
 return ret;
 }
 
+static void coroutine_fn blk_aio_zone_report_entry(void *opaque)
+{
+BlkAioEmAIOCB *acb = opaque;
+BlkRwCo *rwco = &acb->rwco;
+
+rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
+   rwco->zone_report.nr_zones,
+   rwco->zone_report.zones);
+blk_aio_complete(acb);
+}
+
+BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
+unsigned int *nr_zones,
+BlockZoneDescriptor  *zones,
+BlockCompletionFunc *cb, void *opaque)
+{
+BlkAioEmAIOCB *acb;
+Coroutine *co;
+IO_CODE();
+
+blk_inc_in_flight(blk);
+acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
+acb->rwco = (BlkRwCo) {
+.blk= blk,
+.offset = offset,
+.ret= NOT_DONE,
+.zone_report = {
+.zones = zones,
+.nr_zones = nr_zones,
+},
+};
+acb->has_returned = false;
+
+co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
+bdrv_coroutine_enter(blk_bs(blk), co);
+
+acb->has_returned = true;
+if (acb->rwco.ret != NOT_DONE) {
+replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
+ blk_aio_complete_bh, acb);
+}
+
+return &acb->common;
+}
+
+static void coroutine_fn blk_aio_zone_mgmt_entry(void *opaque)
+{
+BlkAioEmAIOCB *acb = opaque;
+BlkRwCo *rwco = &acb->rwco;
+
+rwco->ret = blk_co_zone_mgmt(rwco->blk, rwco->zone_mgmt.op,
+ rwco->offset, acb->bytes);
+blk_aio_complete(acb);
+}
+
+BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
+  int64_t offset, int64_t len,
+  BlockCompletionFunc *cb, void *opaque) {
+BlkAioEmAIOCB *acb;
+Coroutine *co;
+IO_CODE();
+
+blk_inc_in_flight(blk);
+acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
+acb->rwco = (BlkRwCo) {
+.blk= blk,
+.offset = offset,
+.ret= NOT_DONE,
+.zone_mgmt = {
+.op = op,
+},
+};
+acb->bytes = len;
+acb->has_returned = false;
+
+co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
+bdrv_coroutine_enter(blk_bs(blk), co);
+
+acb->has_returned = true;
+if (acb->rwco.ret != NOT_DONE) {
+replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
+ blk_aio_complete_bh, acb);
+}
+
+return &acb->common;
+}
+
+/*
+ * Send a zone_report command.
+ * offset is a byte offset from the start of the device. No alignment
+ * required for offset.
+ * nr_zones represents IN maximum and OUT actual.
+ */
+int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
+unsigned int *nr_zones,
+BlockZoneDescriptor *zones)
+{
+int ret;
+IO_CODE();
+
+blk_inc_in_flight(blk); /* increase before waiting */
+blk_wait_while

[PATCH v14 2/8] file-posix: introduce helper functions for sysfs attributes

2022-12-18 Thread Sam Li
Use get_sysfs_str_val() to get the string value of device
zoned model. Then get_sysfs_zoned_model() can convert it to
BlockZoneModel type of QEMU.

Use get_sysfs_long_val() to get the long value of zoned device
information.

Signed-off-by: Sam Li 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Damien Le Moal 
Reviewed-by: Dmitry Fomichev 
---
 block/file-posix.c   | 124 ++-
 include/block/block_int-common.h |   3 +
 2 files changed, 91 insertions(+), 36 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index b9647c5ffc..676dd65c65 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1201,66 +1201,112 @@ static int hdev_get_max_hw_transfer(int fd, struct 
stat *st)
 #endif
 }
 
-static int hdev_get_max_segments(int fd, struct stat *st)
-{
+/*
+ * Get a sysfs attribute value as character string.
+ */
+static int get_sysfs_str_val(struct stat *st, const char *attribute,
+ char **val) {
 #ifdef CONFIG_LINUX
-char buf[32];
-const char *end;
-char *sysfspath = NULL;
+g_autofree char *sysfspath = NULL;
 int ret;
-int sysfd = -1;
-long max_segments;
+size_t len;
 
-if (S_ISCHR(st->st_mode)) {
-if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
-return ret;
-}
+if (!S_ISBLK(st->st_mode)) {
 return -ENOTSUP;
 }
 
-if (!S_ISBLK(st->st_mode)) {
-return -ENOTSUP;
+sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
+major(st->st_rdev), minor(st->st_rdev),
+attribute);
+ret = g_file_get_contents(sysfspath, val, &len, NULL);
+if (ret == -1) {
+return -ENOENT;
 }
 
-sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-major(st->st_rdev), minor(st->st_rdev));
-sysfd = open(sysfspath, O_RDONLY);
-if (sysfd == -1) {
-ret = -errno;
-goto out;
+/* The file is ended with '\n' */
+char *p;
+p = *val;
+if (*(p + len - 1) == '\n') {
+*(p + len - 1) = '\0';
 }
-do {
-ret = read(sysfd, buf, sizeof(buf) - 1);
-} while (ret == -1 && errno == EINTR);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int get_sysfs_zoned_model(struct stat *st, BlockZoneModel *zoned)
+{
+g_autofree char *val = NULL;
+int ret;
+
+ret = get_sysfs_str_val(st, "zoned", &val);
 if (ret < 0) {
-ret = -errno;
-goto out;
-} else if (ret == 0) {
-ret = -EIO;
-goto out;
+return ret;
 }
-buf[ret] = 0;
-/* The file is ended with '\n', pass 'end' to accept that. */
-ret = qemu_strtol(buf, &end, 10, &max_segments);
-if (ret == 0 && end && *end == '\n') {
-ret = max_segments;
+
+if (strcmp(val, "host-managed") == 0) {
+*zoned = BLK_Z_HM;
+} else if (strcmp(val, "host-aware") == 0) {
+*zoned = BLK_Z_HA;
+} else if (strcmp(val, "none") == 0) {
+*zoned = BLK_Z_NONE;
+} else {
+return -ENOTSUP;
 }
+return 0;
+}
 
-out:
-if (sysfd != -1) {
-close(sysfd);
+/*
+ * Get a sysfs attribute value as a long integer.
+ */
+static long get_sysfs_long_val(struct stat *st, const char *attribute)
+{
+#ifdef CONFIG_LINUX
+g_autofree char *str = NULL;
+const char *end;
+long val;
+int ret;
+
+ret = get_sysfs_str_val(st, attribute, &str);
+if (ret < 0) {
+return ret;
+}
+
+/* The file is ended with '\n', pass 'end' to accept that. */
+ret = qemu_strtol(str, &end, 10, &val);
+if (ret == 0 && end && *end == '\0') {
+ret = val;
 }
-g_free(sysfspath);
 return ret;
 #else
 return -ENOTSUP;
 #endif
 }
 
+static int hdev_get_max_segments(int fd, struct stat *st)
+{
+#ifdef CONFIG_LINUX
+int ret;
+
+if (S_ISCHR(st->st_mode)) {
+if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
+return ret;
+}
+return -ENOTSUP;
+}
+return get_sysfs_long_val(st, "max_segments");
+#else
+return -ENOTSUP;
+#endif
+}
+
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
 struct stat st;
+int ret;
+BlockZoneModel zoned;
 
 s->needs_alignment = raw_needs_alignment(bs);
 raw_probe_alignment(bs, s->fd, errp);
@@ -1298,6 +1344,12 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 bs->bl.max_hw_iov = ret;
 }
 }
+
+ret = get_sysfs_zoned_model(&st, &zoned);
+if (ret < 0) {
+zoned = BLK_Z_NONE;
+}
+bs->bl.zoned = zoned;
 }
 
 static int check_for_dasd(int fd)
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index c34c525fa6..4941c24488 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -840,6 +840,9 @@ typ

[PATCH v14 1/8] include: add zoned device structs

2022-12-18 Thread Sam Li
Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Damien Le Moal 
Reviewed-by: Hannes Reinecke 
---
 include/block/block-common.h | 43 
 1 file changed, 43 insertions(+)

diff --git a/include/block/block-common.h b/include/block/block-common.h
index 4749c46a5e..8995066e4c 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -64,6 +64,49 @@ typedef struct BlockDriver BlockDriver;
 typedef struct BdrvChild BdrvChild;
 typedef struct BdrvChildClass BdrvChildClass;
 
+typedef enum BlockZoneOp {
+BLK_ZO_OPEN,
+BLK_ZO_CLOSE,
+BLK_ZO_FINISH,
+BLK_ZO_RESET,
+} BlockZoneOp;
+
+typedef enum BlockZoneModel {
+BLK_Z_NONE = 0x0, /* Regular block device */
+BLK_Z_HM = 0x1, /* Host-managed zoned block device */
+BLK_Z_HA = 0x2, /* Host-aware zoned block device */
+} BlockZoneModel;
+
+typedef enum BlockZoneState {
+BLK_ZS_NOT_WP = 0x0,
+BLK_ZS_EMPTY = 0x1,
+BLK_ZS_IOPEN = 0x2,
+BLK_ZS_EOPEN = 0x3,
+BLK_ZS_CLOSED = 0x4,
+BLK_ZS_RDONLY = 0xD,
+BLK_ZS_FULL = 0xE,
+BLK_ZS_OFFLINE = 0xF,
+} BlockZoneState;
+
+typedef enum BlockZoneType {
+BLK_ZT_CONV = 0x1, /* Conventional random writes supported */
+BLK_ZT_SWR = 0x2, /* Sequential writes required */
+BLK_ZT_SWP = 0x3, /* Sequential writes preferred */
+} BlockZoneType;
+
+/*
+ * Zone descriptor data structure.
+ * Provides information on a zone with all position and size values in bytes.
+ */
+typedef struct BlockZoneDescriptor {
+uint64_t start;
+uint64_t length;
+uint64_t cap;
+uint64_t wp;
+BlockZoneType type;
+BlockZoneState state;
+} BlockZoneDescriptor;
+
 typedef struct BlockDriverInfo {
 /* in bytes, 0 if irrelevant */
 int cluster_size;
-- 
2.38.1




[PATCH v14 0/8] Add support for zoned device

2022-12-18 Thread Sam Li
Zoned Block Devices (ZBDs) devide the LBA space to block regions called zones
that are larger than the LBA size. It can only allow sequential writes, which
reduces write amplification in SSD, leading to higher throughput and increased
capacity. More details about ZBDs can be found at:

https://zonedstorage.io/docs/introduction/zoned-storage

The zoned device support aims to let guests (virtual machines) access zoned
storage devices on the host (hypervisor) through a virtio-blk device. This
involves extending QEMU's block layer and virtio-blk emulation code.  In its
current status, the virtio-blk device is not aware of ZBDs but the guest sees
host-managed drives as regular drive that will runs correctly under the most
common write workloads.

This patch series extend the block layer APIs with the minimum set of zoned
commands that are necessary to support zoned devices. The commands are - Report
Zones, four zone operations and Zone Append (developing).

It can be tested on a null_blk device using qemu-io or qemu-iotests. For
example, to test zone report using qemu-io:
$ path/to/qemu-io --image-opts -n driver=zoned_host_device,filename=/dev/nullb0
-c "zrp offset nr_zones"

v14:
- address Stefan's comments of probing block sizes

v13:
- add some tracing points for new zone APIs [Dmitry]
- change error handling in zone_mgmt [Damien, Stefan]

v12:
- address review comments
  * drop BLK_ZO_RESET_ALL bit [Damien]
  * fix error messages, style, and typos[Damien, Hannes]

v11:
- address review comments
  * fix possible BLKZONED config compiling warnings [Stefan]
  * fix capacity field compiling warnings on older kernel [Stefan,Damien]

v10:
- address review comments
  * deal with the last small zone case in zone_mgmt operations [Damien]
  * handle the capacity field outdated in old kernel(before 5.9) [Damien]
  * use byte unit in block layer to be consistent with QEMU [Eric]
  * fix coding style related problems [Stefan]

v9:
- address review comments
  * specify units of zone commands requests [Stefan]
  * fix some error handling in file-posix [Stefan]
  * introduce zoned_host_devcie in the commit message [Markus]

v8:
- address review comments
  * solve patch conflicts and merge sysfs helper funcations into one patch
  * add cache.direct=on check in config

v7:
- address review comments
  * modify sysfs attribute helper funcations
  * move the input validation and error checking into raw_co_zone_* function
  * fix checks in config

v6:
- drop virtio-blk emulation changes
- address Stefan's review comments
  * fix CONFIG_BLKZONED configs in related functions
  * replace reading fd by g_file_get_contents() in get_sysfs_str_val()
  * rewrite documentation for zoned storage

v5:
- add zoned storage emulation to virtio-blk device
- add documentation for zoned storage
- address review comments
  * fix qemu-iotests
  * fix check to block layer
  * modify interfaces of sysfs helper functions
  * rename zoned device structs according to QEMU styles
  * reorder patches

v4:
- add virtio-blk headers for zoned device
- add configurations for zoned host device
- add zone operations for raw-format
- address review comments
  * fix memory leak bug in zone_report
  * add checks to block layers
  * fix qemu-iotests format
  * fix sysfs helper functions

v3:
- add helper functions to get sysfs attributes
- address review comments
  * fix zone report bugs
  * fix the qemu-io code path
  * use thread pool to avoid blocking ioctl() calls

v2:
- add qemu-io sub-commands
- address review comments
  * modify interfaces of APIs

v1:
- add block layer APIs resembling Linux ZoneBlockDevice ioctls

Sam Li (8):
  include: add zoned device structs
  file-posix: introduce helper functions for sysfs attributes
  block: add block layer APIs resembling Linux ZonedBlockDevice ioctls
  raw-format: add zone operations to pass through requests
  config: add check to block layer
  qemu-iotests: test new zone operations
  block: add some trace events for new block layer APIs
  docs/zoned-storage: add zoned device documentation

 block.c|  19 +
 block/block-backend.c  | 147 
 block/file-posix.c | 503 +++--
 block/io.c |  41 ++
 block/raw-format.c |  14 +
 block/trace-events |   2 +
 docs/devel/zoned-storage.rst   |  43 +++
 docs/system/qemu-block-drivers.rst.inc |   6 +
 include/block/block-common.h   |  43 +++
 include/block/block-io.h   |   7 +
 include/block/block_int-common.h   |  29 ++
 include/block/raw-aio.h|   6 +-
 include/sysemu/block-backend-io.h  |  18 +
 meson.build|   4 +
 qapi/block-core.json   |   8 +-
 qemu-io-cmds.c | 149 
 tests/qemu-iotests/tests/zoned.out |  53 +++
 tests/qemu-iotests/tests/zoned.sh  |  86 +
 18 files changed, 1139 in

Re: [PATCH 01/11] audio: log unimplemented audio device sample rates

2022-12-18 Thread Volker Rümelin

Am 18.12.22 um 21:26 schrieb Christian Schoenebeck:

On Sunday, December 18, 2022 6:15:29 PM CET Volker Rümelin wrote:

Some emulated audio devices allow guests to select very low
sample rates that the audio subsystem doesn't support. The lowest
supported sample rate depends on the audio backend used and in
most cases can be changed with various -audiodev arguments. Until
now, the audio_bug function emits an error message similar to the
following error message

A bug was just triggered in audio_calloc
Save all your work and restart without audio
I am sorry
Context:
audio_pcm_sw_alloc_resources_out passed invalid arguments to
  audio_calloc
nmemb=0 size=16 (len=0)
audio: Could not allocate buffer for `ac97.po' (0 samples)

and the audio subsystem continues without sound for the affected
device.

The fact that the selected sample rate is not supported is not a
guest error. Instead of displaying an error message, the missing
audio support is now logged. Simply continuing without sound is
correct, since the audio stream won't transport anything
reasonable at such high resample ratios anyway.

The AUD_open_* functions return NULL like before. The opened
audio device will not be registered in the audio subsystem and
consequently the audio frontend callback functions will not be
called. The AUD_read and AUD_write functions return early in this
case. This is necessary because, for example, the Sound Blaster 16
emulation calls AUD_write from the DMA callback function.

Signed-off-by: Volker Rümelin
---
  audio/audio.c  |  1 +
  audio/audio_template.h | 13 +
  2 files changed, 14 insertions(+)

diff --git a/audio/audio.c b/audio/audio.c
index d849a94a81..f6b420688d 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -31,6 +31,7 @@
  #include "qapi/qobject-input-visitor.h"
  #include "qapi/qapi-visit-audio.h"
  #include "qemu/cutils.h"
+#include "qemu/log.h"
  #include "qemu/module.h"
  #include "qemu/help_option.h"
  #include "sysemu/sysemu.h"
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 720a32e57e..bfa94b4d22 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -115,6 +115,19 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
  #else
  samples = (int64_t)sw->HWBUF->size * sw->ratio >> 32;
  #endif
+if (samples == 0) {
+HW *hw = sw->hw;
+size_t f_fe_min;
+
+/* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */
+f_fe_min = (hw->info.freq + HWBUF->size - 1) / HWBUF->size;
+qemu_log_mask(LOG_UNIMP,
+  AUDIO_CAP ": The guest selected a " NAME " sample rate"
+  " of %d Hz for %s. Only sample rates >= %zu Hz are"
+  " supported.\n",
+  sw->info.freq, sw->name, f_fe_min);
+return -1;

You probably want to `sw->buf = NULL;` before returning here, or adjust the
condition for the error message below.


sw->buf is always NULL here. In the audio_pcm_create_voice_pair_*() 
functions we have sw = audio_calloc(__func__, 1, sizeof(*sw)) (after 
patch 08/11 sw = g_new0(SW, 1)) and the audio_pcm_sw_free_resources_*() 
functions also set sw->buf = NULL after freeing sw->buf.



The other thing that puzzles me, in error case these template functions return
-1, which would then be feed to g_malloc*()?


Sorry, I can't see where -1 would be fed to g_malloc*().

On error the audio_pcm_sw_alloc_resources_*() functions return error 
code -1, and that error code propagates up to the AUD_open_*() functions 
or the audio_pcm_create_voice_pair_*() functions which return NULL.



+}
  
  sw->buf = audio_calloc(__func__, samples, sizeof(struct st_sample));

  if (!sw->buf) {






Re: [PATCH v4 20b/27] tcg: Vary the allocation size for TCGOp

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 23:44, Richard Henderson wrote:

On 12/18/22 13:49, Philippe Mathieu-Daudé wrote:

+ found:
  memset(op, 0, offsetof(TCGOp, link));
  op->opc = opc;
-    s->nb_ops++;
+    op->nargs = nargs;


We can move this assignation before the 'found' label.


No, affected by the memset.


Oh, I missed that, good point.




Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 23:39, Strahinja Jankovic wrote:

Hi,

On Sun, Dec 18, 2022 at 11:23 PM Philippe Mathieu-Daudé
 wrote:


On 18/12/22 23:12, Strahinja Jankovic wrote:

Hi,

On Sun, Dec 18, 2022 at 11:07 PM Philippe Mathieu-Daudé
 wrote:


On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch adds minimal support for AXP-209 PMU.
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
the chip ID register, reset values for two more registers used by A10
U-Boot SPL are covered.

Signed-off-by: Strahinja Jankovic 
---
hw/arm/Kconfig  |   1 +
hw/misc/Kconfig |   4 +
hw/misc/allwinner-axp-209.c | 238 
hw/misc/meson.build |   1 +
hw/misc/trace-events|   5 +
5 files changed, 249 insertions(+)
create mode 100644 hw/misc/allwinner-axp-209.c




+config ALLWINNER_AXP_209


This controller is not specific to AllWinner. It can be plugged on any
i2c bus. Please rename it AXP209_PMU. Otherwise LGTM!


Do you mean only in Kconfig, or everywhere (file name, function names,
etc.)? Thanks.


Keeping the file / functions names with 'allwinner' would give the false
idea this is AllWinner specific; rather confusing isn't it? Besides it
is not part of the SoC, this is an external component sitting on the
bus. So "everywhere".


I was expecting that answer, but I wanted to check :)
When I started writing code for AXP209 it was indeed without allwinner
prefix, but then checkpatch.pl complained about missing lines in
MAINTAINERS. At that time it was easier to add the prefix (and get a
match in MAINTAINERS) than to investigate if I should update the
MAINTAINERS file or ignore the checkpatch.pl complaint.

I will update everything related to AXP209 so it does not have the
Allwinner prefix.


Add a new AXP209 MAINTAINERS's section with your name :) Or add the new
file to the Allwinner-a10 section and add your name as designated
reviewer or co-maintainer :)



Re: [PATCH v2 0/7] Enable Cubieboard A10 boot SPL from SD card

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 23:57, Strahinja Jankovic wrote:

Hi,

I just looked around a bit more. Would OpenWrt image be acceptable?


Sure.


It looks like there are releases for cubieboard that are kept for a
longer time, and I just checked that they work properly, so I could
add them to the acceptance test.

Best regards,
Strahinja

On Sun, Dec 18, 2022 at 11:34 PM Strahinja Jankovic
 wrote:


Hi,


On Sun, Dec 18, 2022 at 11:17 PM Philippe Mathieu-Daudé
 wrote:


On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch series adds missing Allwinner A10 modules needed for
successful SPL boot:
- Clock controller module
- DRAM controller
- I2C0 controller (added also for Allwinner H3 since it is the same)
- AXP-209 connected to I2C0 bus

It also updates Allwinner A10 emulation so SPL is copied from attached
SD card if `-kernel` parameter is not passed when starting QEMU
(approach adapted from Allwinner H3 implementation).

Boot from SD card has been tested with Cubieboard Armbian SD card image and 
custom
Yocto image built for Cubieboard.
Example usage for Armbian image:
qemu-system-arm -M cubieboard -nographic -sd 
~/Armbian_22.11.0-trunk_Cubieboard_kinetic_edge_6.0.7.img


As a follow-up, could you add a test similar to
test_arm_orangepi_bionic_20_08() in tests/avocado/boot_linux_console.py?

This test could be refactored as do_test_arm_allwinner_armbian(), called
for orangepi and cubieboard with the corresponding url / hash.


I was planning to do it (I already have a patch for cubieboard), but
there is a problem with finding a stable-enough image for cubieboard
for automated testing.
Unfortunately, Cubieboard does not have supported Armbian images as
OrangePi-PC has (it only has weekly builds).


Developers shouldn't worry about that but focus on the testing. The
QEMU project doesn't have dedicated sysadmin / storage, but if it had
it should be their problem, not yours. Meanwhile such a test is still
useful. Artifacts come with their hash, so can be uploaded elsewhere
later.


From the images that can
be found on archive.armbian.com, there is only one bionic image
(21.02) and it won't boot because it hangs due to the musb issue (I
tried both with my patches and without, by extracting
kernel/dtb/initrd).


Similar approach:
https://lore.kernel.org/qemu-devel/20201018205551.1537927-4-f4...@amsat.org/


Other images are focal, but for some reason, in
those images it is impossible to interrupt U-Boot (tested with 21.08),
so I could not append to bootcmd to make boot process more verbose and
easier to monitor for automated testing.

That is why, for now, I would suggest not updating the SPL/SD boot
test for Cubieboard.


Niek can tell how many times his tests catched regressions for his
OrangePi machine; I remember at least 3 occasions :)

Regards,

Phil.



Re: [RFC PATCH-for-8.0 2/3] hw/ppc/spapr: Replace tswap64(HPTE) by cpu_to_be64(HPTE)

2022-12-18 Thread David Gibson
On Fri, Dec 16, 2022 at 09:39:19PM +, Peter Maydell wrote:
> On Fri, 16 Dec 2022 at 19:11, Daniel Henrique Barboza
>  wrote:
> >
> >
> >
> > On 12/13/22 10:51, Peter Maydell wrote:
> > > On Tue, 13 Dec 2022 at 12:52, Philippe Mathieu-Daudé  
> > > wrote:
> > >>
> > >> The tswap64() calls introduced in commit 4be21d561d ("pseries:
> > >> savevm support for pseries machine") are used to store the HTAB
> > >> in the migration stream (see savevm_htab_handlers) and are in
> > >> big-endian format.
> > >
> > > I think they're reading the run-time spapr->htab data structure
> > > (some of which is stuck onto the wire as a stream-of-bytes buffer
> > > and some of which is not). But either way, it's a target-endian
> > > data structure, because the code in hw/ppc/spapr_softmmu.c which
> > > reads and writes entries in it is using ldq_p() and stq_p(),
> > > and the current in-tree version of these macros is doing a
> > > "read host 64-bit and convert to/from target endianness wih tswap64".
> > >
> > >>   #define HPTE(_table, _i)   (void *)(((uint64_t *)(_table)) + ((_i) * 
> > >> 2))
> > >> -#define HPTE_VALID(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & 
> > >> HPTE64_V_VALID)
> > >> -#define HPTE_DIRTY(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & 
> > >> HPTE64_V_HPTE_DIRTY)
> > >> -#define CLEAN_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) &= 
> > >> tswap64(~HPTE64_V_HPTE_DIRTY))
> > >> -#define DIRTY_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) |= 
> > >> tswap64(HPTE64_V_HPTE_DIRTY))
> > >> +#define HPTE_VALID(_hpte)  (be64_to_cpu(*((uint64_t *)(_hpte))) & 
> > >> HPTE64_V_VALID)
> > >> +#define HPTE_DIRTY(_hpte)  (be64_to_cpu(*((uint64_t *)(_hpte))) & 
> > >> HPTE64_V_HPTE_DIRTY)
> > >> +#define CLEAN_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) &= 
> > >> cpu_to_be64(~HPTE64_V_HPTE_DIRTY))
> > >> +#define DIRTY_HPTE(_hpte)  ((*(uint64_t *)(_hpte)) |= 
> > >> cpu_to_be64(HPTE64_V_HPTE_DIRTY))
> > >
> > > This means we now have one file that's accessing this data structure
> > > as "this is target-endian", and one file that's accessing it as
> > > "this is big-endian". It happens that that ends up meaning the same
> > > thing because PPC is always TARGET_BIG_ENDIAN, but it seems a bit
> > > inconsistent.
> > >
> > > We should decide whether we're thinking of the data structure
> > > as target-endian or big-endian and change all the accessors
> > > appropriately (or none of them -- currently we're completely
> > > consistent about treating it as "target endian", I think).
> >
> > Yes, most if not all accesses are being handled as "target endian", even
> > though the target is always big endian.

So "target is always big endian" is pretty misleading for POWER.  We
always define "TARGET_BIG_ENDIAN" in qemu, but for at least 10 years
the CPUs have been capable of running in either big endian or little
endian mode (selected at runtime).  Some variants can choose
endianness on a per-page basis.  Since the creation of the ISA it's
had "byte reversed" load and store instructions that let it use little
endian for specific memory accesses.

Really the whole notion of an ISA having an "endianness" doesn't make
a lot of sense - it's an individual load or store to memory that has
an endianness which can depend on a bunch of factors.  When these
macros were created, an ISA nearly always used the same endianness,
but that's not really true any more - not just for POWER, but for a
bunch of targets.  So from that point of view, I think getting rid of
tswap() - particularly one that has compile time semantics, rather
than behaviour which can depend on cpu mode/state is a good idea.

I believe that even when running in little-endian mode, the hash page
tables are encoded in big-endian, so I think the proposed change makes
sense.

> > IIUC the idea behind Phil's cleanups is exactly to replace uses of
> > "target-something" if the endianess of the host is irrelevant, which
> > is the case for ppc64. We would then change the semantics of the code
> > gradually to make it consistent again.
> 
> I would be happier if we just did all the functions that read and
> write this byte array at once -- there are not many of them.
> 
> thanks
> -- PMM
> 

-- 
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 v2 0/6] Support for new CPU model SapphireRapids

2022-12-18 Thread Wang, Lei
Kindly ping for any comments:)

BR,
Lei

On 11/2/2022 4:52 PM, Wang, Lei wrote:
> This series aims to add a new CPU model SapphireRapids, and tries to
> address the problem stated in
> https://lore.kernel.org/all/20220812055751.14553-1-lei4.w...@intel.com/T/#mcf67dbd1ad37c65d7988c36a2b267be9afd2fb30,
> so that named CPU model can define its own AMX values, and QEMU won't
> pass the wrong AMX values to KVM in future platforms if they have
> different values supported.
> 
> The original patch is
> https://lore.kernel.org/all/20220812055751.14553-1-lei4.w...@intel.com/T/#u.
> 
> ---
> 
> Changelog:
> 
> v2:
>  - Fix when passing all zeros of AMX-related CPUID, QEMU will warn
>unsupported.
>  - Remove unnecessary function definition and make code cleaner.
>  - Fix some typos.
>  - v1:
>
> https://lore.kernel.org/qemu-devel/20221027020036.373140-1-lei4.w...@intel.com/T/#t
> 
> Wang, Lei (6):
>   i386: Introduce FeatureWordInfo for AMX CPUID leaf 0x1D and 0x1E
>   i386: Remove unused parameter "uint32_t bit" in
> feature_word_description()
>   i386: Introduce new struct "MultiBitFeatureInfo" for multi-bit
> features
>   i386: Mask and report unavailable multi-bit feature values
>   i386: Initialize AMX CPUID leaves with corresponding env->features[]
> leaves
>   i386: Add new CPU model SapphireRapids
> 
>  target/i386/cpu-internal.h |  11 ++
>  target/i386/cpu.c  | 311 +++--
>  target/i386/cpu.h  |  16 ++
>  3 files changed, 322 insertions(+), 16 deletions(-)
> 



Re: [PATCH 4/4] coroutine: Break inclusion loop

2022-12-18 Thread Markus Armbruster
Paolo Bonzini  writes:

> On 12/15/22 07:49, Markus Armbruster wrote:
>>> linux-user/ does not use coroutines, so I'd like to avoid that it
>>> includes qemu/coroutine.h.
>> They include it even before the patch, via lockable.h.
>
> They do but there's a difference between "including lockable.h and implictly 
> getting coroutine.h due to dependencies" and "including 
> coroutine.h when you really wanted QEMU_LOCK_GUARD()".
>
>> My patch actually enables*not*  including coroutine.h: with it applied,
>> including lockable.h no longer gets you coroutine.h as well.
>> If you include lockable.h and make use of certain macros, the compile
>> fails, and you fix it by including coroutine.h instead like pretty much
>> everything else.  Is this really too objectionable to be committed?
>
> s/certain macros/all macros/.  All you can do is qemu_lockable_lock/unlock, 
> which is the less common usage of 
> qemu/lockable.h:
>
> - qemu_lockable_lock/unlock: used in include/qemu/seqlock.h, 
> tests/unit/test-coroutine.c, util/qemu-coroutine-lock.c
>
> - QEMU_LOCK_GUARD and WITH_QEMU_LOCK_GUARD are used in 49 files.
>
 1) qemu/coroutine.h keeps including qemu/lockable.h
>>
>> As in my patch.
>
> That's where the similarity ends. :)
>
 2) qemu/lockable.h is modified as follows to omit the reference to CoMutex:

 diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h
 index 86db7cb04c9c..db59656538a4 100644
 --- a/include/qemu/lockable.h
 +++ b/include/qemu/lockable.h
 @@ -71,9 +71,11 @@ qemu_null_lockable(void *x)
 void *: qemu_null_lockable(x), 
 \
 QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)),
 \
 QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x,
 rec_mutex)), \
 - CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),   \
 + QEMU_MAKE_CO_MUTEX_LOCKABLE(x) \
 QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))

 +#define QEMU_MAKE_CO_MUTEX_LOCKABLE(x)
 +
/**
 * QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
 *

 3) the following hack is added in qemu/coroutine.h, right after including
 qemu/lockable.h:

 #undef QEMU_MAKE_CO_MUTEX_LOCKABLE(x)
 #define QEMU_MAKE_CO_MUTEX_LOCKABLE(x) \
CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),
>>
>> Let me see...  if I include just lockable.h and make use of certain
>> (generic) macro(s), the macro(s) won't have a case for QemuMutex *.
>> Using them with a QemuMutex * argument won't compile.
>
> s/QemuMutex/CoMutex/.  That is, you get the CoMutex case only if you include 
> qemu/coroutine.h.  Which you probably did anyway, because 
> CoMutexes are almost always embedded (not used as pointers).  In fact I 
> suspect the above trick also makes it possible to remove CoMutex from 
> qemu/typedefs.h.
>
> Furthermore, using qemu_lockable_lock/unlock with CoMutexes still works, even 
> if you don't include qemu/coroutine.h, just like in your patch.
>
 Neither is particularly pretty, so I vote for leaving things as is with
 a comment above the two #include directives.
>>
>> Inlusion loops are landmines.  Evidence: the compilation failure Phil
>> ran in, leading to his
>>  Subject: [PATCH-for-8.0] coroutine: Add missing  include
>>  Message-Id:<20221125175532.48858-1-phi...@linaro.org>
>> Your macro hack I find too off-putting 😄
>
> I think the macro is much better than nerfing qemu/lockable.h.

The core of the problem is that lockable.h wants to provide _Generic()
with a CoMutex case if CoMutex exists.

The solution you proposed approximates this as follows.  lockable.h
makes the case configurable, default off.  coroutine.h configures it to
on, and includes lockable.h.  Works as long as we include only
coroutine.h, or coroutine.h before lockable.h.  Falls apart if we
include lockable.h, and only then coroutine.h.

For a robust solution, we'd need to enable lockable.h to detect "this
compilation unit may use coroutines".  Could CONFIG_USB_ONLY be pressed
into service?

> Another alternative is to add a new header qemu/lockable-protos.h and move 
> qemu_co_mutex_{lock,unlock} there (possibly other prototypes as 
> well).  Then include it from both qemu/lockable.h and qemu/coroutine.h.

Only from lockable.h, because coroutine.h gets it via lockable.h, right?

Lazy^Wpragmatic solution: move the coroutine.h parts lockable.h needs to
lockable.h.  As far as I can tell:

typedef CoMutex (unless we keep it in typedefs.h)
qemu_co_mutex_lock()
qemu_co_mutex_unlock()

Could throw in

qemu_co_mutex_init()
qemu_co_mutex_assert_locked()

to avoid splitting the co_mutex interface.

If keeping this in lockable.h bothers you, we could create comutex.h for
it.

Can't see what adding more to the new header would buy us (other than
arguments on

[PATCH] target/i386/gdbstub: Fix a bug about order of FPU stack in 'g' packets.

2022-12-18 Thread TaiseiIto
Before this commit, when GDB attached an OS working on QEMU, order of FPU
stack registers printed by GDB command 'info float' was wrong. There was a
bug causing the problem in 'g' packets sent by QEMU to GDB. The packets have
values of registers of machine emulated by QEMU containing FPU stack
registers. There are 2 ways to specify a x87 FPU stack register. The first
is specifying by absolute indexed register names (R0, ..., R7). The second
is specifying by stack top relative indexed register names (ST0, ..., ST7).
Values of the FPU stack registers should be located in 'g' packet and be
ordered by the relative index. But QEMU had located these registers ordered
by the absolute index. After this commit, when QEMU reads registers to make
a 'g' packet, QEMU specifies FPU stack registers by the relative index.
Then, the registers are ordered correctly in the packet. As a result, GDB,
the packet receiver, can print FPU stack registers in the correct order.

Signed-off-by: TaiseiIto 
---
 target/i386/gdbstub.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index c3a2cf6f28..6109ad166d 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -121,7 +121,9 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
 }
 } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS];
+int st_index = n - IDX_FP_REGS;
+int r_index = (st_index + env->fpstt) % 8;
+floatx80 *fp = &env->fpregs[r_index].d;
 int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low));
 len += gdb_get_reg16(mem_buf, cpu_to_le16(fp->high));
 return len;
-- 
2.34.1




[PATCH] target/i386/gdbstub: Fix a bug about order of FPU stack in 'g' packets.

2022-12-18 Thread TaiseiIto
Before this commit, when GDB attached an OS working on QEMU, order of FPU
stack registers printed by GDB command 'info float' was wrong. There was a
bug causing the problem in 'g' packets sent by QEMU to GDB. The packets have
values of registers of machine emulated by QEMU containing FPU stack
registers. There are 2 ways to specify a x87 FPU stack register. The first
is specifying by absolute indexed register names (R0, ..., R7). The second
is specifying by stack top relative indexed register names (ST0, ..., ST7).
Values of the FPU stack registers should be located in 'g' packet and be
ordered by the relative index. But QEMU had located these registers ordered
by the absolute index. After this commit, when QEMU reads registers to make
a 'g' packet, QEMU specifies FPU stack registers by the relative index.
Then, the registers are ordered correctly in the packet. As a result, GDB,
the packet receiver, can print FPU stack registers in the correct order.

Signed-off-by: TaiseiIto 
---
 target/i386/gdbstub.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index c3a2cf6f28..6109ad166d 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -121,7 +121,9 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
 }
 } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS];
+int st_index = n - IDX_FP_REGS;
+int r_index = (st_index + env->fpstt) % 8;
+floatx80 *fp = &env->fpregs[r_index].d;
 int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low));
 len += gdb_get_reg16(mem_buf, cpu_to_le16(fp->high));
 return len;
-- 
2.34.1




[PULL 20/45] target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()

2022-12-18 Thread Alistair Francis
From: Bin Meng 

sstatus register dump is currently missing in riscv_cpu_dump_state().
As sstatus is a copy of mstatus, which is described in the priv spec,
it seems redundant to print the same information twice.

Add some comments for this to let people know this is intentional.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221125050354.3166023-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6fe176e483..b2c132e269 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -382,6 +382,10 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
int flags)
 CSR_MHARTID,
 CSR_MSTATUS,
 CSR_MSTATUSH,
+/*
+ * CSR_SSTATUS is intentionally omitted here as its value
+ * can be figured out by looking at CSR_MSTATUS
+ */
 CSR_HSTATUS,
 CSR_VSSTATUS,
 CSR_MIP,
-- 
2.38.1




[PULL 42/45] hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb

2022-12-18 Thread Alistair Francis
From: Bin Meng 

Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt 
machine")
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
should include interrupt source 0 but "riscv,ndev" does not.

While we are here, we also fix the comments of platform bus irq range
which is now "64 to 96", but should be "64 to 95", introduced since
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").

Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt 
machine")
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-13-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 5 ++---
 hw/riscv/virt.c | 3 ++-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 62513e075c..e1ce0048af 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -87,14 +87,13 @@ enum {
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
 PCIE_IRQ = 0x20, /* 32 to 35 */
-VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
-VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
+VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
 };
 
 #define VIRT_PLATFORM_BUS_NUM_IRQS 32
 
 #define VIRT_IRQCHIP_NUM_MSIS 255
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
+#define VIRT_IRQCHIP_NUM_SOURCES 96
 #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 6cf9355b99..94ff2a1584 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -468,7 +468,8 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
 plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
-qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
+qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
+  VIRT_IRQCHIP_NUM_SOURCES - 1);
 riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
 qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
 plic_phandles[socket]);
-- 
2.38.1




[PULL 08/45] hw/riscv/opentitan: add aon_timer base unimpl

2022-12-18 Thread Alistair Francis
From: Wilfred Mallawa 

Adds the updated `aon_timer` base as an unimplemented device. This is
used by TockOS, patch ensures the guest doesn't hit load faults.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221025043335.339815-3-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 1 +
 hw/riscv/opentitan.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 1fc055cdff..7659d1bc5b 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -81,6 +81,7 @@ enum {
 IBEX_DEV_RSTMGR,
 IBEX_DEV_CLKMGR,
 IBEX_DEV_PINMUX,
+IBEX_DEV_AON_TIMER,
 IBEX_DEV_USBDEV,
 IBEX_DEV_FLASH_CTRL,
 IBEX_DEV_PLIC,
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 92493c629d..78f895d773 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -56,6 +56,7 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_RSTMGR] = {  0x4041,  0x1000  },
 [IBEX_DEV_CLKMGR] = {  0x4042,  0x1000  },
 [IBEX_DEV_PINMUX] = {  0x4046,  0x1000  },
+[IBEX_DEV_AON_TIMER] =  {  0x4047,  0x1000  },
 [IBEX_DEV_SENSOR_CTRL] ={  0x4049,  0x1000  },
 [IBEX_DEV_FLASH_CTRL] = {  0x4100,  0x1000  },
 [IBEX_DEV_AES] ={  0x4110,  0x1000  },
@@ -272,6 +273,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
 create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
 memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
+create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
+memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
 create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
 memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
 create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
-- 
2.38.1




[PULL 22/45] hw/riscv: pfsoc: add missing FICs as unimplemented

2022-12-18 Thread Alistair Francis
From: Conor Dooley 

The Fabric Interconnect Controllers provide interfaces between the FPGA
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
does not show up on the MSS memory map. FIC4 is dedicated to the User
Crypto Processor and does not show up on the MSS memory map either.

FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
are represented in QEMU, leading to load access violations while booting
Linux for Icicle if PCIe is enabled as the root port is connected via
either FIC 0 or 1.

Acked-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-Id: <20221117225518.4102575-3-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h |   2 +
 hw/riscv/microchip_pfsoc.c | 115 -
 2 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index a757b240e0..7e7950dd36 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -121,6 +121,8 @@ enum {
 MICROCHIP_PFSOC_USB,
 MICROCHIP_PFSOC_QSPI_XIP,
 MICROCHIP_PFSOC_IOSCB,
+MICROCHIP_PFSOC_FABRIC_FIC0,
+MICROCHIP_PFSOC_FABRIC_FIC1,
 MICROCHIP_PFSOC_FABRIC_FIC3,
 MICROCHIP_PFSOC_DRAM_LO,
 MICROCHIP_PFSOC_DRAM_LO_ALIAS,
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index a821263d4f..2a24e3437a 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -86,58 +86,61 @@
  * describes the complete IOSCB modules memory maps
  */
 static const MemMapEntry microchip_pfsoc_memmap[] = {
-[MICROCHIP_PFSOC_RSVD0] =   {0x0,  0x100 },
-[MICROCHIP_PFSOC_DEBUG] =   {  0x100,  0xf00 },
-[MICROCHIP_PFSOC_E51_DTIM] ={  0x100, 0x2000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT0] ={  0x170, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT1] ={  0x1701000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT2] ={  0x1702000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT3] ={  0x1703000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT4] ={  0x1704000, 0x1000 },
-[MICROCHIP_PFSOC_CLINT] =   {  0x200,0x1 },
-[MICROCHIP_PFSOC_L2CC] ={  0x201, 0x1000 },
-[MICROCHIP_PFSOC_DMA] = {  0x300,   0x10 },
-[MICROCHIP_PFSOC_L2LIM] =   {  0x800,  0x200 },
-[MICROCHIP_PFSOC_PLIC] ={  0xc00,  0x400 },
-[MICROCHIP_PFSOC_MMUART0] = { 0x2000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG0] =   { 0x20001000, 0x1000 },
-[MICROCHIP_PFSOC_SYSREG] =  { 0x20002000, 0x2000 },
-[MICROCHIP_PFSOC_AXISW] =   { 0x20004000, 0x1000 },
-[MICROCHIP_PFSOC_MPUCFG] =  { 0x20005000, 0x1000 },
-[MICROCHIP_PFSOC_FMETER] =  { 0x20006000, 0x1000 },
-[MICROCHIP_PFSOC_DDR_SGMII_PHY] =   { 0x20007000, 0x1000 },
-[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
-[MICROCHIP_PFSOC_DDR_CFG] = { 0x2008,0x4 },
-[MICROCHIP_PFSOC_MMUART1] = { 0x2010, 0x1000 },
-[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
-[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
-[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG1] =   { 0x20101000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG2] =   { 0x20103000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG3] =   { 0x20105000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG4] =   { 0x20106000, 0x1000 },
-[MICROCHIP_PFSOC_SPI0] ={ 0x20108000, 0x1000 },
-[MICROCHIP_PFSOC_SPI1] ={ 0x20109000, 0x1000 },
-[MICROCHIP_PFSOC_I2C0] ={ 0x2010a000, 0x1000 },
-[MICROCHIP_PFSOC_I2C1] ={ 0x2010b000, 0x1000 },
-[MICROCHIP_PFSOC_CAN0] ={ 0x2010c000, 0x1000 },
-[MICROCHIP_PFSOC_CAN1] ={ 0x2010d000, 0x1000 },
-[MICROCHIP_PFSOC_GEM0] ={ 0x2011, 0x2000 },
-[MICROCHIP_PFSOC_GEM1] ={ 0x20112000, 0x2000 },
-[MICROCHIP_PFSOC_GPIO0] =   { 0x2012, 0x1000 },
-[MICROCHIP_PFSOC_GPIO1] =   { 0x20121000, 0x1000 },
-[MICROCHIP_PFSOC_GPIO2] =   { 0x20122000, 0x1000 },
-[MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
-[MICROCHIP_PFSOC_ENVM_CFG] ={ 0x2020, 0x1000 },
-[MICROCHIP_PFSOC_ENVM_DATA] =   { 0x2022,0x2 },
-[MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
-[MICROCHIP_PFSOC_QSPI_XIP] ={ 0x2100,  0x100 },
-[MICROCHIP_PFSOC_IOSCB] =   { 0x3000, 0x1000 },
-[MICROCHIP_PFSOC_FABRIC_FIC3] = 

[PULL 23/45] hw/{misc, riscv}: pfsoc: add system controller as unimplemented

2022-12-18 Thread Alistair Francis
From: Conor Dooley 

The system controller on PolarFire SoC is access via a mailbox. The
control registers for this mailbox lie in the "IOSCB" region & the
interrupt is cleared via write to the "SYSREG" region. It also has a
QSPI controller, usually connected to a flash chip, that is used for
storing FPGA bitstreams and used for In-Application Programming (IAP).

Linux has an implementation of the system controller, through which the
hwrng is accessed, leading to load/store access faults.

Add the QSPI as unimplemented and a very basic (effectively
unimplemented) version of the system controller's mailbox. Rather than
purely marking the regions as unimplemented, service the mailbox
requests by reporting failures and raising the interrupt so a guest can
better handle the lack of support.

Signed-off-by: Conor Dooley 
Acked-by: Alistair Francis 
Message-Id: <20221117225518.4102575-4-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/misc/mchp_pfsoc_ioscb.h  |  3 ++
 include/hw/misc/mchp_pfsoc_sysreg.h |  1 +
 include/hw/riscv/microchip_pfsoc.h  |  1 +
 hw/misc/mchp_pfsoc_ioscb.c  | 72 -
 hw/misc/mchp_pfsoc_sysreg.c | 18 ++--
 hw/riscv/microchip_pfsoc.c  |  6 +++
 6 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h 
b/include/hw/misc/mchp_pfsoc_ioscb.h
index 687b213742..a1104862c8 100644
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
@@ -29,6 +29,8 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion lane01;
 MemoryRegion lane23;
 MemoryRegion ctrl;
+MemoryRegion qspixip;
+MemoryRegion mailbox;
 MemoryRegion cfg;
 MemoryRegion ccc;
 MemoryRegion pll_mss;
@@ -41,6 +43,7 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion cfm_sgmii;
 MemoryRegion bc_sgmii;
 MemoryRegion io_calib_sgmii;
+qemu_irq irq;
 } MchpPfSoCIoscbState;
 
 #define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h 
b/include/hw/misc/mchp_pfsoc_sysreg.h
index 546ba68f6a..3cebe40ea9 100644
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
@@ -28,6 +28,7 @@
 typedef struct MchpPfSoCSysregState {
 SysBusDevice parent;
 MemoryRegion sysreg;
+qemu_irq irq;
 } MchpPfSoCSysregState;
 
 #define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 7e7950dd36..69a686b54a 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -147,6 +147,7 @@ enum {
 MICROCHIP_PFSOC_MMUART2_IRQ = 92,
 MICROCHIP_PFSOC_MMUART3_IRQ = 93,
 MICROCHIP_PFSOC_MMUART4_IRQ = 94,
+MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
 };
 
 #define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT1
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
index f976e42f72..a71d134295 100644
--- a/hw/misc/mchp_pfsoc_ioscb.c
+++ b/hw/misc/mchp_pfsoc_ioscb.c
@@ -24,6 +24,7 @@
 #include "qemu/bitops.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "hw/irq.h"
 #include "hw/sysbus.h"
 #include "hw/misc/mchp_pfsoc_ioscb.h"
 
@@ -34,6 +35,9 @@
 #define IOSCB_WHOLE_REG_SIZE0x1000
 #define IOSCB_SUBMOD_REG_SIZE   0x1000
 #define IOSCB_CCC_REG_SIZE  0x200
+#define IOSCB_CTRL_REG_SIZE 0x800
+#define IOSCB_QSPIXIP_REG_SIZE  0x200
+
 
 /*
  * There are many sub-modules in the IOSCB module.
@@ -45,6 +49,8 @@
 #define IOSCB_LANE01_BASE   0x0650
 #define IOSCB_LANE23_BASE   0x0651
 #define IOSCB_CTRL_BASE 0x0702
+#define IOSCB_QSPIXIP_BASE  0x07020100
+#define IOSCB_MAILBOX_BASE  0x07020800
 #define IOSCB_CFG_BASE  0x0708
 #define IOSCB_CCC_BASE  0x0800
 #define IOSCB_PLL_MSS_BASE  0x0E001000
@@ -143,6 +149,58 @@ static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = 
{
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+#define SERVICES_CR 0x50
+#define SERVICES_SR 0x54
+#define SERVICES_STATUS_SHIFT   16
+
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+uint32_t val = 0;
+
+switch (offset) {
+case SERVICES_SR:
+/*
+ * Although some services have no error codes, most do. All services
+ * that do implement errors, begin their error codes at 1. Treat all
+ * service requests as failures & return 1.
+ * See the "PolarFire® FPGA and PolarFire SoC FPGA System Services"
+ * user guide for more information on service error codes.
+ */
+val = 1u << SERVICES_STATUS_SHIFT;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
+  "(size %d, offset 0x%" HWADDR_PRIx ")\n",
+  __func__, size, offset);
+}
+

[PULL 11/45] target/riscv: generate virtual instruction exception

2022-12-18 Thread Alistair Francis
From: Mayuresh Chitale 

This patch adds a mechanism to generate a virtual instruction
instruction exception instead of an illegal instruction exception
during instruction decode when virt is enabled.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-4-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index db123da5ec..8b0bd38bb2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -76,6 +76,7 @@ typedef struct DisasContext {
to reset this known value.  */
 int frm;
 RISCVMXL ol;
+bool virt_inst_excp;
 bool virt_enabled;
 const RISCVCPUConfig *cfg_ptr;
 bool hlsx;
@@ -243,7 +244,11 @@ static void gen_exception_illegal(DisasContext *ctx)
 {
 tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
offsetof(CPURISCVState, bins));
-generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+if (ctx->virt_inst_excp) {
+generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
+} else {
+generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+}
 }
 
 static void gen_exception_inst_addr_mis(DisasContext *ctx)
@@ -1062,6 +1067,7 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
 };
 
+ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
 if (!has_ext(ctx, RVC)) {
-- 
2.38.1




[PULL 00/45] riscv-to-apply queue

2022-12-18 Thread Alistair Francis
From: Alistair Francis 

The following changes since commit 562d4af32ec2213061f844b3838223fd7711b56a:

  Merge tag 'pull-loongarch-20221215' of https://gitlab.com/gaosong/qemu into 
staging (2022-12-18 13:53:29 +)

are available in the Git repository at:

  https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221219-3

for you to fetch changes up to e59b3c6ece6a1351aeca6b916cd9674e23d15e89:

  hw/intc: sifive_plic: Fix the pending register range check (2022-12-19 
10:42:14 +1000)


First RISC-V PR for QEMU 8.0

* Fix PMP propagation for tlb
* Collection of bug fixes
* Add the `FIELDx_1CLEAR()` macro
* Bump the OpenTitan supported version
* Add smstateen support
* Support native debug icount trigger
* Remove the redundant ipi-id property in the virt machine
* Support cache-related PMU events in virtual mode
* Add some missing PolarFire SoC io regions
* Fix mret exception cause when no pmp rule is configured
* Fix bug where disabling compressed instructions would crash QEMU
* Add Zawrs ISA extension support
* A range of code refactoring and cleanups


Anup Patel (1):
  target/riscv: Typo fix in sstc() predicate

Atish Patra (1):
  hw/riscv: virt: Remove the redundant ipi-id property

Bin Meng (20):
  target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
  target/riscv: Fix mret exception cause when no pmp rule is configured
  target/riscv: Simplify helper_sret() a little bit
  target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
  hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
  hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
  hw/riscv: Fix opentitan dependency to SIFIVE_PLIC
  hw/riscv: Sort machines Kconfig options in alphabetical order
  hw/riscv: spike: Remove misleading comments
  hw/intc: sifive_plic: Drop PLICMode_H
  hw/intc: sifive_plic: Improve robustness of the PLIC config parser
  hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp 
in sifive_plic_realize()
  hw/intc: sifive_plic: Update "num-sources" property default value
  hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC
  hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC
  hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"
  hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb
  hw/intc: sifive_plic: Change "priority-base" to start from interrupt 
source 0
  hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization
  hw/intc: sifive_plic: Fix the pending register range check

Christoph Muellner (1):
  RISC-V: Add Zawrs ISA extension support

Conor Dooley (3):
  hw/misc: pfsoc: add fabric clocks to ioscb
  hw/riscv: pfsoc: add missing FICs as unimplemented
  hw/{misc, riscv}: pfsoc: add system controller as unimplemented

Frédéric Pétrot (1):
  hw/intc: sifive_plic: Renumber the S irqs for numa support

Jim Shu (2):
  target/riscv: support cache-related PMU events in virtual mode
  hw/intc: sifive_plic: fix out-of-bound access of source_priority array

LIU Zhiwei (5):
  target/riscv: Fix PMP propagation for tlb
  target/riscv: Add itrigger support when icount is not enabled
  target/riscv: Add itrigger support when icount is enabled
  target/riscv: Enable native debug itrigger
  target/riscv: Add itrigger_enabled field to CPURISCVState

Mayuresh Chitale (3):
  target/riscv: Add smstateen support
  target/riscv: smstateen check for h/s/envcfg
  target/riscv: generate virtual instruction exception

Richard Henderson (4):
  tcg/riscv: Fix range matched by TCG_CT_CONST_M12
  tcg/riscv: Fix reg overlap case in tcg_out_addsub2
  tcg/riscv: Fix base register for user-only qemu_ld/st
  target/riscv: Set pc_succ_insn for !rvc illegal insn

Wilfred Mallawa (4):
  hw/registerfields: add `FIELDx_1CLEAR()` macro
  hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro
  hw/riscv/opentitan: bump opentitan
  hw/riscv/opentitan: add aon_timer base unimpl

 include/hw/intc/sifive_plic.h  |   1 -
 include/hw/misc/mchp_pfsoc_ioscb.h |   4 +
 include/hw/misc/mchp_pfsoc_sysreg.h|   1 +
 include/hw/registerfields.h|  22 ++
 include/hw/riscv/microchip_pfsoc.h |   7 +-
 include/hw/riscv/opentitan.h   |  10 +-
 include/hw/riscv/shakti_c.h|   2 +-
 include/hw/riscv/sifive_e.h|   9 +-
 include/hw/riscv/sifive_u.h|   2 +-
 include/hw/riscv/virt.h|   8 +-
 target/riscv/cpu.h |  10 +
 target/riscv/cpu_bits.h|  37 +++
 target/riscv/debug.h   |  13 +
 target/riscv/helper

[PULL 35/45] hw/intc: sifive_plic: Drop PLICMode_H

2022-12-18 Thread Alistair Francis
From: Bin Meng 

H-mode has been removed since priv spec 1.10. Drop it.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-6-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/intc/sifive_plic.h | 1 -
 hw/intc/sifive_plic.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
index 134cf39a96..d3f45ec248 100644
--- a/include/hw/intc/sifive_plic.h
+++ b/include/hw/intc/sifive_plic.h
@@ -33,7 +33,6 @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
 typedef enum PLICMode {
 PLICMode_U,
 PLICMode_S,
-PLICMode_H,
 PLICMode_M
 } PLICMode;
 
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 0c7696520d..936dcf74bc 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -42,7 +42,6 @@ static PLICMode char_to_mode(char c)
 switch (c) {
 case 'U': return PLICMode_U;
 case 'S': return PLICMode_S;
-case 'H': return PLICMode_H;
 case 'M': return PLICMode_M;
 default:
 error_report("plic: invalid mode '%c'", c);
-- 
2.38.1




[PULL 37/45] hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize()

2022-12-18 Thread Alistair Francis
From: Bin Meng 

The realize() callback has an errp for us to propagate the error up.
While we are here, correct the wrong multi-line comment format.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221211030829.802437-8-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index c9af94a888..9cb4c6d6d4 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -379,7 +379,8 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
 qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
 
-/* We can't allow the supervisor to control SEIP as this would allow the
+/*
+ * We can't allow the supervisor to control SEIP as this would allow the
  * supervisor to clear a pending external interrupt which will result in
  * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
  * hardware controlled when a PLIC is attached.
@@ -387,8 +388,8 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 for (i = 0; i < s->num_harts; i++) {
 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
 if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
-error_report("SEIP already claimed");
-exit(1);
+error_setg(errp, "SEIP already claimed");
+return;
 }
 }
 
-- 
2.38.1




[PULL 17/45] target/riscv: Typo fix in sstc() predicate

2022-12-18 Thread Alistair Francis
From: Anup Patel 

We should use "&&" instead of "&" when checking hcounteren.TM and
henvcfg.STCE bits.

Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
Signed-off-by: Anup Patel 
Reviewed-by: Alistair Francis 
Message-Id: <20221108125703.1463577-2-apa...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 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 71236f2b5d..0db2c233e5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -940,7 +940,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 }
 
 if (riscv_cpu_virt_enabled(env)) {
-if (!(get_field(env->hcounteren, COUNTEREN_TM) &
+if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
   get_field(env->henvcfg, HENVCFG_STCE))) {
 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 }
-- 
2.38.1




[PULL 06/45] tcg/riscv: Fix base register for user-only qemu_ld/st

2022-12-18 Thread Alistair Francis
From: Richard Henderson 

When guest_base != 0, we were not coordinating the usage of
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
of the input address being discarded.

Shuffle the alignment check to the front, because that does not
depend on the zero-extend, and it keeps the register usage clear.
Set base after each step of the address arithmetic instead of before.

Return the base register used from tcg_out_tlb_load, so as to
keep that register choice localized to that function.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <2022102327.2846860-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 39 +-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 2a84c57bec..e3b608034f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -923,9 +923,9 @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit 
*target)
 tcg_debug_assert(ok);
 }
 
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
- TCGReg addrh, MemOpIdx oi,
- tcg_insn_unit **label_ptr, bool is_load)
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
+   TCGReg addrh, MemOpIdx oi,
+   tcg_insn_unit **label_ptr, bool is_load)
 {
 MemOp opc = get_memop(oi);
 unsigned s_bits = opc & MO_SIZE;
@@ -975,6 +975,7 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
 addrl = TCG_REG_TMP0;
 }
 tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
+return TCG_REG_TMP0;
 }
 
 static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
@@ -1177,7 +1178,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 #else
 unsigned a_bits;
 #endif
-TCGReg base = TCG_REG_TMP0;
+TCGReg base;
 
 data_regl = *args++;
 data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
@@ -1187,23 +1188,25 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 opc = get_memop(oi);
 
 #if defined(CONFIG_SOFTMMU)
-tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
+base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
 add_qemu_ldst_label(s, 1, oi,
 (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
 data_regl, data_regh, addr_regl, addr_regh,
 s->code_ptr, label_ptr);
 #else
-if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
-tcg_out_ext32u(s, base, addr_regl);
-addr_regl = base;
-}
 a_bits = get_alignment_bits(opc);
 if (a_bits) {
 tcg_out_test_alignment(s, true, addr_regl, a_bits);
 }
+base = addr_regl;
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, TCG_REG_TMP0, base);
+base = TCG_REG_TMP0;
+}
 if (guest_base != 0) {
-tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
+base = TCG_REG_TMP0;
 }
 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
 #endif
@@ -1249,7 +1252,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 #else
 unsigned a_bits;
 #endif
-TCGReg base = TCG_REG_TMP0;
+TCGReg base;
 
 data_regl = *args++;
 data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
@@ -1259,23 +1262,25 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 opc = get_memop(oi);
 
 #if defined(CONFIG_SOFTMMU)
-tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
+base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
 tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
 add_qemu_ldst_label(s, 0, oi,
 (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
 data_regl, data_regh, addr_regl, addr_regh,
 s->code_ptr, label_ptr);
 #else
-if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
-tcg_out_ext32u(s, base, addr_regl);
-addr_regl = base;
-}
 a_bits = get_alignment_bits(opc);
 if (a_bits) {
 tcg_out_test_alignment(s, false, addr_regl, a_bits);
 }
+base = addr_regl;
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, TCG_REG_TMP0, base);
+base = TCG_REG_TMP0;
+}
 if (guest_base != 0) {
-tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
+base = TCG_REG_TMP0;
 }
 tcg_out_qemu_st_

[PULL 45/45] hw/intc: sifive_plic: Fix the pending register range check

2022-12-18 Thread Alistair Francis
From: Bin Meng 

The pending register upper limit is currently set to
plic->num_sources >> 3, which is wrong, e.g.: considering
plic->num_sources is 7, the upper limit becomes 0 which fails
the range check if reading the pending register at pending_base.

Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-16-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 1a792cc3f5..5522ede2cf 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -143,7 +143,8 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, 
unsigned size)
 uint32_t irq = (addr - plic->priority_base) >> 2;
 
 return plic->source_priority[irq];
-} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) 
{
+} else if (addr_between(addr, plic->pending_base,
+(plic->num_sources + 31) >> 3)) {
 uint32_t word = (addr - plic->pending_base) >> 2;
 
 return plic->pending[word];
@@ -202,7 +203,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, 
uint64_t value,
 sifive_plic_update(plic);
 }
 } else if (addr_between(addr, plic->pending_base,
-plic->num_sources >> 3)) {
+(plic->num_sources + 31) >> 3)) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: invalid pending write: 0x%" HWADDR_PRIx "",
   __func__, addr);
-- 
2.38.1




[PULL 38/45] hw/intc: sifive_plic: Update "num-sources" property default value

2022-12-18 Thread Alistair Francis
From: Bin Meng 

At present the default value of "num-sources" property is zero,
which does not make a lot of sense, as in sifive_plic_realize()
we see s->bitfield_words is calculated by:

  s->bitfield_words = (s->num_sources + 31) >> 5;

if the we don't configure "num-sources" property its default value
zero makes s->bitfield_words zero too, which isn't true because
interrupt source 0 still occupies one word.

Let's change the default value to 1 meaning that only interrupt
source 0 is supported by default and a sanity check in realize().

While we are here, add a comment to describe the exact meaning of
this property that the number should include interrupt source 0.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-9-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 9cb4c6d6d4..1edeb1e1ed 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -363,6 +363,11 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 
 parse_hart_config(s);
 
+if (!s->num_sources) {
+error_setg(errp, "plic: invalid number of interrupt sources");
+return;
+}
+
 s->bitfield_words = (s->num_sources + 31) >> 5;
 s->num_enables = s->bitfield_words * s->num_addrs;
 s->source_priority = g_new0(uint32_t, s->num_sources);
@@ -420,7 +425,8 @@ static const VMStateDescription vmstate_sifive_plic = {
 static Property sifive_plic_properties[] = {
 DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
 DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
-DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
+/* number of interrupt sources including interrupt source 0 */
+DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
 DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
 DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
 DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
-- 
2.38.1




[PULL 03/45] hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro

2022-12-18 Thread Alistair Francis
From: Wilfred Mallawa 

use the `FIELD32_1CLEAR` macro to implement register
`rw1c` functionality to `ibex_spi`.

This change was tested by running the `SPI_HOST` from TockOS.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221017054950.317584-3-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 hw/ssi/ibex_spi_host.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
index 57df462e3c..0a456cd1ed 100644
--- a/hw/ssi/ibex_spi_host.c
+++ b/hw/ssi/ibex_spi_host.c
@@ -342,7 +342,7 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
 {
 IbexSPIHostState *s = opaque;
 uint32_t val32 = val64;
-uint32_t shift_mask = 0xff, status = 0, data = 0;
+uint32_t shift_mask = 0xff, status = 0;
 uint8_t txqd_len;
 
 trace_ibex_spi_host_write(addr, size, val64);
@@ -355,12 +355,11 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
 case IBEX_SPI_HOST_INTR_STATE:
 /* rw1c status register */
 if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
-data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, ERROR);
 }
 if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
-data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, 
SPI_EVENT);
 }
-s->regs[addr] = data;
 break;
 case IBEX_SPI_HOST_INTR_ENABLE:
 s->regs[addr] = val32;
@@ -505,27 +504,25 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
  *  When an error occurs, the corresponding bit must be cleared
  *  here before issuing any further commands
  */
-status = s->regs[addr];
 /* rw1c status register */
 if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
-status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CMDBUSY);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
-status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
OVERFLOW);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
-status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
UNDERFLOW);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CMDINVAL);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CSIDINVAL);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
ACCESSINVAL);
 }
-s->regs[addr] = status;
 break;
 case IBEX_SPI_HOST_EVENT_ENABLE:
 /* Controls which classes of SPI events raise an interrupt. */
-- 
2.38.1




[PULL 19/45] target/riscv: support cache-related PMU events in virtual mode

2022-12-18 Thread Alistair Francis
From: Jim Shu 

let tlb_fill() function also increments PMU counter when it is from
two-stage translation, so QEMU could also monitor these PMU events when
CPU runs in VS/VU mode (like running guest OS).

Signed-off-by: Jim Shu 
Reviewed-by: Alistair Francis 
Message-Id: <20221123090635.6574-1-jim@sifive.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 427d4d4386..1ff6ab5746 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1258,6 +1258,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 
+pmu_tlb_fill_incr_ctr(cpu, access_type);
 if (riscv_cpu_virt_enabled(env) ||
 ((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
  access_type != MMU_INST_FETCH)) {
@@ -1321,7 +1322,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 } else {
-pmu_tlb_fill_incr_ctr(cpu, access_type);
 /* Single stage lookup */
 ret = get_physical_address(env, &pa, &prot, address, NULL,
access_type, mmu_idx, true, false, false);
-- 
2.38.1




[PULL 39/45] hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC

2022-12-18 Thread Alistair Francis
From: Bin Meng 

Per chapter 6.5.2 in [1], the number of interupt sources including
interrupt source 0 should be 187.

[1] PolarFire SoC MSS TRM:
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf

Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC 
Icicle Kit board")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Reviewed-by: Conor Dooley 
Message-Id: <20221211030829.802437-10-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 69a686b54a..577efad0c4 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -153,7 +153,7 @@ enum {
 #define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT1
 #define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT   4
 
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES185
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES187
 #define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
 #define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x04
 #define MICROCHIP_PFSOC_PLIC_PENDING_BASE   0x1000
-- 
2.38.1




[PULL 14/45] target/riscv: Enable native debug itrigger

2022-12-18 Thread Alistair Francis
From: LIU Zhiwei 

When QEMU is not in icount mode, execute instruction one by one. The
tdata1 can be read directly.

When QEMU is in icount mode, use a timer to simulate the itrigger. The
tdata1 may be not right because of lazy update of count in tdata1. Thus,
We should pack the adjusted count into tdata1 before read it back.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-4-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/debug.c | 72 
 1 file changed, 72 insertions(+)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 371862cf38..b3574b250f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -624,10 +624,80 @@ void riscv_itrigger_update_priv(CPURISCVState *env)
 riscv_itrigger_update_count(env);
 }
 
+static target_ulong itrigger_validate(CPURISCVState *env,
+  target_ulong ctrl)
+{
+target_ulong val;
+
+/* validate the generic part first */
+val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
+
+/* validate unimplemented (always zero) bits */
+warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
+warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
+warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
+
+/* keep the mode and attribute bits */
+val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
+   ITRIGGER_M | ITRIGGER_COUNT);
+
+return val;
+}
+
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
+   int tdata_index, target_ulong val)
+{
+target_ulong new_val;
+
+switch (tdata_index) {
+case TDATA1:
+/* set timer for icount */
+new_val = itrigger_validate(env, val);
+if (new_val != env->tdata1[index]) {
+env->tdata1[index] = new_val;
+if (icount_enabled()) {
+env->last_icount = icount_get_raw();
+/* set the count to timer */
+timer_mod(env->itrigger_timer[index],
+  env->last_icount + itrigger_get_count(env, index));
+}
+}
+break;
+case TDATA2:
+qemu_log_mask(LOG_UNIMP,
+  "tdata2 is not supported for icount trigger\n");
+break;
+case TDATA3:
+qemu_log_mask(LOG_UNIMP,
+  "tdata3 is not supported for icount trigger\n");
+break;
+default:
+g_assert_not_reached();
+}
+
+return;
+}
+
+static int itrigger_get_adjust_count(CPURISCVState *env)
+{
+int count = itrigger_get_count(env, env->trigger_cur), executed;
+if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) {
+executed = icount_get_raw() - env->last_icount;
+count += executed;
+}
+return count;
+}
+
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
 {
+int trigger_type;
 switch (tdata_index) {
 case TDATA1:
+trigger_type = extract_trigger_type(env, 
env->tdata1[env->trigger_cur]);
+if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
+return deposit64(env->tdata1[env->trigger_cur], 10, 14,
+ itrigger_get_adjust_count(env));
+}
 return env->tdata1[env->trigger_cur];
 case TDATA2:
 return env->tdata2[env->trigger_cur];
@@ -656,6 +726,8 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, 
target_ulong val)
 type6_reg_write(env, env->trigger_cur, tdata_index, val);
 break;
 case TRIGGER_TYPE_INST_CNT:
+itrigger_reg_write(env, env->trigger_cur, tdata_index, val);
+break;
 case TRIGGER_TYPE_INT:
 case TRIGGER_TYPE_EXCP:
 case TRIGGER_TYPE_EXT_SRC:
-- 
2.38.1




[PULL 32/45] hw/riscv: Fix opentitan dependency to SIFIVE_PLIC

2022-12-18 Thread Alistair Francis
From: Bin Meng 

Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
the IBEX PLIC model was replaced with the SiFive PLIC model in the
'opentitan' machine but we forgot the add the dependency there.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-3-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 167dc4cca6..1e4b58024f 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -19,6 +19,7 @@ config MICROCHIP_PFSOC
 config OPENTITAN
 bool
 select IBEX
+select SIFIVE_PLIC
 select UNIMP
 
 config SHAKTI_C
-- 
2.38.1




[PULL 15/45] target/riscv: Add itrigger_enabled field to CPURISCVState

2022-12-18 Thread Alistair Francis
From: LIU Zhiwei 

Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
As the itrigger enable status can only be changed when write
tdata1, migration load or itrigger fire, update env->itrigger_enabled
at these places.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-5-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  1 +
 target/riscv/cpu_helper.c |  3 +--
 target/riscv/debug.c  |  3 +++
 target/riscv/machine.c| 15 +++
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b0b4048de9..37f9516941 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -331,6 +331,7 @@ struct CPUArchState {
 struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
 QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
 int64_t last_icount;
+bool itrigger_enabled;
 
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6230f65f70..427d4d4386 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -106,8 +106,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
get_field(env->mstatus_hs, MSTATUS_VS));
 }
 if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
-flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
-   riscv_itrigger_enabled(env));
+flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
 }
 #endif
 
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index b3574b250f..bf4840a6a3 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -563,6 +563,7 @@ void helper_itrigger_match(CPURISCVState *env)
 }
 itrigger_set_count(env, i, count--);
 if (!count) {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
 do_trigger_action(env, i);
 }
 }
@@ -660,6 +661,8 @@ static void itrigger_reg_write(CPURISCVState *env, 
target_ulong index,
 /* set the count to timer */
 timer_mod(env->itrigger_timer[index],
   env->last_icount + itrigger_get_count(env, index));
+} else {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
 }
 }
 break;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index e687f9fce0..65a8549ec2 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -21,6 +21,8 @@
 #include "qemu/error-report.h"
 #include "sysemu/kvm.h"
 #include "migration/cpu.h"
+#include "sysemu/cpu-timers.h"
+#include "debug.h"
 
 static bool pmp_needed(void *opaque)
 {
@@ -229,11 +231,24 @@ static bool debug_needed(void *opaque)
 return riscv_feature(env, RISCV_FEATURE_DEBUG);
 }
 
+static int debug_post_load(void *opaque, int version_id)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = &cpu->env;
+
+if (icount_enabled()) {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
+}
+
+return 0;
+}
+
 static const VMStateDescription vmstate_debug = {
 .name = "cpu/debug",
 .version_id = 2,
 .minimum_version_id = 2,
 .needed = debug_needed,
+.post_load = debug_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
 VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
-- 
2.38.1




[PULL 13/45] target/riscv: Add itrigger support when icount is enabled

2022-12-18 Thread Alistair Francis
From: LIU Zhiwei 

The max count in itrigger can be 0x3FFF, which will cause a no trivial
translation and execution overload.

When icount is enabled, QEMU provides API that can fetch guest
instruction number. Thus, we can set an timer for itrigger with
the count as deadline.

Only when timer expires or priviledge mode changes, do lazy update
to count.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-3-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/debug.h  |  1 +
 target/riscv/cpu_helper.c |  3 ++
 target/riscv/debug.c  | 59 +++
 4 files changed, 65 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c32e484c0b..b0b4048de9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -329,6 +329,8 @@ struct CPUArchState {
 target_ulong tdata3[RV_MAX_TRIGGERS];
 struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
 struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
+QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
+int64_t last_icount;
 
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index cc3358e69b..c471748d5a 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -146,4 +146,5 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp);
 void riscv_trigger_init(CPURISCVState *env);
 
 bool riscv_itrigger_enabled(CPURISCVState *env);
+void riscv_itrigger_update_priv(CPURISCVState *env);
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9d1d1bf9f1..6230f65f70 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -676,6 +676,9 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
 if (newpriv == PRV_H) {
 newpriv = PRV_U;
 }
+if (icount_enabled() && newpriv != env->priv) {
+riscv_itrigger_update_priv(env);
+}
 /* tlb_flush is unnecessary as mode is contained in mmu_idx */
 env->priv = newpriv;
 env->xl = cpu_recompute_xl(env);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 036161649f..371862cf38 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -30,6 +30,7 @@
 #include "trace.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
+#include "sysemu/cpu-timers.h"
 
 /*
  * The following M-mode trigger CSRs are implemented:
@@ -567,6 +568,62 @@ void helper_itrigger_match(CPURISCVState *env)
 }
 }
 
+static void riscv_itrigger_update_count(CPURISCVState *env)
+{
+int count, executed;
+/*
+ * Record last icount, so that we can evaluate the executed instructions
+ * since last priviledge mode change or timer expire.
+ */
+int64_t last_icount = env->last_icount, current_icount;
+current_icount = env->last_icount = icount_get_raw();
+
+for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
+if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
+continue;
+}
+count = itrigger_get_count(env, i);
+if (!count) {
+continue;
+}
+/*
+ * Only when priviledge is changed or itrigger timer expires,
+ * the count field in itrigger tdata1 register is updated.
+ * And the count field in itrigger only contains remaining value.
+ */
+if (check_itrigger_priv(env, i)) {
+/*
+ * If itrigger enabled in this priviledge mode, the number of
+ * executed instructions since last priviledge change
+ * should be reduced from current itrigger count.
+ */
+executed = current_icount - last_icount;
+itrigger_set_count(env, i, count - executed);
+if (count == executed) {
+do_trigger_action(env, i);
+}
+} else {
+/*
+ * If itrigger is not enabled in this priviledge mode,
+ * the number of executed instructions will be discard and
+ * the count field in itrigger will not change.
+ */
+timer_mod(env->itrigger_timer[i],
+  current_icount + count);
+}
+}
+}
+
+static void riscv_itrigger_timer_cb(void *opaque)
+{
+riscv_itrigger_update_count((CPURISCVState *)opaque);
+}
+
+void riscv_itrigger_update_priv(CPURISCVState *env)
+{
+riscv_itrigger_update_count(env);
+}
+
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
 {
 switch (tdata_index) {
@@ -796,5 +853,7 @@ void riscv_trigger_init(CPURISCVState *env)
 env->tdata3[i] = 0;
 env->cpu_breakpoint[i] = NULL;
 env->cpu_watchpoint[i] = NULL;
+env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  riscv_itrigger_timer_cb, env);
 }
 }
-- 
2.38.1




[PULL 43/45] hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0

2022-12-18 Thread Alistair Francis
From: Bin Meng 

At present the SiFive PLIC model "priority-base" expects interrupt
priority register base starting from source 1 instead source 0,
that's why on most platforms "priority-base" is set to 0x04 except
'opentitan' machine. 'opentitan' should have set "priority-base"
to 0x04 too.

Note the irq number calculation in sifive_plic_{read,write} is
correct as the codes make up for the irq number by adding 1.

Let's simply update "priority-base" to start from interrupt source
0 and add a comment to make it crystal clear.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-14-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h | 2 +-
 include/hw/riscv/shakti_c.h| 2 +-
 include/hw/riscv/sifive_e.h| 2 +-
 include/hw/riscv/sifive_u.h| 2 +-
 include/hw/riscv/virt.h| 2 +-
 hw/intc/sifive_plic.c  | 5 +++--
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 577efad0c4..e65ffeb02d 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -155,7 +155,7 @@ enum {
 
 #define MICROCHIP_PFSOC_PLIC_NUM_SOURCES187
 #define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x04
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x00
 #define MICROCHIP_PFSOC_PLIC_PENDING_BASE   0x1000
 #define MICROCHIP_PFSOC_PLIC_ENABLE_BASE0x2000
 #define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE  0x80
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
index daf0aae13f..539fe1156d 100644
--- a/include/hw/riscv/shakti_c.h
+++ b/include/hw/riscv/shakti_c.h
@@ -65,7 +65,7 @@ enum {
 #define SHAKTI_C_PLIC_NUM_SOURCES 28
 /* Excluding Priority 0 */
 #define SHAKTI_C_PLIC_NUM_PRIORITIES 2
-#define SHAKTI_C_PLIC_PRIORITY_BASE 0x04
+#define SHAKTI_C_PLIC_PRIORITY_BASE 0x00
 #define SHAKTI_C_PLIC_PENDING_BASE 0x1000
 #define SHAKTI_C_PLIC_ENABLE_BASE 0x2000
 #define SHAKTI_C_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 9e58247fd8..b824a79e2d 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -89,7 +89,7 @@ enum {
  */
 #define SIFIVE_E_PLIC_NUM_SOURCES 53
 #define SIFIVE_E_PLIC_NUM_PRIORITIES 7
-#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
+#define SIFIVE_E_PLIC_PRIORITY_BASE 0x00
 #define SIFIVE_E_PLIC_PENDING_BASE 0x1000
 #define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
 #define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 8f63a183c4..e680d61ece 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -158,7 +158,7 @@ enum {
 
 #define SIFIVE_U_PLIC_NUM_SOURCES 54
 #define SIFIVE_U_PLIC_NUM_PRIORITIES 7
-#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
+#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
 #define SIFIVE_U_PLIC_PENDING_BASE 0x1000
 #define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
 #define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index e1ce0048af..3407c9e8dd 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -98,7 +98,7 @@ enum {
 #define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
 
-#define VIRT_PLIC_PRIORITY_BASE 0x04
+#define VIRT_PLIC_PRIORITY_BASE 0x00
 #define VIRT_PLIC_PENDING_BASE 0x1000
 #define VIRT_PLIC_ENABLE_BASE 0x2000
 #define VIRT_PLIC_ENABLE_STRIDE 0x80
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 1edeb1e1ed..1a792cc3f5 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -140,7 +140,7 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, 
unsigned size)
 SiFivePLICState *plic = opaque;
 
 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
-uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
+uint32_t irq = (addr - plic->priority_base) >> 2;
 
 return plic->source_priority[irq];
 } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) 
{
@@ -187,7 +187,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, 
uint64_t value,
 SiFivePLICState *plic = opaque;
 
 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
-uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
+uint32_t irq = (addr - plic->priority_base) >> 2;
 
 if (((plic->num_priorities + 1) & plic->num_priorities) == 0) {
 /*
@@ -428,6 +428,7 @@ static Property sifive_plic_properties[] = {
 /* number of interrupt sources including interrupt source 0 */
 DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
 DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
+/* interrupt priority register base 

[PULL 24/45] hw/intc: sifive_plic: fix out-of-bound access of source_priority array

2022-12-18 Thread Alistair Francis
From: Jim Shu 

If the number of interrupt is not multiple of 32, PLIC will have
out-of-bound access to source_priority array. Compute the number of
interrupt in the last word to avoid this out-of-bound access of array.

Signed-off-by: Jim Shu 
Reviewed-by: Bin Meng 
Message-Id: <20221127165753.30533-1-jim@sifive.com>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index b4949bef97..0c7696520d 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -78,6 +78,7 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, 
uint32_t addrid)
 uint32_t max_irq = 0;
 uint32_t max_prio = plic->target_priority[addrid];
 int i, j;
+int num_irq_in_word = 32;
 
 for (i = 0; i < plic->bitfield_words; i++) {
 uint32_t pending_enabled_not_claimed =
@@ -88,7 +89,16 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, 
uint32_t addrid)
 continue;
 }
 
-for (j = 0; j < 32; j++) {
+if (i == (plic->bitfield_words - 1)) {
+/*
+ * If plic->num_sources is not multiple of 32, num-of-irq in last
+ * word is not 32. Compute the num-of-irq of last word to avoid
+ * out-of-bound access of source_priority array.
+ */
+num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) 
<< 5);
+}
+
+for (j = 0; j < num_irq_in_word; j++) {
 int irq = (i << 5) + j;
 uint32_t prio = plic->source_priority[irq];
 int enabled = pending_enabled_not_claimed & (1 << j);
-- 
2.38.1




[PULL 29/45] RISC-V: Add Zawrs ISA extension support

2022-12-18 Thread Alistair Francis
From: Christoph Muellner 

This patch adds support for the Zawrs ISA extension.
Given the current (incomplete) implementation of reservation sets
there seems to be no way to provide a full emulation of the WRS
instruction (wake on reservation set invalidation or timeout or
interrupt). Therefore, we just exit the TB and return to the main loop.

The specification can be found here:
  https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc

Note, that the Zawrs extension is frozen, but not ratified yet.

Changes since v3:
* Remove "RFC" since the extension is frozen
* Rebase on master and fix integration issues
* Fix entry ordering in extension list

Changes since v2:
* Rebase on master and resolve conflicts
* Adjustments according to a specification change
* Inline REQUIRE_ZAWRS() since it has only one user

Changes since v1:
* Adding zawrs to the ISA string that is passed to the kernel

Signed-off-by: Christoph Müllner 
Reviewed-by: Alistair Francis 
Message-Id: <20221005144948.3421504-1-christoph.muell...@vrull.eu>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |  1 +
 target/riscv/insn32.decode  |  4 ++
 target/riscv/cpu.c  |  7 +++
 target/riscv/translate.c|  1 +
 target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +
 5 files changed, 64 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 37f9516941..f5609b62a2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -453,6 +453,7 @@ struct RISCVCPUConfig {
 bool ext_svnapot;
 bool ext_svpbmt;
 bool ext_zdinx;
+bool ext_zawrs;
 bool ext_zfh;
 bool ext_zfhmin;
 bool ext_zfinx;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d0253b8104..b7e7613ea2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -718,6 +718,10 @@ vsetvli 0 ... . 111 . 1010111  
@r2_zimm11
 vsetivli11 .. . 111 . 1010111  @r2_zimm10
 vsetvl  100 . . 111 . 1010111  @r
 
+# *** Zawrs Standard Extension ***
+wrs_nto1101 0 000 0 1110011
+wrs_sto00011101 0 000 0 1110011
+
 # *** RV32 Zba Standard Extension ***
 sh1add 001 .. 010 . 0110011 @r
 sh2add 001 .. 100 . 0110011 @r
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b2c132e269..cc75ca7667 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -76,6 +76,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
 ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
 ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, 
ext_zihintpause),
+ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
 ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
@@ -766,6 +767,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
+error_setg(errp, "Zawrs extension requires A extension");
+return;
+}
+
 if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
 error_setg(errp, "Zfh/Zfhmin extensions require F extension");
 return;
@@ -1021,6 +1027,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
+DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 160aefc3df..df38db7553 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1060,6 +1060,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvh.c.inc"
 #include "insn_trans/trans_rvv.c.inc"
 #include "insn_trans/trans_rvb.c.inc"
+#include "insn_trans/trans_rvzawrs.c.inc"
 #include "insn_trans/trans_rvzfh.c.inc"
 #include "insn_trans/trans_rvk.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc 
b/target/riscv/insn_trans/trans_rvzawrs.c.inc
new file mode 100644
index 00..8254e7dfe2
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
@@ -0,0 +1,51 @@
+/*
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
+ *
+ * Co

[PULL 07/45] hw/riscv/opentitan: bump opentitan

2022-12-18 Thread Alistair Francis
From: Wilfred Mallawa 

This patch updates the OpenTitan model to match
the specified register layout as per [1]. Which is also the latest
commit of OpenTitan supported by TockOS.

Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
much detail regarding this, except for a note that states `TODO: this
section needs to be updated to reflect the pinmux/padctrl merger`

[1] 
https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Message-Id: <20221025043335.339815-2-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h |  9 -
 hw/riscv/opentitan.c | 21 +
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 6665cd5794..1fc055cdff 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -81,7 +81,6 @@ enum {
 IBEX_DEV_RSTMGR,
 IBEX_DEV_CLKMGR,
 IBEX_DEV_PINMUX,
-IBEX_DEV_PADCTRL,
 IBEX_DEV_USBDEV,
 IBEX_DEV_FLASH_CTRL,
 IBEX_DEV_PLIC,
@@ -109,10 +108,10 @@ enum {
 IBEX_UART0_RX_TIMEOUT_IRQ = 7,
 IBEX_UART0_RX_PARITY_ERR_IRQ  = 8,
 IBEX_TIMER_TIMEREXPIRED0_0= 127,
-IBEX_SPI_HOST0_ERR_IRQ= 151,
-IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 152,
-IBEX_SPI_HOST1_ERR_IRQ= 153,
-IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 154,
+IBEX_SPI_HOST0_ERR_IRQ= 134,
+IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 135,
+IBEX_SPI_HOST1_ERR_IRQ= 136,
+IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 137,
 };
 
 #endif
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index be7ff1eea0..92493c629d 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -28,8 +28,16 @@
 #include "qemu/units.h"
 #include "sysemu/sysemu.h"
 
+/*
+ * This version of the OpenTitan machine currently supports
+ * OpenTitan RTL version:
+ * 
+ *
+ * MMIO mapping as per (specified commit):
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
+ */
 static const MemMapEntry ibex_memmap[] = {
-[IBEX_DEV_ROM] ={  0x8000,   0x8000 },
+[IBEX_DEV_ROM] ={  0x8000,  0x8000 },
 [IBEX_DEV_RAM] ={  0x1000,  0x2 },
 [IBEX_DEV_FLASH] =  {  0x2000,  0x10 },
 [IBEX_DEV_UART] =   {  0x4000,  0x1000  },
@@ -38,17 +46,17 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_I2C] ={  0x4008,  0x1000  },
 [IBEX_DEV_PATTGEN] ={  0x400e,  0x1000  },
 [IBEX_DEV_TIMER] =  {  0x4010,  0x1000  },
-[IBEX_DEV_SENSOR_CTRL] ={  0x4011,  0x1000  },
 [IBEX_DEV_OTP_CTRL] =   {  0x4013,  0x4000  },
 [IBEX_DEV_LC_CTRL] ={  0x4014,  0x1000  },
-[IBEX_DEV_USBDEV] = {  0x4015,  0x1000  },
+[IBEX_DEV_ALERT_HANDLER] =  {  0x4015,  0x1000  },
 [IBEX_DEV_SPI_HOST0] =  {  0x4030,  0x1000  },
 [IBEX_DEV_SPI_HOST1] =  {  0x4031,  0x1000  },
+[IBEX_DEV_USBDEV] = {  0x4032,  0x1000  },
 [IBEX_DEV_PWRMGR] = {  0x4040,  0x1000  },
 [IBEX_DEV_RSTMGR] = {  0x4041,  0x1000  },
 [IBEX_DEV_CLKMGR] = {  0x4042,  0x1000  },
 [IBEX_DEV_PINMUX] = {  0x4046,  0x1000  },
-[IBEX_DEV_PADCTRL] ={  0x4047,  0x1000  },
+[IBEX_DEV_SENSOR_CTRL] ={  0x4049,  0x1000  },
 [IBEX_DEV_FLASH_CTRL] = {  0x4100,  0x1000  },
 [IBEX_DEV_AES] ={  0x4110,  0x1000  },
 [IBEX_DEV_HMAC] =   {  0x4111,  0x1000  },
@@ -59,10 +67,9 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_ENTROPY] ={  0x4116,  0x1000  },
 [IBEX_DEV_EDNO] =   {  0x4117,  0x1000  },
 [IBEX_DEV_EDN1] =   {  0x4118,  0x1000  },
-[IBEX_DEV_ALERT_HANDLER] =  {  0x411b,  0x1000  },
 [IBEX_DEV_NMI_GEN] ={  0x411c,  0x1000  },
 [IBEX_DEV_PERI] =   {  0x411f,  0x1 },
-[IBEX_DEV_PLIC] =   {  0x4800,  0x4005000  },
+[IBEX_DEV_PLIC] =   {  0x4800,  0x4005000 },
 [IBEX_DEV_FLASH_VIRTUAL] =  {  0x8000,  0x8 },
 };
 
@@ -265,8 +272,6 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
 create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
 memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
-create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
-memmap[IBEX_DEV_PADCTRL].base

[PULL 25/45] target/riscv: Fix mret exception cause when no pmp rule is configured

2022-12-18 Thread Alistair Francis
From: Bin Meng 

The priv spec v1.12 says:

  If no PMP entry matches an M-mode access, the access succeeds. If
  no PMP entry matches an S-mode or U-mode access, but at least one
  PMP entry is implemented, the access fails. Failed accesses generate
  an instruction, load, or store access-fault exception.

At present the exception cause is set to 'illegal instruction' but
should have been 'instruction access fault'.

Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is 
configured")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221205065303.204095-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 09f1f5185d..d7af7f056b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -202,7 +202,7 @@ target_ulong helper_mret(CPURISCVState *env)
 
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
-riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
 }
 
 target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
-- 
2.38.1




[PULL 36/45] hw/intc: sifive_plic: Improve robustness of the PLIC config parser

2022-12-18 Thread Alistair Francis
From: Bin Meng 

At present the PLIC config parser can only handle legal config string
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
given the parser won't get the correct configuration.

This commit improves the config parser to make it more robust.

Signed-off-by: Bin Meng 
Acked-by: Alistair Francis 
Message-Id: <20221211030829.802437-7-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 936dcf74bc..c9af94a888 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -290,7 +290,7 @@ static void sifive_plic_reset(DeviceState *dev)
  */
 static void parse_hart_config(SiFivePLICState *plic)
 {
-int addrid, hartid, modes;
+int addrid, hartid, modes, m;
 const char *p;
 char c;
 
@@ -299,11 +299,13 @@ static void parse_hart_config(SiFivePLICState *plic)
 p = plic->hart_config;
 while ((c = *p++)) {
 if (c == ',') {
-addrid += ctpop8(modes);
-modes = 0;
-hartid++;
+if (modes) {
+addrid += ctpop8(modes);
+hartid++;
+modes = 0;
+}
 } else {
-int m = 1 << char_to_mode(c);
+m = 1 << char_to_mode(c);
 if (modes == (modes | m)) {
 error_report("plic: duplicate mode '%c' in config: %s",
  c, plic->hart_config);
@@ -314,8 +316,9 @@ static void parse_hart_config(SiFivePLICState *plic)
 }
 if (modes) {
 addrid += ctpop8(modes);
+hartid++;
+modes = 0;
 }
-hartid++;
 
 plic->num_addrs = addrid;
 plic->num_harts = hartid;
@@ -326,11 +329,16 @@ static void parse_hart_config(SiFivePLICState *plic)
 p = plic->hart_config;
 while ((c = *p++)) {
 if (c == ',') {
-hartid++;
+if (modes) {
+hartid++;
+modes = 0;
+}
 } else {
+m = char_to_mode(c);
 plic->addr_config[addrid].addrid = addrid;
 plic->addr_config[addrid].hartid = hartid;
-plic->addr_config[addrid].mode = char_to_mode(c);
+plic->addr_config[addrid].mode = m;
+modes |= (1 << m);
 addrid++;
 }
 }
-- 
2.38.1




[PULL 30/45] hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC

2022-12-18 Thread Alistair Francis
From: Bin Meng 

hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
controllers regardless of how MSI is implemented. msi_nonbroken is
initialized to true in sifive_plic_realize().

Let SIFIVE_PLIC select MSI_NONBROKEN and drop the selection from
RISC-V machines.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/Kconfig  | 1 +
 hw/riscv/Kconfig | 5 -
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index ecd2883ceb..1d4573e803 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -78,6 +78,7 @@ config RISCV_IMSIC
 
 config SIFIVE_PLIC
 bool
+select MSI_NONBROKEN
 
 config GOLDFISH_PIC
 bool
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 79ff61c464..167dc4cca6 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -11,7 +11,6 @@ config MICROCHIP_PFSOC
 select MCHP_PFSOC_IOSCB
 select MCHP_PFSOC_MMUART
 select MCHP_PFSOC_SYSREG
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_PDMA
 select SIFIVE_PLIC
@@ -37,7 +36,6 @@ config RISCV_VIRT
 imply TPM_TIS_SYSBUS
 select RISCV_NUMA
 select GOLDFISH_RTC
-select MSI_NONBROKEN
 select PCI
 select PCI_EXPRESS_GENERIC_BRIDGE
 select PFLASH_CFI01
@@ -53,7 +51,6 @@ config RISCV_VIRT
 
 config SIFIVE_E
 bool
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_GPIO
 select SIFIVE_PLIC
@@ -64,7 +61,6 @@ config SIFIVE_E
 config SIFIVE_U
 bool
 select CADENCE
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_GPIO
 select SIFIVE_PDMA
@@ -82,6 +78,5 @@ config SPIKE
 bool
 select RISCV_NUMA
 select HTIF
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_PLIC
-- 
2.38.1




[PULL 26/45] target/riscv: Set pc_succ_insn for !rvc illegal insn

2022-12-18 Thread Alistair Francis
From: Richard Henderson 

Failure to set pc_succ_insn may result in a TB covering zero bytes,
which triggers an assert within the code generator.

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221203175744.151365-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c  | 12 
 tests/tcg/Makefile.target |  2 ++
 tests/tcg/riscv64/Makefile.target |  5 +
 tests/tcg/riscv64/test-noc.S  | 32 +++
 4 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 tests/tcg/riscv64/test-noc.S

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index cd5eb25ee8..160aefc3df 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1096,14 +1096,10 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
-gen_exception_illegal(ctx);
-} else {
-ctx->opcode = opcode;
-ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (decode_insn16(ctx, opcode)) {
-return;
-}
+ctx->opcode = opcode;
+ctx->pc_succ_insn = ctx->base.pc_next + 2;
+if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
+return;
 }
 } else {
 uint32_t opcode32 = opcode;
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index 75257f2b29..14bc013181 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -117,6 +117,8 @@ endif
 
 %: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+%: %.S
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
 else
 # For softmmu targets we include a different Makefile fragement as the
 # build options for bare programs are usually pretty different. They
diff --git a/tests/tcg/riscv64/Makefile.target 
b/tests/tcg/riscv64/Makefile.target
index b5b89dfb0e..9973ba3b5f 100644
--- a/tests/tcg/riscv64/Makefile.target
+++ b/tests/tcg/riscv64/Makefile.target
@@ -4,3 +4,8 @@
 VPATH += $(SRC_PATH)/tests/tcg/riscv64
 TESTS += test-div
 TESTS += noexec
+
+# Disable compressed instructions for test-noc
+TESTS += test-noc
+test-noc: LDFLAGS = -nostdlib -static
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
new file mode 100644
index 00..e29d60c8b3
--- /dev/null
+++ b/tests/tcg/riscv64/test-noc.S
@@ -0,0 +1,32 @@
+#include 
+
+   .text
+   .globl _start
+_start:
+   .option norvc
+   li  a0, 4   /* SIGILL */
+   la  a1, sa
+   li  a2, 0
+   li  a3, 8
+   li  a7, __NR_rt_sigaction
+   scall
+
+   .option rvc
+   li  a0, 1
+   j   exit
+   .option norvc
+
+pass:
+   li  a0, 0
+exit:
+   li  a7, __NR_exit
+   scall
+
+   .data
+   /* struct kernel_sigaction sa = { .sa_handler = pass }; */
+   .type   sa, @object
+   .size   sa, 32
+sa:
+   .dword  pass
+   .zero   24
+
-- 
2.38.1




[PULL 41/45] hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"

2022-12-18 Thread Alistair Francis
From: Bin Meng 

At present magic number is used to create "riscv,ndev" property
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
is used to instantiate the PLIC model instead.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-12-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index b139824aab..b40a4767e2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -287,7 +287,8 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_DEV_PLIC].base,
 0x0, memmap[SIFIVE_U_DEV_PLIC].size);
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
+qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
+  SIFIVE_U_PLIC_NUM_SOURCES - 1);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
-- 
2.38.1




[PULL 28/45] target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+

2022-12-18 Thread Alistair Francis
From: Bin Meng 

Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
leaving M-mode.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221207090037.281452-2-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index a047d38152..878bcb03b8 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -154,6 +154,9 @@ target_ulong helper_sret(CPURISCVState *env)
 get_field(mstatus, MSTATUS_SPIE));
 mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
 mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+if (env->priv_ver >= PRIV_VERSION_1_12_0) {
+mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
+}
 env->mstatus = mstatus;
 
 if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
@@ -203,6 +206,9 @@ target_ulong helper_mret(CPURISCVState *env)
 mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
 mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
 mstatus = set_field(mstatus, MSTATUS_MPV, 0);
+if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
+mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
+}
 env->mstatus = mstatus;
 riscv_cpu_set_mode(env, prev_priv);
 
-- 
2.38.1




[PULL 44/45] hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization

2022-12-18 Thread Alistair Francis
From: Bin Meng 

"hartid-base" and "priority-base" are zero by default. There is no
need to initialize them to zero again.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-15-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/opentitan.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 78f895d773..85ffdac5be 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -173,10 +173,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 
 /* PLIC */
 qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
-qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
 qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
 qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
-qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
 qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
 qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
 qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
-- 
2.38.1




[PULL 31/45] hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers

2022-12-18 Thread Alistair Francis
From: Bin Meng 

hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
controllers regardless of how MSI is implemented. msi_nonbroken is
initialized to true in both riscv_aplic_realize() and
riscv_imsic_realize().

Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221211030829.802437-2-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 1d4573e803..21441d0a0c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -72,9 +72,11 @@ config RISCV_ACLINT
 
 config RISCV_APLIC
 bool
+select MSI_NONBROKEN
 
 config RISCV_IMSIC
 bool
+select MSI_NONBROKEN
 
 config SIFIVE_PLIC
 bool
-- 
2.38.1




[PULL 04/45] tcg/riscv: Fix range matched by TCG_CT_CONST_M12

2022-12-18 Thread Alistair Francis
From: Richard Henderson 

We were matching a signed 13-bit range, not a 12-bit range.
Expand the commentary within the function and be explicit
about all of the ranges.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221022095821.2441874-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 81a83e45b1..191197853f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -154,13 +154,26 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
+/*
+ * Sign extended from 12 bits: [-0x800, 0x7ff].
+ * Used for most arithmetic, as this is the isa field.
+ */
+if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
+/*
+ * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
+ * Used for subtraction, where a constant must be handled by ADDI.
+ */
+if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
+/*
+ * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
+ * Used by addsub2, which may need the negative operation,
+ * and requires the modified constant to be representable.
+ */
+if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
 return 1;
 }
 return 0;
-- 
2.38.1




[PULL 40/45] hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC

2022-12-18 Thread Alistair Francis
From: Bin Meng 

Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
supports 52 interrupt sources while G000 supports 51 interrupt sources.

We use the value of G002 and G003, so it is 53 (including source 0).

[1] G000 manual:
https://sifive.cdn.prismic.io/sifive/4faf3e34-4a42-4c2f-be9e-c77baa4928c7_fe310-g000-manual-v3p2.pdf

[2] G002 manual:
https://sifive.cdn.prismic.io/sifive/034760b5-ac6a-4b1c-911c-f4148bb2c4a5_fe310-g002-v1p5.pdf

[3] G003 manual:
https://sifive.cdn.prismic.io/sifive/3af39c59-6498-471e-9dab-5355a0d539eb_fe310-g003-manual.pdf

Fixes: eb637edb1241 ("SiFive Freedom E Series RISC-V Machine")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-11-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/sifive_e.h | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index d738745925..9e58247fd8 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -82,7 +82,12 @@ enum {
 };
 
 #define SIFIVE_E_PLIC_HART_CONFIG "M"
-#define SIFIVE_E_PLIC_NUM_SOURCES 127
+/*
+ * Freedom E310 G002 and G003 supports 52 interrupt sources while
+ * Freedom E310 G000 supports 51 interrupt sources. We use the value
+ * of G002 and G003, so it is 53 (including interrupt source 0).
+ */
+#define SIFIVE_E_PLIC_NUM_SOURCES 53
 #define SIFIVE_E_PLIC_NUM_PRIORITIES 7
 #define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
 #define SIFIVE_E_PLIC_PENDING_BASE 0x1000
-- 
2.38.1




[PULL 10/45] target/riscv: smstateen check for h/s/envcfg

2022-12-18 Thread Alistair Francis
From: Mayuresh Chitale 

Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
generated.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-3-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 87 ++
 1 file changed, 80 insertions(+), 7 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c861424e85..71236f2b5d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -41,6 +41,42 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 }
 
 /* Predicates */
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
+   uint64_t bit)
+{
+bool virt = riscv_cpu_virt_enabled(env);
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_NONE;
+}
+
+if (!(env->mstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
+if (!(env->sstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
+return RISCV_EXCP_NONE;
+}
+#endif
+
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -1874,6 +1910,13 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->senvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1882,15 +1925,27 @@ static RISCVException write_senvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
+RISCVException ret;
 
-env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1899,6 +1954,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
 if (riscv_cpu_mxl(env) == MXL_RV64) {
 mask |= HENVCFG_PBMTE | HENVCFG_STCE;
@@ -1912,6 +1973,13 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg >> 32;
 return RISCV_EXCP_NONE;
 }
@@ -1921,9 +1989,14 @@ static RISCVException write_henvcfgh(CPURISCVState *env, 
int csrno,
 {
 uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
 uint64_t valh = (uint64_t)val << 32;
+RISCVException ret;
 
-env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
 return RISCV_EXCP_NONE;
 }
 
@@ -1949,7 +2022,7 @@ static RISCVException write_mstateen(CPURISCVState *env, 
int csrno,
 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
   target_ulong new_val)
 {
-uint64_t wr_mask = SMSTATEEN_STATEEN;
+uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
 return write_mstateen(env, csrno, wr_mask, new_val);
 }
@@ -1984,7 +2057,7 @@ static RISCVException write_mstateenh(CPURISCVState *env, 
int csrno,
 static RISCVException write_mstateen0h(

[PULL 16/45] hw/intc: sifive_plic: Renumber the S irqs for numa support

2022-12-18 Thread Alistair Francis
From: Frédéric Pétrot 

Commit 40244040a7a changed the way the S irqs are numbered. This breaks when
using numa configuration, e.g.:
./qemu-system-riscv64 -nographic -machine virt,dumpdtb=numa-tree.dtb \
  -m 2G -smp cpus=16 \
  -object memory-backend-ram,id=mem0,size=512M \
  -object memory-backend-ram,id=mem1,size=512M \
  -object memory-backend-ram,id=mem2,size=512M \
  -object memory-backend-ram,id=mem3,size=512M \
  -numa node,cpus=0-3,memdev=mem0,nodeid=0 \
  -numa node,cpus=4-7,memdev=mem1,nodeid=1 \
  -numa node,cpus=8-11,memdev=mem2,nodeid=2 \
  -numa node,cpus=12-15,memdev=mem3,nodeid=3
leads to:
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
qemu-system-riscv64: Property 'riscv.sifive.plic.unnamed-gpio-out[8]' not
found

This patch makes the nubering of the S irqs identical to what it was before.

Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Frédéric Pétrot 
Message-Id: <20221114135122.1668703-1-frederic.pet...@univ-grenoble-alpes.fr>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index c2dfacf028..b4949bef97 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -476,11 +476,11 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
*hart_config,
 CPUState *cpu = qemu_get_cpu(cpu_num);
 
 if (plic->addr_config[i].mode == PLICMode_M) {
-qdev_connect_gpio_out(dev, num_harts - plic->hartid_base + cpu_num,
+qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
   qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
 }
 if (plic->addr_config[i].mode == PLICMode_S) {
-qdev_connect_gpio_out(dev, cpu_num,
+qdev_connect_gpio_out(dev, cpu_num - hartid_base,
   qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
 }
 }
-- 
2.38.1




[PULL 33/45] hw/riscv: Sort machines Kconfig options in alphabetical order

2022-12-18 Thread Alistair Francis
From: Bin Meng 

SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-4-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/Kconfig | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 1e4b58024f..4550b3b938 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -4,6 +4,8 @@ config RISCV_NUMA
 config IBEX
 bool
 
+# RISC-V machines in alphabetical order
+
 config MICROCHIP_PFSOC
 bool
 select CADENCE_SDHCI
@@ -22,13 +24,6 @@ config OPENTITAN
 select SIFIVE_PLIC
 select UNIMP
 
-config SHAKTI_C
-bool
-select UNIMP
-select SHAKTI_UART
-select RISCV_ACLINT
-select SIFIVE_PLIC
-
 config RISCV_VIRT
 bool
 imply PCI_DEVICES
@@ -50,6 +45,13 @@ config RISCV_VIRT
 select FW_CFG_DMA
 select PLATFORM_BUS
 
+config SHAKTI_C
+bool
+select RISCV_ACLINT
+select SHAKTI_UART
+select SIFIVE_PLIC
+select UNIMP
+
 config SIFIVE_E
 bool
 select RISCV_ACLINT
-- 
2.38.1




[PULL 18/45] hw/riscv: virt: Remove the redundant ipi-id property

2022-12-18 Thread Alistair Francis
From: Atish Patra 

The imsic DT binding[1] has changed and no longer require an ipi-id.
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
is not defined.

Get rid of the unused dt property which may lead to confusion.

[1] 
https://lore.kernel.org/lkml/2022044207.1478350-5-apa...@ventanamicro.com/

Signed-off-by: Atish Patra 
Reviewed-by: Alistair Francis 
Message-Id: <20221122080529.1692533-1-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 1 -
 hw/riscv/virt.c | 4 
 2 files changed, 5 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index be4ab8fe7f..62513e075c 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -93,7 +93,6 @@ enum {
 
 #define VIRT_PLATFORM_BUS_NUM_IRQS 32
 
-#define VIRT_IRQCHIP_IPI_MSI 1
 #define VIRT_IRQCHIP_NUM_MSIS 255
 #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
 #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a5bc7353b4..6cf9355b99 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -546,8 +546,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const 
MemMapEntry *memmap,
 riscv_socket_count(mc) * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
 VIRT_IRQCHIP_NUM_MSIS);
-qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
-VIRT_IRQCHIP_IPI_MSI);
 if (riscv_socket_count(mc) > 1) {
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
 imsic_num_bits(imsic_max_hart_per_socket));
@@ -597,8 +595,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const 
MemMapEntry *memmap,
 riscv_socket_count(mc) * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
 VIRT_IRQCHIP_NUM_MSIS);
-qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
-VIRT_IRQCHIP_IPI_MSI);
 if (imsic_guest_bits) {
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
 imsic_guest_bits);
-- 
2.38.1




[PULL 27/45] target/riscv: Simplify helper_sret() a little bit

2022-12-18 Thread Alistair Francis
From: Bin Meng 

There are 2 paths in helper_sret() and the same mstatus update codes
are replicated. Extract the common parts to simplify it a little bit.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221207090037.281452-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index d7af7f056b..a047d38152 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -149,21 +149,21 @@ target_ulong helper_sret(CPURISCVState *env)
 }
 
 mstatus = env->mstatus;
+prev_priv = get_field(mstatus, MSTATUS_SPP);
+mstatus = set_field(mstatus, MSTATUS_SIE,
+get_field(mstatus, MSTATUS_SPIE));
+mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
+mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+env->mstatus = mstatus;
 
 if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
 /* We support Hypervisor extensions and virtulisation is disabled */
 target_ulong hstatus = env->hstatus;
 
-prev_priv = get_field(mstatus, MSTATUS_SPP);
 prev_virt = get_field(hstatus, HSTATUS_SPV);
 
 hstatus = set_field(hstatus, HSTATUS_SPV, 0);
-mstatus = set_field(mstatus, MSTATUS_SPP, 0);
-mstatus = set_field(mstatus, SSTATUS_SIE,
-get_field(mstatus, SSTATUS_SPIE));
-mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
 
-env->mstatus = mstatus;
 env->hstatus = hstatus;
 
 if (prev_virt) {
@@ -171,14 +171,6 @@ target_ulong helper_sret(CPURISCVState *env)
 }
 
 riscv_cpu_set_virt_enabled(env, prev_virt);
-} else {
-prev_priv = get_field(mstatus, MSTATUS_SPP);
-
-mstatus = set_field(mstatus, MSTATUS_SIE,
-get_field(mstatus, MSTATUS_SPIE));
-mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
-mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
-env->mstatus = mstatus;
 }
 
 riscv_cpu_set_mode(env, prev_priv);
-- 
2.38.1




[PULL 21/45] hw/misc: pfsoc: add fabric clocks to ioscb

2022-12-18 Thread Alistair Francis
From: Conor Dooley 

On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
on the FPGA bitstream & can be locked to one particular {D,P}LL - in the
Icicle Kit Reference Design v2022.09 or later this is/will be the case.

Linux v6.1+ will have a driver for this peripheral and devicetrees that
previously relied on "fixed-frequency" clock nodes have been switched
over to clock-controller nodes. The IOSCB region is represented in QEMU,
but the specific region of it that the CCCs occupy has not so v6.1-rcN
kernels fail to boot in QEMU.

Add the regions as unimplemented so that the status-quo in terms of boot
is maintained.

Acked-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-Id: <20221117225518.4102575-2-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
 hw/misc/mchp_pfsoc_ioscb.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h 
b/include/hw/misc/mchp_pfsoc_ioscb.h
index 9235523e33..687b213742 100644
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
@@ -30,6 +30,7 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion lane23;
 MemoryRegion ctrl;
 MemoryRegion cfg;
+MemoryRegion ccc;
 MemoryRegion pll_mss;
 MemoryRegion cfm_mss;
 MemoryRegion pll_ddr;
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
index f4fd55a0e5..f976e42f72 100644
--- a/hw/misc/mchp_pfsoc_ioscb.c
+++ b/hw/misc/mchp_pfsoc_ioscb.c
@@ -33,6 +33,7 @@
  */
 #define IOSCB_WHOLE_REG_SIZE0x1000
 #define IOSCB_SUBMOD_REG_SIZE   0x1000
+#define IOSCB_CCC_REG_SIZE  0x200
 
 /*
  * There are many sub-modules in the IOSCB module.
@@ -45,6 +46,7 @@
 #define IOSCB_LANE23_BASE   0x0651
 #define IOSCB_CTRL_BASE 0x0702
 #define IOSCB_CFG_BASE  0x0708
+#define IOSCB_CCC_BASE  0x0800
 #define IOSCB_PLL_MSS_BASE  0x0E001000
 #define IOSCB_CFM_MSS_BASE  0x0E002000
 #define IOSCB_PLL_DDR_BASE  0x0E01
@@ -168,6 +170,10 @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, 
Error **errp)
   "mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
 memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
 
+memory_region_init_io(&s->ccc, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
+  "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
+memory_region_add_subregion(&s->container, IOSCB_CCC_BASE, &s->ccc);
+
 memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
   "mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
 memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, 
&s->pll_mss);
-- 
2.38.1




[PULL 34/45] hw/riscv: spike: Remove misleading comments

2022-12-18 Thread Alistair Francis
From: Bin Meng 

PLIC is not included in the 'spike' machine.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-5-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/spike.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 1e1d752c00..13946acf0d 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -8,7 +8,6 @@
  *
  * 0) HTIF Console and Poweroff
  * 1) CLINT (Timer and IPI)
- * 2) PLIC (Platform Level Interrupt Controller)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
-- 
2.38.1




[PULL 05/45] tcg/riscv: Fix reg overlap case in tcg_out_addsub2

2022-12-18 Thread Alistair Francis
From: Richard Henderson 

There was a typo using opc_addi instead of opc_add with the
two registers.  While we're at it, simplify the gating test
to al == bl to improve dynamic scheduling even when the
output register does not overlap the inputs.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20221020233836.2341671-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 191197853f..2a84c57bec 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -700,9 +700,15 @@ static void tcg_out_addsub2(TCGContext *s,
 if (cbl) {
 tcg_out_opc_imm(s, opc_addi, rl, al, bl);
 tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
-} else if (rl == al && rl == bl) {
+} else if (al == bl) {
+/*
+ * If the input regs overlap, this is a simple doubling
+ * and carry-out is the input msb.  This special case is
+ * required when the output reg overlaps the input,
+ * but we might as well use it always.
+ */
 tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
-tcg_out_opc_reg(s, opc_addi, rl, al, bl);
+tcg_out_opc_reg(s, opc_add, rl, al, al);
 } else {
 tcg_out_opc_reg(s, opc_add, rl, al, bl);
 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
-- 
2.38.1




[PULL 09/45] target/riscv: Add smstateen support

2022-12-18 Thread Alistair Francis
From: Mayuresh Chitale 

Smstateen extension specifies a mechanism to close
the potential covert channels that could cause security issues.

This patch adds the CSRs defined in the specification and
the corresponding predicates and read/write functions.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-2-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |   4 +
 target/riscv/cpu_bits.h |  37 +
 target/riscv/csr.c  | 316 
 target/riscv/machine.c  |  21 +++
 4 files changed, 378 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 443d15a47c..5cac0c5eec 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -366,6 +366,9 @@ struct CPUArchState {
 
 /* CSRs for execution enviornment configuration */
 uint64_t menvcfg;
+uint64_t mstateen[SMSTATEEN_MAX_COUNT];
+uint64_t hstateen[SMSTATEEN_MAX_COUNT];
+uint64_t sstateen[SMSTATEEN_MAX_COUNT];
 target_ulong senvcfg;
 uint64_t henvcfg;
 #endif
@@ -441,6 +444,7 @@ struct RISCVCPUConfig {
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zihintpause;
+bool ext_smstateen;
 bool ext_sstc;
 bool ext_svinval;
 bool ext_svnapot;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index d8f5f0abed..8b0d7e20ea 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -197,6 +197,12 @@
 /* Supervisor Configuration CSRs */
 #define CSR_SENVCFG 0x10A
 
+/* Supervisor state CSRs */
+#define CSR_SSTATEEN0   0x10C
+#define CSR_SSTATEEN1   0x10D
+#define CSR_SSTATEEN2   0x10E
+#define CSR_SSTATEEN3   0x10F
+
 /* Supervisor Trap Handling */
 #define CSR_SSCRATCH0x140
 #define CSR_SEPC0x141
@@ -244,6 +250,16 @@
 #define CSR_HENVCFG 0x60A
 #define CSR_HENVCFGH0x61A
 
+/* Hypervisor state CSRs */
+#define CSR_HSTATEEN0   0x60C
+#define CSR_HSTATEEN0H  0x61C
+#define CSR_HSTATEEN1   0x60D
+#define CSR_HSTATEEN1H  0x61D
+#define CSR_HSTATEEN2   0x60E
+#define CSR_HSTATEEN2H  0x61E
+#define CSR_HSTATEEN3   0x60F
+#define CSR_HSTATEEN3H  0x61F
+
 /* Virtual CSRs */
 #define CSR_VSSTATUS0x200
 #define CSR_VSIE0x204
@@ -289,6 +305,27 @@
 #define CSR_MENVCFG 0x30A
 #define CSR_MENVCFGH0x31A
 
+/* Machine state CSRs */
+#define CSR_MSTATEEN0   0x30C
+#define CSR_MSTATEEN0H  0x31C
+#define CSR_MSTATEEN1   0x30D
+#define CSR_MSTATEEN1H  0x31D
+#define CSR_MSTATEEN2   0x30E
+#define CSR_MSTATEEN2H  0x31E
+#define CSR_MSTATEEN3   0x30F
+#define CSR_MSTATEEN3H  0x31F
+
+/* Common defines for all smstateen */
+#define SMSTATEEN_MAX_COUNT 4
+#define SMSTATEEN0_CS   (1ULL << 0)
+#define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_HSCONTXT (1ULL << 57)
+#define SMSTATEEN0_IMSIC(1ULL << 58)
+#define SMSTATEEN0_AIA  (1ULL << 59)
+#define SMSTATEEN0_SVSLCT   (1ULL << 60)
+#define SMSTATEEN0_HSENVCFG (1ULL << 62)
+#define SMSTATEEN_STATEEN   (1ULL << 63)
+
 /* Enhanced Physical Memory Protection (ePMP) */
 #define CSR_MSECCFG 0x747
 #define CSR_MSECCFGH0x757
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5c9a7ee287..c861424e85 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -283,6 +283,72 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
 return umode(env, csrno);
 }
 
+static RISCVException mstateen(CPURISCVState *env, int csrno)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return any(env, csrno);
+}
+
+static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (env->priv < PRV_M) {
+if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
+return hmode(env, csrno);
+}
+
+static RISCVException hstateen(CPURISCVState *env, int csrno)
+{
+return hstateen_pred(env, csrno, CSR_HSTATEEN0);
+}
+
+static RISCVException hstateenh(CPURISCVState *env, int csrno)
+{
+return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
+}
+
+static RISCVException sstateen(CPURISCVState *env, int csrno)
+{
+bool virt = riscv_cpu_virt_enabled(env);
+int index = csrno - CSR_SSTATEEN0;
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (env->priv < PRV_M) {
+if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[index] & SMSTAT

[PULL 02/45] hw/registerfields: add `FIELDx_1CLEAR()` macro

2022-12-18 Thread Alistair Francis
From: Wilfred Mallawa 

Adds a helper macro that implements the register `w1c`
functionality.

Ex:
  uint32_t data = FIELD32_1CLEAR(val, REG, FIELD);

If ANY bits of the specified `FIELD` is set
then the respective field is cleared and returned to `data`.

If the field is cleared (0), then no change and
val is returned.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221017054950.317584-2-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/registerfields.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
index 1330ca77de..0b8404c2f7 100644
--- a/include/hw/registerfields.h
+++ b/include/hw/registerfields.h
@@ -115,6 +115,28 @@
   R_ ## reg ## _ ## field ## _LENGTH, _v.v);  \
 _d; })
 
+/*
+ * Clear the specified field in storage if
+ * any field bits are set, else no changes made. Implements
+ * single/multi-bit `w1c`
+ *
+ */
+#define FIELD8_1CLEAR(storage, reg, field)\
+(FIELD_EX8(storage, reg, field) ? \
+FIELD_DP8(storage, reg, field, 0x00) : storage)
+
+#define FIELD16_1CLEAR(storage, reg, field)   \
+(FIELD_EX16(storage, reg, field) ?\
+FIELD_DP16(storage, reg, field, 0x00) : storage)
+
+#define FIELD32_1CLEAR(storage, reg, field)   \
+(FIELD_EX32(storage, reg, field) ?\
+FIELD_DP32(storage, reg, field, 0x00) : storage)
+
+#define FIELD64_1CLEAR(storage, reg, field)   \
+(FIELD_EX64(storage, reg, field) ?\
+FIELD_DP64(storage, reg, field, 0x00) : storage)
+
 #define FIELD_SDP8(storage, reg, field, val) ({   \
 struct {  \
 signed int v:R_ ## reg ## _ ## field ## _LENGTH;  \
-- 
2.38.1




[PULL 12/45] target/riscv: Add itrigger support when icount is not enabled

2022-12-18 Thread Alistair Francis
From: LIU Zhiwei 

When icount is not enabled, there is no API in QEMU that can get the
guest instruction number.

Translate the guest code in a way that each TB only has one instruction.
After executing the instruction, decrease the count by 1 until it reaches 0
where the itrigger fires.

Note that only when priviledge matches the itrigger configuration,
the count will decrease.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-2-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 +
 target/riscv/debug.h  | 12 
 target/riscv/helper.h |  2 +
 target/riscv/cpu_helper.c |  6 ++
 target/riscv/debug.c  | 71 +++
 target/riscv/translate.c  | 33 -
 .../riscv/insn_trans/trans_privileged.c.inc   |  4 +-
 target/riscv/insn_trans/trans_rvi.c.inc   |  8 +--
 target/riscv/insn_trans/trans_rvv.c.inc   |  4 +-
 9 files changed, 131 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5cac0c5eec..c32e484c0b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -625,6 +625,8 @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 FIELD(TB_FLAGS, VTA, 24, 1)
 FIELD(TB_FLAGS, VMA, 25, 1)
+/* Native debug itrigger */
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index a1226b4d29..cc3358e69b 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -118,6 +118,17 @@ enum {
 SIZE_NUM = 16
 };
 
+/* itrigger filed masks */
+#define ITRIGGER_ACTION   0x3f
+#define ITRIGGER_UBIT(6)
+#define ITRIGGER_SBIT(7)
+#define ITRIGGER_PENDING  BIT(8)
+#define ITRIGGER_MBIT(9)
+#define ITRIGGER_COUNT(0x3fff << 10)
+#define ITRIGGER_HIT  BIT(24)
+#define ITRIGGER_VU   BIT(25)
+#define ITRIGGER_VS   BIT(26)
+
 bool tdata_available(CPURISCVState *env, int tdata_index);
 
 target_ulong tselect_csr_read(CPURISCVState *env);
@@ -134,4 +145,5 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp);
 
 void riscv_trigger_init(CPURISCVState *env);
 
+bool riscv_itrigger_enabled(CPURISCVState *env);
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a03014fe67..227c7122ef 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -109,6 +109,8 @@ DEF_HELPER_1(sret, tl, env)
 DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
+/* Native Debug */
+DEF_HELPER_1(itrigger_match, void, env)
 #endif
 
 /* Hypervisor functions */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5d66246c2c..9d1d1bf9f1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -27,7 +27,9 @@
 #include "tcg/tcg-op.h"
 #include "trace.h"
 #include "semihosting/common-semi.h"
+#include "sysemu/cpu-timers.h"
 #include "cpu_bits.h"
+#include "debug.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -103,6 +105,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
 }
+if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
+flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
+   riscv_itrigger_enabled(env));
+}
 #endif
 
 flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index e44848d0d7..036161649f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -29,6 +29,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "exec/exec-all.h"
+#include "exec/helper-proto.h"
 
 /*
  * The following M-mode trigger CSRs are implemented:
@@ -496,6 +497,76 @@ static void type6_reg_write(CPURISCVState *env, 
target_ulong index,
 return;
 }
 
+/* icount trigger type */
+static inline int
+itrigger_get_count(CPURISCVState *env, int index)
+{
+return get_field(env->tdata1[index], ITRIGGER_COUNT);
+}
+
+static inline void
+itrigger_set_count(CPURISCVState *env, int index, int value)
+{
+env->tdata1[index] = set_field(env->tdata1[index],
+   ITRIGGER_COUNT, value);
+}
+
+static bool check_itrigger_priv(CPURISCVState *env, int index)
+{
+target_ulong tdata1 = env->tdata1[index];
+if (riscv_cpu_virt_enabled(env)) {
+/* check VU/VS bit against current privilege level */
+return (get_field(tdata1, ITRIGGER_VS) == env->priv) ||
+   (get_field(tdata1, ITRIGGER_VU) == env->priv);
+} else {
+/* check U/S/M bit against current privilege level */
+return (get_fi

[PULL 01/45] target/riscv: Fix PMP propagation for tlb

2022-12-18 Thread Alistair Francis
From: LIU Zhiwei 

Only the pmp index that be checked by pmp_hart_has_privs can be used
by pmp_get_tlb_size to avoid an error pmp index.

Before modification, we may use an error pmp index. For example,
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
will return true;

However, this checked pmp index is discarded as pmp_hart_has_privs
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
a pmp rule [0x10, 0x14), it will be misused as it is legal in
pmp_get_tlb_size.

As we have already known the correct pmp index, just remove the
remove the pmp_is_range_in_tlb and get tlb size directly from
pmp_get_tlb_size.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221012060016.30856-1-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.h|  6 +--
 target/riscv/cpu_helper.c | 16 ---
 target/riscv/pmp.c| 90 +--
 3 files changed, 42 insertions(+), 70 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a8dd797476..da32c61c85 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -72,11 +72,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
 target_ulong val);
 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
 target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
 target_ulong mode);
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+  target_ulong tlb_sa, target_ulong tlb_ea);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
 uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 278d163803..5d66246c2c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -706,24 +706,26 @@ static int get_physical_address_pmp(CPURISCVState *env, 
int *prot,
 int mode)
 {
 pmp_priv_t pmp_priv;
-target_ulong tlb_size_pmp = 0;
+int pmp_index = -1;
 
 if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TRANSLATE_SUCCESS;
 }
 
-if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
-mode)) {
+pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+   &pmp_priv, mode);
+if (pmp_index < 0) {
 *prot = 0;
 return TRANSLATE_PMP_FAIL;
 }
 
 *prot = pmp_priv_to_page_prot(pmp_priv);
-if (tlb_size != NULL) {
-if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
-*tlb_size = tlb_size_pmp;
-}
+if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
+target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+
+*tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
 }
 
 return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2b43e399b8..d1126a6066 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -292,8 +292,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, 
target_ulong addr,
 
 /*
  * Check if the address has required RWX privs to complete desired operation
+ * Return PMP rule index if a pmp rule match
+ * Return MAX_RISCV_PMPS if default match
+ * Return negtive value if no match
  */
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
 target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
 target_ulong mode)
 {
@@ -305,8 +308,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
-return pmp_hart_has_privs_default(env, addr, size, privs,
-  allowed_privs, mode);
+if (pmp_hart_has_privs_default(env, addr, size, privs,
+   allowed_privs, mode)) {
+ret = MAX_RISCV_PMPS;
+}
 }
 
 if (size == 0) {
@@ -333,7 +338,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 if ((s + e) == 1) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "pmp violation - access is partially inside\n");
-ret = 0;
+ret = -1;

Re: [PATCH] virtio-mem: Fix the bitmap index of the section offset

2022-12-18 Thread Chenyi Qiang



On 12/16/2022 6:30 PM, David Hildenbrand wrote:
> On 16.12.22 09:52, David Hildenbrand wrote:
>> On 16.12.22 07:22, Chenyi Qiang wrote:
>>> vmem->bitmap indexes the memory region of the virtio-mem backend at a
>>> granularity of block_size. To calculate the index of target section
>>> offset,
>>> the block_size should be divided instead of the bitmap_size.
>>
>> I'm curious, what's the user-visible effect and how did you identify
>> this issue?
>>
>> IIUC, we could end up our search for a plugged/unplugged block "too
>> late", such that we miss to process blocks.
>>
>> That would be the case if the bitmap_size < block_size, which should
>> effectively always happen ...
>>
>>
>> unplug_all and migration would be affected, which is why a simple test
>> case without a guest reboot/migration wouldn't run into it.
> 
> I just realized that unplug_all is fine because only vfio implements the
> ram_discard_listener so far and always sets
> double_discard_supported=true. So migration should be the issue (and
> IIRC migration with VFIO is still shaky).

Yes, actually, no obvious visible effect on my side. I was just learning
the RamDiscardManager interface and found this issue. :)

> 



Re: [PATCH v2 0/7] Enable Cubieboard A10 boot SPL from SD card

2022-12-18 Thread Strahinja Jankovic
Hi,

I just looked around a bit more. Would OpenWrt image be acceptable?
It looks like there are releases for cubieboard that are kept for a
longer time, and I just checked that they work properly, so I could
add them to the acceptance test.

Best regards,
Strahinja

On Sun, Dec 18, 2022 at 11:34 PM Strahinja Jankovic
 wrote:
>
> Hi,
>
>
> On Sun, Dec 18, 2022 at 11:17 PM Philippe Mathieu-Daudé
>  wrote:
> >
> > On 18/12/22 22:19, Strahinja Jankovic wrote:
> > > This patch series adds missing Allwinner A10 modules needed for
> > > successful SPL boot:
> > > - Clock controller module
> > > - DRAM controller
> > > - I2C0 controller (added also for Allwinner H3 since it is the same)
> > > - AXP-209 connected to I2C0 bus
> > >
> > > It also updates Allwinner A10 emulation so SPL is copied from attached
> > > SD card if `-kernel` parameter is not passed when starting QEMU
> > > (approach adapted from Allwinner H3 implementation).
> > >
> > > Boot from SD card has been tested with Cubieboard Armbian SD card image 
> > > and custom
> > > Yocto image built for Cubieboard.
> > > Example usage for Armbian image:
> > > qemu-system-arm -M cubieboard -nographic -sd 
> > > ~/Armbian_22.11.0-trunk_Cubieboard_kinetic_edge_6.0.7.img
> >
> > As a follow-up, could you add a test similar to
> > test_arm_orangepi_bionic_20_08() in tests/avocado/boot_linux_console.py?
> >
> > This test could be refactored as do_test_arm_allwinner_armbian(), called
> > for orangepi and cubieboard with the corresponding url / hash.
>
> I was planning to do it (I already have a patch for cubieboard), but
> there is a problem with finding a stable-enough image for cubieboard
> for automated testing.
> Unfortunately, Cubieboard does not have supported Armbian images as
> OrangePi-PC has (it only has weekly builds). From the images that can
> be found on archive.armbian.com, there is only one bionic image
> (21.02) and it won't boot because it hangs due to the musb issue (I
> tried both with my patches and without, by extracting
> kernel/dtb/initrd). Other images are focal, but for some reason, in
> those images it is impossible to interrupt U-Boot (tested with 21.08),
> so I could not append to bootcmd to make boot process more verbose and
> easier to monitor for automated testing.
>
> That is why, for now, I would suggest not updating the SPL/SD boot
> test for Cubieboard.
>
> Best regards,
> Strahinja



Re: [PATCH v4 20b/27] tcg: Vary the allocation size for TCGOp

2022-12-18 Thread Richard Henderson

On 12/18/22 13:49, Philippe Mathieu-Daudé wrote:

+ found:
  memset(op, 0, offsetof(TCGOp, link));
  op->opc = opc;
-    s->nb_ops++;
+    op->nargs = nargs;


We can move this assignation before the 'found' label.


No, affected by the memset.


r~



Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Strahinja Jankovic
Hi,

On Sun, Dec 18, 2022 at 11:23 PM Philippe Mathieu-Daudé
 wrote:
>
> On 18/12/22 23:12, Strahinja Jankovic wrote:
> > Hi,
> >
> > On Sun, Dec 18, 2022 at 11:07 PM Philippe Mathieu-Daudé
> >  wrote:
> >>
> >> On 18/12/22 22:19, Strahinja Jankovic wrote:
> >>> This patch adds minimal support for AXP-209 PMU.
> >>> Most important is chip ID since U-Boot SPL expects version 0x1. Besides
> >>> the chip ID register, reset values for two more registers used by A10
> >>> U-Boot SPL are covered.
> >>>
> >>> Signed-off-by: Strahinja Jankovic 
> >>> ---
> >>>hw/arm/Kconfig  |   1 +
> >>>hw/misc/Kconfig |   4 +
> >>>hw/misc/allwinner-axp-209.c | 238 
> >>>hw/misc/meson.build |   1 +
> >>>hw/misc/trace-events|   5 +
> >>>5 files changed, 249 insertions(+)
> >>>create mode 100644 hw/misc/allwinner-axp-209.c
> >>
> >>
> >>> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> >>> index 052fb54310..3855d937fd 100644
> >>> --- a/hw/misc/Kconfig
> >>> +++ b/hw/misc/Kconfig
> >>> @@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
> >>>config ALLWINNER_A10_DRAMC
> >>>bool
> >>>
> >>> +config ALLWINNER_AXP_209
> >>
> >> This controller is not specific to AllWinner. It can be plugged on any
> >> i2c bus. Please rename it AXP209_PMU. Otherwise LGTM!
> >
> > Do you mean only in Kconfig, or everywhere (file name, function names,
> > etc.)? Thanks.
>
> Keeping the file / functions names with 'allwinner' would give the false
> idea this is AllWinner specific; rather confusing isn't it? Besides it
> is not part of the SoC, this is an external component sitting on the
> bus. So "everywhere".

I was expecting that answer, but I wanted to check :)
When I started writing code for AXP209 it was indeed without allwinner
prefix, but then checkpatch.pl complained about missing lines in
MAINTAINERS. At that time it was easier to add the prefix (and get a
match in MAINTAINERS) than to investigate if I should update the
MAINTAINERS file or ignore the checkpatch.pl complaint.

I will update everything related to AXP209 so it does not have the
Allwinner prefix.

>
> Also, the "select ALLWINNER_AXP_209/AXP209_PMU" line in hw/arm/Kconfig
> belongs to the next patch "hw/arm: Add AXP-209 to Cubieboard".

I agree, will fix it.

Best regards,
Strahinja

>
> Regards,
>
> Phil.



Re: [PATCH v2 0/7] Enable Cubieboard A10 boot SPL from SD card

2022-12-18 Thread Strahinja Jankovic
Hi,


On Sun, Dec 18, 2022 at 11:17 PM Philippe Mathieu-Daudé
 wrote:
>
> On 18/12/22 22:19, Strahinja Jankovic wrote:
> > This patch series adds missing Allwinner A10 modules needed for
> > successful SPL boot:
> > - Clock controller module
> > - DRAM controller
> > - I2C0 controller (added also for Allwinner H3 since it is the same)
> > - AXP-209 connected to I2C0 bus
> >
> > It also updates Allwinner A10 emulation so SPL is copied from attached
> > SD card if `-kernel` parameter is not passed when starting QEMU
> > (approach adapted from Allwinner H3 implementation).
> >
> > Boot from SD card has been tested with Cubieboard Armbian SD card image and 
> > custom
> > Yocto image built for Cubieboard.
> > Example usage for Armbian image:
> > qemu-system-arm -M cubieboard -nographic -sd 
> > ~/Armbian_22.11.0-trunk_Cubieboard_kinetic_edge_6.0.7.img
>
> As a follow-up, could you add a test similar to
> test_arm_orangepi_bionic_20_08() in tests/avocado/boot_linux_console.py?
>
> This test could be refactored as do_test_arm_allwinner_armbian(), called
> for orangepi and cubieboard with the corresponding url / hash.

I was planning to do it (I already have a patch for cubieboard), but
there is a problem with finding a stable-enough image for cubieboard
for automated testing.
Unfortunately, Cubieboard does not have supported Armbian images as
OrangePi-PC has (it only has weekly builds). From the images that can
be found on archive.armbian.com, there is only one bionic image
(21.02) and it won't boot because it hangs due to the musb issue (I
tried both with my patches and without, by extracting
kernel/dtb/initrd). Other images are focal, but for some reason, in
those images it is impossible to interrupt U-Boot (tested with 21.08),
so I could not append to bootcmd to make boot process more verbose and
easier to monitor for automated testing.

That is why, for now, I would suggest not updating the SPL/SD boot
test for Cubieboard.

Best regards,
Strahinja



Re: [PATCH v2] contrib/vhost-user-blk: Replace lseek64 with lseek

2022-12-18 Thread Raphael Norwitz



> On Dec 19, 2022, at 12:07 AM, Khem Raj  wrote:
> 
> 64bit off_t is already in use since build uses _FILE_OFFSET_BITS=64
> already. Using lseek/off_t also makes it work with latest musl without
> using _LARGEFILE64_SOURCE macro. This macro is implied with _GNU_SOURCE
> when using glibc but not with musl.
> 
> Signed-off-by: Khem Raj 
> Cc: Michael S. Tsirkin 
> CC: Raphael Norwitz 
> ---
> v2: Fix typo must->musl
> 
> contrib/vhost-user-blk/vhost-user-blk.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/contrib/vhost-user-blk/vhost-user-blk.c 
> b/contrib/vhost-user-blk/vhost-user-blk.c
> index aa99877fcd..7941694e53 100644
> --- a/contrib/vhost-user-blk/vhost-user-blk.c
> +++ b/contrib/vhost-user-blk/vhost-user-blk.c
> @@ -532,9 +532,9 @@ vub_get_blocksize(int fd)
> static void
> vub_initialize_config(int fd, struct virtio_blk_config *config)
> {
> -off64_t capacity;
> +off_t capacity;
> 
> -capacity = lseek64(fd, 0, SEEK_END);
> +capacity = lseek(fd, 0, SEEK_END);
> config->capacity = capacity >> 9;
> config->blk_size = vub_get_blocksize(fd);
> config->size_max = 65536;
> -- 
> 2.39.0
> 


Reviewed-by: Raphael Norwitz 


Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 23:12, Strahinja Jankovic wrote:

Hi,

On Sun, Dec 18, 2022 at 11:07 PM Philippe Mathieu-Daudé
 wrote:


On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch adds minimal support for AXP-209 PMU.
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
the chip ID register, reset values for two more registers used by A10
U-Boot SPL are covered.

Signed-off-by: Strahinja Jankovic 
---
   hw/arm/Kconfig  |   1 +
   hw/misc/Kconfig |   4 +
   hw/misc/allwinner-axp-209.c | 238 
   hw/misc/meson.build |   1 +
   hw/misc/trace-events|   5 +
   5 files changed, 249 insertions(+)
   create mode 100644 hw/misc/allwinner-axp-209.c




diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 052fb54310..3855d937fd 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
   config ALLWINNER_A10_DRAMC
   bool

+config ALLWINNER_AXP_209


This controller is not specific to AllWinner. It can be plugged on any
i2c bus. Please rename it AXP209_PMU. Otherwise LGTM!


Do you mean only in Kconfig, or everywhere (file name, function names,
etc.)? Thanks.


Keeping the file / functions names with 'allwinner' would give the false
idea this is AllWinner specific; rather confusing isn't it? Besides it
is not part of the SoC, this is an external component sitting on the
bus. So "everywhere".

Also, the "select ALLWINNER_AXP_209/AXP209_PMU" line in hw/arm/Kconfig
belongs to the next patch "hw/arm: Add AXP-209 to Cubieboard".

Regards,

Phil.



Re: [PATCH v2 0/7] Enable Cubieboard A10 boot SPL from SD card

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch series adds missing Allwinner A10 modules needed for
successful SPL boot:
- Clock controller module
- DRAM controller
- I2C0 controller (added also for Allwinner H3 since it is the same)
- AXP-209 connected to I2C0 bus

It also updates Allwinner A10 emulation so SPL is copied from attached
SD card if `-kernel` parameter is not passed when starting QEMU
(approach adapted from Allwinner H3 implementation).

Boot from SD card has been tested with Cubieboard Armbian SD card image and 
custom
Yocto image built for Cubieboard.
Example usage for Armbian image:
qemu-system-arm -M cubieboard -nographic -sd 
~/Armbian_22.11.0-trunk_Cubieboard_kinetic_edge_6.0.7.img


As a follow-up, could you add a test similar to
test_arm_orangepi_bionic_20_08() in tests/avocado/boot_linux_console.py?

This test could be refactored as do_test_arm_allwinner_armbian(), called
for orangepi and cubieboard with the corresponding url / hash.



Re: [PATCH v2 6/7] hw/arm: Allwinner A10 enable SPL load from MMC

2022-12-18 Thread Strahinja Jankovic
Hi,

On Sun, Dec 18, 2022 at 10:59 PM Philippe Mathieu-Daudé
 wrote:
>
> On 18/12/22 22:19, Strahinja Jankovic wrote:
> > This patch enables copying of SPL from MMC if `-kernel` parameter is not
> > passed when starting QEMU. SPL is copied to SRAM_A.
> >
> > The approach is reused from Allwinner H3 implementation.
> >
> > Tested with Armbian and custom Yocto image.
> >
> > Signed-off-by: Strahinja Jankovic 
> >
> > Reviewed-by: Niek Linnenbank 
> > ---
> >   hw/arm/allwinner-a10.c | 18 ++
> >   hw/arm/cubieboard.c|  5 +
> >   include/hw/arm/allwinner-a10.h | 21 +
> >   3 files changed, 44 insertions(+)
> >
> > diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
> > index 17e439777e..dc1966ff7a 100644
> > --- a/hw/arm/allwinner-a10.c
> > +++ b/hw/arm/allwinner-a10.c
> > @@ -24,7 +24,9 @@
> >   #include "sysemu/sysemu.h"
> >   #include "hw/boards.h"
> >   #include "hw/usb/hcd-ohci.h"
> > +#include "hw/loader.h"
> >
> > +#define AW_A10_SRAM_A_BASE  0x
> >   #define AW_A10_DRAMC_BASE   0x01c01000
> >   #define AW_A10_MMC0_BASE0x01c0f000
> >   #define AW_A10_CCM_BASE 0x01c2
> > @@ -38,6 +40,22 @@
> >   #define AW_A10_RTC_BASE 0x01c20d00
> >   #define AW_A10_I2C0_BASE0x01c2ac00
> >
> > +void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk)
> > +{
> > +const int64_t rom_size = 32 * KiB;
> > +g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
> > +
> > +if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
> > +error_setg(&error_fatal, "%s: failed to read BlockBackend data",
> > +   __func__);
> > +return;
> > +}
> > +
> > +rom_add_blob("allwinner-a10.bootrom", buffer, rom_size,
> > +  rom_size, AW_A10_SRAM_A_BASE,
> > +  NULL, NULL, NULL, NULL, false);
> > +}
> > +
> >   static void aw_a10_init(Object *obj)
> >   {
> >   AwA10State *s = AW_A10(obj);
> > diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
> > index afc7980414..37659c35fd 100644
> > --- a/hw/arm/cubieboard.c
> > +++ b/hw/arm/cubieboard.c
> > @@ -99,6 +99,11 @@ static void cubieboard_init(MachineState *machine)
> >   memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
> >   machine->ram);
> >
> > +/* Load target kernel or start using BootROM */
> > +if (!machine->kernel_filename && blk && blk_is_available(blk)) {
> > +/* Use Boot ROM to copy data from SD card to SRAM */
> > +allwinner_a10_bootrom_setup(a10, blk);
> > +}
> >   /* TODO create and connect IDE devices for ide_drive_get() */
> >
> >   cubieboard_binfo.ram_size = machine->ram_size;
> > diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
> > index 763935fca9..b3c9ed24c7 100644
> > --- a/include/hw/arm/allwinner-a10.h
> > +++ b/include/hw/arm/allwinner-a10.h
> > @@ -15,6 +15,7 @@
> >   #include "hw/misc/allwinner-a10-ccm.h"
> >   #include "hw/misc/allwinner-a10-dramc.h"
> >   #include "hw/i2c/allwinner-i2c.h"
> > +#include "sysemu/block-backend.h"
> >
> >   #include "target/arm/cpu.h"
> >   #include "qom/object.h"
> > @@ -47,4 +48,24 @@ struct AwA10State {
> >   OHCISysBusState ohci[AW_A10_NUM_USB];
> >   };
> >
> > +/**
> > + * Emulate Boot ROM firmware setup functionality.
> > + *
> > + * A real Allwinner A10 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
>
> "at offset 8 KiB" ?

Yes, that is correct. I will update the function description.

Best regards,
Strahinja

>
> > from the given block device and writes it to
> > + * the start of the first internal SRAM memory.
> > + *
> > + * @s: Allwinner A10 state object pointer
> > + * @blk: Block backend device object pointer
> > + */
> > +void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk);
> > +
> >   #endif
>



Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Strahinja Jankovic
Hi,

On Sun, Dec 18, 2022 at 11:07 PM Philippe Mathieu-Daudé
 wrote:
>
> On 18/12/22 22:19, Strahinja Jankovic wrote:
> > This patch adds minimal support for AXP-209 PMU.
> > Most important is chip ID since U-Boot SPL expects version 0x1. Besides
> > the chip ID register, reset values for two more registers used by A10
> > U-Boot SPL are covered.
> >
> > Signed-off-by: Strahinja Jankovic 
> > ---
> >   hw/arm/Kconfig  |   1 +
> >   hw/misc/Kconfig |   4 +
> >   hw/misc/allwinner-axp-209.c | 238 
> >   hw/misc/meson.build |   1 +
> >   hw/misc/trace-events|   5 +
> >   5 files changed, 249 insertions(+)
> >   create mode 100644 hw/misc/allwinner-axp-209.c
>
>
> > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > index 052fb54310..3855d937fd 100644
> > --- a/hw/misc/Kconfig
> > +++ b/hw/misc/Kconfig
> > @@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
> >   config ALLWINNER_A10_DRAMC
> >   bool
> >
> > +config ALLWINNER_AXP_209
>
> This controller is not specific to AllWinner. It can be plugged on any
> i2c bus. Please rename it AXP209_PMU. Otherwise LGTM!

Do you mean only in Kconfig, or everywhere (file name, function names,
etc.)? Thanks.

Best regards,
Strahinja


>
> > +bool
> > +depends on I2C
> > +
> >   source macio/Kconfig
> > diff --git a/hw/misc/allwinner-axp-209.c b/hw/misc/allwinner-axp-209.c
> > new file mode 100644
> > index 00..cf79175034
> > --- /dev/null
> > +++ b/hw/misc/allwinner-axp-209.c
> > @@ -0,0 +1,238 @@
> > +/*
> > + * AXP-209 Emulation
> > + *
> > + * Copyright (C) 2022 Strahinja Jankovic 



Re: [PATCH v2] contrib/vhost-user-blk: Replace lseek64 with lseek

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 23:07, Khem Raj wrote:

64bit off_t is already in use since build uses _FILE_OFFSET_BITS=64
already. Using lseek/off_t also makes it work with latest musl without
using _LARGEFILE64_SOURCE macro. This macro is implied with _GNU_SOURCE
when using glibc but not with musl.

Signed-off-by: Khem Raj 
Cc: Michael S. Tsirkin 
CC: Raphael Norwitz 
---
v2: Fix typo must->musl

  contrib/vhost-user-blk/vhost-user-blk.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/vhost-user-blk/vhost-user-blk.c 
b/contrib/vhost-user-blk/vhost-user-blk.c
index aa99877fcd..7941694e53 100644
--- a/contrib/vhost-user-blk/vhost-user-blk.c
+++ b/contrib/vhost-user-blk/vhost-user-blk.c
@@ -532,9 +532,9 @@ vub_get_blocksize(int fd)
  static void
  vub_initialize_config(int fd, struct virtio_blk_config *config)
  {
-off64_t capacity;
+off_t capacity;
  
-capacity = lseek64(fd, 0, SEEK_END);

+capacity = lseek(fd, 0, SEEK_END);
  config->capacity = capacity >> 9;
  config->blk_size = vub_get_blocksize(fd);
  config->size_max = 65536;


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 7/7] docs/system/arm: Update Allwinner with TWI (I2C)

2022-12-18 Thread Strahinja Jankovic
Hi,

On Sun, Dec 18, 2022 at 11:02 PM Philippe Mathieu-Daudé
 wrote:
>
> On 18/12/22 22:19, Strahinja Jankovic wrote:
> > TWI (I2C) is supported so docs are updated for Cubieboard and
> > Orangepi-PC board.
> >
> > Signed-off-by: Strahinja Jankovic 
> > ---
> >   docs/system/arm/cubieboard.rst | 1 +
> >   docs/system/arm/orangepi.rst   | 1 +
> >   2 files changed, 2 insertions(+)
> >
> > diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
> > index 344ff8cef9..8d485f5435 100644
> > --- a/docs/system/arm/cubieboard.rst
> > +++ b/docs/system/arm/cubieboard.rst
> > @@ -14,3 +14,4 @@ Emulated devices:
> >   - SDHCI
> >   - USB controller
> >   - SATA controller
> > +- TWI (I2C) controller
> > diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
> > index 83c7445197..e5973600a1 100644
> > --- a/docs/system/arm/orangepi.rst
> > +++ b/docs/system/arm/orangepi.rst
> > @@ -25,6 +25,7 @@ The Orange Pi PC machine supports the following devices:
> >* Clock Control Unit
> >* System Control module
> >* Security Identifier device
> > + * TWI (I2C)
> >
> >   Limitations
> >   """
>
> Squash to patch #3 "hw/i2c: Allwinner TWI/I2C Emulation"?

Yes, that makes sense, I will do it. Thanks.

Best regards,
Strahinja



[PATCH v2] contrib/vhost-user-blk: Replace lseek64 with lseek

2022-12-18 Thread Khem Raj
64bit off_t is already in use since build uses _FILE_OFFSET_BITS=64
already. Using lseek/off_t also makes it work with latest musl without
using _LARGEFILE64_SOURCE macro. This macro is implied with _GNU_SOURCE
when using glibc but not with musl.

Signed-off-by: Khem Raj 
Cc: Michael S. Tsirkin 
CC: Raphael Norwitz 
---
v2: Fix typo must->musl

 contrib/vhost-user-blk/vhost-user-blk.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/vhost-user-blk/vhost-user-blk.c 
b/contrib/vhost-user-blk/vhost-user-blk.c
index aa99877fcd..7941694e53 100644
--- a/contrib/vhost-user-blk/vhost-user-blk.c
+++ b/contrib/vhost-user-blk/vhost-user-blk.c
@@ -532,9 +532,9 @@ vub_get_blocksize(int fd)
 static void
 vub_initialize_config(int fd, struct virtio_blk_config *config)
 {
-off64_t capacity;
+off_t capacity;
 
-capacity = lseek64(fd, 0, SEEK_END);
+capacity = lseek(fd, 0, SEEK_END);
 config->capacity = capacity >> 9;
 config->blk_size = vub_get_blocksize(fd);
 config->size_max = 65536;
-- 
2.39.0




Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch adds minimal support for AXP-209 PMU.
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
the chip ID register, reset values for two more registers used by A10
U-Boot SPL are covered.

Signed-off-by: Strahinja Jankovic 
---
  hw/arm/Kconfig  |   1 +
  hw/misc/Kconfig |   4 +
  hw/misc/allwinner-axp-209.c | 238 
  hw/misc/meson.build |   1 +
  hw/misc/trace-events|   5 +
  5 files changed, 249 insertions(+)
  create mode 100644 hw/misc/allwinner-axp-209.c




diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 052fb54310..3855d937fd 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
  config ALLWINNER_A10_DRAMC
  bool
  
+config ALLWINNER_AXP_209


This controller is not specific to AllWinner. It can be plugged on any
i2c bus. Please rename it AXP209_PMU. Otherwise LGTM!


+bool
+depends on I2C
+
  source macio/Kconfig
diff --git a/hw/misc/allwinner-axp-209.c b/hw/misc/allwinner-axp-209.c
new file mode 100644
index 00..cf79175034
--- /dev/null
+++ b/hw/misc/allwinner-axp-209.c
@@ -0,0 +1,238 @@
+/*
+ * AXP-209 Emulation
+ *
+ * Copyright (C) 2022 Strahinja Jankovic 




Re: [PATCH v2 7/7] docs/system/arm: Update Allwinner with TWI (I2C)

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:19, Strahinja Jankovic wrote:

TWI (I2C) is supported so docs are updated for Cubieboard and
Orangepi-PC board.

Signed-off-by: Strahinja Jankovic 
---
  docs/system/arm/cubieboard.rst | 1 +
  docs/system/arm/orangepi.rst   | 1 +
  2 files changed, 2 insertions(+)

diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
index 344ff8cef9..8d485f5435 100644
--- a/docs/system/arm/cubieboard.rst
+++ b/docs/system/arm/cubieboard.rst
@@ -14,3 +14,4 @@ Emulated devices:
  - SDHCI
  - USB controller
  - SATA controller
+- TWI (I2C) controller
diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
index 83c7445197..e5973600a1 100644
--- a/docs/system/arm/orangepi.rst
+++ b/docs/system/arm/orangepi.rst
@@ -25,6 +25,7 @@ The Orange Pi PC machine supports the following devices:
   * Clock Control Unit
   * System Control module
   * Security Identifier device
+ * TWI (I2C)
  
  Limitations

  """


Squash to patch #3 "hw/i2c: Allwinner TWI/I2C Emulation"?



Re: [PATCH v2 6/7] hw/arm: Allwinner A10 enable SPL load from MMC

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:19, Strahinja Jankovic wrote:

This patch enables copying of SPL from MMC if `-kernel` parameter is not
passed when starting QEMU. SPL is copied to SRAM_A.

The approach is reused from Allwinner H3 implementation.

Tested with Armbian and custom Yocto image.

Signed-off-by: Strahinja Jankovic 

Reviewed-by: Niek Linnenbank 
---
  hw/arm/allwinner-a10.c | 18 ++
  hw/arm/cubieboard.c|  5 +
  include/hw/arm/allwinner-a10.h | 21 +
  3 files changed, 44 insertions(+)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 17e439777e..dc1966ff7a 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -24,7 +24,9 @@
  #include "sysemu/sysemu.h"
  #include "hw/boards.h"
  #include "hw/usb/hcd-ohci.h"
+#include "hw/loader.h"
  
+#define AW_A10_SRAM_A_BASE  0x

  #define AW_A10_DRAMC_BASE   0x01c01000
  #define AW_A10_MMC0_BASE0x01c0f000
  #define AW_A10_CCM_BASE 0x01c2
@@ -38,6 +40,22 @@
  #define AW_A10_RTC_BASE 0x01c20d00
  #define AW_A10_I2C0_BASE0x01c2ac00
  
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk)

+{
+const int64_t rom_size = 32 * KiB;
+g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
+
+if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
+error_setg(&error_fatal, "%s: failed to read BlockBackend data",
+   __func__);
+return;
+}
+
+rom_add_blob("allwinner-a10.bootrom", buffer, rom_size,
+  rom_size, AW_A10_SRAM_A_BASE,
+  NULL, NULL, NULL, NULL, false);
+}
+
  static void aw_a10_init(Object *obj)
  {
  AwA10State *s = AW_A10(obj);
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index afc7980414..37659c35fd 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -99,6 +99,11 @@ static void cubieboard_init(MachineState *machine)
  memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
  machine->ram);
  
+/* Load target kernel or start using BootROM */

+if (!machine->kernel_filename && blk && blk_is_available(blk)) {
+/* Use Boot ROM to copy data from SD card to SRAM */
+allwinner_a10_bootrom_setup(a10, blk);
+}
  /* TODO create and connect IDE devices for ide_drive_get() */
  
  cubieboard_binfo.ram_size = machine->ram_size;

diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index 763935fca9..b3c9ed24c7 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -15,6 +15,7 @@
  #include "hw/misc/allwinner-a10-ccm.h"
  #include "hw/misc/allwinner-a10-dramc.h"
  #include "hw/i2c/allwinner-i2c.h"
+#include "sysemu/block-backend.h"
  
  #include "target/arm/cpu.h"

  #include "qom/object.h"
@@ -47,4 +48,24 @@ struct AwA10State {
  OHCISysBusState ohci[AW_A10_NUM_USB];
  };
  
+/**

+ * Emulate Boot ROM firmware setup functionality.
+ *
+ * A real Allwinner A10 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


"at offset 8 KiB" ?


from the given block device and writes it to
+ * the start of the first internal SRAM memory.
+ *
+ * @s: Allwinner A10 state object pointer
+ * @blk: Block backend device object pointer
+ */
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk);
+
  #endif





Re: [PATCH v2 5/7] hw/arm: Add AXP-209 to Cubieboard

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:19, Strahinja Jankovic wrote:

SPL Boot for Cubieboard expects AXP-209 connected to I2C0 bus.

Signed-off-by: Strahinja Jankovic 
---
  hw/arm/cubieboard.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index 5e3372a3c7..afc7980414 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -20,6 +20,7 @@
  #include "hw/boards.h"
  #include "hw/qdev-properties.h"
  #include "hw/arm/allwinner-a10.h"
+#include "hw/i2c/i2c.h"
  
  static struct arm_boot_info cubieboard_binfo = {

  .loader_start = AW_A10_SDRAM_BASE,
@@ -34,6 +35,7 @@ static void cubieboard_init(MachineState *machine)
  BlockBackend *blk;
  BusState *bus;
  DeviceState *carddev;
+I2CBus *i2c;
  
  /* BIOS is not supported by this board */

  if (machine->firmware) {
@@ -80,6 +82,10 @@ static void cubieboard_init(MachineState *machine)
  exit(1);
  }
  
+/* Connect AXP 209 */

+i2c = (I2CBus *)qdev_get_child_bus(DEVICE(&a10->i2c0), "i2c");


Preferably using I2C_BUS() instead of the cast:

Reviewed-by: Philippe Mathieu-Daudé 


+i2c_slave_create_simple(i2c, "allwinner.axp209", 0x34);
+
  /* Retrieve SD bus */
  di = drive_get(IF_SD, 0, 0);
  blk = di ? blk_by_legacy_dinfo(di) : NULL;





Re: [PATCH v4 20b/27] tcg: Vary the allocation size for TCGOp

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:18, Philippe Mathieu-Daudé wrote:

From: Richard Henderson 

We have been allocating a worst case number of arguments
to support calls.  Instead, allow the size to vary.
By default leave space for 4 args, to maximize reuse,
but allow calls to increase the number of args to 32.

Signed-off-by: Richard Henderson 
[PMD: Split patch in two]
Signed-off-by: Philippe Mathieu-Daudé 
---
  accel/tcg/plugin-gen.c | 10 -
  include/exec/helper-head.h |  2 --
  include/tcg/tcg.h  | 46 +-
  tcg/tcg.c  | 35 +
  4 files changed, 47 insertions(+), 46 deletions(-)




diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3f172cb1d6..ccbe947222 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1513,7 +1513,12 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
  }
  }
  
-max_args = ARRAY_SIZE(op->args);

+/*
+ * A Call op needs up to 4 + 2N parameters on 32-bit archs,
+ * and up to 4 + N parameters on 64-bit archs
+ * (N = number of input arguments + output arguments).
+ */
+max_args = (64 / TCG_TARGET_REG_BITS) * nargs + 4;
  op = tcg_emit_op(INDEX_op_call, max_args);
  
  pi = 0;

@@ -2298,19 +2303,31 @@ void tcg_remove_ops_after(TCGOp *op)
  static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
  {
  TCGContext *s = tcg_ctx;
-TCGOp *op;
+TCGOp *op = NULL;
  
-assert(nargs < ARRAY_SIZE(op->args));

-if (likely(QTAILQ_EMPTY(&s->free_ops))) {
-op = tcg_malloc(sizeof(TCGOp));
-} else {
-op = QTAILQ_FIRST(&s->free_ops);
-QTAILQ_REMOVE(&s->free_ops, op, link);
+if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) {
+QTAILQ_FOREACH(op, &s->free_ops, link) {
+if (nargs <= op->nargs) {
+QTAILQ_REMOVE(&s->free_ops, op, link);
+nargs = op->nargs;
+goto found;
+}
+}
  }
+
+/* Most opcodes have 3 or 4 operands: reduce fragmentation. */
+nargs = MAX(4, nargs);
+op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs);
+
+ found:
  memset(op, 0, offsetof(TCGOp, link));
  op->opc = opc;
-s->nb_ops++;
+op->nargs = nargs;


We can move this assignation before the 'found' label.

  
+/* Check for bitfield overflow. */

+tcg_debug_assert(op->nargs == nargs);
+
+s->nb_ops++;
  return op;
  }
  


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v4 20a/27] tcg: Pass number of arguments to tcg_emit_op() / tcg_op_insert_*()

2022-12-18 Thread Philippe Mathieu-Daudé

On 18/12/22 22:18, Philippe Mathieu-Daudé wrote:

In order to have variable size allocated TCGOp, pass the number
of arguments we use (and would allocate) up to tcg_op_alloc().

This alters tcg_emit_op(), tcg_op_insert_before() and
tcg_op_insert_after() prototypes.

In tcg_op_alloc() ensure the number of arguments is in range.

Signed-off-by: Richard Henderson 


Reviewed-by: Philippe Mathieu-Daudé 


[PMD: Extracted from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
  accel/tcg/plugin-gen.c |  5 -
  include/tcg/tcg-op.h   |  2 +-
  include/tcg/tcg.h  |  8 +---
  tcg/optimize.c |  4 ++--
  tcg/tcg-op-vec.c   |  8 
  tcg/tcg-op.c   | 12 ++--
  tcg/tcg.c  | 30 +-
  7 files changed, 39 insertions(+), 30 deletions(-)





Re: [PATCH v4 09/27] tcg: Simplify calls to temp_sync vs mem_coherent

2022-12-18 Thread Philippe Mathieu-Daudé

On 13/12/22 22:25, Richard Henderson wrote:

The first thing that temp_sync does is check mem_coherent,
so there's no need for the caller to do so.

Signed-off-by: Richard Henderson 
---
  tcg/tcg.c | 8 ++--
  1 file changed, 2 insertions(+), 6 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v4 06/27] target/sparc: Avoid TCGV_{LOW,HIGH}

2022-12-18 Thread Philippe Mathieu-Daudé

On 13/12/22 22:25, Richard Henderson wrote:

Use the official extend/extract functions instead of routines
that will shortly be internal to tcg.

Cc: Mark Cave-Ayland 
Signed-off-by: Richard Henderson 
---
  target/sparc/translate.c | 21 -
  1 file changed, 4 insertions(+), 17 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Strahinja Jankovic
I forgot to add Philippe Mathieu-Daudé in CC for this patch, so I'm
fixing it now.

Best regards,
Strahinja Jankovic

On Sun, Dec 18, 2022 at 10:19 PM Strahinja Jankovic
 wrote:
>
> This patch adds minimal support for AXP-209 PMU.
> Most important is chip ID since U-Boot SPL expects version 0x1. Besides
> the chip ID register, reset values for two more registers used by A10
> U-Boot SPL are covered.
>
> Signed-off-by: Strahinja Jankovic 
> ---
>  hw/arm/Kconfig  |   1 +
>  hw/misc/Kconfig |   4 +
>  hw/misc/allwinner-axp-209.c | 238 
>  hw/misc/meson.build |   1 +
>  hw/misc/trace-events|   5 +
>  5 files changed, 249 insertions(+)
>  create mode 100644 hw/misc/allwinner-axp-209.c
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index eefe1fd134..67c6e83fe6 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -323,6 +323,7 @@ config ALLWINNER_A10
>  select ALLWINNER_A10_DRAMC
>  select ALLWINNER_EMAC
>  select ALLWINNER_I2C
> +select ALLWINNER_AXP_209
>  select SERIAL
>  select UNIMP
>
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index 052fb54310..3855d937fd 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
>  config ALLWINNER_A10_DRAMC
>  bool
>
> +config ALLWINNER_AXP_209
> +bool
> +depends on I2C
> +
>  source macio/Kconfig
> diff --git a/hw/misc/allwinner-axp-209.c b/hw/misc/allwinner-axp-209.c
> new file mode 100644
> index 00..cf79175034
> --- /dev/null
> +++ b/hw/misc/allwinner-axp-209.c
> @@ -0,0 +1,238 @@
> +/*
> + * AXP-209 Emulation
> + *
> + * Copyright (C) 2022 Strahinja Jankovic 
> + *
> + * 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.
> + *
> + * SPDX-License-Identifier: MIT
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "trace.h"
> +#include "hw/i2c/i2c.h"
> +#include "migration/vmstate.h"
> +
> +#define TYPE_AXP_209 "allwinner.axp209"
> +
> +#define AXP_209(obj) \
> +OBJECT_CHECK(AXP209I2CState, (obj), TYPE_AXP_209)
> +
> +/* registers */
> +enum {
> +REG_POWER_STATUS = 0x0u,
> +REG_OPERATING_MODE,
> +REG_OTG_VBUS_STATUS,
> +REG_CHIP_VERSION,
> +REG_DATA_CACHE_0,
> +REG_DATA_CACHE_1,
> +REG_DATA_CACHE_2,
> +REG_DATA_CACHE_3,
> +REG_DATA_CACHE_4,
> +REG_DATA_CACHE_5,
> +REG_DATA_CACHE_6,
> +REG_DATA_CACHE_7,
> +REG_DATA_CACHE_8,
> +REG_DATA_CACHE_9,
> +REG_DATA_CACHE_A,
> +REG_DATA_CACHE_B,
> +REG_POWER_OUTPUT_CTRL = 0x12u,
> +REG_DC_DC2_OUT_V_CTRL = 0x23u,
> +REG_DC_DC2_DVS_CTRL = 0x25u,
> +REG_DC_DC3_OUT_V_CTRL = 0x27u,
> +REG_LDO2_4_OUT_V_CTRL,
> +REG_LDO3_OUT_V_CTRL,
> +REG_VBUS_CH_MGMT = 0x30u,
> +REG_SHUTDOWN_V_CTRL,
> +REG_SHUTDOWN_CTRL,
> +REG_CHARGE_CTRL_1,
> +REG_CHARGE_CTRL_2,
> +REG_SPARE_CHARGE_CTRL,
> +REG_PEK_KEY_CTRL,
> +REG_DC_DC_FREQ_SET,
> +REG_CHR_TEMP_TH_SET,
> +REG_CHR_HIGH_TEMP_TH_CTRL,
> +REG_IPSOUT_WARN_L1,
> +REG_IPSOUT_WARN_L2,
> +REG_DISCHR_TEMP_TH_SET,
> +REG_DISCHR_HIGH_TEMP_TH_CTRL,
> +REG_IRQ_BANK_1_CTRL = 0x40u,
> +REG_IRQ_BANK_2_CTRL,
> +REG_IRQ_BANK_3_CTRL,
> +REG_IRQ_BANK_4_CTRL,
> +REG_IRQ_BANK_5_CTRL,
> +REG_IRQ_BANK_1_STAT = 0x48u,
> +REG_IRQ_BANK_2_STAT,
> +REG_IRQ_BANK_3_STAT,
> +REG_IRQ_BANK_4_STAT,
> +REG_IRQ_BANK_5_STAT,
> +REG_ADC_ACIN_V_H = 0x56u,
> +REG_ADC_ACIN_V_L,
> +REG_ADC_ACIN_CURR_H,
> +REG_ADC_ACIN_CURR_L,
> +REG_ADC_VBUS_V_H,
> +REG_ADC_VBUS_V_L,
> +REG_ADC_VBUS_CURR_H,
> +REG_ADC_VBUS_CURR_L,
> +REG_ADC_INT_TEMP_H,
> +REG_ADC_INT_TEMP_L,
> +REG_ADC_TEMP_SENS_V_H = 0x62u,
> +REG_ADC_TEMP_SENS_V_L,
> +REG_ADC_BAT_V_H = 0x78u,
> +REG_ADC_BAT_V_L,
> +REG_ADC_BAT_DISCHR_CURR_H,
> +REG_ADC_BAT_DISCHR_CURR_L,
> +REG_ADC_BAT_CHR

Re: [PATCH v4 17/27] accel/tcg/plugin: Don't search for the function pointer index

2022-12-18 Thread Philippe Mathieu-Daudé

On 13/12/22 22:25, Richard Henderson wrote:

The function pointer is immediately after the output and input
operands; no need to search.

Signed-off-by: Richard Henderson 
---
Cc: Alex Bennée 
---
  accel/tcg/plugin-gen.c | 29 +++--
  1 file changed, 11 insertions(+), 18 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v4 26/27] tcg/aarch64: Merge tcg_out_callr into tcg_out_call

2022-12-18 Thread Philippe Mathieu-Daudé

On 13/12/22 22:25, Richard Henderson wrote:

There is only one use, and BLR is perhaps even more
self-documentary than CALLR.

Signed-off-by: Richard Henderson 
---
  tcg/aarch64/tcg-target.c.inc | 7 +--
  1 file changed, 1 insertion(+), 6 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 6/7] hw/arm: Allwinner A10 enable SPL load from MMC

2022-12-18 Thread Strahinja Jankovic
This patch enables copying of SPL from MMC if `-kernel` parameter is not
passed when starting QEMU. SPL is copied to SRAM_A.

The approach is reused from Allwinner H3 implementation.

Tested with Armbian and custom Yocto image.

Signed-off-by: Strahinja Jankovic 

Reviewed-by: Niek Linnenbank 
---
 hw/arm/allwinner-a10.c | 18 ++
 hw/arm/cubieboard.c|  5 +
 include/hw/arm/allwinner-a10.h | 21 +
 3 files changed, 44 insertions(+)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 17e439777e..dc1966ff7a 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -24,7 +24,9 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/usb/hcd-ohci.h"
+#include "hw/loader.h"
 
+#define AW_A10_SRAM_A_BASE  0x
 #define AW_A10_DRAMC_BASE   0x01c01000
 #define AW_A10_MMC0_BASE0x01c0f000
 #define AW_A10_CCM_BASE 0x01c2
@@ -38,6 +40,22 @@
 #define AW_A10_RTC_BASE 0x01c20d00
 #define AW_A10_I2C0_BASE0x01c2ac00
 
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk)
+{
+const int64_t rom_size = 32 * KiB;
+g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
+
+if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
+error_setg(&error_fatal, "%s: failed to read BlockBackend data",
+   __func__);
+return;
+}
+
+rom_add_blob("allwinner-a10.bootrom", buffer, rom_size,
+  rom_size, AW_A10_SRAM_A_BASE,
+  NULL, NULL, NULL, NULL, false);
+}
+
 static void aw_a10_init(Object *obj)
 {
 AwA10State *s = AW_A10(obj);
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index afc7980414..37659c35fd 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -99,6 +99,11 @@ static void cubieboard_init(MachineState *machine)
 memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
 machine->ram);
 
+/* Load target kernel or start using BootROM */
+if (!machine->kernel_filename && blk && blk_is_available(blk)) {
+/* Use Boot ROM to copy data from SD card to SRAM */
+allwinner_a10_bootrom_setup(a10, blk);
+}
 /* TODO create and connect IDE devices for ide_drive_get() */
 
 cubieboard_binfo.ram_size = machine->ram_size;
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index 763935fca9..b3c9ed24c7 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -15,6 +15,7 @@
 #include "hw/misc/allwinner-a10-ccm.h"
 #include "hw/misc/allwinner-a10-dramc.h"
 #include "hw/i2c/allwinner-i2c.h"
+#include "sysemu/block-backend.h"
 
 #include "target/arm/cpu.h"
 #include "qom/object.h"
@@ -47,4 +48,24 @@ struct AwA10State {
 OHCISysBusState ohci[AW_A10_NUM_USB];
 };
 
+/**
+ * Emulate Boot ROM firmware setup functionality.
+ *
+ * A real Allwinner A10 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 A10 state object pointer
+ * @blk: Block backend device object pointer
+ */
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk);
+
 #endif
-- 
2.30.2




[PATCH v2 5/7] hw/arm: Add AXP-209 to Cubieboard

2022-12-18 Thread Strahinja Jankovic
SPL Boot for Cubieboard expects AXP-209 connected to I2C0 bus.

Signed-off-by: Strahinja Jankovic 
---
 hw/arm/cubieboard.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index 5e3372a3c7..afc7980414 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -20,6 +20,7 @@
 #include "hw/boards.h"
 #include "hw/qdev-properties.h"
 #include "hw/arm/allwinner-a10.h"
+#include "hw/i2c/i2c.h"
 
 static struct arm_boot_info cubieboard_binfo = {
 .loader_start = AW_A10_SDRAM_BASE,
@@ -34,6 +35,7 @@ static void cubieboard_init(MachineState *machine)
 BlockBackend *blk;
 BusState *bus;
 DeviceState *carddev;
+I2CBus *i2c;
 
 /* BIOS is not supported by this board */
 if (machine->firmware) {
@@ -80,6 +82,10 @@ static void cubieboard_init(MachineState *machine)
 exit(1);
 }
 
+/* Connect AXP 209 */
+i2c = (I2CBus *)qdev_get_child_bus(DEVICE(&a10->i2c0), "i2c");
+i2c_slave_create_simple(i2c, "allwinner.axp209", 0x34);
+
 /* Retrieve SD bus */
 di = drive_get(IF_SD, 0, 0);
 blk = di ? blk_by_legacy_dinfo(di) : NULL;
-- 
2.30.2




[PATCH v4 20b/27] tcg: Vary the allocation size for TCGOp

2022-12-18 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

We have been allocating a worst case number of arguments
to support calls.  Instead, allow the size to vary.
By default leave space for 4 args, to maximize reuse,
but allow calls to increase the number of args to 32.

Signed-off-by: Richard Henderson 
[PMD: Split patch in two]
Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/plugin-gen.c | 10 -
 include/exec/helper-head.h |  2 --
 include/tcg/tcg.h  | 46 +-
 tcg/tcg.c  | 35 +
 4 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 62e775d34d..c7d6514840 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -258,12 +258,12 @@ static TCGOp *rm_ops(TCGOp *op)
 
 static TCGOp *copy_op_nocheck(TCGOp **begin_op, TCGOp *op)
 {
-unsigned nargs = ARRAY_SIZE(op->args);
+TCGOp *old_op = QTAILQ_NEXT(*begin_op, link);
+unsigned nargs = old_op->nargs;
 
-*begin_op = QTAILQ_NEXT(*begin_op, link);
-tcg_debug_assert(*begin_op);
-op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc, nargs);
-memcpy(op->args, (*begin_op)->args, sizeof(op->args));
+*begin_op = old_op;
+op = tcg_op_insert_after(tcg_ctx, op, old_op->opc, nargs);
+memcpy(op->args, old_op->args, sizeof(op->args[0]) * nargs);
 
 return op;
 }
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index e242fed46e..8bdf0f6ea2 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -133,6 +133,4 @@
 #define DEF_HELPER_7(name, ret, t1, t2, t3, t4, t5, t6, t7) \
 DEF_HELPER_FLAGS_7(name, 0, ret, t1, t2, t3, t4, t5, t6, t7)
 
-/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
-
 #endif /* EXEC_HELPER_HEAD_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index c55fa21a89..d430ea10c8 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -38,20 +38,6 @@
 /* XXX: make safe guess about sizes */
 #define MAX_OP_PER_INSTR 266
 
-#if HOST_LONG_BITS == 32
-#define MAX_OPC_PARAM_PER_ARG 2
-#else
-#define MAX_OPC_PARAM_PER_ARG 1
-#endif
-#define MAX_OPC_PARAM_IARGS 7
-#define MAX_OPC_PARAM_OARGS 1
-#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
-
-/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
- * and up to 4 + N parameters on 64-bit archs
- * (N = number of input arguments + output arguments).  */
-#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
-
 #define CPU_TEMP_BUF_NLONGS 128
 #define TCG_STATIC_FRAME_SIZE  (CPU_TEMP_BUF_NLONGS * sizeof(long))
 
@@ -493,34 +479,34 @@ typedef struct TCGTempSet {
 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
 } TCGTempSet;
 
-/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding,
-   this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands.
-   There are never more than 2 outputs, which means that we can store all
-   dead + sync data within 16 bits.  */
-#define DEAD_ARG  4
-#define SYNC_ARG  1
-typedef uint16_t TCGLifeData;
+/*
+ * With 1 128-bit output, a 32-bit host requires 4 output parameters,
+ * which leaves a maximum of 28 other slots.  Which is enough for 7
+ * 128-bit operands.
+ */
+#define DEAD_ARG  (1 << 4)
+#define SYNC_ARG  (1 << 0)
+typedef uint32_t TCGLifeData;
 
-/* The layout here is designed to avoid a bitfield crossing of
-   a 32-bit boundary, which would cause GCC to add extra padding.  */
 typedef struct TCGOp {
-TCGOpcode opc   : 8;/*  8 */
+TCGOpcode opc   : 8;
+unsigned nargs  : 8;
 
 /* Parameters for this opcode.  See below.  */
-unsigned param1 : 4;/* 12 */
-unsigned param2 : 4;/* 16 */
+unsigned param1 : 8;
+unsigned param2 : 8;
 
 /* Lifetime data of the operands.  */
-unsigned life   : 16;   /* 32 */
+TCGLifeData life;
 
 /* Next and previous opcodes.  */
 QTAILQ_ENTRY(TCGOp) link;
 
-/* Arguments for the opcode.  */
-TCGArg args[MAX_OPC_PARAM];
-
 /* Register preferences for the output(s).  */
 TCGRegSet output_pref[2];
+
+/* Arguments for the opcode.  */
+TCGArg args[];
 } TCGOp;
 
 #define TCGOP_CALLI(X)(X)->param1
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3f172cb1d6..ccbe947222 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1513,7 +1513,12 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 }
 }
 
-max_args = ARRAY_SIZE(op->args);
+/*
+ * A Call op needs up to 4 + 2N parameters on 32-bit archs,
+ * and up to 4 + N parameters on 64-bit archs
+ * (N = number of input arguments + output arguments).
+ */
+max_args = (64 / TCG_TARGET_REG_BITS) * nargs + 4;
 op = tcg_emit_op(INDEX_op_call, max_args);
 
 pi = 0;
@@ -2298,19 +2303,31 @@ void tcg_remove_ops_after(TCGOp *op)
 static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
 {
 TCGContext *s = tcg_ctx;
-   

[PATCH v2 1/7] hw/misc: Allwinner-A10 Clock Controller Module Emulation

2022-12-18 Thread Strahinja Jankovic
During SPL boot several Clock Controller Module (CCM) registers are
read, most important are PLL and Tuning, as well as divisor registers.

This patch adds these registers and initializes reset values from user's
guide.

Signed-off-by: Strahinja Jankovic 

Reviewed-by: Niek Linnenbank 
---
 hw/arm/Kconfig  |   1 +
 hw/arm/allwinner-a10.c  |   7 +
 hw/misc/Kconfig |   3 +
 hw/misc/allwinner-a10-ccm.c | 224 
 hw/misc/meson.build |   1 +
 include/hw/arm/allwinner-a10.h  |   2 +
 include/hw/misc/allwinner-a10-ccm.h |  67 +
 7 files changed, 305 insertions(+)
 create mode 100644 hw/misc/allwinner-a10-ccm.c
 create mode 100644 include/hw/misc/allwinner-a10-ccm.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 17fcde8e1c..14f52b41af 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -319,6 +319,7 @@ config ALLWINNER_A10
 select AHCI
 select ALLWINNER_A10_PIT
 select ALLWINNER_A10_PIC
+select ALLWINNER_A10_CCM
 select ALLWINNER_EMAC
 select SERIAL
 select UNIMP
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 79082289ea..86baeeeca2 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -26,6 +26,7 @@
 #include "hw/usb/hcd-ohci.h"
 
 #define AW_A10_MMC0_BASE0x01c0f000
+#define AW_A10_CCM_BASE 0x01c2
 #define AW_A10_PIC_REG_BASE 0x01c20400
 #define AW_A10_PIT_REG_BASE 0x01c20c00
 #define AW_A10_UART0_REG_BASE   0x01c28000
@@ -46,6 +47,8 @@ static void aw_a10_init(Object *obj)
 
 object_initialize_child(obj, "timer", &s->timer, TYPE_AW_A10_PIT);
 
+object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
+
 object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
 
 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
@@ -103,6 +106,10 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 memory_region_add_subregion(get_system_memory(), 0x, &s->sram_a);
 create_unimplemented_device("a10-sram-ctrl", 0x01c0, 4 * KiB);
 
+/* Clock Control Module */
+sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
+
 /* FIXME use qdev NIC properties instead of nd_table[] */
 if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index cbabe9f78c..ed07bf4133 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -174,4 +174,7 @@ config VIRT_CTRL
 config LASI
 bool
 
+config ALLWINNER_A10_CCM
+bool
+
 source macio/Kconfig
diff --git a/hw/misc/allwinner-a10-ccm.c b/hw/misc/allwinner-a10-ccm.c
new file mode 100644
index 00..68146ee340
--- /dev/null
+++ b/hw/misc/allwinner-a10-ccm.c
@@ -0,0 +1,224 @@
+/*
+ * Allwinner A10 Clock Control Module emulation
+ *
+ * Copyright (C) 2022 Strahinja Jankovic 
+ *
+ *  This file is derived from Allwinner H3 CCU,
+ *  by 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 "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/misc/allwinner-a10-ccm.h"
+
+/* CCM register offsets */
+enum {
+REG_PLL1_CFG = 0x, /* PLL1 Control */
+REG_PLL1_TUN = 0x0004, /* PLL1 Tuning */
+REG_PLL2_CFG = 0x0008, /* PLL2 Control */
+REG_PLL2_TUN = 0x000C, /* PLL2 Tuning */
+REG_PLL3_CFG = 0x0010, /* PLL3 Control */
+REG_PLL4_CFG = 0x0018, /* PLL4 Control */
+REG_PLL5_CFG = 0x0020, /* PLL5 Control */
+REG_PLL5_TUN = 0x0024, /* PLL5 Tuning */
+REG_PLL6_CFG = 0x0028, /* PLL6 Control */
+REG_PLL6_TUN = 0x002C, /* PLL6 Tuning */
+REG_PLL7_CFG = 0x0030, /* PLL7 Control */
+REG_PLL1_TUN2= 0x0038, /* PLL1 Tuning2 */
+REG_PLL5_TUN2= 0x003C, /* PLL5 Tuning2 */
+REG_PLL8_CFG = 0x0040, /* PLL8 Control */
+REG_OSC24M_CFG   = 0x0050, /* OSC24M Control */
+REG_CPU_AHB_APB0_CFG = 0x0054, /* CPU, AHB and APB0 Divide Ratio */
+};
+
+#define REG_INDEX(offset)(offset / sizeof(uint32_t))
+
+/* CCM register reset val

[PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation

2022-12-18 Thread Strahinja Jankovic
This patch adds minimal support for AXP-209 PMU.
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
the chip ID register, reset values for two more registers used by A10
U-Boot SPL are covered.

Signed-off-by: Strahinja Jankovic 
---
 hw/arm/Kconfig  |   1 +
 hw/misc/Kconfig |   4 +
 hw/misc/allwinner-axp-209.c | 238 
 hw/misc/meson.build |   1 +
 hw/misc/trace-events|   5 +
 5 files changed, 249 insertions(+)
 create mode 100644 hw/misc/allwinner-axp-209.c

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index eefe1fd134..67c6e83fe6 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -323,6 +323,7 @@ config ALLWINNER_A10
 select ALLWINNER_A10_DRAMC
 select ALLWINNER_EMAC
 select ALLWINNER_I2C
+select ALLWINNER_AXP_209
 select SERIAL
 select UNIMP
 
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 052fb54310..3855d937fd 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM
 config ALLWINNER_A10_DRAMC
 bool
 
+config ALLWINNER_AXP_209
+bool
+depends on I2C
+
 source macio/Kconfig
diff --git a/hw/misc/allwinner-axp-209.c b/hw/misc/allwinner-axp-209.c
new file mode 100644
index 00..cf79175034
--- /dev/null
+++ b/hw/misc/allwinner-axp-209.c
@@ -0,0 +1,238 @@
+/*
+ * AXP-209 Emulation
+ *
+ * Copyright (C) 2022 Strahinja Jankovic 
+ *
+ * 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.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/i2c/i2c.h"
+#include "migration/vmstate.h"
+
+#define TYPE_AXP_209 "allwinner.axp209"
+
+#define AXP_209(obj) \
+OBJECT_CHECK(AXP209I2CState, (obj), TYPE_AXP_209)
+
+/* registers */
+enum {
+REG_POWER_STATUS = 0x0u,
+REG_OPERATING_MODE,
+REG_OTG_VBUS_STATUS,
+REG_CHIP_VERSION,
+REG_DATA_CACHE_0,
+REG_DATA_CACHE_1,
+REG_DATA_CACHE_2,
+REG_DATA_CACHE_3,
+REG_DATA_CACHE_4,
+REG_DATA_CACHE_5,
+REG_DATA_CACHE_6,
+REG_DATA_CACHE_7,
+REG_DATA_CACHE_8,
+REG_DATA_CACHE_9,
+REG_DATA_CACHE_A,
+REG_DATA_CACHE_B,
+REG_POWER_OUTPUT_CTRL = 0x12u,
+REG_DC_DC2_OUT_V_CTRL = 0x23u,
+REG_DC_DC2_DVS_CTRL = 0x25u,
+REG_DC_DC3_OUT_V_CTRL = 0x27u,
+REG_LDO2_4_OUT_V_CTRL,
+REG_LDO3_OUT_V_CTRL,
+REG_VBUS_CH_MGMT = 0x30u,
+REG_SHUTDOWN_V_CTRL,
+REG_SHUTDOWN_CTRL,
+REG_CHARGE_CTRL_1,
+REG_CHARGE_CTRL_2,
+REG_SPARE_CHARGE_CTRL,
+REG_PEK_KEY_CTRL,
+REG_DC_DC_FREQ_SET,
+REG_CHR_TEMP_TH_SET,
+REG_CHR_HIGH_TEMP_TH_CTRL,
+REG_IPSOUT_WARN_L1,
+REG_IPSOUT_WARN_L2,
+REG_DISCHR_TEMP_TH_SET,
+REG_DISCHR_HIGH_TEMP_TH_CTRL,
+REG_IRQ_BANK_1_CTRL = 0x40u,
+REG_IRQ_BANK_2_CTRL,
+REG_IRQ_BANK_3_CTRL,
+REG_IRQ_BANK_4_CTRL,
+REG_IRQ_BANK_5_CTRL,
+REG_IRQ_BANK_1_STAT = 0x48u,
+REG_IRQ_BANK_2_STAT,
+REG_IRQ_BANK_3_STAT,
+REG_IRQ_BANK_4_STAT,
+REG_IRQ_BANK_5_STAT,
+REG_ADC_ACIN_V_H = 0x56u,
+REG_ADC_ACIN_V_L,
+REG_ADC_ACIN_CURR_H,
+REG_ADC_ACIN_CURR_L,
+REG_ADC_VBUS_V_H,
+REG_ADC_VBUS_V_L,
+REG_ADC_VBUS_CURR_H,
+REG_ADC_VBUS_CURR_L,
+REG_ADC_INT_TEMP_H,
+REG_ADC_INT_TEMP_L,
+REG_ADC_TEMP_SENS_V_H = 0x62u,
+REG_ADC_TEMP_SENS_V_L,
+REG_ADC_BAT_V_H = 0x78u,
+REG_ADC_BAT_V_L,
+REG_ADC_BAT_DISCHR_CURR_H,
+REG_ADC_BAT_DISCHR_CURR_L,
+REG_ADC_BAT_CHR_CURR_H,
+REG_ADC_BAT_CHR_CURR_L,
+REG_ADC_IPSOUT_V_H,
+REG_ADC_IPSOUT_V_L,
+REG_DC_DC_MOD_SEL = 0x80u,
+REG_ADC_EN_1,
+REG_ADC_EN_2,
+REG_ADC_SR_CTRL,
+REG_ADC_IN_RANGE,
+REG_GPIO1_ADC_IRQ_RISING_TH,
+REG_GPIO1_ADC_IRQ_FALLING_TH,
+REG_TIMER_CTRL = 0x8au,
+REG_VBUS_CTRL_MON_SRP,
+REG_OVER_TEMP_SHUTDOWN = 0x8fu,
+REG_GPIO0_FEAT_SET,
+REG_GPIO_OUT_HIGH_SET,
+REG_GPIO1_FEAT_SET,
+REG_GPIO2_FEAT_SET,
+   

[PATCH v2 7/7] docs/system/arm: Update Allwinner with TWI (I2C)

2022-12-18 Thread Strahinja Jankovic
TWI (I2C) is supported so docs are updated for Cubieboard and
Orangepi-PC board.

Signed-off-by: Strahinja Jankovic 
---
 docs/system/arm/cubieboard.rst | 1 +
 docs/system/arm/orangepi.rst   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
index 344ff8cef9..8d485f5435 100644
--- a/docs/system/arm/cubieboard.rst
+++ b/docs/system/arm/cubieboard.rst
@@ -14,3 +14,4 @@ Emulated devices:
 - SDHCI
 - USB controller
 - SATA controller
+- TWI (I2C) controller
diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
index 83c7445197..e5973600a1 100644
--- a/docs/system/arm/orangepi.rst
+++ b/docs/system/arm/orangepi.rst
@@ -25,6 +25,7 @@ The Orange Pi PC machine supports the following devices:
  * Clock Control Unit
  * System Control module
  * Security Identifier device
+ * TWI (I2C)
 
 Limitations
 """
-- 
2.30.2




[PATCH v2 2/7] hw/misc: Allwinner A10 DRAM Controller Emulation

2022-12-18 Thread Strahinja Jankovic
During SPL boot several DRAM Controller registers are used. Most
important registers are those related to DRAM initialization and
calibration, where SPL initiates process and waits until certain bit is
set/cleared.

This patch adds these registers, initializes reset values from user's
guide and updates state of registers as SPL expects it.

Signed-off-by: Strahinja Jankovic 

Reviewed-by: Niek Linnenbank 
---
 hw/arm/Kconfig|   1 +
 hw/arm/allwinner-a10.c|   7 +
 hw/misc/Kconfig   |   3 +
 hw/misc/allwinner-a10-dramc.c | 179 ++
 hw/misc/meson.build   |   1 +
 include/hw/arm/allwinner-a10.h|   2 +
 include/hw/misc/allwinner-a10-dramc.h |  68 ++
 7 files changed, 261 insertions(+)
 create mode 100644 hw/misc/allwinner-a10-dramc.c
 create mode 100644 include/hw/misc/allwinner-a10-dramc.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 14f52b41af..140f142ae5 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -320,6 +320,7 @@ config ALLWINNER_A10
 select ALLWINNER_A10_PIT
 select ALLWINNER_A10_PIC
 select ALLWINNER_A10_CCM
+select ALLWINNER_A10_DRAMC
 select ALLWINNER_EMAC
 select SERIAL
 select UNIMP
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 86baeeeca2..a5f7a36ac9 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -25,6 +25,7 @@
 #include "hw/boards.h"
 #include "hw/usb/hcd-ohci.h"
 
+#define AW_A10_DRAMC_BASE   0x01c01000
 #define AW_A10_MMC0_BASE0x01c0f000
 #define AW_A10_CCM_BASE 0x01c2
 #define AW_A10_PIC_REG_BASE 0x01c20400
@@ -49,6 +50,8 @@ static void aw_a10_init(Object *obj)
 
 object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
 
+object_initialize_child(obj, "dramc", &s->dramc, TYPE_AW_A10_DRAMC);
+
 object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
 
 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
@@ -110,6 +113,10 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
 
+/* DRAM Control Module */
+sysbus_realize(SYS_BUS_DEVICE(&s->dramc), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 0, AW_A10_DRAMC_BASE);
+
 /* FIXME use qdev NIC properties instead of nd_table[] */
 if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index ed07bf4133..052fb54310 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -177,4 +177,7 @@ config LASI
 config ALLWINNER_A10_CCM
 bool
 
+config ALLWINNER_A10_DRAMC
+bool
+
 source macio/Kconfig
diff --git a/hw/misc/allwinner-a10-dramc.c b/hw/misc/allwinner-a10-dramc.c
new file mode 100644
index 00..e118b0c2fd
--- /dev/null
+++ b/hw/misc/allwinner-a10-dramc.c
@@ -0,0 +1,179 @@
+/*
+ * Allwinner A10 DRAM Controller emulation
+ *
+ * Copyright (C) 2022 Strahinja Jankovic 
+ *
+ *  This file is derived from Allwinner H3 DRAMC,
+ *  by 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 "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/misc/allwinner-a10-dramc.h"
+
+/* DRAMC register offsets */
+enum {
+REG_SDR_CCR = 0x,
+REG_SDR_ZQCR0 = 0x00a8,
+REG_SDR_ZQSR = 0x00b0
+};
+
+#define REG_INDEX(offset)(offset / sizeof(uint32_t))
+
+/* DRAMC register flags */
+enum {
+REG_SDR_CCR_DATA_TRAINING = (1 << 30),
+REG_SDR_CCR_DRAM_INIT = (1 << 31),
+};
+enum {
+REG_SDR_ZQSR_ZCAL = (1 << 31),
+};
+
+/* DRAMC register reset values */
+enum {
+REG_SDR_CCR_RESET   = 0x8002,
+REG_SDR_ZQCR0_RESET = 0x07b0,
+REG_SDR_ZQSR_RESET  = 0x8000
+};
+
+static uint64_t allwinner_a10_dramc_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+const AwA10DramControllerState *s = AW_A10_DRAMC(opaque);
+const uint32_t idx = REG_INDEX(offset);
+
+switch (offset) {
+case REG_SDR_CCR:
+case REG_SDR_ZQCR0:
+case REG_SDR_ZQSR:
+break;
+case 0x2e4 ... AW_A10_DRAMC_IOSIZE:
+qemu_log_mask(LOG_

[PATCH v2 0/7] Enable Cubieboard A10 boot SPL from SD card

2022-12-18 Thread Strahinja Jankovic
This patch series adds missing Allwinner A10 modules needed for
successful SPL boot:
- Clock controller module
- DRAM controller
- I2C0 controller (added also for Allwinner H3 since it is the same)
- AXP-209 connected to I2C0 bus

It also updates Allwinner A10 emulation so SPL is copied from attached
SD card if `-kernel` parameter is not passed when starting QEMU
(approach adapted from Allwinner H3 implementation).

Boot from SD card has been tested with Cubieboard Armbian SD card image and 
custom
Yocto image built for Cubieboard.
Example usage for Armbian image:
qemu-system-arm -M cubieboard -nographic -sd 
~/Armbian_22.11.0-trunk_Cubieboard_kinetic_edge_6.0.7.img

v2 from v1:
* replaced DB_PRINTF with tracing functions
* removed .init function in AXP209 since .reset covers functionality
* moved defines to allwinner_i2c.c from header file
* updated docs with information about TWI
* minor code style fixes

Strahinja Jankovic (7):
  hw/misc: Allwinner-A10 Clock Controller Module Emulation
  hw/misc: Allwinner A10 DRAM Controller Emulation
  hw/i2c: Allwinner TWI/I2C Emulation
  hw/misc: Allwinner AXP-209 Emulation
  hw/arm: Add AXP-209 to Cubieboard
  hw/arm: Allwinner A10 enable SPL load from MMC
  docs/system/arm: Update Allwinner with TWI (I2C)

 docs/system/arm/cubieboard.rst|   1 +
 docs/system/arm/orangepi.rst  |   1 +
 hw/arm/Kconfig|   5 +
 hw/arm/allwinner-a10.c|  40 +++
 hw/arm/allwinner-h3.c |  11 +-
 hw/arm/cubieboard.c   |  11 +
 hw/i2c/Kconfig|   4 +
 hw/i2c/allwinner-i2c.c| 459 ++
 hw/i2c/meson.build|   1 +
 hw/i2c/trace-events   |   5 +
 hw/misc/Kconfig   |  10 +
 hw/misc/allwinner-a10-ccm.c   | 224 +
 hw/misc/allwinner-a10-dramc.c | 179 ++
 hw/misc/allwinner-axp-209.c   | 238 +
 hw/misc/meson.build   |   3 +
 hw/misc/trace-events  |   5 +
 include/hw/arm/allwinner-a10.h|  27 ++
 include/hw/arm/allwinner-h3.h |   3 +
 include/hw/i2c/allwinner-i2c.h|  55 +++
 include/hw/misc/allwinner-a10-ccm.h   |  67 
 include/hw/misc/allwinner-a10-dramc.h |  68 
 21 files changed, 1416 insertions(+), 1 deletion(-)
 create mode 100644 hw/i2c/allwinner-i2c.c
 create mode 100644 hw/misc/allwinner-a10-ccm.c
 create mode 100644 hw/misc/allwinner-a10-dramc.c
 create mode 100644 hw/misc/allwinner-axp-209.c
 create mode 100644 include/hw/i2c/allwinner-i2c.h
 create mode 100644 include/hw/misc/allwinner-a10-ccm.h
 create mode 100644 include/hw/misc/allwinner-a10-dramc.h

-- 
2.30.2




[PATCH v4 20a/27] tcg: Pass number of arguments to tcg_emit_op() / tcg_op_insert_*()

2022-12-18 Thread Philippe Mathieu-Daudé
In order to have variable size allocated TCGOp, pass the number
of arguments we use (and would allocate) up to tcg_op_alloc().

This alters tcg_emit_op(), tcg_op_insert_before() and
tcg_op_insert_after() prototypes.

In tcg_op_alloc() ensure the number of arguments is in range.

Signed-off-by: Richard Henderson 
[PMD: Extracted from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 accel/tcg/plugin-gen.c |  5 -
 include/tcg/tcg-op.h   |  2 +-
 include/tcg/tcg.h  |  8 +---
 tcg/optimize.c |  4 ++--
 tcg/tcg-op-vec.c   |  8 
 tcg/tcg-op.c   | 12 ++--
 tcg/tcg.c  | 30 +-
 7 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index a6aaacd053..62e775d34d 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -258,10 +258,13 @@ static TCGOp *rm_ops(TCGOp *op)
 
 static TCGOp *copy_op_nocheck(TCGOp **begin_op, TCGOp *op)
 {
+unsigned nargs = ARRAY_SIZE(op->args);
+
 *begin_op = QTAILQ_NEXT(*begin_op, link);
 tcg_debug_assert(*begin_op);
-op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc);
+op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc, nargs);
 memcpy(op->args, (*begin_op)->args, sizeof(op->args));
+
 return op;
 }
 
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 8176f194cb..79b1cf786f 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -818,7 +818,7 @@ static inline void tcg_gen_plugin_cb_start(unsigned from, 
unsigned type,
 
 static inline void tcg_gen_plugin_cb_end(void)
 {
-tcg_emit_op(INDEX_op_plugin_cb_end);
+tcg_emit_op(INDEX_op_plugin_cb_end, 0);
 }
 
 #if TARGET_LONG_BITS == 32
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 8bcd60d0ed..c55fa21a89 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -1014,10 +1014,12 @@ bool tcg_op_supported(TCGOpcode op);
 
 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
 
-TCGOp *tcg_emit_op(TCGOpcode opc);
+TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
 void tcg_op_remove(TCGContext *s, TCGOp *op);
-TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc);
-TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc);
+TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
+TCGOpcode opc, unsigned nargs);
+TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
+   TCGOpcode opc, unsigned nargs);
 
 /**
  * tcg_remove_ops_after:
diff --git a/tcg/optimize.c b/tcg/optimize.c
index ae081ab29c..1afd50175b 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -962,7 +962,7 @@ static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool 
add)
 rh = op->args[1];
 
 /* The proper opcode is supplied by tcg_opt_gen_mov. */
-op2 = tcg_op_insert_before(ctx->tcg, op, 0);
+op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2);
 
 tcg_opt_gen_movi(ctx, op, rl, al);
 tcg_opt_gen_movi(ctx, op2, rh, ah);
@@ -1613,7 +1613,7 @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
 rh = op->args[1];
 
 /* The proper opcode is supplied by tcg_opt_gen_mov. */
-op2 = tcg_op_insert_before(ctx->tcg, op, 0);
+op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2);
 
 tcg_opt_gen_movi(ctx, op, rl, l);
 tcg_opt_gen_movi(ctx, op2, rh, h);
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
index 5bf100ea7d..966d41d65a 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -152,7 +152,7 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
 
 void vec_gen_2(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r, TCGArg a)
 {
-TCGOp *op = tcg_emit_op(opc);
+TCGOp *op = tcg_emit_op(opc, 2);
 TCGOP_VECL(op) = type - TCG_TYPE_V64;
 TCGOP_VECE(op) = vece;
 op->args[0] = r;
@@ -162,7 +162,7 @@ void vec_gen_2(TCGOpcode opc, TCGType type, unsigned vece, 
TCGArg r, TCGArg a)
 void vec_gen_3(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg r, TCGArg a, TCGArg b)
 {
-TCGOp *op = tcg_emit_op(opc);
+TCGOp *op = tcg_emit_op(opc, 3);
 TCGOP_VECL(op) = type - TCG_TYPE_V64;
 TCGOP_VECE(op) = vece;
 op->args[0] = r;
@@ -173,7 +173,7 @@ void vec_gen_3(TCGOpcode opc, TCGType type, unsigned vece,
 void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg r, TCGArg a, TCGArg b, TCGArg c)
 {
-TCGOp *op = tcg_emit_op(opc);
+TCGOp *op = tcg_emit_op(opc, 4);
 TCGOP_VECL(op) = type - TCG_TYPE_V64;
 TCGOP_VECE(op) = vece;
 op->args[0] = r;
@@ -185,7 +185,7 @@ void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
 static void vec_gen_6(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r,
   TCGArg a, TCGArg b, TCGArg c, TCGArg d, TCGArg e)
 {
-TCGOp *op = tcg_emit_op(opc);
+TCGOp *op = tcg_emit_op(opc, 6);
 TCGOP_VECL(op) = type - TCG_TYPE_V64;
 TCGOP_VECE(op

[PATCH v2 3/7] hw/i2c: Allwinner TWI/I2C Emulation

2022-12-18 Thread Strahinja Jankovic
This patch implements Allwinner TWI/I2C controller emulation. Only
master-mode functionality is implemented.

The SPL boot for Cubieboard expects AXP209 PMIC on TWI0/I2C0 bus, so this is
first part enabling the TWI/I2C bus operation.

Since both Allwinner A10 and H3 use the same module, it is added for
both boards.

Signed-off-by: Strahinja Jankovic 
---
 hw/arm/Kconfig |   2 +
 hw/arm/allwinner-a10.c |   8 +
 hw/arm/allwinner-h3.c  |  11 +-
 hw/i2c/Kconfig |   4 +
 hw/i2c/allwinner-i2c.c | 459 +
 hw/i2c/meson.build |   1 +
 hw/i2c/trace-events|   5 +
 include/hw/arm/allwinner-a10.h |   2 +
 include/hw/arm/allwinner-h3.h  |   3 +
 include/hw/i2c/allwinner-i2c.h |  55 
 10 files changed, 549 insertions(+), 1 deletion(-)
 create mode 100644 hw/i2c/allwinner-i2c.c
 create mode 100644 include/hw/i2c/allwinner-i2c.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 140f142ae5..eefe1fd134 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -322,6 +322,7 @@ config ALLWINNER_A10
 select ALLWINNER_A10_CCM
 select ALLWINNER_A10_DRAMC
 select ALLWINNER_EMAC
+select ALLWINNER_I2C
 select SERIAL
 select UNIMP
 
@@ -329,6 +330,7 @@ config ALLWINNER_H3
 bool
 select ALLWINNER_A10_PIT
 select ALLWINNER_SUN8I_EMAC
+select ALLWINNER_I2C
 select SERIAL
 select ARM_TIMER
 select ARM_GIC
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index a5f7a36ac9..17e439777e 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -36,6 +36,7 @@
 #define AW_A10_OHCI_BASE0x01c14400
 #define AW_A10_SATA_BASE0x01c18000
 #define AW_A10_RTC_BASE 0x01c20d00
+#define AW_A10_I2C0_BASE0x01c2ac00
 
 static void aw_a10_init(Object *obj)
 {
@@ -56,6 +57,8 @@ static void aw_a10_init(Object *obj)
 
 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
 
+object_initialize_child(obj, "i2c0", &s->i2c0, TYPE_AW_I2C);
+
 if (machine_usb(current_machine)) {
 int i;
 
@@ -176,6 +179,11 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 /* RTC */
 sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->rtc), 0, AW_A10_RTC_BASE, 10);
+
+/* I2C */
+sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7));
 }
 
 static void aw_a10_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index 308ed15552..bfce3c8d92 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -53,6 +53,7 @@ const hwaddr allwinner_h3_memmap[] = {
 [AW_H3_DEV_UART1]  = 0x01c28400,
 [AW_H3_DEV_UART2]  = 0x01c28800,
 [AW_H3_DEV_UART3]  = 0x01c28c00,
+[AW_H3_DEV_TWI0]   = 0x01c2ac00,
 [AW_H3_DEV_EMAC]   = 0x01c3,
 [AW_H3_DEV_DRAMCOM]= 0x01c62000,
 [AW_H3_DEV_DRAMCTL]= 0x01c63000,
@@ -106,7 +107,6 @@ struct AwH3Unimplemented {
 { "uart1", 0x01c28400, 1 * KiB },
 { "uart2", 0x01c28800, 1 * KiB },
 { "uart3", 0x01c28c00, 1 * KiB },
-{ "twi0",  0x01c2ac00, 1 * KiB },
 { "twi1",  0x01c2b000, 1 * KiB },
 { "twi2",  0x01c2b400, 1 * KiB },
 { "scr",   0x01c2c400, 1 * KiB },
@@ -150,6 +150,7 @@ enum {
 AW_H3_GIC_SPI_UART1 =  1,
 AW_H3_GIC_SPI_UART2 =  2,
 AW_H3_GIC_SPI_UART3 =  3,
+AW_H3_GIC_SPI_TWI0  =  6,
 AW_H3_GIC_SPI_TIMER0= 18,
 AW_H3_GIC_SPI_TIMER1= 19,
 AW_H3_GIC_SPI_MMC0  = 60,
@@ -225,6 +226,8 @@ static void allwinner_h3_init(Object *obj)
   "ram-size");
 
 object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN6I);
+
+object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C);
 }
 
 static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@@ -423,6 +426,12 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
 sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, s->memmap[AW_H3_DEV_RTC]);
 
+/* I2C */
+sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, s->memmap[AW_H3_DEV_TWI0]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0,
+   qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI0));
+
 /* Unimplemented devices */
 for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
 create_unimplemented_device(unimplemented[i].device_name,
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
index 9bb8870517..f8ec461be3 100644
--- a/hw/i2c/Kconfig
+++ b/hw/i2c/Kconfig
@@ -34,6 +34,10 @@ config MPC_I2C
 bool
 select I2C
 
+config ALLWINNER_I2C
+bool
+select I2C
+
 config PCA954X
   

Re: [PATCH v4 20/27] tcg: Vary the allocation size for TCGOp

2022-12-18 Thread Philippe Mathieu-Daudé
Splitting this patch in 2 to ease review.

Philippe Mathieu-Daudé (1):
  tcg: Pass number of arguments to tcg_emit_op() / tcg_op_insert_*()

Richard Henderson (1):
  tcg: Vary the allocation size for TCGOp

 accel/tcg/plugin-gen.c | 11 ---
 include/exec/helper-head.h |  2 --
 include/tcg/tcg-op.h   |  2 +-
 include/tcg/tcg.h  | 54 +
 tcg/optimize.c |  4 +--
 tcg/tcg-op-vec.c   |  8 ++---
 tcg/tcg-op.c   | 12 
 tcg/tcg.c  | 61 +-
 8 files changed, 82 insertions(+), 72 deletions(-)

-- 
2.38.1




Re: [PATCH 08/11] audio/audio_template: use g_new0() to replace audio_calloc()

2022-12-18 Thread Richard Henderson

On 12/18/22 09:15, Volker Rümelin wrote:

Replace audio_calloc() with the equivalent g_new0().

With a n_structs argument >= 1, g_new0() never returns NULL.
Also remove the unnecessary NULL checks.

Signed-off-by: Volker Rümelin
---
  audio/audio_template.h | 23 ++-
  1 file changed, 6 insertions(+), 17 deletions(-)


Reviewed-by: Richard Henderson 

r~



  1   2   >