From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787549331; cv=none; d=zohomail.com; s=zohoarc; b=lrADEOe9lrutywfd/sFA6m08ss4cFKX0BHQqqT8ITXFzoqZh9XVbf6rG424OKaJT6z4FFsTO0/c/u+FNi5jrx+gnPKmShkurk9B3WEP6k0gmfXWJsoLsuWmzok9MxGCzOl+D17T28kvBVDm+Q5KGhsxoPaMATdcsVWUGeulq8us= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787549331; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3Ctwq1zcty+C8QKKWz8B/yZl3m/lkcBBHrDFtLloLd8=; b=hPo1glI9N2G2xykaYzXfJNaiyivK7HN9bSArO92sD3XIefCuXYKfPyXSFpyxG43SpadjQqrFSfREj3d31YiIGITp6doSBoVnKumD+WFRN5mkI4AEhO6a+jgmBnwo1jmJ0YMtkwfRRCEnWnyPJqHXAN13IYQvVaFd6tSqIWuOBz8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787549331941631.3948023104887; Sun, 23 Aug 2026 22:28:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyNEQ-0008NJ-Ef; Mon, 24 Aug 2026 01:28:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyNEF-0008KS-Mz for qemu-devel@nongnu.org; Mon, 24 Aug 2026 01:28:16 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wyNED-0006eT-6A for qemu-devel@nongnu.org; Mon, 24 Aug 2026 01:28:15 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-38e347638adso2716366a91.0 for ; Sun, 23 Aug 2026 22:28:12 -0700 (PDT) Received: from jeuk-MS-7D42.. ([211.226.54.223]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-395e494f9fdsm8557346a91.3.2026.08.23.22.28.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 22:28:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787549292; x=1788154092; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3Ctwq1zcty+C8QKKWz8B/yZl3m/lkcBBHrDFtLloLd8=; b=iLwUa983zSej84lxJtabRj8YMc9Mx0oMxdzwMCVS4AoQLv92Bq6SHjuzTTrBN987ty 9eTP8J7eZvxMJYnYJNH2pf1rIUDoaqfviTxDgpECeugrl9FA+pLPSrxJl53ug9x+UiYz NO4c7g6QkduNGY0TTGF5abXZ3DeDf0j3o1Zb4RWOn6gK5hLQ0/2V+1IitrNGRO+o3hGb O9fBG06mChuHBalzj97uwvQ+NU34oRV4tdJwT7QUAtl1t/wg2zEmGGxd/WXonpdMyaVl fvDBo+liLqPn3pfFeZ4K99X9Gn+cMmR0sdjOggeHEHozkJgKmGWUa+uahgNn+vRfnJTX W2dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787549292; x=1788154092; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3Ctwq1zcty+C8QKKWz8B/yZl3m/lkcBBHrDFtLloLd8=; b=CdniYeuQAWPkD0Un4pL9l4PbRxyz3Nv9l1qQ9ynlBvhyRCS6/pHXmFIxAijEncnqs9 0+ek74m+ZeB4SNlvaaO2qUIPAx+agRWFNERl01SP047srANGrcMRYvFwDWTZAloYeWVu 3izt6YddKCoJKxYj4BsKHCFV/jLGISn+VWefMfOgchLjnPgfvvtC8/CsQtjlgQuHo1uX g8esXjET8K8gEBIaJzme6geH9s5/Gsjz3ovQSGY6Oue/O81Ggv5zpqeYIF5YGjvqG8Ve gfJPH/mQnyNueoW06Pp4gtvnC/JW5qIY4LlNzFFOeyDL8JP2cV2nzmI976ZGXuTKPIMp OPAA== X-Gm-Message-State: AFuF++lL5ip7y3So2gwh/0mX8yMeLAY6S2PTI+pK7l9I8w2n9tLD00sc P5G9HxMTVvhmbrftMkBbmRBuH7bVSWf397zvTnse3+i906DE80h4utUVBKRG7A== X-Gm-Gg: AR+sD11U71xEm9aMTWbz2YzblyE0oqDUAaGlsnFv6W69eNnne3TBSdzHILl1yOQtqBI i/lEagQ/7sVzkxZ9lZyP/WH6AnDeNH6XXafklYBeqEHDkaUZy73LLoFbDRoK7tE+ISbtkhnpyoG 92EjzZPxd0r+OsMpgR/1Y1yRgjrvB3B7IR16pYFi5l956TuonwXMFSKU1n9yhY3I7GfrJM/iu5S Xt7v0dg1EpFtQXfrN5nVXh4pybu5jtpYK/HqOPvZ8UxzXU6O9AzUan07oveX3ikWW/I8O1tEiw1 +ffbbpJmJylim7jlhN5CNcRNP10aVuU4SjNs2m7VBtcF662KdE5ICrjC1nt6o0JE/4LF2HeCfvS pMIoYo9ZeaCRl5sjBsTRttLEz8badGI6af4vDfzI+YIiCTN8dhDepV+Hq3D70ZjgjNBWE6J0c83 wHH2Y1MbV3Px+7hI9OTHvjACbtQS5HtqHpeJ1e/8IaRfO6bE5YZpXMQfX//xX8itzWnV8EEbIJg u81 X-Received: by 2002:a17:90b:5112:b0:37f:c22a:c188 with SMTP id 98e67ed59e1d1-395dee8a5c5mr30859924a91.4.1787549291496; Sun, 23 Aug 2026 22:28:11 -0700 (PDT) From: Jeuk Kim To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, pbonzini@redhat.com, qemu-block@nongnu.org, jeuk20.kim@samsung.com, j-young.choi@samsung.com, mikail.sadic@ibm.com, clg@kaod.org, Jeuk Kim Subject: [PULL 1/2] hw/ufs: Separate the controller core from the PCI frontend Date: Mon, 24 Aug 2026 14:27:55 +0900 Message-ID: <42feb94b790523f83c1d39141c59face0e327211.1787548791.git.jeuk20.kim@samsung.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=jeuk20.kim@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1787549334106158500 Content-Type: text/plain; charset="utf-8" UfsHc is currently also the PCI device instance, tying common code to PCI-specific DMA and IRQ interfaces and preventing reuse by non-PCI frontends. Make UfsHc transport-independent and embed it in UfsPciState. Move the PCI-specific handling to ufs-pci.c, pass the owning DeviceState and DMA AddressSpace to the core, and record the core explicitly in UfsBus. Split the common implementation into CONFIG_UFS, selected by CONFIG_UFS_PCI. The user-visible "ufs" device and its properties remain unchanged. No functional change is intended. Signed-off-by: Jeuk Kim --- hw/ufs/Kconfig | 5 ++ hw/ufs/lu.c | 2 +- hw/ufs/meson.build | 3 +- hw/ufs/trace-events | 4 +- hw/ufs/ufs-pci.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ hw/ufs/ufs.c | 109 +++++++++--------------------------------- hw/ufs/ufs.h | 14 ++++-- 7 files changed, 153 insertions(+), 96 deletions(-) create mode 100644 hw/ufs/ufs-pci.c diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig index b7b3392e85..47e28a30ea 100644 --- a/hw/ufs/Kconfig +++ b/hw/ufs/Kconfig @@ -1,4 +1,9 @@ +config UFS + bool + select SCSI + config UFS_PCI bool default y if PCI_DEVICES depends on PCI + select UFS diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c index 13f4a90145..eeca865eb5 100644 --- a/hw/ufs/lu.c +++ b/hw/ufs/lu.c @@ -497,7 +497,7 @@ static void ufs_lu_realize(DeviceState *dev, Error **er= rp) { UfsLu *lu =3D DO_UPCAST(UfsLu, qdev, dev); BusState *s =3D qdev_get_parent_bus(dev); - UfsHc *u =3D UFS(s->parent); + UfsHc *u =3D UFS_BUS(s)->hc; BlockBackend *blk =3D lu->conf.blk; =20 if (!ufs_lu_check_constraints(lu, errp)) { diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build index 6e68328b93..880fc52c05 100644 --- a/hw/ufs/meson.build +++ b/hw/ufs/meson.build @@ -1 +1,2 @@ -system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs.c', 'lu.c')) +system_ss.add(when: 'CONFIG_UFS', if_true: files('ufs.c', 'lu.c')) +system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs-pci.c')) diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events index 662d9afee3..0cd3ba9b02 100644 --- a/hw/ufs/trace-events +++ b/hw/ufs/trace-events @@ -1,6 +1,6 @@ # ufs.c -ufs_irq_raise(void) "INTx" -ufs_irq_lower(void) "INTx" +ufs_irq_raise(void) "IRQ" +ufs_irq_lower(void) "IRQ" ufs_mmio_read(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx6= 4" data 0x%"PRIx64" size %d" ufs_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx= 64" data 0x%"PRIx64" size %d" ufs_process_db(uint32_t slot) "UTRLDBR slot %"PRIu32"" diff --git a/hw/ufs/ufs-pci.c b/hw/ufs/ufs-pci.c new file mode 100644 index 0000000000..8abd7d98e3 --- /dev/null +++ b/hw/ufs/ufs-pci.c @@ -0,0 +1,112 @@ +/* + * QEMU Universal Flash Storage (UFS) PCI Controller + * + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved. + * + * Written by Jeuk Kim + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/** + * Usage + * ----- + * + * Add options: + * -drive file=3D,if=3Dnone,id=3D + * -device ufs,serial=3D,id=3D, \ + * nutrs=3D,nutmrs=3D + * -device ufs-lu,drive=3D,bus=3D + */ + +#include "qemu/osdep.h" +#include "hw/core/irq.h" +#include "hw/core/qdev-properties.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" +#include "migration/vmstate.h" +#include "ufs.h" + +#define TYPE_UFS_PCI "ufs" +OBJECT_DECLARE_SIMPLE_TYPE(UfsPciState, UFS_PCI) + +struct UfsPciState { + PCIDevice parent_obj; + UfsHc ufs; +}; + +static void ufs_pci_realize(PCIDevice *pci_dev, Error **errp) +{ + UfsPciState *s =3D UFS_PCI(pci_dev); + UfsHc *u =3D &s->ufs; + uint8_t *pci_conf =3D pci_dev->config; + + pci_conf[PCI_INTERRUPT_PIN] =3D 1; + pci_config_set_prog_interface(pci_conf, 0x1); + u->irq =3D pci_allocate_irq(pci_dev); + if (!ufs_realize(u, DEVICE(pci_dev), pci_get_address_space(pci_dev), + errp)) { + qemu_free_irq(u->irq); + u->irq =3D NULL; + return; + } + + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &u->iomem); +} + +static void ufs_pci_exit(PCIDevice *pci_dev) +{ + UfsPciState *s =3D UFS_PCI(pci_dev); + + ufs_unrealize(&s->ufs); + qemu_free_irq(s->ufs.irq); +} + +static const Property ufs_pci_props[] =3D { + DEFINE_PROP_STRING("serial", UfsPciState, ufs.params.serial), + DEFINE_PROP_UINT8("nutrs", UfsPciState, ufs.params.nutrs, 32), + DEFINE_PROP_UINT8("nutmrs", UfsPciState, ufs.params.nutmrs, 8), + DEFINE_PROP_BOOL("mcq", UfsPciState, ufs.params.mcq, false), + DEFINE_PROP_UINT8("mcq-maxq", UfsPciState, ufs.params.mcq_maxq, 2), + DEFINE_PROP_UINT32("wb-max-size", UfsPciState, ufs.params.wb_max_size, + 0x400), + DEFINE_PROP_UINT32("wb-min-size", UfsPciState, ufs.params.wb_min_size, + 0x100), +}; + +static const VMStateDescription ufs_pci_vmstate =3D { + .name =3D "ufs", + .unmigratable =3D 1, +}; + +static void ufs_pci_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + PCIDeviceClass *pc =3D PCI_DEVICE_CLASS(oc); + + pc->realize =3D ufs_pci_realize; + pc->exit =3D ufs_pci_exit; + pc->vendor_id =3D PCI_VENDOR_ID_REDHAT; + pc->device_id =3D PCI_DEVICE_ID_REDHAT_UFS; + pc->class_id =3D PCI_CLASS_STORAGE_UFS; + + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + dc->desc =3D "Universal Flash Storage"; + device_class_set_props(dc, ufs_pci_props); + dc->vmsd =3D &ufs_pci_vmstate; +} + +static const TypeInfo ufs_pci_info =3D { + .name =3D TYPE_UFS_PCI, + .parent =3D TYPE_PCI_DEVICE, + .class_init =3D ufs_pci_class_init, + .instance_size =3D sizeof(UfsPciState), + .interfaces =3D (const InterfaceInfo[]){ { INTERFACE_PCIE_DEVICE }, {}= }, +}; + +static void ufs_pci_register_types(void) +{ + type_register_static(&ufs_pci_info); +} + +type_init(ufs_pci_register_types) diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 464fd465b3..160a4ac4f3 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -11,19 +11,10 @@ /** * Reference Specs: https://www.jedec.org/, 4.1 * - * Usage - * ----- - * - * Add options: - * -drive file=3D,if=3Dnone,id=3D - * -device ufs,serial=3D,id=3D, \ - * nutrs=3D,nutmrs=3D - * -device ufs-lu,drive=3D,bus=3D */ =20 #include "qemu/osdep.h" #include "qapi/error.h" -#include "migration/vmstate.h" #include "scsi/constants.h" #include "hw/core/irq.h" #include "trace.h" @@ -102,7 +93,7 @@ static MemTxResult ufs_addr_read(UfsHc *u, hwaddr addr, = void *buf, int size) return MEMTX_DECODE_ERROR; } =20 - return pci_dma_read(PCI_DEVICE(u), addr, buf, size); + return dma_memory_read(u->dma_as, addr, buf, size, MEMTXATTRS_UNSPECIF= IED); } =20 static MemTxResult ufs_addr_write(UfsHc *u, hwaddr addr, const void *buf, @@ -117,7 +108,7 @@ static MemTxResult ufs_addr_write(UfsHc *u, hwaddr addr= , const void *buf, return MEMTX_DECODE_ERROR; } =20 - return pci_dma_write(PCI_DEVICE(u), addr, buf, size); + return dma_memory_write(u->dma_as, addr, buf, size, MEMTXATTRS_UNSPECI= FIED); } =20 static inline hwaddr ufs_get_utrd_addr(UfsHc *u, uint32_t slot) @@ -222,7 +213,7 @@ static MemTxResult ufs_dma_read_prdt(UfsRequest *req) } =20 req->sg =3D g_malloc0(sizeof(QEMUSGList)); - pci_dma_sglist_init(req->sg, PCI_DEVICE(u), prdt_len); + qemu_sglist_init(req->sg, u->dev, prdt_len, u->dma_as); req->data_len =3D 0; =20 for (uint16_t i =3D 0; i < prdt_len; ++i) { @@ -317,14 +308,12 @@ static MemTxResult ufs_dma_write_upiu(UfsRequest *req) =20 static void ufs_irq_check(UfsHc *u) { - PCIDevice *pci =3D PCI_DEVICE(u); - if ((u->reg.is & UFS_INTR_MASK) & u->reg.ie) { trace_ufs_irq_raise(); - pci_irq_assert(pci); + qemu_irq_raise(u->irq); } else { trace_ufs_irq_lower(); - pci_irq_deassert(pci); + qemu_irq_lower(u->irq); } } =20 @@ -596,7 +585,7 @@ static bool ufs_mcq_create_sq(UfsHc *u, uint8_t qid, ui= nt32_t attr) sq->size =3D qsize; =20 sq->bh =3D qemu_bh_new_guarded(ufs_mcq_process_sq, sq, - &DEVICE(u)->mem_reentrancy_guard); + &u->dev->mem_reentrancy_guard); sq->req =3D g_new0(UfsRequest, sq->size); QTAILQ_INIT(&sq->req_list); for (int i =3D 0; i < sq->size; i++) { @@ -690,7 +679,7 @@ static bool ufs_mcq_create_cq(UfsHc *u, uint8_t qid, ui= nt32_t attr) cq->size =3D qsize; =20 cq->bh =3D qemu_bh_new_guarded(ufs_mcq_process_cq, cq, - &DEVICE(u)->mem_reentrancy_guard); + &u->dev->mem_reentrancy_guard); QTAILQ_INIT(&cq->req_list); =20 u->cq[qid] =3D cq; @@ -2488,19 +2477,6 @@ static bool ufs_check_constraints(UfsHc *u, Error **= errp) return true; } =20 -static void ufs_init_pci(UfsHc *u, PCIDevice *pci_dev) -{ - uint8_t *pci_conf =3D pci_dev->config; - - pci_conf[PCI_INTERRUPT_PIN] =3D 1; - pci_config_set_prog_interface(pci_conf, 0x1); - - memory_region_init_io(&u->iomem, OBJECT(u), &ufs_mmio_ops, u, "ufs", - u->reg_size); - pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &u->iomem); - u->irq =3D pci_allocate_irq(pci_dev); -} - static void ufs_init_state(UfsHc *u) { u->req_list =3D g_new0(UfsRequest, u->params.nutrs); @@ -2512,10 +2488,10 @@ static void ufs_init_state(UfsHc *u) u->req_list[i].state =3D UFS_REQUEST_IDLE; } =20 - u->doorbell_bh =3D qemu_bh_new_guarded(ufs_process_req, u, - &DEVICE(u)->mem_reentrancy_guard); - u->complete_bh =3D qemu_bh_new_guarded(ufs_sendback_req, u, - &DEVICE(u)->mem_reentrancy_guard); + u->doorbell_bh =3D + qemu_bh_new_guarded(ufs_process_req, u, &u->dev->mem_reentrancy_gu= ard); + u->complete_bh =3D + qemu_bh_new_guarded(ufs_sendback_req, u, &u->dev->mem_reentrancy_g= uard); =20 if (u->params.mcq) { memset(u->sq, 0, sizeof(u->sq)); @@ -2689,35 +2665,35 @@ static void ufs_init_hc(UfsHc *u) timer_mod(&u->idle_timer, now + UFS_IDLE_TIMER_TICK); } =20 -static void ufs_realize(PCIDevice *pci_dev, Error **errp) +bool ufs_realize(UfsHc *u, DeviceState *dev, AddressSpace *dma_as, Error *= *errp) { - UfsHc *u =3D UFS(pci_dev); + u->dev =3D dev; + u->dma_as =3D dma_as; =20 if (!ufs_check_constraints(u, errp)) { - return; + return false; } =20 - qbus_init(&u->bus, sizeof(UfsBus), TYPE_UFS_BUS, &pci_dev->qdev, - u->parent_obj.qdev.id); + qbus_init(&u->bus, sizeof(UfsBus), TYPE_UFS_BUS, dev, dev->id); + u->bus.hc =3D u; =20 ufs_init_state(u); ufs_init_hc(u); - ufs_init_pci(u, pci_dev); + memory_region_init_io(&u->iomem, OBJECT(dev), &ufs_mmio_ops, u, "ufs", + u->reg_size); =20 ufs_init_wlu(&u->report_wlu, UFS_UPIU_REPORT_LUNS_WLUN); ufs_init_wlu(&u->dev_wlu, UFS_UPIU_UFS_DEVICE_WLUN); ufs_init_wlu(&u->boot_wlu, UFS_UPIU_BOOT_WLUN); ufs_init_wlu(&u->rpmb_wlu, UFS_UPIU_RPMB_WLUN); + + return true; } =20 -static void ufs_exit(PCIDevice *pci_dev) +void ufs_unrealize(UfsHc *u) { - UfsHc *u =3D UFS(pci_dev); - timer_del(&u->idle_timer); =20 - qemu_free_irq(u->irq); - qemu_bh_delete(u->doorbell_bh); qemu_bh_delete(u->complete_bh); =20 @@ -2740,38 +2716,6 @@ static void ufs_exit(PCIDevice *pci_dev) } } =20 -static const Property ufs_props[] =3D { - DEFINE_PROP_STRING("serial", UfsHc, params.serial), - DEFINE_PROP_UINT8("nutrs", UfsHc, params.nutrs, 32), - DEFINE_PROP_UINT8("nutmrs", UfsHc, params.nutmrs, 8), - DEFINE_PROP_BOOL("mcq", UfsHc, params.mcq, false), - DEFINE_PROP_UINT8("mcq-maxq", UfsHc, params.mcq_maxq, 2), - DEFINE_PROP_UINT32("wb-max-size", UfsHc, params.wb_max_size, 0x400), - DEFINE_PROP_UINT32("wb-min-size", UfsHc, params.wb_min_size, 0x100), -}; - -static const VMStateDescription ufs_vmstate =3D { - .name =3D "ufs", - .unmigratable =3D 1, -}; - -static void ufs_class_init(ObjectClass *oc, const void *data) -{ - DeviceClass *dc =3D DEVICE_CLASS(oc); - PCIDeviceClass *pc =3D PCI_DEVICE_CLASS(oc); - - pc->realize =3D ufs_realize; - pc->exit =3D ufs_exit; - pc->vendor_id =3D PCI_VENDOR_ID_REDHAT; - pc->device_id =3D PCI_DEVICE_ID_REDHAT_UFS; - pc->class_id =3D PCI_CLASS_STORAGE_UFS; - - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->desc =3D "Universal Flash Storage"; - device_class_set_props(dc, ufs_props); - dc->vmsd =3D &ufs_vmstate; -} - static bool ufs_bus_check_address(BusState *qbus, DeviceState *qdev, Error **errp) { @@ -2798,14 +2742,6 @@ static void ufs_bus_class_init(ObjectClass *class, c= onst void *data) bc->check_address =3D ufs_bus_check_address; } =20 -static const TypeInfo ufs_info =3D { - .name =3D TYPE_UFS, - .parent =3D TYPE_PCI_DEVICE, - .class_init =3D ufs_class_init, - .instance_size =3D sizeof(UfsHc), - .interfaces =3D (const InterfaceInfo[]){ { INTERFACE_PCIE_DEVICE }, {}= }, -}; - static const TypeInfo ufs_bus_info =3D { .name =3D TYPE_UFS_BUS, .parent =3D TYPE_BUS, @@ -2816,7 +2752,6 @@ static const TypeInfo ufs_bus_info =3D { =20 static void ufs_register_types(void) { - type_register_static(&ufs_info); type_register_static(&ufs_bus_info); } =20 diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h index feb47f460d..aa8361d93d 100644 --- a/hw/ufs/ufs.h +++ b/hw/ufs/ufs.h @@ -11,9 +11,11 @@ #ifndef HW_UFS_UFS_H #define HW_UFS_UFS_H =20 -#include "hw/pci/pci_device.h" +#include "hw/core/qdev.h" #include "hw/scsi/scsi.h" #include "block/ufs.h" +#include "scsi/constants.h" +#include "system/dma.h" =20 #define UFS_MAX_LUS 32 #define UFS_MAX_MCQ_QNUM 32 @@ -27,6 +29,7 @@ typedef struct UfsBusClass { =20 typedef struct UfsBus { BusState parent_bus; + struct UfsHc *hc; } UfsBus; =20 #define TYPE_UFS_BUS "ufs-bus" @@ -141,7 +144,8 @@ typedef struct UfsWb { } UfsWb; =20 typedef struct UfsHc { - PCIDevice parent_obj; + DeviceState *dev; + AddressSpace *dma_as; UfsBus bus; MemoryRegion iomem; UfsReg reg; @@ -268,9 +272,6 @@ static inline bool ufs_is_write_req(UfsRequest *req) return (cmd =3D=3D WRITE_6) || (cmd =3D=3D WRITE_10) || (cmd =3D=3D WR= ITE_16); } =20 -#define TYPE_UFS "ufs" -#define UFS(obj) OBJECT_CHECK(UfsHc, (obj), TYPE_UFS) - #define TYPE_UFS_LU "ufs-lu" #define UFSLU(obj) OBJECT_CHECK(UfsLu, (obj), TYPE_UFS_LU) =20 @@ -302,4 +303,7 @@ void ufs_build_query_response(UfsRequest *req); void ufs_complete_req(UfsRequest *req, UfsReqResult req_result); void ufs_wb_update_avail_buffer(UfsHc *u); void ufs_init_wlu(UfsLu *wlu, uint8_t wlun); +bool ufs_realize(UfsHc *u, DeviceState *dev, AddressSpace *dma_as, + Error **errp); +void ufs_unrealize(UfsHc *u); #endif /* HW_UFS_UFS_H */ --=20 2.43.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787549331; cv=none; d=zohomail.com; s=zohoarc; b=EpV4cFGHPOS1fwDAW01fcLBNEZtcuA37ytqc99/47G8IZVEDi0ycL9CGDLRWqlTSTuRdCw5rOeC6alv7hGJvGrehdhC76Z8XosGCJOVXeXvsTEjlK+DzS8XohaD7ugfn7KAa2tuvCsxQ+C7Bm7whjvusoal5z6XhVxjSrSI4MdA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787549331; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GBf7j30tCwZkHaEPfJB/Zz5KRf4bjAJ+JkM3UIPIc40=; b=Ncx7wlFM7bPO/wEDlvZCMClOe1EbB+7bPoRS+QLuPcWabl+hxUkhYpKN0u4XiklsXWmUqH/MiSPc/+EtoEetlmbAhPBhgFDkkQlEIoeZsNV1TYmTFb7LGFhNKk9MhPQXx06HpBd4umMqO2d21z7MLaKscbdncIci/FHxXzTUXsc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787549331729286.6562609129709; Sun, 23 Aug 2026 22:28:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyNEL-0008M9-Rq; Mon, 24 Aug 2026 01:28:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyNEH-0008LN-C0 for qemu-devel@nongnu.org; Mon, 24 Aug 2026 01:28:17 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wyNEF-0006f6-NS for qemu-devel@nongnu.org; Mon, 24 Aug 2026 01:28:17 -0400 Received: by mail-pg1-x532.google.com with SMTP id 41be03b00d2f7-ca12086c06eso2310522a12.0 for ; Sun, 23 Aug 2026 22:28:15 -0700 (PDT) Received: from jeuk-MS-7D42.. ([211.226.54.223]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-395e494f9fdsm8557346a91.3.2026.08.23.22.28.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2026 22:28:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787549294; x=1788154094; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GBf7j30tCwZkHaEPfJB/Zz5KRf4bjAJ+JkM3UIPIc40=; b=Ee30XnYajfQoO3JYmuNfTI82rH6MfKBz+1A1Bgk3Wd7/uiz/zomLbYx41WxiDrZsz0 wSpRuifFD2wrGdWSYtQhLlwYrPEQ/HVMvOv5sWMZgUSTO1E159hhq7SrVi0K+Jfz5sVC qJMw30FSrfrTUIZy+NaUKH6HeeUYWii2VHrKUZUP3m0MP6dDtwUtTBSbD8W22xkbtWrk /Y+X5HhX7I4nieOMS1o853Lcv/H5KDHg6lByZiP3sigoqaUqKEPG0HfW2Ju4ILU2KnN7 O2cHXaorX0tnuQV0ZoxDnV9m/NvYdxR1+YQ8931INvA08hHhhCjeJnQji0tTKZ18YpeS xV+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787549294; x=1788154094; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=GBf7j30tCwZkHaEPfJB/Zz5KRf4bjAJ+JkM3UIPIc40=; b=LcO78nfvVzJ6JXGFvuuxg3KuhrygEUIlPsyHlgYss+2RclOKXDfgKOyC1SXcKdxICf ljxyH+4bY4fefovYAGEX4oPbdw3bcao4Ouaxuuz432s0H4nHYW8VJRdg6vSN9c13oAFP IAf4309DwmARx553cxsguiotsg+qj1s0ovrLIgPVGLoZz0yVtq8JAUumOWp4Hm9bpxoY zgH/LiBga2AOVg7CzPQV09N8BqQM4iz/4ZDLrWG/K+XNgq27qpgsYASC6ayTgYuAon32 ZMBXawjJN2i0B2wpw3h92CPdkRvZzI1fEhqG43jmcRP9nL+lTDtu8JLlA5QGQSquJR8D fvHA== X-Gm-Message-State: AFuF++mjVmOEv0vdielFGPSSdZe/h7FfxltyNjZuEiX9ZbGiIKH5dKYR Ib9jNUL/tycE8bGlNJNCGXQRNEpqmbKAe/7PzMEiyzcfriqZMBgDFaZ17lCU5Q== X-Gm-Gg: AR+sD10ZY5ndbBI5SnWWIayf+L/DsHmxzNpgd3tcd4B3XgGniygL8ndVJiePL9T0iJW hOB6b1otVjCJT0tYb0gw+1LqJ21Dtk6mtrM+HSOpPltIMv43jetn8OEq2pOjvVfEkoifdcISYtQ 31WAglCbFpuHLY/WpUDTJD6L5tfilGrVvHMyJXVmjSe9eF0QOFKUCp/SVhqWCQul+wNr8KE2sOf VKVWJA4hIzTHGlXHaMgB99jC2xVoYhErLqFHZ2W82jstscuS7mXBS/fC/hYnS07G7B7+Swsbb5f pGiSHkTACIrLJY1U5Fgb776q+tyOdBTYHOpW8MXeUZy/cKW+uTEIBSUMikm8TAGmM0UNgV/qdHp SWQJYTFgffILPO/QBVgOniI1uBHw3ZRfXAYI5Dn+hLZ7qbcvGyoASJB7/lxS4yiBCKye0hFMOQq cdz/aNytpSDVnjU4Hpc/ij/LSSGtx2dxSUjxdHr2lYVTr/yIlAboBs9aHdWe8jqIypdmahM91z3 S+s X-Received: by 2002:a17:90b:280a:b0:38e:bfe:81e9 with SMTP id 98e67ed59e1d1-395dee56103mr31979891a91.1.1787549293998; Sun, 23 Aug 2026 22:28:13 -0700 (PDT) From: Jeuk Kim To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, pbonzini@redhat.com, qemu-block@nongnu.org, jeuk20.kim@samsung.com, j-young.choi@samsung.com, mikail.sadic@ibm.com, clg@kaod.org, Jeuk Kim Subject: [PULL 2/2] hw/ufs: Add a generic SysBus frontend Date: Mon, 24 Aug 2026 14:27:56 +0900 Message-ID: <6ed05d5e65208a5ee23a02667d5df0dc6491c156.1787548791.git.jeuk20.kim@samsung.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::532; envelope-from=jeuk20.kim@gmail.com; helo=mail-pg1-x532.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1787549334169158500 Content-Type: text/plain; charset="utf-8" Add TYPE_SYSBUS_UFS as a reusable frontend for the transport-independent UFS controller core. Use the system memory address space for DMA, expose the controller MMIO region and IRQ through SysBus, and provide the same properties and migration policy as the PCI frontend. Platform-specific controllers can derive from this type and keep only their hardware-specific behavior. Signed-off-by: Jeuk Kim --- hw/ufs/Kconfig | 4 +++ hw/ufs/meson.build | 1 + hw/ufs/ufs-sysbus.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ hw/ufs/ufs-sysbus.h | 22 +++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 hw/ufs/ufs-sysbus.c create mode 100644 hw/ufs/ufs-sysbus.h diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig index 47e28a30ea..0e40f08a41 100644 --- a/hw/ufs/Kconfig +++ b/hw/ufs/Kconfig @@ -7,3 +7,7 @@ config UFS_PCI default y if PCI_DEVICES depends on PCI select UFS + +config UFS_SYSBUS + bool + select UFS diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build index 880fc52c05..a84627b96a 100644 --- a/hw/ufs/meson.build +++ b/hw/ufs/meson.build @@ -1,2 +1,3 @@ system_ss.add(when: 'CONFIG_UFS', if_true: files('ufs.c', 'lu.c')) system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs-pci.c')) +system_ss.add(when: 'CONFIG_UFS_SYSBUS', if_true: files('ufs-sysbus.c')) diff --git a/hw/ufs/ufs-sysbus.c b/hw/ufs/ufs-sysbus.c new file mode 100644 index 0000000000..84de2e95ac --- /dev/null +++ b/hw/ufs/ufs-sysbus.c @@ -0,0 +1,80 @@ +/* + * QEMU Universal Flash Storage (UFS) sysbus controller + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/core/qdev-properties.h" +#include "ufs-sysbus.h" +#include "migration/vmstate.h" +#include "system/address-spaces.h" + +static void ufs_sysbus_realize(DeviceState *dev, Error **errp) +{ + SysbusUfsState *s =3D SYSBUS_UFS(dev); + + if (!ufs_realize(&s->ufs, dev, &address_space_memory, errp)) { + return; + } + + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->ufs.iomem); +} + +static void ufs_sysbus_unrealize(DeviceState *dev) +{ + SysbusUfsState *s =3D SYSBUS_UFS(dev); + + ufs_unrealize(&s->ufs); +} + +static void ufs_sysbus_init(Object *obj) +{ + SysbusUfsState *s =3D SYSBUS_UFS(obj); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->ufs.irq); +} + +static const Property ufs_sysbus_props[] =3D { + DEFINE_PROP_STRING("serial", SysbusUfsState, ufs.params.serial), + DEFINE_PROP_UINT8("nutrs", SysbusUfsState, ufs.params.nutrs, 32), + DEFINE_PROP_UINT8("nutmrs", SysbusUfsState, ufs.params.nutmrs, 8), + DEFINE_PROP_BOOL("mcq", SysbusUfsState, ufs.params.mcq, false), + DEFINE_PROP_UINT8("mcq-maxq", SysbusUfsState, ufs.params.mcq_maxq, 2), + DEFINE_PROP_UINT32("wb-max-size", SysbusUfsState, ufs.params.wb_max_si= ze, + 0x400), + DEFINE_PROP_UINT32("wb-min-size", SysbusUfsState, ufs.params.wb_min_si= ze, + 0x100), +}; + +static const VMStateDescription ufs_sysbus_vmstate =3D { + .name =3D TYPE_SYSBUS_UFS, + .unmigratable =3D 1, +}; + +static void ufs_sysbus_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + + dc->realize =3D ufs_sysbus_realize; + dc->unrealize =3D ufs_sysbus_unrealize; + dc->vmsd =3D &ufs_sysbus_vmstate; + dc->desc =3D "Universal Flash Storage"; + device_class_set_props(dc, ufs_sysbus_props); + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo ufs_sysbus_info =3D { + .name =3D TYPE_SYSBUS_UFS, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(SysbusUfsState), + .instance_init =3D ufs_sysbus_init, + .class_init =3D ufs_sysbus_class_init, +}; + +static void ufs_sysbus_register_types(void) +{ + type_register_static(&ufs_sysbus_info); +} + +type_init(ufs_sysbus_register_types) diff --git a/hw/ufs/ufs-sysbus.h b/hw/ufs/ufs-sysbus.h new file mode 100644 index 0000000000..71b6787d3a --- /dev/null +++ b/hw/ufs/ufs-sysbus.h @@ -0,0 +1,22 @@ +/* + * QEMU Universal Flash Storage (UFS) sysbus controller + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_UFS_UFS_SYSBUS_H +#define HW_UFS_UFS_SYSBUS_H + +#include "hw/core/sysbus.h" +#include "ufs.h" + +#define TYPE_SYSBUS_UFS "sysbus-ufs" +OBJECT_DECLARE_SIMPLE_TYPE(SysbusUfsState, SYSBUS_UFS) + +struct SysbusUfsState { + SysBusDevice parent_obj; + + UfsHc ufs; +}; + +#endif /* HW_UFS_UFS_SYSBUS_H */ --=20 2.43.0