Re: [PATCH RESEND 2/2] scsi-disk: Fix crash of VMs configured with the CDROM device
Ping On Mon, Apr 8, 2024 at 8:08 PM Hyman Huang wrote: > When configuring VMs with the CDROM device using the USB bus > in Libvirt, do as follows: > > > > > > > > > > > The destination Qemu process crashed, causing the VM migration > to fail; the backtrace reveals the following: > > Program terminated with signal SIGSEGV, Segmentation fault. > 0 __memmove_sse2_unaligned_erms () at > ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:312 > 312movq-8(%rsi,%rdx), %rcx > [Current thread is 1 (Thread 0x7f0a9025fc00 (LWP 3286206))] > (gdb) bt > 0 __memmove_sse2_unaligned_erms () at > ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:312 > 1 memcpy (__len=8, __src=, __dest=) at > /usr/include/bits/string_fortified.h:34 > 2 iov_from_buf_full (iov=, iov_cnt=, > offset=, buf=0x0, bytes=bytes@entry=8) at ../util/iov.c:33 > 3 iov_from_buf (bytes=8, buf=, offset=, > iov_cnt=, iov=) >at > /usr/src/debug/qemu-6-6.2.0-75.7.oe1.smartx.git.40.x86_64/include/qemu/iov.h:49 > 4 usb_packet_copy (p=p@entry=0x56066b2fb5a0, ptr=, > bytes=bytes@entry=8) at ../hw/usb/core.c:636 > 5 usb_msd_copy_data (s=s@entry=0x56066c62c770, p=p@entry=0x56066b2fb5a0) > at ../hw/usb/dev-storage.c:186 > 6 usb_msd_handle_data (dev=0x56066c62c770, p=0x56066b2fb5a0) at > ../hw/usb/dev-storage.c:496 > 7 usb_handle_packet (dev=0x56066c62c770, p=p@entry=0x56066b2fb5a0) at > ../hw/usb/core.c:455 > 8 uhci_handle_td (s=s@entry=0x56066bd5f210, q=0x56066bb7fbd0, q@entry=0x0, > qh_addr=qh_addr@entry=902518530, td=td@entry=0x7fffe6e788f0, > td_addr=, >int_mask=int_mask@entry=0x7fffe6e788e4) at ../hw/usb/hcd-uhci.c:885 > 9 uhci_process_frame (s=s@entry=0x56066bd5f210) at > ../hw/usb/hcd-uhci.c:1061 > 10 uhci_frame_timer (opaque=opaque@entry=0x56066bd5f210) at > ../hw/usb/hcd-uhci.c:1159 > 11 timerlist_run_timers (timer_list=0x56066af26bd0) at > ../util/qemu-timer.c:642 > 12 qemu_clock_run_timers (type=QEMU_CLOCK_VIRTUAL) at > ../util/qemu-timer.c:656 > 13 qemu_clock_run_all_timers () at ../util/qemu-timer.c:738 > 14 main_loop_wait (nonblocking=nonblocking@entry=0) at > ../util/main-loop.c:542 > 15 qemu_main_loop () at ../softmmu/runstate.c:739 > 16 main (argc=, argv=, envp=) > at ../softmmu/main.c:52 > (gdb) frame 5 > (gdb) p ((SCSIDiskReq *)s->req)->iov > $1 = {iov_base = 0x0, iov_len = 0} > (gdb) p/x s->req->tag > $2 = 0x472 > > The scsi commands that the CDROM issued are wrapped as the > payload of the USB protocol in Qemu's implementation of a > USB mass storage device, which is used to implement a > CDROM device that uses a USB bus. > > In general, the USB controller processes SCSI commands in > two phases. Sending the OUT USB package that encapsulates > the SCSI command is the first stage; scsi-disk would handle > this by emulating the SCSI operation. Receiving the IN USB > package containing the SCSI operation's output is the second > stage. Additionally, the SCSI request tag tracks the request > during the procedure. > > Since QEMU did not migrate the flying SCSI request, the > output of the SCSI may be lost if the live migration is > initiated between the two previously mentioned steps. > > In our scenario, the SCSI command is GET_EVENT_STATUS_NOTIFICATION, > the QEMU log information below demonstrates how the SCSI command > is being handled (first step) on the source: > > usb_packet_state_change bus 0, port 2, ep 2, packet 0x559f9ba14b00, state > undef -> setup > usb_msd_cmd_submit lun 0, tag 0x472, flags 0x0080, len 10, data-len 8 > > After migration, the VM crashed as soon as the destination's UHCI > controller began processing the remaining portion of the SCSI > request (second step)! Here is how the QEMU logged out: > > usb_packet_state_change bus 0, port 2, ep 1, packet 0x56066b2fb5a0, state > undef -> setup > usb_msd_data_in 8/8 (scsi 8) > shutting down, reason=crashed > > To summarize, the missing scsi request during a live migration > may cause a VM configured with a CDROM to crash. > > Migrating the SCSI request that the scsi-disk is handling is > the simple approach, assuming that it actually exists. > > Signed-off-by: Hyman Huang > --- > hw/scsi/scsi-disk.c | 24 +++- > 1 file changed, 23 insertions(+), 1 deletion(-) > > diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c > index 0985676f73..d6e9d9e8d4 100644 > --- a/hw/scsi/scsi-disk.c > +++ b/hw/scsi/scsi-disk.c > @@ -160,6 +160,16 @@ static void scsi_disk_save_request(QEMUFile *f, > SCSIRequest *req) > } > } > > +static void scsi_disk_emulate_save_request(QEMUFile *f, SCSIRequest *req) > +{ > +SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); > +SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); > + > +if (s->migrate_emulate_scsi_request) { > +scsi_disk_save_request(f, req); > +} > +} > + > static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req) > { > SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); > @@ -183,6 +193,16 @@ static void
Re: [PATCH v4 5/5] tests/qtest : Add testcase for DM163
On 14/04/2024 15.05, Inès Varhol wrote: `test_dm163_bank()` Checks that the pin "sout" of the DM163 led driver outputs the values received on pin "sin" with the expected latency (depending on the bank). `test_dm163_gpio_connection()` Check that changes to relevant STM32L4x5 GPIO pins are propagated to the DM163 device. Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- tests/qtest/dm163-test.c | 192 +++ tests/qtest/meson.build | 5 + 2 files changed, 197 insertions(+) create mode 100644 tests/qtest/dm163-test.c ... diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 36c5c13a7b..2c6fd4ebbb 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -207,6 +207,9 @@ qtests_stm32l4x5 = \ 'stm32l4x5_rcc-test', 'stm32l4x5_gpio-test'] +qtests_dm163 = \ + ['dm163-test'] Do you plan to add more tests to qtests_dm163 later? If no, it might be more straight forward to inline ['dm163-test'] in the hunk below instead. qtests_arm = \ (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \ (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \ @@ -222,6 +225,8 @@ qtests_arm = \ (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) + \ (config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \ + (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and + config_all_devices.has_key('CONFIG_DM163')? qtests_dm163 : []) + \ With qtests_dm163 preferably replaced by ['dm163-test'] : Acked-by: Thomas Huth
RE: COLO state?
> -Original Message- > From: Fabiano Rosas > Sent: Thursday, April 11, 2024 10:40 PM > To: Zhang, Hailiang ; Zhang, Chen > ; Li Zhijian > Cc: qemu-devel@nongnu.org; Peter Xu > Subject: COLO state? > > Hi COLO maintainers, > > Would you please take a look at this issue? > > https://gitlab.com/qemu-project/qemu/-/issues/2277 > Sure, please share more details in gitlab of your test. For example the primary/secondary VM boot scripts and the backtrace...etc... > The reporter claims it affects from 9.0-rc2 all the way back to QEMU 7.2. I > don't have any kind of setup for COLO, so it will take me a while to be able > to > verify this. > > Could you also provide clarification on what is the state of COLO these days? > Are any of you looking at it? Do we know of active users of the feature? Currently, all the COLO code already merged by QEMU. But there is no support for libvirt (Need to passthrough QMP command to QEMU for enable COLO). Any users can use the WIKI page(https://wiki.qemu.org/Features/COLO) to setup COLO based on upstream code.(Maybe have issues? I will double check it... ). As we know, many cloud services provider build there HA/FT system or products based on COLO project. > > Also, is the MAINTAINERS file reflecting the actual maintenance state > according to you? I will check w/ Hailiang/Zhijian/Congyang/Changlong(Block replication) to see if he will keep working on COLO or not. Thanks Chen > > COLO Framework > M: Hailiang Zhang > S: Maintained > F: migration/colo* > F: include/migration/colo.h > F: include/migration/failover.h > F: docs/COLO-FT.txt > > COLO Proxy > M: Zhang Chen > M: Li Zhijian > S: Supported > F: docs/colo-proxy.txt > F: net/colo* > F: net/filter-rewriter.c > F: net/filter-mirror.c > F: tests/qtest/test-filter* > > Thanks
Re: [RFC PATCH 0/4] target/riscv/kvm: QEMU support for KVM Guest Debug on RISC-V
Gentle ping... On 2024-04-09 17:43, Chao Du wrote: > > Hi Daniel and all, > > The KVM patches have been reviewd and are in the queue. > https://lore.kernel.org/all/20240402062628.5425-1-duc...@eswincomputing.com/ > > Could you please review in the QEMU side ? > Then I will rebase this series with your comments. > > Some Notes: > 1. As the first stage, only the software breakpoints is implemented. > 2. A 'corner case' in which the debug exception is not inserted by the > debugger, need to be re-injected to the guest. This is not handled yet > in this series. > > Thanks, > Chao > > > On 2023-12-22 22:16, Daniel Henrique Barboza > wrote: > > > > Hi, > > > > It seems that we still need the kernel KVM side to be sorted out first [1], > > so I believe we should wait a bit until we can review this RFC. Otherwise we > > might risk reviewing something that has to be changed later. > > > > > > [1] > > https://lore.kernel.org/kvm/20231221095002.7404-1-duc...@eswincomputing.com/ > > > > > > Thanks, > > > > Daniel > > > > On 12/21/23 06:49, Chao Du wrote: > > > This series implements QEMU KVM Guest Debug on RISC-V. Currently, we can > > > debug RISC-V KVM guest from the host side, with software breakpoints. > > > > > > A brief test was done on QEMU RISC-V hypervisor emulator. > > > > > > A TODO list which will be added later: > > > 1. HW breakpoints support > > > 2. Test cases > > > > > > This series is based on QEMU 8.2.0-rc4 and is also available at: > > > https://github.com/Du-Chao/qemu/tree/riscv_gd_sw > > > > > > This is dependent on KVM side changes: > > > https://github.com/Du-Chao/linux/tree/riscv_gd_sw > > > > > > Chao Du (4): > > >target/riscv/kvm: add software breakpoints support > > >target/riscv/kvm: implement kvm_arch_update_guest_debug() > > >target/riscv/kvm: handle the exit with debug reason > > >linux-headers: enable KVM GUEST DEBUG for RISC-V > > > > > > accel/kvm/kvm-all.c | 8 +-- > > > include/sysemu/kvm.h | 6 +- > > > linux-headers/asm-riscv/kvm.h | 1 + > > > target/arm/kvm64.c| 6 +- > > > target/i386/kvm/kvm.c | 6 +- > > > target/mips/kvm.c | 6 +- > > > target/ppc/kvm.c | 6 +- > > > target/riscv/kvm/kvm-cpu.c| 101 ++ > > > target/s390x/kvm/kvm.c| 6 +- > > > 9 files changed, 130 insertions(+), 16 deletions(-) > > > > > > -- > > > 2.17.1 > > >
Re: [PATCH v6] virtio-pci: Fix the crash that the vector was used after released.
QE tested this patch with regression tests, everything works fine. Tested-by: Lei Yang On Fri, Apr 12, 2024 at 2:37 PM Cindy Lu wrote: > > Hi All > I apologize for bothering you again > I send the new patch is because I found that the function > kvm_virtio_pci_vector_use_one/kvm_virtio_pci_vector_release_one > can only change the vector that already set to the device. > > ret = virtio_pci_get_notifier(proxy, queue_no, , ); > if (ret < 0) { > return; > } > ... > So I move the setting vector into the function > virtio_pci_set_and_change_vector() > the other part are the same . > > the sanity test is passed and the qemu qtest is also passed > > Thanks > Cindy > > On Fri, Apr 12, 2024 at 2:28 PM Cindy Lu wrote: > > > > During the booting process of the non-standard image, the behavior of the > > called function in qemu is as follows: > > > > 1. vhost_net_stop() was triggered by guest image. This will call the > > function > > virtio_pci_set_guest_notifiers() with assgin= false, > > virtio_pci_set_guest_notifiers() will release the irqfd for vector 0 > > > > 2. virtio_reset() was triggered, this will set configure vector to > > VIRTIO_NO_VECTOR > > > > 3.vhost_net_start() was called (at this time, the configure vector is > > still VIRTIO_NO_VECTOR) and then call virtio_pci_set_guest_notifiers() with > > assgin=true, so the irqfd for vector 0 is still not "init" during this > > process > > > > 4. The system continues to boot and sets the vector back to 0. After that > > msix_fire_vector_notifier() was triggered to unmask the vector 0 and meet > > the crash > > > > To fix the issue, we need to support changing the vector after > > VIRTIO_CONFIG_S_DRIVER_OK is set. > > > > (gdb) bt > > 0 __pthread_kill_implementation (threadid=, > > signo=signo@entry=6, no_tid=no_tid@entry=0) > > at pthread_kill.c:44 > > 1 0x7fc87148ec53 in __pthread_kill_internal (signo=6, > > threadid=) at pthread_kill.c:78 > > 2 0x7fc87143e956 in __GI_raise (sig=sig@entry=6) at > > ../sysdeps/posix/raise.c:26 > > 3 0x7fc8714287f4 in __GI_abort () at abort.c:79 > > 4 0x7fc87142871b in __assert_fail_base > > (fmt=0x7fc8715bbde0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", > > assertion=0x5606413efd53 "ret == 0", file=0x5606413ef87d > > "../accel/kvm/kvm-all.c", line=1837, function=) at > > assert.c:92 > > 5 0x7fc871437536 in __GI___assert_fail > > (assertion=0x5606413efd53 "ret == 0", file=0x5606413ef87d > > "../accel/kvm/kvm-all.c", line=1837, function=0x5606413f06f0 > > <__PRETTY_FUNCTION__.19> "kvm_irqchip_commit_routes") at assert.c:101 > > 6 0x560640f884b5 in kvm_irqchip_commit_routes (s=0x560642cae1f0) at > > ../accel/kvm/kvm-all.c:1837 > > 7 0x560640c98f8e in virtio_pci_one_vector_unmask > > (proxy=0x560643c65f00, queue_no=4294967295, vector=0, msg=..., > > n=0x560643c6e4c8) > > at ../hw/virtio/virtio-pci.c:1005 > > 8 0x560640c99201 in virtio_pci_vector_unmask (dev=0x560643c65f00, > > vector=0, msg=...) > > at ../hw/virtio/virtio-pci.c:1070 > > 9 0x560640bc402e in msix_fire_vector_notifier (dev=0x560643c65f00, > > vector=0, is_masked=false) > > at ../hw/pci/msix.c:120 > > 10 0x560640bc40f1 in msix_handle_mask_update (dev=0x560643c65f00, > > vector=0, was_masked=true) > > at ../hw/pci/msix.c:140 > > 11 0x560640bc4503 in msix_table_mmio_write (opaque=0x560643c65f00, > > addr=12, val=0, size=4) > > at ../hw/pci/msix.c:231 > > 12 0x560640f26d83 in memory_region_write_accessor > > (mr=0x560643c66540, addr=12, value=0x7fc86b7bc628, size=4, shift=0, > > mask=4294967295, attrs=...) > > at ../system/memory.c:497 > > 13 0x560640f270a6 in access_with_adjusted_size > > > > (addr=12, value=0x7fc86b7bc628, size=4, access_size_min=1, > > access_size_max=4, access_fn=0x560640f26c8d , > > mr=0x560643c66540, attrs=...) at ../system/memory.c:573 > > 14 0x560640f2a2b5 in memory_region_dispatch_write (mr=0x560643c66540, > > addr=12, data=0, op=MO_32, attrs=...) > > at ../system/memory.c:1521 > > 15 0x560640f37bac in flatview_write_continue > > (fv=0x7fc65805e0b0, addr=4273803276, attrs=..., ptr=0x7fc871e9c028, > > len=4, addr1=12, l=4, mr=0x560643c66540) > > at ../system/physmem.c:2714 > > 16 0x560640f37d0f in flatview_write > > (fv=0x7fc65805e0b0, addr=4273803276, attrs=..., buf=0x7fc871e9c028, > > len=4) at ../system/physmem.c:2756 > > 17 0x560640f380bf in address_space_write > > (as=0x560642161ae0 , addr=4273803276, attrs=..., > > buf=0x7fc871e9c028, len=4) > > at ../system/physmem.c:2863 > > 18 0x560640f3812c in address_space_rw > > (as=0x560642161ae0 , addr=4273803276, attrs=..., > > buf=0x7fc871e9c028, len=4, is_write=true) at ../system/physmem.c:2873 > > --Type for more, q to quit, c to continue without paging-- > > 19 0x560640f8aa55 in kvm_cpu_exec (cpu=0x560642f205e0) at > > ../accel/kvm/kvm-all.c:2915 > > 20 0x560640f8d731 in
Re: [PATCH] target/sparc: resolve ASI_USERTXT correctly
Hi Henry, I want to thank you for every chance I get to learn from you. Each email excites me. On Sun, Apr 14, 2024 at 1:20 PM Richard Henderson wrote: > The "current" permission, as computed by > > > -case ASI_KERNELTXT: /* Supervisor code access */ > > -oi = make_memop_idx(memop, cpu_mmu_index(env_cpu(env), true)); > > was correct for ASI_KERNELTXT, because as you say "lda" is a supervisor-only > instruction > prior to sparcv9. > I noticed that cpu_mmu_index() would have returned MMU_USER_IDX if the supervisor bit hadn't happened to be set (not sure if this execution path can occur for lda). Note that this check is gone in your patch. I consider you my sensei, so while I'm confident in your work I also want to show the things I catch. If I understand everything you've taught me, then the following patch would have also satisfied the permissions issue. Could you confirm this please? The essential change is the MMU_USER_IDX in the call to make_memop_idx() diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c index e581bb42ac..be3c03a3b6 100644 --- a/target/sparc/ldst_helper.c +++ b/target/sparc/ldst_helper.c @@ -702,6 +702,24 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, break; } break; +case ASI_USERTXT: /* User code access */ +oi = make_memop_idx(memop, MMU_USER_IDX); +switch (size) { +case 1: +ret = cpu_ldb_code_mmu(env, addr, oi, GETPC()); +break; +case 2: +ret = cpu_ldw_code_mmu(env, addr, oi, GETPC()); +break; +default: +case 4: +ret = cpu_ldl_code_mmu(env, addr, oi, GETPC()); +break; +case 8: +ret = cpu_ldq_code_mmu(env, addr, oi, GETPC()); +break; +} +break; case ASI_M_TXTC_TAG: /* SparcStation 5 I-cache tag */ case ASI_M_TXTC_DATA: /* SparcStation 5 I-cache data */ case ASI_M_DATAC_TAG: /* SparcStation 5 D-cache tag */ @@ -779,7 +797,6 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, case 0x4c: /* SuperSPARC MMU Breakpoint Action */ ret = env->mmubpaction; break; -case ASI_USERTXT: /* User code access, XXX */ default: sparc_raise_mmu_fault(cs, addr, false, false, asi, size, GETPC()); ret = 0; > Unfortunately, we do not have any good documentation for tcg softmmu or the > intended role > of the mmu_idx. Partly that's due to the final use of the mmu_idx is > target-specific. I love learning from code, but the lack of documentation definitely increases the value of your discourse with me. Thank you, Sincerely, -bazz
Re: [PATCH] m25p80: Add support for the GD25WQ32E flash
PING Hi all, could you have a look at this small patch? See also: https://patchew.org/QEMU/20240330203520.64892-1-giacomo.parmeggi...@gmail.com/ BR, Giacomo Parmeggiani On Sat, Mar 30, 2024 at 9:36 PM Giacomo Parmeggiani < giacomo.parmeggi...@gmail.com> wrote: > This introduces the GigaDevice GD25WQ32E flash, including the SFDP table > > Signed-off-by: Giacomo Parmeggiani > --- > hw/block/m25p80.c | 2 ++ > hw/block/m25p80_sfdp.c | 40 > hw/block/m25p80_sfdp.h | 2 ++ > 3 files changed, 44 insertions(+) > > diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c > index 8dec134832..6cc05b63e5 100644 > --- a/hw/block/m25p80.c > +++ b/hw/block/m25p80.c > @@ -205,6 +205,8 @@ static const FlashPartInfo known_devices[] = { > /* GigaDevice */ > { INFO("gd25q32", 0xc84016, 0, 64 << 10, 64, ER_4K) }, > { INFO("gd25q64", 0xc84017, 0, 64 << 10, 128, ER_4K) }, > +{ INFO("gd25wq32e", 0xc86516, 0, 64 << 10, 64, ER_4K), > + .sfdp_read = m25p80_sfdp_gd25wq32e }, > > /* Intel/Numonyx -- xxxs33b */ > { INFO("160s33b", 0x898911, 0, 64 << 10, 32, 0) }, > diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c > index 6ee2cfaf11..cb0963328d 100644 > --- a/hw/block/m25p80_sfdp.c > +++ b/hw/block/m25p80_sfdp.c > @@ -406,3 +406,43 @@ static const uint8_t sfdp_is25wp256[] = { > 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > }; > define_sfdp_read(is25wp256); > + > +/* > + * GigaDevice > + */ > + > +static const uint8_t sfdp_gd25wq32e[] = { > +0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff, > +0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff, > +0xc8, 0x00, 0x01, 0x03, 0x90, 0x00, 0x00, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xe5, 0x20, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x01, > +0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x42, 0xbb, > +0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, > +0xff, 0xff, 0x00, 0xff, 0x0c, 0x20, 0x0f, 0x52, > +0x10, 0xd8, 0x00, 0xff, 0x63, 0x92, 0xfd, 0xfe, > +0x83, 0x2f, 0x26, 0x46, 0xec, 0x82, 0x18, 0x44, > +0x7a, 0x75, 0x7a, 0x75, 0x04, 0xbd, 0xd5, 0x5c, > +0x00, 0x06, 0x64, 0x00, 0x08, 0x10, 0x00, 0x00, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0x00, 0x36, 0x50, 0x16, 0x9e, 0xf9, 0x77, 0x64, > +0xfc, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff > +}; > +define_sfdp_read(gd25wq32e); > diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h > index 1733b56950..7d1f60f2ee 100644 > --- a/hw/block/m25p80_sfdp.h > +++ b/hw/block/m25p80_sfdp.h > @@ -29,4 +29,6 @@ uint8_t m25p80_sfdp_w25q01jvq(uint32_t addr); > > uint8_t m25p80_sfdp_is25wp256(uint32_t addr); > > +uint8_t m25p80_sfdp_gd25wq32e(uint32_t addr); > + > #endif > -- > 2.32.1 (Apple Git-133) > > -- *Giacomo Parmeggiani*
Re: Intention to work on GSoC project
Hi, On Friday, April 5, 2024 12:36:02 AM IST Sahil wrote: > [...] > I'll set up this environment as well. I would like to post an update here. I spent the last week trying to set up the environment as described in the blog [1]. I initially tried to get the L1 VM running on my host machine (Arch Linux). However, I was unable to use virt-sysprep or virt-cutomize to install packages in the qcow2 image. It wasn't able to resolve the hosts while downloading the packages. According to the logs, /etc/resolv.conf was a dangling symlink. I tried to use "virt-rescue" to configure DNS resolution. I tried following these sections [2], [3] in the Arch wiki but that didn't work either. I tried using qemu-nbd as well following this section [4] to access the image. While I managed gain access to the image, I wasn't able to install packages after performing a chroot. One workaround was to set this environment up in a VM. I decided to set up the environment with a Fedora image in virtualbox acting as L0. I have managed to set up an L1 VM in this environment and I can load it using qemu-kvm. I have one question though. One of the options (use case 1 in [1]) given to the "qemu-kvm" command is: > -device virtio-net-pci,netdev=vhost-vdpa0,bus=pcie.0,addr=0x7\ > ,disable-modern=off,page-per-vq=on This gives an error: > Bus "pcie.0" not found Does pcie refer to PCI Express? Changing this to pci.0 works. I read through the "device buses" section in QEMU's user documentation [5], but I have still not understood this. "ls /sys/bus/pci/devices/* | grep vdpa" does not give any results. Replacing pci with pci_express doesn't give any results either. How does one know which pci bus the vdpa device is connected to? I have gone through the "vDPA bus drivers" section of the "vDPA kernel framework" article [6] but I haven't managed to find an answer yet. Am I missing something here? There's one more thing. In "use case 1" of "Running traffic with vhost_vdpa in Guest" [1], running "modprobe pktgen" in the L1 VM gives an error: > module pktgen couldn't be found in /lib/modules/6.5.6-300.fc39.x86_64. The kernel version is 6.5.6-300.fc39.x86_64. I haven't tried building pktgen manually in L1. I'll try that and will check if vdpa_sim works as expected after that. [1] https://www.redhat.com/en/blog/hands-vdpa-what-do-you-do-when-you-aint-got-hardware-part-1 [2] https://wiki.archlinux.org/title/QEMU#User-mode_networking [3] https://wiki.archlinux.org/title/Systemd-networkd#Required_services_and_setup [4] https://wiki.archlinux.org/title/QEMU#Mounting_a_partition_from_a_qcow2_image [5] https://qemu-project.gitlab.io/qemu/system/device-emulation.html [6] https://www.redhat.com/en/blog/vdpa-kernel-framework-part-1-vdpa-bus-abstracting-hardware Thanks, Sahil
[PATCH v2] tests/qtest : Use `g_assert_cmphex` instead of `g_assert_cmpuint`
The messages for assertions using hexadecimal numbers will be easier to understand with `g_assert_cmphex`. Cases changed : "cmpuint.*0x", "cmpuint.*<<" Signed-off-by: Inès Varhol --- tests/qtest/aspeed_fsi-test.c | 20 ++-- tests/qtest/cmsdk-apb-dualtimer-test.c | 2 +- tests/qtest/cmsdk-apb-watchdog-test.c | 2 +- tests/qtest/erst-test.c| 2 +- tests/qtest/ivshmem-test.c | 10 +- tests/qtest/libqos/ahci.c | 4 +- tests/qtest/microbit-test.c| 46 - tests/qtest/sse-timer-test.c | 4 +- tests/qtest/stm32l4x5_exti-test.c | 138 - tests/qtest/stm32l4x5_syscfg-test.c| 74 ++--- 10 files changed, 151 insertions(+), 151 deletions(-) diff --git a/tests/qtest/aspeed_fsi-test.c b/tests/qtest/aspeed_fsi-test.c index b3020dd821..f5ab269972 100644 --- a/tests/qtest/aspeed_fsi-test.c +++ b/tests/qtest/aspeed_fsi-test.c @@ -63,22 +63,22 @@ static void test_fsi_setup(QTestState *s, uint32_t base_addr) /* Unselect FSI1 */ aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x0); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT); -g_assert_cmpuint(curval, ==, 0x0); +g_assert_cmphex(curval, ==, 0x0); /* Select FSI0 */ aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x1); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT); -g_assert_cmpuint(curval, ==, 0x1); +g_assert_cmphex(curval, ==, 0x1); } else if (base_addr == AST2600_OPB_FSI1_BASE_ADDR) { /* Unselect FSI0 */ aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x0); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT); -g_assert_cmpuint(curval, ==, 0x0); +g_assert_cmphex(curval, ==, 0x0); /* Select FSI1 */ aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x1); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT); -g_assert_cmpuint(curval, ==, 0x1); +g_assert_cmphex(curval, ==, 0x1); } else { g_assert_not_reached(); } @@ -145,11 +145,11 @@ static void test_fsi0_getcfam_addr0(const void *data) aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1); curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS); -g_assert_cmpuint(curval, ==, 0x1); +g_assert_cmphex(curval, ==, 0x1); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_STATUS); -g_assert_cmpuint(curval, ==, 0x0); +g_assert_cmphex(curval, ==, 0x0); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_READ_DATA); -g_assert_cmpuint(curval, ==, 0x152d02c0); +g_assert_cmphex(curval, ==, 0x152d02c0); } static void test_fsi1_getcfam_addr0(const void *data) @@ -168,11 +168,11 @@ static void test_fsi1_getcfam_addr0(const void *data) aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1); curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS); -g_assert_cmpuint(curval, ==, 0x2); +g_assert_cmphex(curval, ==, 0x2); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_STATUS); -g_assert_cmpuint(curval, ==, 0x0); +g_assert_cmphex(curval, ==, 0x0); curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_READ_DATA); -g_assert_cmpuint(curval, ==, 0x152d02c0); +g_assert_cmphex(curval, ==, 0x152d02c0); } int main(int argc, char **argv) diff --git a/tests/qtest/cmsdk-apb-dualtimer-test.c b/tests/qtest/cmsdk-apb-dualtimer-test.c index ad6a758289..3b89bed97d 100644 --- a/tests/qtest/cmsdk-apb-dualtimer-test.c +++ b/tests/qtest/cmsdk-apb-dualtimer-test.c @@ -69,7 +69,7 @@ static void test_dualtimer(void) * tick VALUE should have wrapped round to 0x. */ clock_step(40); -g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0x); +g_assert_cmphex(readl(TIMER_BASE + TIMER1VALUE), ==, 0x); /* Check that any write to INTCLR clears interrupt */ writel(TIMER_BASE + TIMER1INTCLR, 1); diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c index 2710cb17b8..00b5dbbc81 100644 --- a/tests/qtest/cmsdk-apb-watchdog-test.c +++ b/tests/qtest/cmsdk-apb-watchdog-test.c @@ -88,7 +88,7 @@ static void test_clock_change(void) /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */ rcc = readl(SSYS_BASE + RCC); -g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf); +g_assert_cmphex(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf); rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7); writel(SSYS_BASE + RCC, rcc); diff --git a/tests/qtest/erst-test.c b/tests/qtest/erst-test.c index c45bee7f05..36bbe122ab 100644 --- a/tests/qtest/erst-test.c +++ b/tests/qtest/erst-test.c @@ -109,7 +109,7 @@ static void setup_vm_cmd(ERSTState *s, const char *cmd) g_assert_cmpuint(s->reg_barsize, ==, 16); s->mem_bar = qpci_iomap(s->dev, 1, >mem_barsize); -
Re: [PATCH] target/sparc: resolve ASI_USERTXT correctly
On 4/13/24 18:54, M Bazz wrote: This thought just came to me. `lda` is a privileged instruction. It has to run in supervisor mode. So, I'm struggling to understand how the kernel permission was wrong. Isn't that the right permission for this instruction? The "current" permission, as computed by -case ASI_KERNELTXT: /* Supervisor code access */ -oi = make_memop_idx(memop, cpu_mmu_index(env_cpu(env), true)); was correct for ASI_KERNELTXT, because as you say "lda" is a supervisor-only instruction prior to sparcv9. However, using the same value for ASI_USERTXT would be incorrect. For ASI_USERTXT and ASI_USERDATA (and the new names for sparcv9, ASI_AIU*, "as-if user"), we need permissions for the user context. That's what +case ASI_USERTXT: /* User text access */ +mem_idx = MMU_USER_IDX; this is for in my patch. This gets passed into the helper, +case GET_ASI_CODE: +#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64) +{ +MemOpIdx oi = make_memop_idx(da->memop, da->mem_idx); +TCGv_i64 t64 = tcg_temp_new_i64(); + +gen_helper_ld_code(t64, tcg_env, addr, tcg_constant_i32(oi)); and then into the core memory access functions, +ret = cpu_ldl_code_mmu(env, addr, oi, ra); Unfortunately, we do not have any good documentation for tcg softmmu or the intended role of the mmu_idx. Partly that's due to the final use of the mmu_idx is target-specific. For sparc32, there are 3 mmu_idx: #define MMU_USER_IDX 0 #define MMU_KERNEL_IDX 1 #define MMU_PHYS_IDX 2 The interpretation of mmu_idx happens in target/sparc/mmu_helper.c, get_physical_address (note there are two versions, for sparc32 and sparc64). Ignoring MMU_PHYS_IDX, which is handled early, the difference between kernel and user is is_user = mmu_idx == MMU_USER_IDX; ... full->prot = perm_table[is_user][access_perms]; This controls the read/write/execute permissions for the page. Note that perm_table matches the Access Allowed table on page 248 of the Sparc V8 architecture manual. r~
Re: [PATCH] tests/qtest : Use `g_assert_cmphex` instead of `g_assert_cmpuint`
- Le 14 Avr 24, à 18:19, Philippe Mathieu-Daudé phi...@linaro.org a écrit : > Hi Inès, Hello Philippe ! > > On 14/4/24 15:24, Inès Varhol wrote: >> The messages for STM32L4x5 tests will be easier to understand with >> `g_assert_cmphex` since the comparisions were made with hexadecimal > > "comparisons" Ouch thank you I'm fixing it. > >> numbers. >> >> Signed-off-by: Inès Varhol >> --- >> tests/qtest/stm32l4x5_exti-test.c | 138 ++-- >> tests/qtest/stm32l4x5_syscfg-test.c | 74 +++ >> 2 files changed, 106 insertions(+), 106 deletions(-) > > $ git grep g_assert_cmpuint.*,\ 0x tests/qtest/stm32*| wc -l > 105 > > Nice cleanup! > > $ git grep g_assert_cmpuint.*,\ 0x | wc -l > 148 > > Still 33 to go... (not asking you to do it!). Very cool tool. I can fix it (also with a regex), should I change those with comparisons to 0x0 and 0x1 though? Best, Ines
Re: [PATCH] tests/qtest : Use `g_assert_cmphex` instead of `g_assert_cmpuint`
Hi Inès, On 14/4/24 15:24, Inès Varhol wrote: The messages for STM32L4x5 tests will be easier to understand with `g_assert_cmphex` since the comparisions were made with hexadecimal "comparisons" numbers. Signed-off-by: Inès Varhol --- tests/qtest/stm32l4x5_exti-test.c | 138 ++-- tests/qtest/stm32l4x5_syscfg-test.c | 74 +++ 2 files changed, 106 insertions(+), 106 deletions(-) $ git grep g_assert_cmpuint.*,\ 0x tests/qtest/stm32*| wc -l 105 Nice cleanup! $ git grep g_assert_cmpuint.*,\ 0x | wc -l 148 Still 33 to go... (not asking you to do it!). Reviewed-by: Philippe Mathieu-Daudé
Re: Qemu for TC377
Hi Sameer, On 13/4/24 14:52, Sameer Kalliadan Poyil wrote: Hello All, I see that Latest qemu supports for tricore TC277 and TC377 image.png But when I downloaded source code and checked for TC377 related file , I didn't find anything I want to run RTOS/bare metal code on TC377 . could you please let me know how to start qemu on TC377 ? Here is the latest version of qemu i have , I didn't download 9.0 $ qemu-system-tricore -cpu help Available CPUs: tc1796 tc1797 tc27x tc37x $ Try 'qemu-system-tricore -machine KIT_AURIX_TC277_TRB -cpu tc37x', this should start a TC377 SoC on an AURIX board (~KIT_A2G_TC377_TRB). Cc'ing Bastian for further help. Regards, Phil. Regards Sameer
Patch "virtio_net: Do not send RSS key if it is not supported" has been added to the 6.8-stable tree
This is a note to let you know that I've just added the patch titled virtio_net: Do not send RSS key if it is not supported to the 6.8-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: virtio_net-do-not-send-rss-key-if-it-is-not-supported.patch and it can be found in the queue-6.8 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From 059a49aa2e25c58f90b50151f109dd3c4cdb3a47 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 3 Apr 2024 08:43:12 -0700 Subject: virtio_net: Do not send RSS key if it is not supported From: Breno Leitao commit 059a49aa2e25c58f90b50151f109dd3c4cdb3a47 upstream. There is a bug when setting the RSS options in virtio_net that can break the whole machine, getting the kernel into an infinite loop. Running the following command in any QEMU virtual machine with virtionet will reproduce this problem: # ethtool -X eth0 hfunc toeplitz This is how the problem happens: 1) ethtool_set_rxfh() calls virtnet_set_rxfh() 2) virtnet_set_rxfh() calls virtnet_commit_rss_command() 3) virtnet_commit_rss_command() populates 4 entries for the rss scatter-gather 4) Since the command above does not have a key, then the last scatter-gatter entry will be zeroed, since rss_key_size == 0. sg_buf_size = vi->rss_key_size; 5) This buffer is passed to qemu, but qemu is not happy with a buffer with zero length, and do the following in virtqueue_map_desc() (QEMU function): if (!sz) { virtio_error(vdev, "virtio: zero sized buffers are not allowed"); 6) virtio_error() (also QEMU function) set the device as broken vdev->broken = true; 7) Qemu bails out, and do not repond this crazy kernel. 8) The kernel is waiting for the response to come back (function virtnet_send_command()) 9) The kernel is waiting doing the following : while (!virtqueue_get_buf(vi->cvq, ) && !virtqueue_is_broken(vi->cvq)) cpu_relax(); 10) None of the following functions above is true, thus, the kernel loops here forever. Keeping in mind that virtqueue_is_broken() does not look at the qemu `vdev->broken`, so, it never realizes that the vitio is broken at QEMU side. Fix it by not sending RSS commands if the feature is not available in the device. Fixes: c7114b1249fa ("drivers/net/virtio_net: Added basic RSS support.") Cc: sta...@vger.kernel.org Cc: qemu-devel@nongnu.org Signed-off-by: Breno Leitao Reviewed-by: Heng Qi Reviewed-by: Xuan Zhuo Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3768,6 +3768,7 @@ static int virtnet_set_rxfh(struct net_d struct netlink_ext_ack *extack) { struct virtnet_info *vi = netdev_priv(dev); + bool update = false; int i; if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && @@ -3775,13 +3776,28 @@ static int virtnet_set_rxfh(struct net_d return -EOPNOTSUPP; if (rxfh->indir) { + if (!vi->has_rss) + return -EOPNOTSUPP; + for (i = 0; i < vi->rss_indir_table_size; ++i) vi->ctrl->rss.indirection_table[i] = rxfh->indir[i]; + update = true; } - if (rxfh->key) + + if (rxfh->key) { + /* If either _F_HASH_REPORT or _F_RSS are negotiated, the +* device provides hash calculation capabilities, that is, +* hash_key is configured. +*/ + if (!vi->has_rss && !vi->has_rss_hash_report) + return -EOPNOTSUPP; + memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size); + update = true; + } - virtnet_commit_rss_command(vi); + if (update) + virtnet_commit_rss_command(vi); return 0; } @@ -4686,13 +4702,15 @@ static int virtnet_probe(struct virtio_d if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) vi->has_rss_hash_report = true; - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { vi->has_rss = true; - if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_indir_table_size = virtio_cread16(vdev, offsetof(struct virtio_net_config, rss_max_indirection_table_length)); + } + + if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_key_size = virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); Patches currently in stable-queue which might be from lei...@debian.org are
[PATCH] tests/qtest : Use `g_assert_cmphex` instead of `g_assert_cmpuint`
The messages for STM32L4x5 tests will be easier to understand with `g_assert_cmphex` since the comparisions were made with hexadecimal numbers. Signed-off-by: Inès Varhol --- tests/qtest/stm32l4x5_exti-test.c | 138 ++-- tests/qtest/stm32l4x5_syscfg-test.c | 74 +++ 2 files changed, 106 insertions(+), 106 deletions(-) diff --git a/tests/qtest/stm32l4x5_exti-test.c b/tests/qtest/stm32l4x5_exti-test.c index 81830be8ae..7092860b9b 100644 --- a/tests/qtest/stm32l4x5_exti-test.c +++ b/tests/qtest/stm32l4x5_exti-test.c @@ -70,44 +70,44 @@ static void test_reg_write_read(void) /* Test that non-reserved bits in xMR and xTSR can be set and cleared */ exti_writel(EXTI_IMR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_IMR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_IMR1), ==, 0x); exti_writel(EXTI_IMR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_IMR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_IMR1), ==, 0x); exti_writel(EXTI_EMR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_EMR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_EMR1), ==, 0x); exti_writel(EXTI_EMR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_EMR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_EMR1), ==, 0x); exti_writel(EXTI_RTSR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x007D); +g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x007D); exti_writel(EXTI_RTSR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x); exti_writel(EXTI_FTSR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x007D); +g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x007D); exti_writel(EXTI_FTSR1, 0x); -g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x); exti_writel(EXTI_IMR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_IMR2), ==, 0x00FF); +g_assert_cmphex(exti_readl(EXTI_IMR2), ==, 0x00FF); exti_writel(EXTI_IMR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_IMR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_IMR2), ==, 0x); exti_writel(EXTI_EMR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_EMR2), ==, 0x00FF); +g_assert_cmphex(exti_readl(EXTI_EMR2), ==, 0x00FF); exti_writel(EXTI_EMR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_EMR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_EMR2), ==, 0x); exti_writel(EXTI_RTSR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x0078); +g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x0078); exti_writel(EXTI_RTSR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x); exti_writel(EXTI_FTSR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x0078); +g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x0078); exti_writel(EXTI_FTSR2, 0x); -g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x); } static void test_direct_lines_write(void) @@ -115,28 +115,28 @@ static void test_direct_lines_write(void) /* Test that direct lines reserved bits are not written to */ exti_writel(EXTI_RTSR1, 0xFF82); -g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x); exti_writel(EXTI_FTSR1, 0xFF82); -g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x); exti_writel(EXTI_SWIER1, 0xFF82); -g_assert_cmpuint(exti_readl(EXTI_SWIER1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_SWIER1), ==, 0x); exti_writel(EXTI_PR1, 0xFF82); -g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x); exti_writel(EXTI_RTSR2, 0x0087); -g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x); exti_writel(EXTI_FTSR2, 0x0087); -g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x); exti_writel(EXTI_SWIER2, 0x0087); -g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x); exti_writel(EXTI_PR2, 0x0087); -g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x); +g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x); } static void test_reserved_bits_write(void) @@ -144,22 +144,22 @@ static void
[PATCH v4 2/5] hw/arm : Pass STM32L4x5 SYSCFG gpios to STM32L4x5 SoC
Exposing SYSCFG inputs to the SoC is practical in order to wire the SoC to the optional DM163 display from the board code (GPIOs outputs need to be connected to both SYSCFG inputs and DM163 inputs). STM32L4x5 SYSCFG in-irq interception needed to be changed accordingly. Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- hw/arm/stm32l4x5_soc.c | 6 -- tests/qtest/stm32l4x5_gpio-test.c | 12 +++- tests/qtest/stm32l4x5_syscfg-test.c | 16 +--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c index 40e294f838..c4b45e6956 100644 --- a/hw/arm/stm32l4x5_soc.c +++ b/hw/arm/stm32l4x5_soc.c @@ -1,8 +1,8 @@ /* * STM32L4x5 SoC family * - * Copyright (c) 2023 Arnaud Minier - * Copyright (c) 2023 Inès Varhol + * Copyright (c) 2024 Arnaud Minier + * Copyright (c) 2024 Inès Varhol * * SPDX-License-Identifier: GPL-2.0-or-later * @@ -221,6 +221,8 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp) } } +qdev_pass_gpios(DEVICE(>syscfg), dev_soc, NULL); + /* EXTI device */ busdev = SYS_BUS_DEVICE(>exti); if (!sysbus_realize(busdev, errp)) { diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c index 0f6bda54d3..495a6fc413 100644 --- a/tests/qtest/stm32l4x5_gpio-test.c +++ b/tests/qtest/stm32l4x5_gpio-test.c @@ -43,6 +43,8 @@ #define OTYPER_PUSH_PULL 0 #define OTYPER_OPEN_DRAIN 1 +#define SYSCFG "/machine/soc" + const uint32_t moder_reset[NUM_GPIOS] = { 0xABFF, 0xFEBF, @@ -284,7 +286,7 @@ static void test_gpio_output_mode(const void *data) uint32_t gpio = test_gpio_addr(data); unsigned int gpio_id = get_gpio_id(gpio); -qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); +qtest_irq_intercept_in(global_qtest, SYSCFG); /* Set a bit in ODR and check nothing happens */ gpio_set_bit(gpio, ODR, pin, 1); @@ -319,7 +321,7 @@ static void test_gpio_input_mode(const void *data) uint32_t gpio = test_gpio_addr(data); unsigned int gpio_id = get_gpio_id(gpio); -qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); +qtest_irq_intercept_in(global_qtest, SYSCFG); /* Configure a line as input, raise it, and check that the pin is high */ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); @@ -348,7 +350,7 @@ static void test_pull_up_pull_down(const void *data) uint32_t gpio = test_gpio_addr(data); unsigned int gpio_id = get_gpio_id(gpio); -qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); +qtest_irq_intercept_in(global_qtest, SYSCFG); /* Configure a line as input with pull-up, check the line is set high */ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); @@ -378,7 +380,7 @@ static void test_push_pull(const void *data) uint32_t gpio = test_gpio_addr(data); uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); -qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); +qtest_irq_intercept_in(global_qtest, SYSCFG); /* Setting a line high externally, configuring it in push-pull output */ /* And checking the pin was disconnected */ @@ -425,7 +427,7 @@ static void test_open_drain(const void *data) uint32_t gpio = test_gpio_addr(data); uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); -qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); +qtest_irq_intercept_in(global_qtest, SYSCFG); /* Setting a line high externally, configuring it in open-drain output */ /* And checking the pin was disconnected */ diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c index ed4801798d..eed9d5940b 100644 --- a/tests/qtest/stm32l4x5_syscfg-test.c +++ b/tests/qtest/stm32l4x5_syscfg-test.c @@ -1,8 +1,8 @@ /* * QTest testcase for STM32L4x5_SYSCFG * - * Copyright (c) 2023 Arnaud Minier - * Copyright (c) 2023 Inès Varhol + * Copyright (c) 2024 Arnaud Minier + * Copyright (c) 2024 Inès Varhol * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -25,6 +25,9 @@ #define SYSCFG_SWPR2 0x28 #define INVALID_ADDR 0x2C +#define EXTI "/machine/soc/exti" +#define SYSCFG "/machine/soc" + static void syscfg_writel(unsigned int offset, uint32_t value) { writel(SYSCFG_BASE_ADDR + offset, value); @@ -37,8 +40,7 @@ static uint32_t syscfg_readl(unsigned int offset) static void syscfg_set_irq(int num, int level) { - qtest_set_irq_in(global_qtest, "/machine/soc/syscfg", -NULL, num, level); + qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level); } static void system_reset(void) @@ -197,7 +199,7 @@ static void test_interrupt(void) * Test that GPIO rising lines result in an irq * with the right configuration */ -qtest_irq_intercept_in(global_qtest, "/machine/soc/exti"); +
[PATCH v4 4/5] hw/arm : Connect DM163 to B-L475E-IOT01A
Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- hw/arm/b-l475e-iot01a.c | 59 +++-- hw/arm/Kconfig | 1 + 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c index 2b570b3e09..6f0bf68ca6 100644 --- a/hw/arm/b-l475e-iot01a.c +++ b/hw/arm/b-l475e-iot01a.c @@ -27,10 +27,37 @@ #include "hw/boards.h" #include "hw/qdev-properties.h" #include "qemu/error-report.h" -#include "hw/arm/stm32l4x5_soc.h" #include "hw/arm/boot.h" +#include "hw/core/split-irq.h" +#include "hw/arm/stm32l4x5_soc.h" +#include "hw/gpio/stm32l4x5_gpio.h" +#include "hw/display/dm163.h" + +/* B-L475E-IOT01A implementation is inspired from netduinoplus2 and arduino */ -/* B-L475E-IOT01A implementation is derived from netduinoplus2 */ +/* + * There are actually 14 input pins in the DM163 device. + * Here the DM163 input pin EN isn't connected to the STM32L4x5 + * GPIOs as the IM120417002 colors shield doesn't actually use + * this pin to drive the RGB matrix. + */ +#define NUM_DM163_INPUTS 13 + +static const int dm163_input[NUM_DM163_INPUTS] = { +1 * GPIO_NUM_PINS + 2, /* ROW0 PB2 */ +0 * GPIO_NUM_PINS + 15, /* ROW1 PA15 */ +0 * GPIO_NUM_PINS + 2, /* ROW2 PA2 */ +0 * GPIO_NUM_PINS + 7, /* ROW3 PA7 */ +0 * GPIO_NUM_PINS + 6, /* ROW4 PA6 */ +0 * GPIO_NUM_PINS + 5, /* ROW5 PA5 */ +1 * GPIO_NUM_PINS + 0, /* ROW6 PB0 */ +0 * GPIO_NUM_PINS + 3, /* ROW7 PA3 */ +0 * GPIO_NUM_PINS + 4, /* SIN (SDA) PA4 */ +1 * GPIO_NUM_PINS + 1, /* DCK (SCK) PB1 */ +2 * GPIO_NUM_PINS + 3, /* RST_B (RST) PC3 */ +2 * GPIO_NUM_PINS + 4, /* LAT_B (LAT) PC4 */ +2 * GPIO_NUM_PINS + 5, /* SELBK (SB) PC5 */ +}; #define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a") OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A) @@ -39,12 +66,16 @@ typedef struct Bl475eMachineState { MachineState parent_obj; Stm32l4x5SocState soc; +SplitIRQ gpio_splitters[NUM_DM163_INPUTS]; +DM163State dm163; } Bl475eMachineState; static void bl475e_init(MachineState *machine) { Bl475eMachineState *s = B_L475E_IOT01A(machine); const Stm32l4x5SocClass *sc; +DeviceState *dev, *gpio_out_splitter; +int gpio, pin; object_initialize_child(OBJECT(machine), "soc", >soc, TYPE_STM32L4X5XG_SOC); @@ -53,6 +84,30 @@ static void bl475e_init(MachineState *machine) sc = STM32L4X5_SOC_GET_CLASS(>soc); armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0, sc->flash_size); + +if (object_class_by_name("dm163")) { +object_initialize_child(OBJECT(machine), "dm163", +>dm163, TYPE_DM163); +dev = DEVICE(>dm163); +qdev_realize(dev, NULL, _abort); + +for (unsigned i = 0; i < NUM_DM163_INPUTS; i++) { +object_initialize_child(OBJECT(machine), "gpio-out-splitters[*]", +>gpio_splitters[i], TYPE_SPLIT_IRQ); +gpio_out_splitter = DEVICE(>gpio_splitters[i]); +qdev_prop_set_uint32(gpio_out_splitter, "num-lines", 2); +qdev_realize(gpio_out_splitter, NULL, _fatal); + +qdev_connect_gpio_out(gpio_out_splitter, 0, +qdev_get_gpio_in(DEVICE(>soc), dm163_input[i])); +qdev_connect_gpio_out(gpio_out_splitter, 1, +qdev_get_gpio_in(dev, i)); +gpio = dm163_input[i] / GPIO_NUM_PINS; +pin = dm163_input[i] % GPIO_NUM_PINS; +qdev_connect_gpio_out(DEVICE(>soc.gpio[gpio]), pin, +qdev_get_gpio_in(DEVICE(gpio_out_splitter), 0)); +} +} } static void bl475e_machine_init(ObjectClass *oc, void *data) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 893a7bff66..8431384402 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -468,6 +468,7 @@ config B_L475E_IOT01A default y depends on TCG && ARM select STM32L4X5_SOC +imply DM163 config STM32L4X5_SOC bool -- 2.43.2
[PATCH v4 0/5] Add device DM163 (led driver, matrix colors shield & display)
This device implements the IM120417002 colors shield v1.1 for Arduino (which relies on the DM163 8x3-channel led driving logic) and features a simple display of an 8x8 RGB matrix. This color shield can be plugged on the Arduino board (or the B-L475E-IOT01A board) to drive an 8x8 RGB led matrix. This RGB led matrix takes advantage of retinal persistance to seemingly display different colors in each row. Hello, I have been very busy this last month, sorry for the delay. In a later version, I will add a more thorough test like suggested by Thomas Huth (thank you for the examples, I will look into it). Following the response of Peter Maydell about the SYSCFG export at STM32L4x5 level, I'm thinking of moving the STM32L4x5 GPIO output splitters from the Bl475e machine to the STM32L4x5 SOC code. In the current code, the GPIO output splitters are created in the Bl475e machine and the machine has to wire some of these splitted outputs to SYSCFG inputs. SYSCFG inputs are exported at SOC level to facilitate this. By moving the splitters inside the STM32L4x5 SOC, the SOC could export GPIO I/O instead of SYSCFG I/O which would be closer to the hardware, and the Bl475e machine would directly connect the DM163 to GPIO outputs. Changes from v3 (review of the 1st commit by Peter Maydell) : - dm163.c : instead of redrawing the entire console each frame, only redraw the rows that changed using a new variable `redraw` - reset all the fields in `dm163_reset_hold` - correcting typos : persistance -> persistence - b-l475e-iot01a.rst : correcting typo Changes from v2 : Corrected typo in the Based-on message id Changes from v1 : - moving the DM163 from the SoC to the B-L475E-IOT01A machine (changing config files and tests accordingly) - restricting DM163 test to ARM & DM163 availability - using `object_class_by_name()` to check for DM163 presence at run-time - exporting SYSCFG inputs to the SoC (and adapting tests accordingly) Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol Inès Varhol (5): hw/display : Add device DM163 hw/arm : Pass STM32L4x5 SYSCFG gpios to STM32L4x5 SoC hw/arm : Create Bl475eMachineState hw/arm : Connect DM163 to B-L475E-IOT01A tests/qtest : Add testcase for DM163 docs/system/arm/b-l475e-iot01a.rst | 3 +- include/hw/display/dm163.h | 58 + hw/arm/b-l475e-iot01a.c | 103 +++-- hw/arm/stm32l4x5_soc.c | 6 +- hw/display/dm163.c | 333 tests/qtest/dm163-test.c| 192 tests/qtest/stm32l4x5_gpio-test.c | 12 +- tests/qtest/stm32l4x5_syscfg-test.c | 16 +- hw/arm/Kconfig | 1 + hw/display/Kconfig | 3 + hw/display/meson.build | 1 + hw/display/trace-events | 14 ++ tests/qtest/meson.build | 5 + 13 files changed, 717 insertions(+), 30 deletions(-) create mode 100644 include/hw/display/dm163.h create mode 100644 hw/display/dm163.c create mode 100644 tests/qtest/dm163-test.c -- 2.43.2
[PATCH v4 5/5] tests/qtest : Add testcase for DM163
`test_dm163_bank()` Checks that the pin "sout" of the DM163 led driver outputs the values received on pin "sin" with the expected latency (depending on the bank). `test_dm163_gpio_connection()` Check that changes to relevant STM32L4x5 GPIO pins are propagated to the DM163 device. Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- tests/qtest/dm163-test.c | 192 +++ tests/qtest/meson.build | 5 + 2 files changed, 197 insertions(+) create mode 100644 tests/qtest/dm163-test.c diff --git a/tests/qtest/dm163-test.c b/tests/qtest/dm163-test.c new file mode 100644 index 00..6f88ceef44 --- /dev/null +++ b/tests/qtest/dm163-test.c @@ -0,0 +1,192 @@ +/* + * QTest testcase for DM163 + * + * Copyright (C) 2024 Samuel Tardieu + * Copyright (C) 2024 Arnaud Minier + * Copyright (C) 2024 Inès Varhol + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "libqtest.h" + +#define SIN 8 +#define DCK 9 +#define RST_B 10 +#define LAT_B 11 +#define SELBK 12 +#define EN_B 13 + +#define DEVICE_NAME "/machine/dm163" +#define GPIO_OUT(name, value) qtest_set_irq_in(qts, DEVICE_NAME, NULL, name, \ + value) +#define GPIO_PULSE(name) \ + do { \ +GPIO_OUT(name, 1); \ +GPIO_OUT(name, 0); \ + } while (0) + + +static void rise_gpio_pin_dck(QTestState *qts) +{ +/* Configure output mode for pin PB1 */ +qtest_writel(qts, 0x48000400, 0xFEB7); +/* Write 1 in ODR for PB1 */ +qtest_writel(qts, 0x48000414, 0x0002); +} + +static void lower_gpio_pin_dck(QTestState *qts) +{ +/* Configure output mode for pin PB1 */ +qtest_writel(qts, 0x48000400, 0xFEB7); +/* Write 0 in ODR for PB1 */ +qtest_writel(qts, 0x48000414, 0x); +} + +static void rise_gpio_pin_selbk(QTestState *qts) +{ +/* Configure output mode for pin PC5 */ +qtest_writel(qts, 0x48000800, 0xF7FF); +/* Write 1 in ODR for PC5 */ +qtest_writel(qts, 0x48000814, 0x0020); +} + +static void lower_gpio_pin_selbk(QTestState *qts) +{ +/* Configure output mode for pin PC5 */ +qtest_writel(qts, 0x48000800, 0xF7FF); +/* Write 0 in ODR for PC5 */ +qtest_writel(qts, 0x48000814, 0x); +} + +static void rise_gpio_pin_lat_b(QTestState *qts) +{ +/* Configure output mode for pin PC4 */ +qtest_writel(qts, 0x48000800, 0xFDFF); +/* Write 1 in ODR for PC4 */ +qtest_writel(qts, 0x48000814, 0x0010); +} + +static void lower_gpio_pin_lat_b(QTestState *qts) +{ +/* Configure output mode for pin PC4 */ +qtest_writel(qts, 0x48000800, 0xFDFF); +/* Write 0 in ODR for PC4 */ +qtest_writel(qts, 0x48000814, 0x); +} + +static void rise_gpio_pin_rst_b(QTestState *qts) +{ +/* Configure output mode for pin PC3 */ +qtest_writel(qts, 0x48000800, 0xFF7F); +/* Write 1 in ODR for PC3 */ +qtest_writel(qts, 0x48000814, 0x0008); +} + +static void lower_gpio_pin_rst_b(QTestState *qts) +{ +/* Configure output mode for pin PC3 */ +qtest_writel(qts, 0x48000800, 0xFF7F); +/* Write 0 in ODR for PC3 */ +qtest_writel(qts, 0x48000814, 0x); +} + +static void rise_gpio_pin_sin(QTestState *qts) +{ +/* Configure output mode for pin PA4 */ +qtest_writel(qts, 0x4800, 0xFDFF); +/* Write 1 in ODR for PA4 */ +qtest_writel(qts, 0x4814, 0x0010); +} + +static void lower_gpio_pin_sin(QTestState *qts) +{ +/* Configure output mode for pin PA4 */ +qtest_writel(qts, 0x4800, 0xFDFF); +/* Write 0 in ODR for PA4 */ +qtest_writel(qts, 0x4814, 0x); +} + +static void test_dm163_bank(const void *opaque) +{ +const long bank = (uintptr_t) opaque; +const int width = bank ? 192 : 144; + +QTestState *qts = qtest_initf("-M b-l475e-iot01a"); +qtest_irq_intercept_out_named(qts, DEVICE_NAME, "sout"); +GPIO_OUT(RST_B, 1); +GPIO_OUT(EN_B, 0); +GPIO_OUT(DCK, 0); +GPIO_OUT(SELBK, bank); +GPIO_OUT(LAT_B, 1); + +/* Fill bank with zeroes */ +GPIO_OUT(SIN, 0); +for (int i = 0; i < width; i++) { +GPIO_PULSE(DCK); +} +/* Fill bank with ones, check that we get the previous zeroes */ +GPIO_OUT(SIN, 1); +for (int i = 0; i < width; i++) { +GPIO_PULSE(DCK); +g_assert(!qtest_get_irq(qts, 0)); +} + +/* Pulse one more bit in the bank, check that we get a one */ +GPIO_PULSE(DCK); +g_assert(qtest_get_irq(qts, 0)); + +qtest_quit(qts); +} + +static void test_dm163_gpio_connection(void) +{ +QTestState *qts = qtest_init("-M b-l475e-iot01a"); +qtest_irq_intercept_in(qts, DEVICE_NAME); + +g_assert_false(qtest_get_irq(qts,
[PATCH v4 3/5] hw/arm : Create Bl475eMachineState
Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- hw/arm/b-l475e-iot01a.c | 44 + 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c index d862aa43fc..2b570b3e09 100644 --- a/hw/arm/b-l475e-iot01a.c +++ b/hw/arm/b-l475e-iot01a.c @@ -2,8 +2,8 @@ * B-L475E-IOT01A Discovery Kit machine * (B-L475E-IOT01A IoT Node) * - * Copyright (c) 2023 Arnaud Minier - * Copyright (c) 2023 Inès Varhol + * Copyright (c) 2024 Arnaud Minier + * Copyright (c) 2024 Inès Varhol * * SPDX-License-Identifier: GPL-2.0-or-later * @@ -32,33 +32,51 @@ /* B-L475E-IOT01A implementation is derived from netduinoplus2 */ -static void b_l475e_iot01a_init(MachineState *machine) +#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a") +OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A) + +typedef struct Bl475eMachineState { +MachineState parent_obj; + +Stm32l4x5SocState soc; +} Bl475eMachineState; + +static void bl475e_init(MachineState *machine) { +Bl475eMachineState *s = B_L475E_IOT01A(machine); const Stm32l4x5SocClass *sc; -DeviceState *dev; -dev = qdev_new(TYPE_STM32L4X5XG_SOC); -object_property_add_child(OBJECT(machine), "soc", OBJECT(dev)); -sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal); +object_initialize_child(OBJECT(machine), "soc", >soc, +TYPE_STM32L4X5XG_SOC); +sysbus_realize(SYS_BUS_DEVICE(>soc), _fatal); -sc = STM32L4X5_SOC_GET_CLASS(dev); +sc = STM32L4X5_SOC_GET_CLASS(>soc); armv7m_load_kernel(ARM_CPU(first_cpu), - machine->kernel_filename, - 0, sc->flash_size); +machine->kernel_filename, 0, sc->flash_size); } -static void b_l475e_iot01a_machine_init(MachineClass *mc) +static void bl475e_machine_init(ObjectClass *oc, void *data) { +MachineClass *mc = MACHINE_CLASS(oc); static const char *machine_valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-m4"), NULL }; mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)"; -mc->init = b_l475e_iot01a_init; +mc->init = bl475e_init; mc->valid_cpu_types = machine_valid_cpu_types; /* SRAM pre-allocated as part of the SoC instantiation */ mc->default_ram_size = 0; } -DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init) +static const TypeInfo bl475e_machine_type[] = { +{ +.name = TYPE_B_L475E_IOT01A, +.parent = TYPE_MACHINE, +.instance_size = sizeof(Bl475eMachineState), +.class_init = bl475e_machine_init, +} +}; + +DEFINE_TYPES(bl475e_machine_type) -- 2.43.2
[PATCH v4 1/5] hw/display : Add device DM163
This device implements the IM120417002 colors shield v1.1 for Arduino (which relies on the DM163 8x3-channel led driving logic) and features a simple display of an 8x8 RGB matrix. The columns of the matrix are driven by the DM163 and the rows are driven externally. Acked-by: Alistair Francis Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol --- docs/system/arm/b-l475e-iot01a.rst | 3 +- include/hw/display/dm163.h | 58 + hw/display/dm163.c | 333 + hw/display/Kconfig | 3 + hw/display/meson.build | 1 + hw/display/trace-events| 14 ++ 6 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 include/hw/display/dm163.h create mode 100644 hw/display/dm163.c diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst index 0afef8e4f4..91de5e82fc 100644 --- a/docs/system/arm/b-l475e-iot01a.rst +++ b/docs/system/arm/b-l475e-iot01a.rst @@ -12,13 +12,14 @@ USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors. Supported devices " -Currently B-L475E-IOT01A machine's only supports the following devices: +Currently B-L475E-IOT01A machines support the following devices: - Cortex-M4F based STM32L4x5 SoC - STM32L4x5 EXTI (Extended interrupts and events controller) - STM32L4x5 SYSCFG (System configuration controller) - STM32L4x5 RCC (Reset and clock control) - STM32L4x5 GPIOs (General-purpose I/Os) +- optional 8x8 led display (based on DM163 driver) Missing devices """ diff --git a/include/hw/display/dm163.h b/include/hw/display/dm163.h new file mode 100644 index 00..00d0504640 --- /dev/null +++ b/include/hw/display/dm163.h @@ -0,0 +1,58 @@ +/* + * QEMU DM163 8x3-channel constant current led driver + * driving columns of associated 8x8 RGB matrix. + * + * Copyright (C) 2024 Samuel Tardieu + * Copyright (C) 2024 Arnaud Minier + * Copyright (C) 2024 Inès Varhol + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_DISPLAY_DM163_H +#define HW_DISPLAY_DM163_H + +#include "qom/object.h" +#include "hw/qdev-core.h" + +#define TYPE_DM163 "dm163" +OBJECT_DECLARE_SIMPLE_TYPE(DM163State, DM163); + +#define DM163_NUM_LEDS 24 +#define RGB_MATRIX_NUM_ROWS 8 +#define RGB_MATRIX_NUM_COLS (DM163_NUM_LEDS / 3) +#define COLOR_BUFFER_SIZE RGB_MATRIX_NUM_ROWS + +typedef struct DM163State { +DeviceState parent_obj; + +/* DM163 driver */ +uint64_t bank0_shift_register[3]; +uint64_t bank1_shift_register[3]; +uint16_t latched_outputs[DM163_NUM_LEDS]; +uint16_t outputs[DM163_NUM_LEDS]; +qemu_irq sout; + +uint8_t sin; +uint8_t dck; +uint8_t rst_b; +uint8_t lat_b; +uint8_t selbk; +uint8_t en_b; + +/* IM120417002 colors shield */ +uint8_t activated_rows; + +/* 8x8 RGB matrix */ +QemuConsole *console; +uint8_t redraw; +/* Rows currently being displayed on the matrix. */ +/* The last row is filled with 0 (turned off row) */ +uint32_t buffer[COLOR_BUFFER_SIZE + 1][RGB_MATRIX_NUM_COLS]; +uint8_t last_buffer_idx; +uint8_t buffer_idx_of_row[RGB_MATRIX_NUM_ROWS]; +/* Used to simulate retinal persistence of rows */ +uint8_t age_of_row[RGB_MATRIX_NUM_ROWS]; +} DM163State; + +#endif /* HW_DISPLAY_DM163_H */ diff --git a/hw/display/dm163.c b/hw/display/dm163.c new file mode 100644 index 00..d4e89dd344 --- /dev/null +++ b/hw/display/dm163.c @@ -0,0 +1,333 @@ +/* + * QEMU DM163 8x3-channel constant current led driver + * driving columns of associated 8x8 RGB matrix. + * + * Copyright (C) 2024 Samuel Tardieu + * Copyright (C) 2024 Arnaud Minier + * Copyright (C) 2024 Inès Varhol + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* + * The reference used for the DM163 is the following : + * http://www.siti.com.tw/product/spec/LED/DM163.pdf + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "migration/vmstate.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/display/dm163.h" +#include "ui/console.h" +#include "trace.h" + +#define LED_SQUARE_SIZE 100 +/* Number of frames a row stays visible after being turned off. */ +#define ROW_PERSISTENCE 3 +#define TURNED_OFF_ROW COLOR_BUFFER_SIZE + +static const VMStateDescription vmstate_dm163 = { +.name = TYPE_DM163, +.version_id = 1, +.minimum_version_id = 1, +.fields = (const VMStateField[]) { +VMSTATE_UINT64_ARRAY(bank0_shift_register, DM163State, 3), +VMSTATE_UINT64_ARRAY(bank1_shift_register, DM163State, 3), +VMSTATE_UINT16_ARRAY(latched_outputs, DM163State, DM163_NUM_LEDS), +VMSTATE_UINT16_ARRAY(outputs, DM163State, DM163_NUM_LEDS), +VMSTATE_UINT8(dck, DM163State), +VMSTATE_UINT8(en_b, DM163State), +VMSTATE_UINT8(lat_b, DM163State), +VMSTATE_UINT8(rst_b, DM163State), +VMSTATE_UINT8(selbk, DM163State), +VMSTATE_UINT8(sin, DM163State), +
Re: [PATCH v2] ppc440_pcix: Do not expose a bridge device on PCI bus
On Sat, 13 Apr 2024, Philippe Mathieu-Daudé wrote: On 11/4/24 21:24, BALATON Zoltan wrote: Real 460EX SoC apparently does not expose a bridge device and having it appear on PCI bus confuses an AmigaOS file system driver that uses this to detect which machine it is running on. Signed-off-by: BALATON Zoltan --- Here's another version that keeps the values and only drops the device so it's even less likely it could break anything, in case this can be accepted for 9.0. hw/pci-host/ppc440_pcix.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) Reviewed-by: Philippe Mathieu-Daudé Thanks. Nick, could you ack this please so it could be merged if you won't send more pull requests? (I'm the maintainer of this file as it's only used by sam460ex so maybe an ack is not needed but it could help to show you have no problem with it.) Regards, BALATON Zoltan
Re: [PULL 0/1] target/sparc late fix
On Fri, 12 Apr 2024 at 19:55, Richard Henderson wrote: > > Since this problem has 4 issues open, let's get it for 9.0. > > > r~ > > > The following changes since commit be72d6ab361a26878752467a17289066dfd5bc28: > > Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging > (2024-04-12 16:01:04 +0100) > > are available in the Git repository at: > > https://gitlab.com/rth7680/qemu.git tags/pull-sp-20240412 > > for you to fetch changes up to c84f5198b0b676ad67962b5250af1b0d0842e319: > > target/sparc: Use GET_ASI_CODE for ASI_KERNELTXT and ASI_USERTXT > (2024-04-12 11:48:26 -0700) > > > target/sparc: Fix ASI_USERTXT for Solaris gdb crashes > Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/9.0 for any user-visible changes. -- PMM
Re: Discrepancy between mmap call on DPDK/libvduse and rust vm-memory crate
On Fri, Apr 12, 2024 at 12:15:40PM +0200, Eugenio Perez Martin wrote: > Hi! > > I'm building a bridge to expose vhost-user devices through VDUSE. The > code is still immature but I'm able to forward packets using > dpdk-l2fwd through VDUSE to VM. I'm now developing exposing virtiofsd, > but I've hit an error I'd like to discuss. > > VDUSE devices can get all the memory regions the driver is using by > VDUSE_IOTLB_GET_FD ioctl. It returns a file descriptor with a memory > region associated that can be mapped with mmap, and an information > entry about the map it contains: > * Start and end addresses from the driver POV > * Offset within the mmaped region of these start and end > * Device permissions over that region. > > [start=0xc3000][last=0xe7fff][offset=0xc3000][perm=1] > > Now when I try to map it, it is impossible for the userspace device to > call mmap with any offset different than 0. How exactly did you allocate memory? hugetlbfs? > So the "straightforward" > mmap with size = entry.last-entry.start and offset = entry.offset does > not work. I don't know if this is a limitation of Linux or VDUSE. > > Checking QEMU's > subprojects/libvduse/libvduse.c:vduse_iova_add_region() I see it > handles the offset by adding it up to the size, instead of using it > directly as a parameter in the mmap: > > void *mmap_addr = mmap(0, size + offset, prot, MAP_SHARED, fd, 0); CC Xie Yongji who wrote this code, too. > I can replicate it on the bridge for sure. > > Now I send the VhostUserMemoryRegion to the vhost-user application. > The struct has these members: > struct VhostUserMemoryRegion { > uint64_t guest_phys_addr; > uint64_t memory_size; > uint64_t userspace_addr; > uint64_t mmap_offset; > }; > > So I can send the offset to the vhost-user device. I can check that > dpdk-l2fwd uses the same trick of adding offset to the size of the > mapping region [1], at > lib/vhost/vhost_user.c:vhost_user_mmap_region(): > > mmap_size = region->size + mmap_offset; > mmap_addr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, > MAP_SHARED | populate, region->fd, 0); > > So mmap is called with offset == 0 and everybody is happy. > > Now I'm moving to virtiofsd, and vm-memory crate in particular. And it > performs the mmap without the size += offset trick, at > MmapRegionBuilder:build() [2]. > > I can try to apply the offset + size trick in my bridge but I don't > think it is the right solution. At first glance, the right solution is > to mmap with the offset as vm-memory crate do. But having libvduse and > DPDK apply the same trick sounds to me like it is a known limitation / > workaround I don't know about. What is the history of this? Can VDUSE > problem (if any) be solved? Am I missing something? > > Thanks! > > [1] > https://github.com/DPDK/dpdk/blob/e2e546ab5bf5e024986ccb5310ab43982f3bb40c/lib/vhost/vhost_user.c#L1305 > [2] https://github.com/rust-vmm/vm-memory/blob/main/src/mmap_unix.rs#L128
Re: [PATCH v9 17/20] ebpf: Fix RSS error handling
On 2024/04/13 21:16, Yuri Benditovich wrote: On Wed, Apr 3, 2024 at 2:12 PM Akihiko Odaki wrote: calculate_rss_hash() was using hash value 0 to tell if it calculated a hash, but the hash value may be 0 on a rare occasion. Have a distinct bool value for correctness. This is interesting question whether in reality the hash value might be 0 or not. On one hand - this seems like a kind of fix. On another hard - this adds computation cycles for each packet, and the corner case that this targets to fix seems hardly reachable if at all. Optimistic estimation is 2.5*10^-8 percent of address:address:port triplets. I would suggest at least to find some proof of the fact that the calculated hash might be 0 in real case where source addresses are not random. Your estimation, which suggests the low probability of error, and the fact that an error in RSS is not fatal and only regresses the performance, should be sufficient to determine how this patch should be handled; this patch is nice to have, but is not worth to backport to stable or to merge before the 9.0 release. Regards, Akihiko Odaki