From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650480; cv=none; d=zohomail.com; s=zohoarc; b=G2M3NM4A05kHYt9f8O111WociC+lcboNlZy9x57pWBBA5kkGhGZI4O+FYlLV6zxPiNUb87Eg2EakdaSbwWhh5Bgq1q1HNkPuKjAPAB/MLOQQJ2CRY/lD6e0PHVgClC3IRKgm7vFv/XnoT+meeaFKr8czeFKyuncbVuIifjysjxk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650480; 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=MPk5kTHM2nqfPP3xg0dST9lJYKclk+CnfN+kSogBrTs=; b=GdF9yF5hic5Y7WsgvMLD1N170Dfcrqwv5DLwgjnaXkFoyUeyZLeJPW4fpNAWXOqcV1KViMQ/wNrG1czCIpOE0nudUVaTt8vB5aTNd6rvssQTZkmz9mURShKtoGOXKBfGwX24uZ7gIBE5MGtvEi9f8NGNseD7z21kcVs8dcp/u/A= 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 1784650480880119.99702896090616; Tue, 21 Jul 2026 09:14:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmD6h-0001Yt-Gk; Tue, 21 Jul 2026 12:14:11 -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 1wmD6f-0001Xi-Qp; Tue, 21 Jul 2026 12:14:09 -0400 Received: from m16.mail.163.com ([117.135.210.2]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD6Y-0006mh-TO; Tue, 21 Jul 2026 12:14:09 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S3; Wed, 22 Jul 2026 00:13:37 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=MP k5kTHM2nqfPP3xg0dST9lJYKclk+CnfN+kSogBrTs=; b=LjBO59jKnR2RBFU805 jTelDwRz0BfVDv6Ed915z5WcRTuvWb7hVufWcRkOeBm2hxfLAd9vtAAzFVQsR7dm WiyrMvIOuxyYILmNrgbmzK53jTcK26ChjiHETeGueIkw3BcZJR5biIi1exX9uGoB ApiuPowzR5nv571ZaS7e0ZfHU= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 1/7] hw/dma: add K230 gsdma Date: Wed, 22 Jul 2026 00:13:29 +0800 Message-ID: <20260721161335.73872-2-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S3 X-Coremail-Antispam: 1Uf129KBjvAXoWfXry8Gr48AryxAFWkZrWkJFb_yoW8ury3Co Z0q3Wjy3W5Jw47urs3GF12qF17t3yYgrsxXan5t390gFZrCr1vva4jvrs8Z3W5Jrs0kF45 WwnFqr1IvFWayF95n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjTRXL0eUUUUU X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC4hNFg2pfmrNpBwAA3F 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=117.135.210.2; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_MSPIKE_H2=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650483186158500 Content-Type: text/plain; charset="utf-8" K230 GSDMA includes SDMA (System Direct Memory Access) and GDMA (Graphic Di= rect Memory Access). In this patch, add SDMA for k230 board. The following features have not bee= n implemented: 1. axi protocol related 2. channel arbitration 3. lower power mode SDMA supports transfer data between memory, in which case SDMA is the contr= oller. It also supports transfer data to decomp_gzip and caching it through SRAM.=20 In this case, decomp_gzip is the controller, which controls SDMA through ha= ndshake signals. According to "K230 Technical Reference Manual v0.3.1" section 2.5.2. https://download.kendryte.com/developer/k230/HDK/K230%E7%A1%AC%E4%BB%B6%E6%= 96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf This commit includes: - K230 SDMA (System Direct Memory Access) model (k230_gsdma.c, k230_gsdma.h) - GSDMA trace log (trace-events) - Kconfig and meson.build Signed-off-by: Tao Ding --- hw/dma/Kconfig | 3 + hw/dma/k230_gsdma.c | 532 ++++++++++++++++++++++++++++++++++++ hw/dma/meson.build | 1 + hw/dma/trace-events | 6 + include/hw/dma/k230_gsdma.h | 128 +++++++++ 5 files changed, 670 insertions(+) create mode 100644 hw/dma/k230_gsdma.c create mode 100644 include/hw/dma/k230_gsdma.h diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig index 98fbb1bb04..0a23e7d7b8 100644 --- a/hw/dma/Kconfig +++ b/hw/dma/Kconfig @@ -30,3 +30,6 @@ config SIFIVE_PDMA config XLNX_CSU_DMA bool select REGISTER + +config K230_GSDMA + bool \ No newline at end of file diff --git a/hw/dma/k230_gsdma.c b/hw/dma/k230_gsdma.c new file mode 100644 index 0000000000..1f76f62fa0 --- /dev/null +++ b/hw/dma/k230_gsdma.c @@ -0,0 +1,532 @@ +/* + * Kendryte K230 GSDMA + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * GSDMA includes SDMA (System Direct Memory Access, K230 TRM section 10.2= ) and + * GDMA (Graphic Direct Memory Access, K230 TRM section 2.5.2). + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "migration/vmstate.h" +#include "system/address-spaces.h" +#include "hw/dma/k230_gsdma.h" +#include "hw/core/irq.h" +#include "trace.h" + +static void k230_gsdma_update_irq(K230GSDMAState *s) +{ + qemu_set_irq(s->irq, !!(s->dma_int_stat & ~s->dma_int_mask)); +} + +static bool k230_gsdma_decomp_enabled(K230GSDMAState *s) +{ + /* Only sdma channel 0 has decomp enable flag */ + return !!(s->channels[0].cfg & K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN); +} + +static bool k230_gsdma_read_sdma_llt(hwaddr addr, K230GSDMALLT *llt) +{ + bool ok =3D address_space_read(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, llt, + sizeof(*llt)) =3D=3D MEMTX_OK; + + if (ok) { + trace_k230_gsdma_read_sdma_llt(addr, le32_to_cpu(llt->cfg), + le32_to_cpu(llt->src_addr), + le32_to_cpu(llt->line_size), + le32_to_cpu(llt->line_cfg), + le32_to_cpu(llt->dst_addr), + le32_to_cpu(llt->next_llt_addr)); + } else { + trace_k230_gsdma_read_sdma_llt_failed(addr); + } + + return ok; +} + +static unsigned int k230_gsdma_usr_data_size(uint32_t cfg) +{ + /* decode usr_dat_size in CH_CFG register */ + switch (extract32(cfg, K230_GSDMA_CH_CFG_USR_DATA_SIZE_SHIFT, 2)) { + case 0: + return 1; + case 1: + return 2; + default: + return 4; + } +} + +static bool k230_gsdma_transfer_llt(K230GSDMAChannel *c, const K230GSDMALL= T *llt) +{ + uint32_t llt_cfg =3D le32_to_cpu(llt->cfg); + hwaddr src =3D le32_to_cpu(llt->src_addr); + hwaddr dst =3D le32_to_cpu(llt->dst_addr); + uint32_t line_size =3D le32_to_cpu(llt->line_size); + uint32_t line_cfg =3D le32_to_cpu(llt->line_cfg); + /* Number of lines required for 2d mode */ + uint32_t line_num =3D + (llt_cfg & K230_GSDMA_LLT_2D_MODE) ? extract32(line_cfg, 0, 16= ) : 1; + /* Stride line size required for 2d mode */ + uint32_t line_space =3D extract32(line_cfg, 16, 16); + + bool dat_mode =3D c->cfg & K230_GSDMA_CH_CFG_DAT_MODE; + bool src_fixed =3D c->cfg & K230_GSDMA_CH_CFG_SRC_FIXED; + bool dst_fixed =3D c->cfg & K230_GSDMA_CH_CFG_DST_FIXED; + + uint8_t buf[8]; /* K230 sdma axi data width is 64-bit */ + uint8_t fill[4]; /* Usr data is 32-bit*/ + unsigned int fill_len =3D k230_gsdma_usr_data_size(c->cfg); + uint32_t i; + + memcpy(fill, &c->usr_data, sizeof(fill)); + if (dat_mode) { + for (i =3D 0; i < (uint32_t)sizeof(buf); i++) { + buf[i] =3D fill[i % fill_len]; + } + } + + for (i =3D 0; i < line_num; i++) { + uint32_t remaining =3D line_size; + hwaddr line_src =3D src; + hwaddr line_dst =3D dst; + + while (remaining) { + uint32_t chunk =3D MIN(remaining, (uint32_t)sizeof(buf)); + + if (!dat_mode && address_space_read(&address_space_memory, lin= e_src, + MEMTXATTRS_UNSPECIFIED, buf, + chunk) !=3D MEMTX_OK) { + return false; + } + + if (address_space_write(&address_space_memory, line_dst, + MEMTXATTRS_UNSPECIFIED, buf, + chunk) !=3D MEMTX_OK) { + return false; + } + + if (!dat_mode && !src_fixed) { + line_src +=3D chunk; + } + if (!dst_fixed) { + line_dst +=3D chunk; + } + remaining -=3D chunk; + } + + if (!dat_mode) { + if (llt_cfg & K230_GSDMA_LLT_2D_MODE) { /*2d mode*/ + src +=3D line_size + line_space; + } else if (!src_fixed) { + src +=3D line_size; + } + } + + if (!dst_fixed) { + dst +=3D line_size; + } + } + + return true; +} + +static void k230_gsdma_sdma_set_idle(K230GSDMAChannel *c) +{ + c->status &=3D ~(K230_GSDMA_SDMA_STATUS_BUSY | K230_GSDMA_SDMA_STATUS_= PAUSE); + c->next_llt =3D 0; +} + +static void k230_gsdma_sdma_set_paused(K230GSDMAChannel *c, hwaddr next_ll= t) +{ + c->status &=3D ~K230_GSDMA_SDMA_STATUS_BUSY; + c->status |=3D K230_GSDMA_SDMA_STATUS_PAUSE; + c->next_llt =3D next_llt; +} + +static void k230_gsdma_run_sdma(K230GSDMAState *s, unsigned int ch, hwaddr= addr) +{ + K230GSDMAChannel *c =3D &s->channels[ch]; + + c->status &=3D ~K230_GSDMA_SDMA_STATUS_PAUSE; + c->status |=3D K230_GSDMA_SDMA_STATUS_BUSY; + c->next_llt =3D 0; + c->current_llt =3D addr; + + while (addr) { + K230GSDMALLT llt; + uint32_t cfg; + hwaddr next; + + if (!k230_gsdma_read_sdma_llt(addr, &llt)) { + k230_gsdma_sdma_set_idle(c); + return; + } + + cfg =3D le32_to_cpu(llt.cfg); + next =3D le32_to_cpu(llt.next_llt_addr); + c->current_llt =3D addr; + + if (!k230_gsdma_transfer_llt(c, &llt)) { + k230_gsdma_sdma_set_idle(c); + return; + } + + if (cfg & K230_GSDMA_LLT_NODE_INTR) { + s->dma_int_stat |=3D K230_GSDMA_SDMA_ITEM_INT(ch); + } + + if (cfg & K230_GSDMA_LLT_PAUSE) { + s->dma_int_stat |=3D K230_GSDMA_SDMA_PAUSE_INT(ch); + k230_gsdma_sdma_set_paused(c, next); + k230_gsdma_update_irq(s); + return; + } + + addr =3D next; + } + + s->dma_int_stat |=3D K230_GSDMA_SDMA_DONE_INT(ch); + k230_gsdma_sdma_set_idle(c); + k230_gsdma_update_irq(s); +} + +/* Decomp gzip request step sdma */ +static void k230_gsdma_step_sdma(K230GSDMAState *s, unsigned int ch, hwadd= r addr) +{ + K230GSDMAChannel *c =3D &s->channels[ch]; + K230GSDMALLT llt; + uint32_t cfg; + hwaddr next; + + if (!addr || !k230_gsdma_read_sdma_llt(addr, &llt)) { + k230_gsdma_sdma_set_idle(c); + return; + } + + cfg =3D le32_to_cpu(llt.cfg); + next =3D le32_to_cpu(llt.next_llt_addr); + + c->status |=3D K230_GSDMA_SDMA_STATUS_BUSY; + c->status &=3D ~K230_GSDMA_SDMA_STATUS_PAUSE; + c->current_llt =3D addr; + + if (!k230_gsdma_transfer_llt(c, &llt)) { + k230_gsdma_sdma_set_idle(c); + return; + } + + if (cfg & K230_GSDMA_LLT_NODE_INTR) { + s->dma_int_stat |=3D K230_GSDMA_SDMA_ITEM_INT(ch); + } + + c->status &=3D ~K230_GSDMA_SDMA_STATUS_BUSY; + c->next_llt =3D next; + if (next =3D=3D 0) { + s->dma_int_stat |=3D K230_GSDMA_SDMA_DONE_INT(ch); + } + + k230_gsdma_update_irq(s); +} + +static const VMStateDescription vmstate_k230_gsdma_channel =3D { + .name =3D "k230.gsdma.channel", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(ctl, K230GSDMAChannel), + VMSTATE_UINT32(status, K230GSDMAChannel), + VMSTATE_UINT32(cfg, K230GSDMAChannel), + VMSTATE_UINT32(usr_data, K230GSDMAChannel), + VMSTATE_UINT32(llt_saddr, K230GSDMAChannel), + VMSTATE_UINT32(current_llt, K230GSDMAChannel), + VMSTATE_UINT32(next_llt, K230GSDMAChannel), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_k230_gsdma =3D { + .name =3D "k230.gsdma", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(dma_ch_en, K230GSDMAState), + VMSTATE_UINT32(dma_int_mask, K230GSDMAState), + VMSTATE_UINT32(dma_int_stat, K230GSDMAState), + VMSTATE_UINT32(dma_cfg, K230GSDMAState), + VMSTATE_UINT32(dma_weight, K230GSDMAState), + VMSTATE_STRUCT_ARRAY(channels, K230GSDMAState, + K230_GSDMA_NUM_SDMA_CHANNELS, 2, + vmstate_k230_gsdma_channel, K230GSDMAChannel), + VMSTATE_END_OF_LIST() + } +}; + +static uint64_t k230_gsdma_read(void *opaque, hwaddr addr, unsigned int si= ze) +{ + K230GSDMAState *s =3D K230_GSDMA(opaque); + unsigned int ch; + hwaddr ch_off; + uint64_t ret =3D 0; + + switch (addr) { + case K230_GSDMA_DMA_CH_EN: + ret =3D s->dma_ch_en; + break; + case K230_GSDMA_DMA_INT_MASK: + ret =3D s->dma_int_mask; + break; + case K230_GSDMA_DMA_INT_STAT: + ret =3D s->dma_int_stat; + break; + case K230_GSDMA_DMA_CFG: + ret =3D s->dma_cfg; + break; + case K230_GSDMA_GDMA_CTRL: + case K230_GSDMA_GDMA_LLI_BASE: + case K230_GSDMA_GDMA_CURRENT_LLT: + case K230_GSDMA_GDMA_CH_CNT0 ... K230_GSDMA_GDMA_CH_CNT_LAST: + break; + case K230_GSDMA_DMA_WEIGHT: + ret =3D s->dma_weight; + break; + default: + break; + } + + ch =3D (addr - K230_GSDMA_CH_BASE) / K230_GSDMA_CH_STRIDE; + ch_off =3D (addr - K230_GSDMA_CH_BASE) % K230_GSDMA_CH_STRIDE; + if (ch < K230_GSDMA_NUM_SDMA_CHANNELS) { + switch (ch_off) { + case K230_GSDMA_CH_CTL: + break; + case K230_GSDMA_CH_STATUS: + ret =3D s->channels[ch].status; + break; + case K230_GSDMA_CH_CFG: + ret =3D s->channels[ch].cfg; + break; + case K230_GSDMA_CH_USR_DATA: + ret =3D s->channels[ch].usr_data; + break; + case K230_GSDMA_CH_LLT_SADDR: + ret =3D s->channels[ch].llt_saddr; + break; + case K230_GSDMA_CH_CURRENT_LLT: + ret =3D s->channels[ch].current_llt; + break; + default: + break; + } + } + + trace_k230_gsdma_read(addr, size, ret); + return ret; +} + +static void k230_gsdma_write_gdma(K230GSDMAState *s, hwaddr addr, uint32_t= value) +{ + switch (addr) { + case K230_GSDMA_GDMA_CTRL: + case K230_GSDMA_GDMA_LLI_BASE: + case K230_GSDMA_GDMA_CURRENT_LLT: + case K230_GSDMA_GDMA_CH_CNT0 ... K230_GSDMA_GDMA_CH_CNT_LAST: + return; + default: + return; + } +} + +static void k230_gsdma_write_channel(K230GSDMAState *s, unsigned int ch, + hwaddr ch_off, uint32_t value) +{ + K230GSDMAChannel *c =3D &s->channels[ch]; + bool handshake_mode =3D ch < 2 && k230_gsdma_decomp_enabled(s); + + switch (ch_off) { + case K230_GSDMA_CH_CTL: + c->ctl =3D value; + if ((value & K230_GSDMA_CTL_STOP) !=3D 0) { + c->started =3D false; + k230_gsdma_sdma_set_idle(c); + break; + } + if ((value & K230_GSDMA_CTL_RESUME) !=3D 0 && + (c->status & K230_GSDMA_SDMA_STATUS_PAUSE) && c->next_llt !=3D= 0) { + k230_gsdma_run_sdma(s, ch, c->next_llt); + break; + } + if (handshake_mode && (value & K230_GSDMA_CTL_START) !=3D 0) { + c->started =3D true; + c->status &=3D ~(K230_GSDMA_SDMA_STATUS_BUSY | + K230_GSDMA_SDMA_STATUS_PAUSE); + c->current_llt =3D 0; + c->next_llt =3D 0; + break; + } + if ((value & K230_GSDMA_CTL_START) !=3D 0 && + (s->dma_ch_en & BIT(ch)) && c->llt_saddr !=3D 0) { + c->started =3D true; + k230_gsdma_run_sdma(s, ch, c->llt_saddr); + } + break; + case K230_GSDMA_CH_CFG: + c->cfg =3D value; + break; + case K230_GSDMA_CH_USR_DATA: + c->usr_data =3D value; + break; + case K230_GSDMA_CH_LLT_SADDR: + c->llt_saddr =3D value; + break; + case K230_GSDMA_CH_CURRENT_LLT: + break; + default: + break; + } +} + +static void k230_gsdma_write(void *opaque, hwaddr addr, + uint64_t value, unsigned int size) +{ + K230GSDMAState *s =3D K230_GSDMA(opaque); + unsigned int ch; + hwaddr ch_off; + uint32_t v =3D value; + + trace_k230_gsdma_write(addr, size, value); + + switch (addr) { + case K230_GSDMA_DMA_CH_EN: + s->dma_ch_en =3D v & K230_GSDMA_DMA_CH_EN_MASK; + return; + case K230_GSDMA_DMA_INT_MASK: + s->dma_int_mask =3D v; + k230_gsdma_update_irq(s); + return; + case K230_GSDMA_DMA_INT_STAT: + s->dma_int_stat &=3D ~v; + k230_gsdma_update_irq(s); + return; + case K230_GSDMA_DMA_CFG: + s->dma_cfg =3D v; + return; + case K230_GSDMA_DMA_WEIGHT: + s->dma_weight =3D v & 0x00ffffff; + return; + default: + break; + } + + if (addr < K230_GSDMA_CH_BASE) { + k230_gsdma_write_gdma(s, addr, v); + return; + } + + ch =3D (addr - K230_GSDMA_CH_BASE) / K230_GSDMA_CH_STRIDE; + ch_off =3D (addr - K230_GSDMA_CH_BASE) % K230_GSDMA_CH_STRIDE; + if (ch >=3D K230_GSDMA_NUM_SDMA_CHANNELS) { + return; + } + + k230_gsdma_write_channel(s, ch, ch_off, v); +} + +static void k230_gsdma_handle_signal(void *opaque, int n, int level) +{ + K230GSDMAState *s =3D opaque; + K230GSDMAChannel *c; + hwaddr addr; + unsigned int ch; + + if (!level || n =3D=3D K230_GSDMA_GPIO_DECOMP_CTRL_EN) { + return; + } + + ch =3D n - 1; + + c =3D &s->channels[ch]; + if (!k230_gsdma_decomp_enabled(s) || !(s->dma_ch_en & BIT(ch)) || !c->= started) { + return; + } + + if (c->current_llt =3D=3D 0) { + addr =3D c->llt_saddr; + } else { + addr =3D c->next_llt; + } + if (!addr) { + return; + } + + k230_gsdma_step_sdma(s, ch, addr); + qemu_set_irq(s->handshake_out[n - 1], 1); + qemu_set_irq(s->handshake_out[n - 1], 0); +} + +static const MemoryRegionOps k230_gsdma_ops =3D { + .read =3D k230_gsdma_read, + .write =3D k230_gsdma_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl.min_access_size =3D 4, + .impl.max_access_size =3D 4, + .valid.min_access_size =3D 4, + .valid.max_access_size =3D 4, +}; + +static void k230_gsdma_reset(DeviceState *dev) +{ + K230GSDMAState *s =3D K230_GSDMA(dev); + + memset(s->channels, 0, sizeof(s->channels)); + s->dma_ch_en =3D 0; + s->dma_int_mask =3D 0; + s->dma_int_stat =3D 0; + s->dma_cfg =3D K230_GSDMA_DMA_CFG_RESET; + s->dma_weight =3D 0; +} + +static void k230_gsdma_realize(DeviceState *dev, Error **errp) +{ + K230GSDMAState *s =3D K230_GSDMA(dev); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + memory_region_init_io(&s->iomem, OBJECT(dev), &k230_gsdma_ops, s, + TYPE_K230_GSDMA, K230_GSDMA_MMIO_SIZE); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); + qdev_init_gpio_in(DEVICE(dev), k230_gsdma_handle_signal, + K230_GSDMA_NUM_GPIOS_IN); + qdev_init_gpio_out(DEVICE(dev), s->handshake_out, + K230_GSDMA_NUM_GPIOS_OUT); +} + +static void k230_gsdma_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D k230_gsdma_realize; + device_class_set_legacy_reset(dc, k230_gsdma_reset); + dc->vmsd =3D &vmstate_k230_gsdma; + dc->desc =3D "Kendryte K230 GSDMA"; +} + +static const TypeInfo k230_gsdma_info =3D { + .name =3D TYPE_K230_GSDMA, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(K230GSDMAState), + .class_init =3D k230_gsdma_class_init, +}; + +static void k230_gsdma_register_types(void) +{ + type_register_static(&k230_gsdma_info); +} + +type_init(k230_gsdma_register_types) diff --git a/hw/dma/meson.build b/hw/dma/meson.build index cc7810beb8..45db5e7357 100644 --- a/hw/dma/meson.build +++ b/hw/dma/meson.build @@ -12,3 +12,4 @@ system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_d= ma.c', 'soc_dma.c')) system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c')) system_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c')) system_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'= )) +system_ss.add(when: 'CONFIG_K230_GSDMA', if_true: files('k230_gsdma.c')) diff --git a/hw/dma/trace-events b/hw/dma/trace-events index 4c09790f9a..a494755b5a 100644 --- a/hw/dma/trace-events +++ b/hw/dma/trace-events @@ -47,3 +47,9 @@ pl330_iomem_read(uint32_t addr, uint32_t data) "addr: 0x%= 08"PRIx32" data: 0x%08" =20 # xilinx_axidma.c xilinx_axidma_loading_desc_fail(uint32_t res) "error:%u" + +# k230_gsdma.c +k230_gsdma_read(uint64_t addr, unsigned int size, uint64_t data) "K230 GSD= MA read: [0x%"PRIx64"] size %u -> 0x%"PRIx64 +k230_gsdma_write(uint64_t addr, unsigned int size, uint64_t data) "K230 GS= DMA write: [0x%"PRIx64"] size %u <- 0x%"PRIx64 +k230_gsdma_read_sdma_llt(uint64_t addr, uint32_t cfg, uint32_t src_addr, u= int32_t line_size, uint32_t line_cfg, uint32_t dst_addr, uint32_t next_llt_= addr) "K230 GSDMA read SDMA LLT: addr=3D0x%"PRIx64" cfg=3D0x%"PRIx32" src= =3D0x%"PRIx32" line_size=3D0x%"PRIx32" line_cfg=3D0x%"PRIx32" dst=3D0x%"PRI= x32" next=3D0x%"PRIx32 +k230_gsdma_read_sdma_llt_failed(uint64_t addr) "K230 GSDMA read SDMA LLT f= ailed: addr=3D0x%"PRIx64 diff --git a/include/hw/dma/k230_gsdma.h b/include/hw/dma/k230_gsdma.h new file mode 100644 index 0000000000..58aaa88674 --- /dev/null +++ b/include/hw/dma/k230_gsdma.h @@ -0,0 +1,128 @@ +/* + * K230 GSDMA + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_DMA_K230_GSDMA_H +#define HW_DMA_K230_GSDMA_H + +#include "hw/core/sysbus.h" + +#define TYPE_K230_GSDMA "riscv.k230.gsdma" +OBJECT_DECLARE_SIMPLE_TYPE(K230GSDMAState, K230_GSDMA) + +#define K230_GSDMA_MMIO_SIZE 0x4000 +#define K230_GSDMA_NUM_SDMA_CHANNELS 4 + +#define K230_GSDMA_CH_STRIDE 0x30 +#define K230_GSDMA_CH_BASE 0x50 + +/* K230 SDMA request input */ +enum { + K230_GSDMA_GPIO_DECOMP_CTRL_EN, + K230_GSDMA_GPIO_DMA_WRITE_REQ, + K230_GSDMA_GPIO_DMA_READ_REQ, + K230_GSDMA_NUM_GPIOS_IN, +}; + +/* K230 SDMA ACK output */ +enum { + K230_GSDMA_GPIO_DMA_WRITE_ACK, + K230_GSDMA_GPIO_DMA_READ_ACK, + K230_GSDMA_NUM_GPIOS_OUT, +}; + +/* K230 GSDMA Registers Map */ +#define K230_GSDMA_DMA_CH_EN 0x00 +#define K230_GSDMA_DMA_INT_MASK 0x04 +#define K230_GSDMA_DMA_INT_STAT 0x08 +#define K230_GSDMA_DMA_CFG 0x0c +#define K230_GSDMA_GDMA_CTRL 0x10 +#define K230_GSDMA_GDMA_LLI_BASE 0x14 +#define K230_GSDMA_GDMA_CH_CNT0 0x18 +#define K230_GSDMA_GDMA_CH_CNT_LAST 0x34 +#define K230_GSDMA_GDMA_CURRENT_LLT 0x38 +#define K230_GSDMA_DMA_WEIGHT 0x48 + +/* K230 GSDMA SDMA Channel Register Map */ +#define K230_GSDMA_CH_CTL 0x00 +#define K230_GSDMA_CH_STATUS 0x04 +#define K230_GSDMA_CH_CFG 0x08 +#define K230_GSDMA_CH_USR_DATA 0x0c +#define K230_GSDMA_CH_LLT_SADDR 0x10 +#define K230_GSDMA_CH_CURRENT_LLT 0x14 + +/* K230 SDMA Control bit */ +#define K230_GSDMA_CTL_START BIT(0) +#define K230_GSDMA_CTL_STOP BIT(1) +#define K230_GSDMA_CTL_RESUME BIT(2) + +/* K230 SDMA States bit */ +#define K230_GSDMA_SDMA_STATUS_BUSY BIT(0) +#define K230_GSDMA_SDMA_STATUS_PAUSE BIT(1) + +/* K230 SDMA Interrupt bit */ +#define K230_GSDMA_SDMA_DONE_INT(ch) BIT(ch) +#define K230_GSDMA_SDMA_ITEM_INT(ch) BIT((ch) + 4) +#define K230_GSDMA_SDMA_PAUSE_INT(ch) BIT((ch) + 8) + + +#define K230_GSDMA_DMA_CH_EN_MASK MAKE_64BIT_MASK(0, 5) +#define K230_GSDMA_DMA_CFG_RESET 0x000007ff + +/* K230 SDMA Linked List bit */ +#define K230_GSDMA_LLT_2D_MODE BIT(28) +#define K230_GSDMA_LLT_PAUSE BIT(29) +#define K230_GSDMA_LLT_NODE_INTR BIT(30) +#define K230_GSDMA_GDMA_LLT_GCH_SHIFT 16 +#define K230_GSDMA_GDMA_LLT_GCH_MASK 0x7 +#define K230_GSDMA_CH_CFG_DAT_MODE BIT(0) +#define K230_GSDMA_CH_CFG_USR_DATA_SIZE_SHIFT 1 +#define K230_GSDMA_CH_CFG_USR_DATA_SIZE_MASK 0x3 +#define K230_GSDMA_CH_CFG_SRC_FIXED BIT(8) +#define K230_GSDMA_CH_CFG_DST_FIXED BIT(9) +#define K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN BIT(10) + +/* K230 SDMA channel state */ +typedef struct K230GSDMAChannel { + uint32_t ctl; + uint32_t status; + uint32_t cfg; + uint32_t usr_data; + uint32_t llt_saddr; + uint32_t current_llt; + uint32_t next_llt; + bool started; +} K230GSDMAChannel; + +/* K230 SDMA Linked List */ +typedef struct K230GSDMALLT { + uint32_t cfg; + uint32_t src_addr; + uint32_t line_size; + uint32_t line_cfg; + uint32_t dst_addr; + uint32_t next_llt_addr; +} K230GSDMALLT; + +/* K230 GSDMA state */ +struct K230GSDMAState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + qemu_irq irq; + qemu_irq handshake_out[K230_GSDMA_NUM_GPIOS_OUT]; + + uint32_t dma_ch_en; + uint32_t dma_int_mask; + uint32_t dma_int_stat; + uint32_t dma_cfg; + uint32_t dma_weight; + + K230GSDMAChannel channels[K230_GSDMA_NUM_SDMA_CHANNELS]; +}; + +#endif --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650480; cv=none; d=zohomail.com; s=zohoarc; b=amHJVSOoUoLWFpbzNiBirswA6EdSTszN/5DOPeDAEeumsuDrROc33b9aQp7MZ62a3b+6z8AUcsVp+vTJtYdkBXdBE2C400Z2l6HxaHku//xyjWkH2ZV1M7hcNkgoAJrICCXSsTV5tu8t48+baWasVrjdj7hA4esn5iXwToukZAY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650480; 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=II50Fy3Cac6gbePrn/7n2QHXw40qsgBU7gkZi59lNOI=; b=TvVGXAKreYXhuHfPyBN65r29pau9N/2Q7ZXOOtcHOtgQqVxZ81Kre9DdWcXpXl+1g5mAVemGSwXdHEyoX+LBY+Cqmxq8pe4nld1o3ssTSDKV/OmTknpSSqHjfX6TKLfZu5Ff3TBRKs3246z8euNHSApbCSHQeYQYCCKpC8Bjsy8= 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 1784650480670341.2575509808929; Tue, 21 Jul 2026 09:14:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmD6f-0001Xd-VI; Tue, 21 Jul 2026 12:14:09 -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 1wmD6d-0001WH-VN; Tue, 21 Jul 2026 12:14:07 -0400 Received: from m16.mail.163.com ([220.197.31.2]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD6Y-0006mq-EU; Tue, 21 Jul 2026 12:14:07 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S4; Wed, 22 Jul 2026 00:13:40 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=II 50Fy3Cac6gbePrn/7n2QHXw40qsgBU7gkZi59lNOI=; b=gAWKurSub5AtPjJ7Np +PgQk3P+5n1BrskA5RzPRwvIohhjqrh/JbHuqCvoo2EC4/RgjUOrOl8x3d3GoMYf bLqsyrfTN0cpopSyVdhGp9WGkFBpvfoaBbkWTyi9Z6GQbIvdndaVVwGm6HCNgFOL 8PPFyXC73b4+1ePZc4TvsOm6E= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 2/7] hw/riscv: k230: add gsdma in K230 board Date: Wed, 22 Jul 2026 00:13:30 +0800 Message-ID: <20260721161335.73872-3-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S4 X-Coremail-Antispam: 1Uf129KBjvJXoWxWF4UAr43uw48Ar18tFy3XFb_yoW5AF45pF sxGFWqyrWrGFn3Aa1ftwsxuryqgwn5GFy3Cw1ru34rGrW7ArZ8tFs3u3WUZry8JFWvy345 CFyvka1Sk3W5Ww7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pR8hL8UUUUU= X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC4hRGhGpfmrRpCwAA3N 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=220.197.31.2; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650483020158500 Content-Type: text/plain; charset="utf-8" This commit replaces the unimplemented part of GSDMA in K230. And connect t= he interrupt to plic. Signed-off-by: Tao Ding --- hw/riscv/Kconfig | 1 + hw/riscv/k230.c | 12 +++++++++--- include/hw/riscv/k230.h | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index de37c08cae..d28ac06043 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -162,3 +162,4 @@ config K230 select SERIAL_MM select UNIMP select K230_WDT + select K230_GSDMA diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 656f28190c..c80bd65694 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -110,6 +110,7 @@ static void k230_soc_init(Object *obj) object_initialize_child(obj, "c908-cpu", cpu0, TYPE_RISCV_HART_ARRAY); object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT); object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT); + object_initialize_child(obj, "k230-gsdma", &s->gsdma, TYPE_K230_GSDMA); =20 qdev_prop_set_uint32(DEVICE(cpu0), "hartid-base", 0); qdev_prop_set_string(DEVICE(cpu0), "cpu-type", TYPE_RISCV_CPU_THEAD_C9= 08); @@ -206,6 +207,14 @@ static void k230_soc_realize(DeviceState *dev, Error *= *errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[1]), 0, qdev_get_gpio_in(DEVICE(s->c908_plic), K230_WDT1_IR= Q)); =20 + /* Gsdma */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gsdma), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gsdma), 0, memmap[K230_DEV_GSDMA].b= ase); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gsdma), 0, + qdev_get_gpio_in(DEVICE(s->c908_plic), K230_GSDMA_I= RQ)); + /* unimplemented devices */ create_unimplemented_device("kpu.l2-cache", memmap[K230_DEV_KPU_L2_CACHE].base, @@ -221,9 +230,6 @@ static void k230_soc_realize(DeviceState *dev, Error **= errp) memmap[K230_DEV_AI_2D_ENGINE].base, memmap[K230_DEV_AI_2D_ENGINE].size); =20 - create_unimplemented_device("gsdma", memmap[K230_DEV_GSDMA].base, - memmap[K230_DEV_GSDMA].size); - create_unimplemented_device("dma", memmap[K230_DEV_DMA].base, memmap[K230_DEV_DMA].size); =20 diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h index 592e1c26bf..156a386edc 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -18,6 +18,7 @@ #include "hw/core/boards.h" #include "hw/riscv/riscv_hart.h" #include "hw/watchdog/k230_wdt.h" +#include "hw/dma/k230_gsdma.h" =20 #define C908_CPU_HARTID (0) =20 @@ -33,6 +34,7 @@ typedef struct K230SoCState { RISCVHartArrayState c908_cpu; /* Small core */ =20 K230WdtState wdt[2]; + K230GSDMAState gsdma; MemoryRegion sram; MemoryRegion bootrom; =20 @@ -129,6 +131,7 @@ enum { K230_UART4_IRQ =3D 20, K230_WDT0_IRQ =3D 107, K230_WDT1_IRQ =3D 108, + K230_GSDMA_IRQ =3D 140, }; =20 #define K230_UART_COUNT 5 --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650490; cv=none; d=zohomail.com; s=zohoarc; b=FaOYA9Ebw+8eMSQa57lRbD1ydby384tqqQlx8Jjx4txKY93c18m5Nuxk8Mlgf2G8IxdKw7t325LJM6ZUjRfhFkn8PIXveGEuku/NuDsmNafOtSmeL35hz3mq7/2dLfNlSdFH64JF7w/QXfuiECm0+Blek9+cW9LrQzg6L5Q4v7Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650490; 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=4vnk1p9039nD7mfwuRDgrYA4OkRRl2hnRJuzTco98K8=; b=YrR4zjmH6hSwIjoY2c+rsvC/+qxehQg5XahYkv3PyYy+CGiCWKk+HOyXyuNIVQseOcWA+ERhBIT76MVIY2Fw59GSySQCCwACVzyOAU5q662njB2+WbmsIjrXdWbRQW+jRq1XRbsQ218E+2cd2LaiOkSICT+H9CjP5bFFxQcPu30= 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 1784650489925365.65781328168373; Tue, 21 Jul 2026 09:14:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmD6g-0001YW-Sv; Tue, 21 Jul 2026 12:14:10 -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 1wmD6e-0001Wt-Su; Tue, 21 Jul 2026 12:14:08 -0400 Received: from m16.mail.163.com ([117.135.210.2]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD6Z-0006mo-Nx; Tue, 21 Jul 2026 12:14:08 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S5; Wed, 22 Jul 2026 00:13:40 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=4v nk1p9039nD7mfwuRDgrYA4OkRRl2hnRJuzTco98K8=; b=gTZo9zzKGMNzfRxP0o w1ZjbLTcH6/s2WArKOUAbE104SbApzdU7YBoXsd/C3nNwmCTB1torgQ5IaWAXiTj tih5V8sEiV8fpKFONoCorXJ3+onOF3ovYYTiH3oQ6DuN3/YUtZqR3im5+fct52qZ z9+PBJqWgv2dBoiemQgLtMBFk= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 3/7] tests/qtest: add test for K230 gsdma Date: Wed, 22 Jul 2026 00:13:31 +0800 Message-ID: <20260721161335.73872-4-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S5 X-Coremail-Antispam: 1Uf129KBjvJXoW3XrWUAFyUWr4UZryDCF48Zwb_yoWfWFW8pa yFkryayr1jkF1rWanrJF1UA3Z8Wrn3Ga4rC3y5W34Uuw1xX3s8tFsIg34UXr98XrWkZryF 93WDKFn8WF1kJaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zMVbkUUUUUU= X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC-hRGhGpfmrRljgAA3Y 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=117.135.210.2; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_MSPIKE_H2=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650490792158500 Content-Type: text/plain; charset="utf-8" This commit adds test cases for GSDMA. Imitate the behavior of the driver, set LLT and sdma registers. After the data transmission is completed, check the destination address dat= a. Run this qtest: $ mkdir build && cd build && ../configure --target-list=3D"riscv64-soft= mmu" $ QTEST_QEMU_BINARY=3D./qemu-system-riscv64 tests/qtest/k230-gsdma-te= st Signed-off-by: Tao Ding --- tests/qtest/k230-gsdma-test.c | 201 ++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 2 +- 2 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 tests/qtest/k230-gsdma-test.c diff --git a/tests/qtest/k230-gsdma-test.c b/tests/qtest/k230-gsdma-test.c new file mode 100644 index 0000000000..44d4248739 --- /dev/null +++ b/tests/qtest/k230-gsdma-test.c @@ -0,0 +1,201 @@ +/* + * QTest testcase for K230 GSDMA + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "exec/hwaddr.h" +#include "hw/dma/k230_gsdma.h" +#include "libqtest.h" + +#define K230_GSDMA_BASE 0x80800000 +#define TEST_LLT_ADDR0 0x10000 +#define TEST_LLT_ADDR1 0x10040 +#define TEST_LLT_ADDR2 0x10080 + +#define TEST_SRC_ADDR0 0x20000 +#define TEST_SRC_ADDR1 0x22000 +#define TEST_SRC_ADDR2 0x23000 +#define TEST_DST_ADDR0 0x30000 +#define TEST_DST_ADDR1 0x32000 +#define TEST_DST_ADDR2 0x33000 + +static inline uint64_t gsdma_reg(hwaddr off) +{ + return K230_GSDMA_BASE + off; +} + +static inline uint64_t gsdma_ch_reg(unsigned int ch, hwaddr off) +{ + return K230_GSDMA_BASE + K230_GSDMA_CH_BASE + + ch * K230_GSDMA_CH_STRIDE + off; +} + +static void write_sdma_llt_node_full(QTestState *qts, hwaddr addr, + uint32_t cfg, hwaddr src, + uint32_t size, hwaddr dst, + hwaddr next) +{ + qtest_writel(qts, addr + offsetof(K230GSDMALLT, cfg), cfg); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, src_addr), src); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_size), size); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_cfg), 0x1); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, dst_addr), dst); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, next_llt_addr), next); +} + +static void write_sdma_llt_node(QTestState *qts, hwaddr addr, uint32_t cfg, + uint32_t next) +{ + write_sdma_llt_node_full(qts, addr, cfg, 0x11110000, 0x200, + 0x22220000, next); +} + +static void fill_pattern(uint8_t *buf, size_t size, uint8_t seed) +{ + for (size_t i =3D 0; i < size; i++) { + buf[i] =3D seed + i * 37; + } +} + +static void test_global_registers(void) +{ + QTestState *qts =3D qtest_init("-machine k230"); + + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_CFG)), =3D= =3D, + K230_GSDMA_DMA_CFG_RESET); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN), 0xff); + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN)), =3D= =3D, + K230_GSDMA_DMA_CH_EN_MASK); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_INT_MASK), 0x12345); + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_MASK)), = =3D=3D, + 0x12345); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CFG), 0xa5a5a5a5); + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_CFG)), =3D= =3D, + 0xa5a5a5a5); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_WEIGHT), 0xff55aa55); + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_WEIGHT)), = =3D=3D, + 0x55aa55); + + qtest_quit(qts); +} + +static void test_sdma_pause_resume(void) +{ + uint32_t int_stat; + QTestState *qts =3D qtest_init("-machine k230"); + + write_sdma_llt_node(qts, TEST_LLT_ADDR0, K230_GSDMA_LLT_PAUSE, + TEST_LLT_ADDR1); + write_sdma_llt_node(qts, TEST_LLT_ADDR1, K230_GSDMA_LLT_NODE_INTR, 0); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN), BIT(0)); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_A= DDR0); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_S= TART); + + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_STATUS)= ), =3D=3D, + K230_GSDMA_SDMA_STATUS_PAUSE); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CURRENT= _LLT)), + =3D=3D, TEST_LLT_ADDR0); + + int_stat =3D qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_PAUSE_INT(0), =3D=3D, + K230_GSDMA_SDMA_PAUSE_INT(0)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_DONE_INT(0), =3D=3D, 0); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT), int_stat); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_R= ESUME); + + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_STATUS)= ), =3D=3D, + 0); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CURRENT= _LLT)), + =3D=3D, TEST_LLT_ADDR1); + + int_stat =3D qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_DONE_INT(0), =3D=3D, + K230_GSDMA_SDMA_DONE_INT(0)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_ITEM_INT(0), =3D=3D, + K230_GSDMA_SDMA_ITEM_INT(0)); + + qtest_quit(qts); +} + +static void test_sdma_three_llt_copy(void) +{ + uint8_t src0[0x1000]; + uint8_t src1[1]; + uint8_t src2[511]; + uint8_t dst0[sizeof(src0)]; + uint8_t dst1[sizeof(src1)]; + uint8_t dst2[sizeof(src2)]; + uint32_t int_stat; + QTestState *qts =3D qtest_init("-machine k230"); + + fill_pattern(src0, sizeof(src0), 0x10); + fill_pattern(src1, sizeof(src1), 0x31); + fill_pattern(src2, sizeof(src2), 0x52); + memset(dst0, 0xa5, sizeof(dst0)); + memset(dst1, 0xa5, sizeof(dst1)); + memset(dst2, 0xa5, sizeof(dst2)); + + qtest_memwrite(qts, TEST_SRC_ADDR0, src0, sizeof(src0)); + qtest_memwrite(qts, TEST_SRC_ADDR1, src1, sizeof(src1)); + qtest_memwrite(qts, TEST_SRC_ADDR2, src2, sizeof(src2)); + qtest_memwrite(qts, TEST_DST_ADDR0, dst0, sizeof(dst0)); + qtest_memwrite(qts, TEST_DST_ADDR1, dst1, sizeof(dst1)); + qtest_memwrite(qts, TEST_DST_ADDR2, dst2, sizeof(dst2)); + + write_sdma_llt_node_full(qts, TEST_LLT_ADDR0, 0, TEST_SRC_ADDR0, + sizeof(src0), TEST_DST_ADDR0, TEST_LLT_ADDR1); + write_sdma_llt_node_full(qts, TEST_LLT_ADDR1, 0, TEST_SRC_ADDR1, + sizeof(src1), TEST_DST_ADDR1, TEST_LLT_ADDR2); + write_sdma_llt_node_full(qts, TEST_LLT_ADDR2, 0, TEST_SRC_ADDR2, + sizeof(src2), TEST_DST_ADDR2, 0); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN), BIT(0)); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_A= DDR0); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_S= TART); + + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_STATUS)= ), =3D=3D, + 0); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CURRENT= _LLT)), + =3D=3D, TEST_LLT_ADDR2); + + int_stat =3D qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_DONE_INT(0), =3D=3D, + K230_GSDMA_SDMA_DONE_INT(0)); + g_assert_cmphex(int_stat & K230_GSDMA_SDMA_PAUSE_INT(0), =3D=3D, 0); + + memset(dst0, 0, sizeof(dst0)); + memset(dst1, 0, sizeof(dst1)); + memset(dst2, 0, sizeof(dst2)); + qtest_memread(qts, TEST_DST_ADDR0, dst0, sizeof(dst0)); + qtest_memread(qts, TEST_DST_ADDR1, dst1, sizeof(dst1)); + qtest_memread(qts, TEST_DST_ADDR2, dst2, sizeof(dst2)); + + g_assert_cmpmem(dst0, sizeof(dst0), src0, sizeof(src0)); + g_assert_cmpmem(dst1, sizeof(dst1), src1, sizeof(src1)); + g_assert_cmpmem(dst2, sizeof(dst2), src2, sizeof(src2)); + + qtest_quit(qts); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/k230-gsdma/global-registers", test_global_registers); + qtest_add_func("/k230-gsdma/sdma-pause-resume", test_sdma_pause_resume= ); + qtest_add_func("/k230-gsdma/sdma-three-llt-copy", + test_sdma_three_llt_copy); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 56ff860e21..1b13a777c9 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -297,7 +297,7 @@ qtests_riscv64 =3D ['riscv-csr-test'] + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test'] : []) + (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test', 'k230-gsd= ma-test'] : []) =20 qtests_hexagon =3D ['boot-serial-test'] =20 --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650480; cv=none; d=zohomail.com; s=zohoarc; b=STB0H/Ocp0gC9csnYlkE5BCMI/gWRvo9+tPSl7atdHvGSNIJ6xDvWZZFjNDCW/DT4bi9Lz/lBYggvjb8vT3Q8ah55AWUIWR9nNSxxz9ETpoFgCdRcyfsA00/aOBOhVQ3I0zUuG8Jg7gNcn0uVaTLHaVJeKiuzXEL9oGyd3yHmQQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650480; 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=/6xFNW3nSjXVU6ABy2yqsYArc1MfpOsaiXfmBHVeH8I=; b=LdpIgNV4FD7YkVsaatER+BkueUCMDH3e0cAEt0k+3yFqveNXDqgIQopDx0u9caCMR4aVnfnOPyuJSRhKF+MGBzSpJUzQaA/F2tuYBbqht+BwjEY81Q8oBw4194LFDfjT4wAwlX6UI//6Lsudp9QgfHDDVZlY5VOHbh/z0V2uWbA= 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 1784650480986870.2559304690045; Tue, 21 Jul 2026 09:14:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmD6g-0001YS-Je; Tue, 21 Jul 2026 12:14:10 -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 1wmD6f-0001XX-L0; Tue, 21 Jul 2026 12:14:09 -0400 Received: from m16.mail.163.com ([117.135.210.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD6Y-0006mn-FL; Tue, 21 Jul 2026 12:14:09 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S6; Wed, 22 Jul 2026 00:13:40 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=/6 xFNW3nSjXVU6ABy2yqsYArc1MfpOsaiXfmBHVeH8I=; b=ZgtTMkddznxp9FJrZd McIl+xRBZz3l38y1K52dUP8GspCu+VZ3yu2Ex8vf4BK5kjNYVw3UInBotryNeDYr S6ybV//U8nU9oRou9w9UyB4R2KGRRdGUm3AqQ+FD2baZZM9NPQSv8qeCJZvXPpRc VO/r2jlepYRKvZRY0P+uhChqI= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 4/7] hw/misc: add K230 decomp gzip Date: Wed, 22 Jul 2026 00:13:32 +0800 Message-ID: <20260721161335.73872-5-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S6 X-Coremail-Antispam: 1Uf129KBjvAXoWfur1xJr1DtF1kCFW3Ary5Arb_yoW8ZFW5Co WavwsYq34UXFyxur4kArs29r43Xw4rGw4qgwn8C3s09a4rAr18GwnF9wn8Wa18Grs8tF93 XF1Yg3s7Jayqyryxn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjTRtKsUDUUUU X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC-RRGhGpfmrRfBAAA3r 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=117.135.210.5; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650483100158500 Content-Type: text/plain; charset="utf-8" Decompression accelerator is mainly used to implement hardware GZIP decompr= ession function. According to the k230 SDK, this hardware will be used during the uboot phas= e to decompress=20 compressed files.=20 Decomp_gzip does not have the ability to access the system bus.=20 Therefore, SDMA is required for data transmission. A typical scenario is SD= MA moving compressed=20 data from DDR to SRAM, and Decomp_gzip reading data from SRAM. After decomp= ression, decomp_gzip=20 writes the data back to SRAM, and SDMA moves the data from SRAM to DDR. According to "K230 Technical Reference Manual v0.3.1" section 15. https://download.kendryte.com/developer/k230/HDK/K230%E7%A1%AC%E4%BB%B6%E6%= 96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf Signed-off-by: Tao Ding --- hw/misc/Kconfig | 3 + hw/misc/k230_decomp_gzip.c | 498 +++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 4 + include/hw/misc/k230_decomp_gzip.h | 92 ++++++ 5 files changed, 598 insertions(+) create mode 100644 hw/misc/k230_decomp_gzip.c create mode 100644 include/hw/misc/k230_decomp_gzip.h diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1543ee6653..28687482f8 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -257,4 +257,7 @@ config XLNX_VERSAL_TRNG config XLNX_ZYNQ_DDRC bool =20 +config K230_DECOMP_GZIP + bool + source macio/Kconfig diff --git a/hw/misc/k230_decomp_gzip.c b/hw/misc/k230_decomp_gzip.c new file mode 100644 index 0000000000..4284262259 --- /dev/null +++ b/hw/misc/k230_decomp_gzip.c @@ -0,0 +1,498 @@ +/* + * Kendryte K230 GZIP decompression engine + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Decompression accelerator is mainly used to implement hardware + * GZIP decompression function. (K230 TRM section 15) + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "hw/core/qdev-properties.h" +#include "migration/vmstate.h" +#include "system/address-spaces.h" +#include "hw/core/irq.h" +#include "hw/misc/k230_decomp_gzip.h" +#include "trace.h" + +#define GZIP_METHOD_DEFLATE 8 +#define GZIP_METHOD_VENDOR_9 9 + + +#define K230_DECOMP_GZIP_OUTPUT_SLOTS 4 +#define K230_DECOMP_GZIP_INPUT_SLOTS 2 + +static void k230_decomp_gzip_set_output(K230DecompGzipState *s, int line, + int level) +{ + qemu_set_irq(s->signal_out[line], level); +} + +static bool k230_decomp_gzip_read_mem(K230DecompGzipState *s, hwaddr addr, + void *buf, size_t len) +{ + MemTxResult ret =3D address_space_read(&address_space_memory, + s->sram_base + addr, + MEMTXATTRS_UNSPECIFIED, buf, len); + + return ret =3D=3D MEMTX_OK; +} + +static bool k230_decomp_gzip_write_mem(K230DecompGzipState *s, hwaddr addr, + const void *buf, size_t len) +{ + return address_space_write(&address_space_memory, s->sram_base + addr, + MEMTXATTRS_UNSPECIFIED, buf, len) =3D=3D ME= MTX_OK; +} + +static hwaddr k230_decomp_gzip_output_addr(K230DecompGzipState *s) +{ + return K230_DECOMP_GZIP_SRAM_OUT_BASE + + s->output.slot * K230_DECOMP_GZIP_BLOCK_SIZE + + s->output.current_offset; +} + +static hwaddr k230_decomp_gzip_input_addr(K230DecompGzipState *s) +{ + return s->input.slot * K230_DECOMP_GZIP_BLOCK_SIZE + + K230_DECOMP_GZIP_SRAM_IN_BASE; +} + +static uint32_t k230_decomp_gzip_current_input_size(K230DecompGzipState *s) +{ + if (s->total_requested =3D=3D 0) { + return 0; + } + + return ((s->total_requested - 1) % K230_DECOMP_GZIP_BLOCK_SIZE) + 1; +} + +static void k230_decomp_gzip_update_ctrl_en(K230DecompGzipState *s) +{ + int level =3D s->active && !!(s->gzip_src_size & K230_DECOMP_GZIP_CTRL= _EN); + + k230_decomp_gzip_set_output(s, K230_DECOMP_GZIP_GPIO_DECOMP_CTRL_EN, + level); +} + +static void k230_decomp_gzip_reset_stream(K230DecompGzipState *s) +{ + if (s->zstream_inited) { + inflateEnd(&s->zs); + s->zstream_inited =3D false; + } + memset(&s->zs, 0, sizeof(s->zs)); +} + +static void k230_decomp_gzip_finish(K230DecompGzipState *s, bool crc_ok) +{ + s->active =3D false; + k230_decomp_gzip_reset_stream(s); + k230_decomp_gzip_update_ctrl_en(s); + if (crc_ok) { + s->decomp_stat |=3D K230_DECOMP_GZIP_STAT_CRC_OK; + } else { + s->decomp_stat &=3D ~K230_DECOMP_GZIP_STAT_CRC_OK; + } +} + +static bool k230_decomp_gzip_load_input(K230DecompGzipState *s, + uint32_t addr, uint32_t size) +{ + s->input.current_offset =3D 0; + + return k230_decomp_gzip_read_mem(s, addr, s->input_buf, size); +} + +static bool k230_decomp_gzip_request_input(K230DecompGzipState *s) +{ + uint32_t total_requested =3D s->total_requested; + + k230_decomp_gzip_set_output(s, K230_DECOMP_GZIP_GPIO_DMA_WRITE_REQ, 1); + if (s->total_requested =3D=3D total_requested) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: dma write request not acknowledged\n", + TYPE_K230_DECOMP_GZIP); + return false; + } + return true; +} + +static bool k230_decomp_gzip_request_output(K230DecompGzipState *s) +{ + uint32_t slot =3D s->output.slot; + uint32_t current_offset =3D s->output.current_offset; + + k230_decomp_gzip_set_output(s, K230_DECOMP_GZIP_GPIO_DMA_READ_REQ, 1); + if (s->output.slot =3D=3D slot && + s->output.current_offset =3D=3D current_offset) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: dma read request not acknowledged\n", + TYPE_K230_DECOMP_GZIP); + return false; + } + return true; +} + +static bool k230_decomp_gzip_init_stream(K230DecompGzipState *s) +{ + /* The compression script for K230 will modify the third byte to 0x9 */ + if (s->input_buf[2] =3D=3D GZIP_METHOD_VENDOR_9) { + s->input_buf[2] =3D GZIP_METHOD_DEFLATE; + } + + if (inflateInit2(&s->zs, 15 + 16) !=3D Z_OK) { + return false; + } + + s->zstream_inited =3D true; + return true; +} + +static bool k230_decomp_gzip_run_inflate(K230DecompGzipState *s) +{ + uint32_t output_size =3D s->gzip_out_size; + uint32_t current_input_size =3D k230_decomp_gzip_current_input_size(s); + uint32_t avail_in; + uint32_t avail_out; + uint32_t consumed; + uint32_t produced; + int ret; + + avail_in =3D current_input_size - s->input.current_offset; + avail_out =3D K230_DECOMP_GZIP_BLOCK_SIZE - s->output.current_offset; + + s->zs.next_in =3D s->input_buf + s->input.current_offset; + s->zs.avail_in =3D avail_in; + s->zs.next_out =3D s->output_buf; + s->zs.avail_out =3D avail_out; + + ret =3D inflate(&s->zs, Z_NO_FLUSH); + if (ret !=3D Z_OK && ret !=3D Z_STREAM_END && ret !=3D Z_BUF_ERROR) { + return false; + } + + consumed =3D avail_in - s->zs.avail_in; + produced =3D avail_out - s->zs.avail_out; + + if (produced) { + if (s->total_produced + produced > output_size || + !k230_decomp_gzip_write_mem(s, k230_decomp_gzip_output_addr(s), + s->output_buf, produced)) { + return false; + } + s->output.current_offset +=3D produced; + s->total_produced +=3D produced; + } + + if (consumed) { + s->input.current_offset +=3D consumed; + } + + if (ret =3D=3D Z_STREAM_END) { + s->stream_end =3D true; + if (s->total_produced !=3D output_size) { + return false; + } + } + + return true; +} + +static void k230_decomp_gzip_kick(K230DecompGzipState *s) +{ + if (!s->active || s->in_kick) { + return; + } + + uint32_t input_size =3D s->gzip_src_size & K230_DECOMP_GZIP_DMA_IN_MAS= K; + s->in_kick =3D true; + while (s->active) { + uint32_t current_input_size =3D k230_decomp_gzip_current_input_siz= e(s); + /* Output is full or last block */ + if (s->output.current_offset =3D=3D K230_DECOMP_GZIP_BLOCK_SIZE || + (s->stream_end && s->output.current_offset !=3D 0)) { + if (!k230_decomp_gzip_request_output(s)) { + k230_decomp_gzip_finish(s, false); + break; + } + continue; + } + + if (!s->zstream_inited) { + if (!k230_decomp_gzip_request_input(s) || + !k230_decomp_gzip_init_stream(s)) { + k230_decomp_gzip_finish(s, false); + break; + } + continue; + } + + /* Transfer finish */ + if (s->stream_end) { + k230_decomp_gzip_finish(s, + s->total_produced =3D=3D s->gzip_out_s= ize); + break; + } + + /* Input buf has has been fully decompreed, need request more */ + if (s->input.current_offset =3D=3D current_input_size) { + if (s->total_requested < input_size) { + if (!k230_decomp_gzip_request_input(s)) { + k230_decomp_gzip_finish(s, false); + break; + } + continue; + } + k230_decomp_gzip_finish(s, false); + break; + } + + /* Decompress the data, input buf or output buf are consumed in on= e block */ + if (!k230_decomp_gzip_run_inflate(s)) { + k230_decomp_gzip_finish(s, false); + break; + } + } + s->in_kick =3D false; +} + +static void k230_decomp_gzip_handle_ack(void *opaque, int n, int level) +{ + K230DecompGzipState *s =3D opaque; + + if (!level || !s->active) { + return; + } + + switch (n) { + case K230_DECOMP_GZIP_GPIO_DMA_WRITE_ACK: + { + uint32_t input_size =3D s->gzip_src_size & K230_DECOMP_GZIP_DMA_IN= _MASK; + uint32_t chunk =3D MIN(K230_DECOMP_GZIP_BLOCK_SIZE, + input_size - s->total_requested); + + if (!k230_decomp_gzip_load_input(s, k230_decomp_gzip_input_addr(s), + chunk)) { + k230_decomp_gzip_finish(s, false); + return; + } + s->total_requested +=3D chunk; + s->input.slot =3D (s->input.slot + 1) % K230_DECOMP_GZIP_INPUT_SLO= TS; + break; + } + case K230_DECOMP_GZIP_GPIO_DMA_READ_ACK: + if (s->output.current_offset =3D=3D 0) { + k230_decomp_gzip_finish(s, false); + return; + } + s->output.slot =3D (s->output.slot + 1) % K230_DECOMP_GZIP_OUTPUT_= SLOTS; + s->output.current_offset =3D 0; + break; + default: + return; + } + + k230_decomp_gzip_kick(s); +} + +static void k230_decomp_gzip_start(K230DecompGzipState *s) +{ + uint32_t input_size =3D s->gzip_src_size & K230_DECOMP_GZIP_DMA_IN_MAS= K; + + k230_decomp_gzip_reset_stream(s); + s->decomp_stat &=3D ~K230_DECOMP_GZIP_STAT_CRC_OK; + s->total_requested =3D 0; + s->total_produced =3D 0; + s->stream_end =3D false; + memset(&s->input, 0, sizeof(s->input)); + memset(&s->output, 0, sizeof(s->output)); + + if (!(s->gzip_src_size & K230_DECOMP_GZIP_CTRL_EN) || + input_size =3D=3D 0 || s->gzip_out_size =3D=3D 0) { + k230_decomp_gzip_finish(s, false); + return; + } + + s->active =3D true; + k230_decomp_gzip_update_ctrl_en(s); + k230_decomp_gzip_kick(s); +} + +static uint64_t k230_decomp_gzip_read(void *opaque, hwaddr offset, + unsigned size) +{ + K230DecompGzipState *s =3D opaque; + uint64_t value =3D 0; + + switch (offset) { + case K230_DECOMP_GZIP_DECOMP_START: + value =3D s->decomp_start; + break; + case K230_DECOMP_GZIP_GZIP_SRC_SIZE: + value =3D s->gzip_src_size; + break; + case K230_DECOMP_GZIP_GZIP_OUT_SIZE: + value =3D s->gzip_out_size; + break; + case K230_DECOMP_GZIP_DECOMP_STAT: + value =3D s->decomp_stat; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad read offset 0x%" HWADDR_PRIx "\n", + TYPE_K230_DECOMP_GZIP, offset); + break; + } + + trace_k230_decomp_gzip_read(offset, size, value); + return value; +} + +static void k230_decomp_gzip_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + K230DecompGzipState *s =3D opaque; + + trace_k230_decomp_gzip_write(offset, size, value); + + switch (offset) { + case K230_DECOMP_GZIP_DECOMP_START: + s->decomp_start =3D value; + if (value & K230_DECOMP_GZIP_START) { + k230_decomp_gzip_start(s); + } + break; + case K230_DECOMP_GZIP_GZIP_SRC_SIZE: + s->gzip_src_size =3D value; + k230_decomp_gzip_update_ctrl_en(s); + break; + case K230_DECOMP_GZIP_GZIP_OUT_SIZE: + s->gzip_out_size =3D value; + break; + case K230_DECOMP_GZIP_DECOMP_STAT: + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad write offset 0x%" HWADDR_PRIx "\n", + TYPE_K230_DECOMP_GZIP, offset); + break; + } +} + +static const MemoryRegionOps k230_decomp_gzip_ops =3D { + .read =3D k230_decomp_gzip_read, + .write =3D k230_decomp_gzip_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 4, + .valid.max_access_size =3D 4, + .impl.min_access_size =3D 4, + .impl.max_access_size =3D 4, +}; + +static const VMStateDescription vmstate_k230_decomp_gzip_slot =3D { + .name =3D "k230.decomp-gzip.slot", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(slot, K230DecompGzipSlotState), + VMSTATE_UINT32(current_offset, K230DecompGzipSlotState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_k230_decomp_gzip =3D { + .name =3D "k230.decomp-gzip", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(decomp_start, K230DecompGzipState), + VMSTATE_UINT32(gzip_src_size, K230DecompGzipState), + VMSTATE_UINT32(gzip_out_size, K230DecompGzipState), + VMSTATE_UINT32(decomp_stat, K230DecompGzipState), + VMSTATE_STRUCT(input, K230DecompGzipState, 1, + vmstate_k230_decomp_gzip_slot, + K230DecompGzipSlotState), + VMSTATE_STRUCT(output, K230DecompGzipState, 1, + vmstate_k230_decomp_gzip_slot, + K230DecompGzipSlotState), + VMSTATE_UINT32(total_requested, K230DecompGzipState), + VMSTATE_UINT32(total_produced, K230DecompGzipState), + VMSTATE_BOOL(active, K230DecompGzipState), + VMSTATE_BOOL(in_kick, K230DecompGzipState), + VMSTATE_BOOL(zstream_inited, K230DecompGzipState), + VMSTATE_BOOL(stream_end, K230DecompGzipState), + VMSTATE_UINT8_ARRAY(input_buf, K230DecompGzipState, + K230_DECOMP_GZIP_BLOCK_SIZE), + VMSTATE_UINT8_ARRAY(output_buf, K230DecompGzipState, + K230_DECOMP_GZIP_BLOCK_SIZE), + VMSTATE_END_OF_LIST() + } +}; + +static void k230_decomp_gzip_reset(DeviceState *dev) +{ + K230DecompGzipState *s =3D K230_DECOMP_GZIP(dev); + + k230_decomp_gzip_reset_stream(s); + memset(&s->zs, 0, sizeof(s->zs)); + s->decomp_start =3D 0; + s->gzip_src_size =3D 0; + s->gzip_out_size =3D 0; + s->decomp_stat =3D 0; + memset(&s->input, 0, sizeof(s->input)); + memset(&s->output, 0, sizeof(s->output)); + s->total_requested =3D 0; + s->total_produced =3D 0; + s->active =3D false; + s->in_kick =3D false; + s->stream_end =3D false; +} + +static void k230_decomp_gzip_realize(DeviceState *dev, Error **errp) +{ + K230DecompGzipState *s =3D K230_DECOMP_GZIP(dev); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + memory_region_init_io(&s->iomem, OBJECT(dev), &k230_decomp_gzip_ops, s, + TYPE_K230_DECOMP_GZIP, + K230_DECOMP_GZIP_MMIO_SIZE); + sysbus_init_mmio(sbd, &s->iomem); + qdev_init_gpio_in(dev, k230_decomp_gzip_handle_ack, + K230_DECOMP_GZIP_NUM_GPIOS_IN); + qdev_init_gpio_out(dev, s->signal_out, + K230_DECOMP_GZIP_NUM_GPIOS_OUT); +} + +static const Property k230_decomp_gzip_properties[] =3D { + DEFINE_PROP_UINT64("sram-base", K230DecompGzipState, sram_base, 0), +}; + +static void k230_decomp_gzip_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + + dc->realize =3D k230_decomp_gzip_realize; + device_class_set_legacy_reset(dc, k230_decomp_gzip_reset); + device_class_set_props(dc, k230_decomp_gzip_properties); + dc->vmsd =3D &vmstate_k230_decomp_gzip; + dc->desc =3D "Kendryte K230 GZIP decompression engine"; +} + +static const TypeInfo k230_decomp_gzip_info =3D { + .name =3D TYPE_K230_DECOMP_GZIP, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(K230DecompGzipState), + .class_init =3D k230_decomp_gzip_class_init, +}; + +static void k230_decomp_gzip_register_types(void) +{ + type_register_static(&k230_decomp_gzip_info); +} + +type_init(k230_decomp_gzip_register_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..6f6bf3c85c 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -36,6 +36,7 @@ system_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: file= s('sifive_e_prci.c')) system_ss.add(when: 'CONFIG_SIFIVE_E_AON', if_true: files('sifive_e_aon.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: files('sifive_u_prci.= c')) +system_ss.add(when: 'CONFIG_K230_DECOMP_GZIP', if_true: files('k230_decomp= _gzip.c')) =20 subdir('macio') =20 diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c9a868b3ef..16db4ba0cc 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -442,3 +442,7 @@ iommu_testdev_dma_read(uint64_t gva, uint32_t len) "gva= =3D0x%" PRIx64 " len=3D%u" iommu_testdev_dma_verify(uint32_t expected, uint32_t actual) "expected=3D0= x%x actual=3D0x%x" iommu_testdev_dma_result(uint32_t result) "DMA completed result=3D0x%x" iommu_testdev_dma_armed(bool armed) "armed=3D%d" + +# k230_decomp_gzip.c +k230_decomp_gzip_read(uint64_t offset, unsigned int size, uint64_t value) = "K230 DECOMP GZIP read: [0x%"PRIx64"] size %u -> 0x%"PRIx64 +k230_decomp_gzip_write(uint64_t offset, unsigned int size, uint64_t value)= "K230 DECOMP GZIP write: [0x%"PRIx64"] size %u <- 0x%"PRIx64 diff --git a/include/hw/misc/k230_decomp_gzip.h b/include/hw/misc/k230_deco= mp_gzip.h new file mode 100644 index 0000000000..9911af0095 --- /dev/null +++ b/include/hw/misc/k230_decomp_gzip.h @@ -0,0 +1,92 @@ +/* + * K230 Decompress Engine + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_K230_DECOMP_GZIP_H +#define HW_MISC_K230_DECOMP_GZIP_H + +#include +#include "hw/core/sysbus.h" + +#define TYPE_K230_DECOMP_GZIP "riscv.k230.decomp-gzip" +OBJECT_DECLARE_SIMPLE_TYPE(K230DecompGzipState, K230_DECOMP_GZIP) + +/* K230 DECOMP GZIP ACK input */ +enum { + K230_DECOMP_GZIP_GPIO_DMA_WRITE_ACK, + K230_DECOMP_GZIP_GPIO_DMA_READ_ACK, + K230_DECOMP_GZIP_NUM_GPIOS_IN, +}; + +/* K230 DECOMP GZIP REQ output */ +enum { + K230_DECOMP_GZIP_GPIO_DECOMP_CTRL_EN, + K230_DECOMP_GZIP_GPIO_DMA_WRITE_REQ, + K230_DECOMP_GZIP_GPIO_DMA_READ_REQ, + K230_DECOMP_GZIP_NUM_GPIOS_OUT, +}; + +#define K230_DECOMP_GZIP_MMIO_SIZE 0x4000 + +/* K230 DECOMP GZIP Registers map */ +/* Start decompression controller */ +#define K230_DECOMP_GZIP_DECOMP_START 0x00 +/* Source data length register */ +#define K230_DECOMP_GZIP_GZIP_SRC_SIZE 0x04 +/* Output data length register */ +#define K230_DECOMP_GZIP_GZIP_OUT_SIZE 0x08 +/* Decompress status register */ +#define K230_DECOMP_GZIP_DECOMP_STAT 0x0c + +/* Start decompression controller */ +#define K230_DECOMP_GZIP_START (1U << 0) + +#define K230_DECOMP_GZIP_CTRL_EN (1U << 31) +#define K230_DECOMP_GZIP_DMA_IN_MASK 0x7fffffffU + +#define K230_DECOMP_GZIP_STAT_CRC_OK (1U << 10) +#define K230_DECOMP_GZIP_STAT_STATE_MASK 0xfU + +#define K230_DECOMP_GZIP_BLOCK_SIZE 0x00020000 +#define K230_DECOMP_GZIP_SRAM_IN_BASE 0x80000 +#define K230_DECOMP_GZIP_SRAM_OUT_BASE 0 + +typedef struct K230DecompGzipSlotState { + uint32_t slot; /* Slot index */ + /* + * Data offset in current slot. + * First valid data in input buffer. Last valid data in output buffer. + */ + uint32_t current_offset; +} K230DecompGzipSlotState; + +struct K230DecompGzipState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + hwaddr sram_base; + qemu_irq signal_out[K230_DECOMP_GZIP_NUM_GPIOS_OUT]; + uint32_t decomp_start; + uint32_t gzip_src_size; + uint32_t gzip_out_size; + uint32_t decomp_stat; + K230DecompGzipSlotState input; /* decomp gzip ring input */ + K230DecompGzipSlotState output; /* decomp gzip ring output */ + uint32_t total_requested; + uint32_t total_produced; + bool active; + bool in_kick; + bool zstream_inited; + bool stream_end; + /* Read from ring input. */ + uint8_t input_buf[K230_DECOMP_GZIP_BLOCK_SIZE]; + /* Write to ring output. */ + uint8_t output_buf[K230_DECOMP_GZIP_BLOCK_SIZE]; + z_stream zs; +}; + +#endif --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650679; cv=none; d=zohomail.com; s=zohoarc; b=XHZfo6UBTXS39AJN1mgucdMeB1fQSj3/SxJGywXfgcro1O2OfjvcV6rRX38uXKDjPaDVbqrvinaIVwzJ2ndeooljYtIOZBkThbxtklFF1g+AnjfLOjm+aQMoYy9T3ZxRGPV8kEPUu/Sp4MUBvqFmz/QmE53+OTH3CLZWjohhfnI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650679; 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=NEigvj1AtoZ75hcw0yHz0h53SARdssi8MLVvDj4Y+UU=; b=LBXfwN4d1c5hfnx5sn6DuNrdH2PmlP8/ZHKzZmqEhNIX8CQraxefsSDTzDak8sZpPtCm1UkjwDBug0GSWiTx8J+X9tHOM+iQV+2svGlotEVtUb96k1+cYgKkz9aqbRiysSEiPh6CUbw2dGJ1OEamxaguK0vG+tQQP/B8pb+vfhs= 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 1784650679626405.23793984779456; Tue, 21 Jul 2026 09:17:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmDA9-0006R0-7m; Tue, 21 Jul 2026 12:17:45 -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 1wmDA5-0006QX-8S; Tue, 21 Jul 2026 12:17:41 -0400 Received: from m16.mail.163.com ([220.197.31.4]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmDA3-0007PG-By; Tue, 21 Jul 2026 12:17:41 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S7; Wed, 22 Jul 2026 00:13:41 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=NE igvj1AtoZ75hcw0yHz0h53SARdssi8MLVvDj4Y+UU=; b=kdaHXxuY80PcqWkJed 6PNPUdxMNECpe2F3CPCBIPZXZ5GrgyBsUdCdQ75LdvwN5eL4IGDzEgVZCOnM+pSt Nm2YkUek7MpKhVkiHPTCBsMOhADt40RaMLnn/aWcmk2UX2mGOX5h4dR5N3raMJNm L8IjAWq5tI85WTZytKzRKxdVE= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 5/7] hw/riscv: k230: add decomp gzip in K230 board Date: Wed, 22 Jul 2026 00:13:33 +0800 Message-ID: <20260721161335.73872-6-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S7 X-Coremail-Antispam: 1Uf129KBjvJXoWxCFWfWw4kKF43AFy8KFWfZrb_yoW5urWrpF sxGr4qyrWxWFyfAa1ftrs7Gryjg3ykKFy3Gw1Sv34rKrWUArZ8tFsIya1Svr18JFWDJa45 uFy8ta1S9w17XaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pELZ2hUUUUU= X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC-hVGhGpfmrVllgAA3A 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=220.197.31.4; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650680109158500 Content-Type: text/plain; charset="utf-8" This commit replaces the unimplemented part of Decomp_gzip in K230. Connect to the handshake interface of GSDMA. Signed-off-by: Tao Ding --- hw/riscv/Kconfig | 1 + hw/riscv/k230.c | 23 +++++++++++++++++++---- include/hw/riscv/k230.h | 2 ++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index d28ac06043..d06ac26648 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -163,3 +163,4 @@ config K230 select UNIMP select K230_WDT select K230_GSDMA + select K230_DECOMP_GZIP diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index c80bd65694..7fd1ec4c25 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -111,6 +111,8 @@ static void k230_soc_init(Object *obj) object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT); object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT); object_initialize_child(obj, "k230-gsdma", &s->gsdma, TYPE_K230_GSDMA); + object_initialize_child(obj, "k230-decomp-gzip", &s->decomp_gzip, + TYPE_K230_DECOMP_GZIP); =20 qdev_prop_set_uint32(DEVICE(cpu0), "hartid-base", 0); qdev_prop_set_string(DEVICE(cpu0), "cpu-type", TYPE_RISCV_CPU_THEAD_C9= 08); @@ -215,6 +217,23 @@ static void k230_soc_realize(DeviceState *dev, Error *= *errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->gsdma), 0, qdev_get_gpio_in(DEVICE(s->c908_plic), K230_GSDMA_I= RQ)); =20 + /* Decomp gzip */ + qdev_prop_set_uint64(DEVICE(&s->decomp_gzip), "sram-base", + memmap[K230_DEV_SRAM].base); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->decomp_gzip), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->decomp_gzip), 0, + memmap[K230_DEV_DECOMP_GZIP].base); + for (int i =3D 0; i < K230_DECOMP_GZIP_NUM_GPIOS_OUT; i++) { + qdev_connect_gpio_out(DEVICE(&s->decomp_gzip), i, + qdev_get_gpio_in(DEVICE(&s->gsdma), i)); + } + for (int i =3D 0; i < K230_DECOMP_GZIP_NUM_GPIOS_IN; i++) { + qdev_connect_gpio_out(DEVICE(&s->gsdma), i, + qdev_get_gpio_in(DEVICE(&s->decomp_gzip), i)= ); + } + /* unimplemented devices */ create_unimplemented_device("kpu.l2-cache", memmap[K230_DEV_KPU_L2_CACHE].base, @@ -233,10 +252,6 @@ static void k230_soc_realize(DeviceState *dev, Error *= *errp) create_unimplemented_device("dma", memmap[K230_DEV_DMA].base, memmap[K230_DEV_DMA].size); =20 - create_unimplemented_device("decomp-gzip", - memmap[K230_DEV_DECOMP_GZIP].base, - memmap[K230_DEV_DECOMP_GZIP].size); - create_unimplemented_device("2d-engine.non-ai", memmap[K230_DEV_NON_AI_2D].base, memmap[K230_DEV_NON_AI_2D].size); diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h index 156a386edc..a12d36965a 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -19,6 +19,7 @@ #include "hw/riscv/riscv_hart.h" #include "hw/watchdog/k230_wdt.h" #include "hw/dma/k230_gsdma.h" +#include "hw/misc/k230_decomp_gzip.h" =20 #define C908_CPU_HARTID (0) =20 @@ -35,6 +36,7 @@ typedef struct K230SoCState { =20 K230WdtState wdt[2]; K230GSDMAState gsdma; + K230DecompGzipState decomp_gzip; MemoryRegion sram; MemoryRegion bootrom; =20 --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650480; cv=none; d=zohomail.com; s=zohoarc; b=E7vndgUyXnloNpGg2tXrHaDnjsnAT+dJq7o1Skc45/mF+d0ATBLIcnyMz+vrkCcCbiFN8NBsnLG9wsIhQVkmV0je03Wn28bV+xyCojBaiuNzIn+qSdcOAqHRxzkcEY26FStO/kwTZL7Z3HopVEmqkuzeNDiv9N1VTQeCyBBTFQg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650480; 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=2Cwr/NQLi2LBpvm2lynDSiv8qhWyCobDkd/OMkiCYzM=; b=FwKQe2t3t2icAEK/RH71c5FGuVwDfVlVFZ7ffThhE4oK3jC5hVMiTUH9azbfMHjA3cTWQWj8c2oYawvkxlDaFLuN2OqS9yCNL3RUGt3WhqKJxaeNF2IECnyw/GFHoSf+MOEZIjgyCUe/cAPgxnZ2v9kzkQLDZ3t5DWe+oYoSroI= 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 17846504808091002.2684126396863; Tue, 21 Jul 2026 09:14:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmD6g-0001Xt-Av; Tue, 21 Jul 2026 12:14:10 -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 1wmD6e-0001Wl-J5; Tue, 21 Jul 2026 12:14:08 -0400 Received: from m16.mail.163.com ([117.135.210.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD6Y-0006mw-Cc; Tue, 21 Jul 2026 12:14:08 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S8; Wed, 22 Jul 2026 00:13:41 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=2C wr/NQLi2LBpvm2lynDSiv8qhWyCobDkd/OMkiCYzM=; b=SmPO91hXFRM2P5A54r DKE96IMIYBXBEayr0VPQ8qpCkRBVishaxe/a6RG1lEb6ng3GPo8J79gU2ePSlRdg ccae12p0v03Zc1AzUOgAExgmmk5rx7rumyt0YDL2ow6iBsVfYjGrGdgHxBbGIwue pfQLcdE/6ikuG3APbrAfvfimY= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 6/7] tests/qtest: add test for K230 decomp gzip Date: Wed, 22 Jul 2026 00:13:34 +0800 Message-ID: <20260721161335.73872-7-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S8 X-Coremail-Antispam: 1Uf129KBjvJXoW3WFyxtFW3tw4xtr4UAw1DWrg_yoW3uFWfp3 s8Gw1Yvr18tF4fGanrXF4kCF15WrZ3K34rC3yjgry09rs7JryktFn3t3yrXwn5G3ykZF1F 9395K3Z09F18XaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pRyCJ9UUUUU= X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC-RVGhGpfmrVfEwAA38 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=117.135.210.5; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650483111158500 Content-Type: text/plain; charset="utf-8" This commit adds test cases for Decomp_gzip. A compressed data segment has been pre-set, configure GSDMA and decomp_gzip. Compare the decompressed data with the original data Run this qtest: $ mkdir build && cd build && ../configure --target-list=3D"riscv64-soft= mmu" $ QTEST_QEMU_BINARY=3D./qemu-system-riscv64 tests/qtest/k230-decomp-g= zip-test Signed-off-by: Tao Ding --- tests/qtest/k230-decomp-gzip-test.c | 181 ++++++++++++++++++++++++++++ tests/qtest/meson.build | 2 +- 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 tests/qtest/k230-decomp-gzip-test.c diff --git a/tests/qtest/k230-decomp-gzip-test.c b/tests/qtest/k230-decomp-= gzip-test.c new file mode 100644 index 0000000000..adddf8f2eb --- /dev/null +++ b/tests/qtest/k230-decomp-gzip-test.c @@ -0,0 +1,181 @@ +/* + * QTest testcase for K230 GZIP decompression engine + * + * Copyright (c) 2026 Tao Ding + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "libqtest.h" +#include "hw/dma/k230_gsdma.h" +#include "hw/misc/k230_decomp_gzip.h" + +#define K230_DECOMP_GZIP_BASE 0x80808000 +#define K230_GSDMA_BASE 0x80800000 +#define K230_SRAM_BASE 0x80200000 +#define TEST_LLT_ADDR0 0x01000000 +#define TEST_LLT_ADDR1 0x01000040 +#define TEST_SRC_ADDR 0x01100000 +#define TEST_DST_ADDR 0x01200000 + +#define TEST_PAYLOAD_LEN (sizeof(test_payload) - 1) + +static inline uint64_t gzip_reg(hwaddr off) +{ + return K230_DECOMP_GZIP_BASE + off; +} + +static inline uint64_t gsdma_reg(hwaddr off) +{ + return K230_GSDMA_BASE + off; +} + +static inline uint64_t gsdma_ch_reg(unsigned int ch, hwaddr off) +{ + return K230_GSDMA_BASE + K230_GSDMA_CH_BASE + + ch * K230_GSDMA_CH_STRIDE + off; +} + +static inline hwaddr k230_sram_addr(hwaddr off) +{ + return K230_SRAM_BASE + off; +} + +static inline hwaddr k230_sram_input_addr(unsigned int slot) +{ + return k230_sram_addr(K230_DECOMP_GZIP_SRAM_IN_BASE + + slot * K230_DECOMP_GZIP_BLOCK_SIZE); +} + +static const uint8_t test_gzip_data[] =3D { + 0x1f, 0x8b, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xff, 0xf3, 0x36, 0x32, 0x36, 0x50, 0x48, + 0xaf, 0xca, 0x2c, 0x50, 0x28, 0x2e, 0x29, 0x4a, + 0x4d, 0xcc, 0xcd, 0xcc, 0x4b, 0x57, 0x28, 0x49, + 0x2d, 0x2e, 0xe1, 0xf2, 0x1e, 0x5a, 0x12, 0x00, + 0xdb, 0x9d, 0xbc, 0xdd, 0xc8, 0x00, 0x00, 0x00, +}; + +static const uint8_t test_payload[] =3D + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n" + "K230 gzip streaming test\n"; + +static void write_sdma_llt_node(QTestState *qts, hwaddr addr, uint32_t src, + uint32_t dst, uint32_t len, uint32_t next) +{ + qtest_writel(qts, addr + offsetof(K230GSDMALLT, cfg), 0); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, src_addr), src); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_size), len); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, line_cfg), 0x1); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, dst_addr), dst); + qtest_writel(qts, addr + offsetof(K230GSDMALLT, next_llt_addr), next); +} + +static void test_reset_and_rw(void) +{ + QTestState *qts =3D qtest_init("-machine k230"); + + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_STAR= T)), + =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SI= ZE)), + =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SI= ZE)), + =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_STAT= )), + =3D=3D, 0); + + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_START), + K230_DECOMP_GZIP_START); + + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE), 0xffffffff= ); + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SI= ZE)), + =3D=3D, 0xffffffff); + + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE), 0x12345678= ); + g_assert_cmphex(qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SI= ZE)), + =3D=3D, 0x12345678); + + qtest_quit(qts); +} + +static void test_gsdma_handshake_flow(void) +{ + QTestState *qts =3D qtest_init("-machine k230"); + uint32_t stat; + uint8_t output[TEST_PAYLOAD_LEN]; + + qtest_memwrite(qts, TEST_SRC_ADDR, test_gzip_data, sizeof(test_gzip_da= ta)); + write_sdma_llt_node(qts, TEST_LLT_ADDR0, TEST_SRC_ADDR, + k230_sram_input_addr(0), + sizeof(test_gzip_data), 0); + write_sdma_llt_node(qts, TEST_LLT_ADDR1, + k230_sram_addr(K230_DECOMP_GZIP_SRAM_OUT_BASE), + TEST_DST_ADDR, TEST_PAYLOAD_LEN, 0); + + qtest_writel(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN), BIT(0) | BIT(1)); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CFG), + K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN); + qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_CFG), 0); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_A= DDR0); + qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_LLT_SADDR), TEST_LLT_A= DDR1); + qtest_writel(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_S= TART); + qtest_writel(qts, gsdma_ch_reg(1, K230_GSDMA_CH_CTL), K230_GSDMA_CTL_S= TART); + + g_assert_cmphex(qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_CH_EN)), + =3D=3D, BIT(0) | BIT(1)); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_CFG)) & + K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN, + =3D=3D, K230_GSDMA_CH0_CFG_DECOMP_CTRL_EN); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(0, K230_GSDMA_CH_LLT_SAD= DR)), + =3D=3D, TEST_LLT_ADDR0); + g_assert_cmphex(qtest_readl(qts, gsdma_ch_reg(1, K230_GSDMA_CH_LLT_SAD= DR)), + =3D=3D, TEST_LLT_ADDR1); + + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_SRC_SIZE), + K230_DECOMP_GZIP_CTRL_EN | sizeof(test_gzip_data)); + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_GZIP_OUT_SIZE), + TEST_PAYLOAD_LEN); + qtest_writel(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_START), + K230_DECOMP_GZIP_START); + + stat =3D qtest_readl(qts, gzip_reg(K230_DECOMP_GZIP_DECOMP_STAT)); + g_assert_cmphex(stat & K230_DECOMP_GZIP_STAT_CRC_OK, =3D=3D, + K230_DECOMP_GZIP_STAT_CRC_OK); + + g_assert_cmphex(qtest_readl(qts, + gsdma_ch_reg(0, K230_GSDMA_CH_CURRENT_LLT)= ), + =3D=3D, TEST_LLT_ADDR0); + g_assert_cmphex(qtest_readl(qts, + gsdma_ch_reg(1, K230_GSDMA_CH_CURRENT_LLT)= ), + =3D=3D, TEST_LLT_ADDR1); + + stat =3D qtest_readl(qts, gsdma_reg(K230_GSDMA_DMA_INT_STAT)); + g_assert_cmphex(stat & K230_GSDMA_SDMA_DONE_INT(0), =3D=3D, + K230_GSDMA_SDMA_DONE_INT(0)); + g_assert_cmphex(stat & K230_GSDMA_SDMA_DONE_INT(1), =3D=3D, + K230_GSDMA_SDMA_DONE_INT(1)); + + qtest_memread(qts, TEST_DST_ADDR, output, sizeof(output)); + g_assert_cmpmem(output, sizeof(output), test_payload, TEST_PAYLOAD_LEN= ); + + qtest_quit(qts); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/k230-decomp-gzip/reset-and-rw", test_reset_and_rw); + qtest_add_func("/k230-decomp-gzip/gsdma-handshake-flow", + test_gsdma_handshake_flow); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 1b13a777c9..7da12421af 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -297,7 +297,7 @@ qtests_riscv64 =3D ['riscv-csr-test'] + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test', 'k230-gsd= ma-test'] : []) + (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test', 'k230-gsd= ma-test', 'k230-decomp-gzip-test'] : []) =20 qtests_hexagon =3D ['boot-serial-test'] =20 --=20 2.43.0 From nobody Sat Jul 25 09:32:07 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=163.com ARC-Seal: i=1; a=rsa-sha256; t=1784650678; cv=none; d=zohomail.com; s=zohoarc; b=KWhvBqZ2VZ6E6jI9R+N/RC4cxmpqFW01nL/OBfOIgFjUzb0cJg9IHPTFW7YyFkwjGdkDB3lej8d49OchklV5F2t3+cH9YWmCZHg3hKd7IzQNUHfIYMuh9lwx9KQ1rfbNYb80Kz5x5Co9dkPDQDnOH+NBmYYnvCBXKV9y+lEdOxQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784650678; 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=SxdsnNk/PbNT1Fg74+0TcDiAssvy53AGnv+mMgSP2dg=; b=kP2h2ZCakUIDmC1WQOHQuFkF3DB5ekjMf5OEDUmbTw5CTTZ1+tumw4jbWorONGLQxtor2SDPowlnPiCkVqwWLhQk76qsO0jBE7cgBlInYye1iGtBorcG68K9qK0wECLBEkuMV9hjmJGLZLRP3rpcVtgu1oGODTBTSkwnf7Fp18c= 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 1784650678265392.0599543619038; Tue, 21 Jul 2026 09:17:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmDA6-0006QZ-Tw; Tue, 21 Jul 2026 12:17:43 -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 1wmDA2-0006QA-KI; Tue, 21 Jul 2026 12:17:38 -0400 Received: from m16.mail.163.com ([220.197.31.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmD9z-0007P6-10; Tue, 21 Jul 2026 12:17:38 -0400 Received: from dt-VM.localdomain (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wD3F6+wml9qkr5qKg--.58375S9; Wed, 22 Jul 2026 00:13:41 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=Sx dsnNk/PbNT1Fg74+0TcDiAssvy53AGnv+mMgSP2dg=; b=b71REtt7fSK1IHX/48 fslMSJ7NRQImbGGJnEEjR0QyB/jeBXMkWa6ahblcowhrzcqS2N22i4WL+1N2jqBr q1a/TLMppED+sEX+BBuZEEPcieNA3UAevSBvxYs4mmMI4H5UsqjgG4IbhIdjNzAh JjWuazwp5MbAO3Qxe2XSdokOE= From: Tao Ding To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, pbonzini@redhat.com, palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu@processmission.com, farosas@suse.de, lvivier@redhat.com, Tao Ding Subject: [PATCH 7/7] hw/riscv: k230: add a noc stub region in K230 board Date: Wed, 22 Jul 2026 00:13:35 +0800 Message-ID: <20260721161335.73872-8-dingtao0430@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260721161335.73872-1-dingtao0430@163.com> References: <20260721161335.73872-1-dingtao0430@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3F6+wml9qkr5qKg--.58375S9 X-Coremail-Antispam: 1Uf129KBjvJXoW7uFyUJF1UArWUJr4fKw13CFg_yoW8Kr1UpF 42kan0k3y8JF45Xa1v9rWDWryjqan5Z3ZxJw18Z34j9r48AFyDtwnak3yrJFW5Xr1fJ347 CF9IyryI9r1UG3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pElkshUUUUU= X-Originating-IP: [101.204.18.42] X-CM-SenderInfo: pglqw3tdrqkjqq6rljoofrz/xtbC4hVGhGpfmrVpMwAA31 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=220.197.31.5; envelope-from=dingtao0430@163.com; helo=m16.mail.163.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 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_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=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 @163.com) X-ZM-MESSAGEID: 1784650680152158500 Content-Type: text/plain; charset="utf-8" The NOC address was accessed in the k230_unzip driver, but it is currently = not in k230. This commit uses create_unimplemented_device to preset the region. Signed-off-by: Tao Ding --- Steps to decompress in uboot: 1. Prepare uboot and k230_sdk u-boot (https://github.com/zevorn/k230-boot-assets) k230_sdk (https://github.com/kendryte/k230_sdk) 2. Compress image (in sh file, modify ROOT and K230_SDK_ROOT) ROOT=3Dk230-boot-assets K230_SDK_ROOT=3Dk230_sdk DST=3D$ROOT/buildroot/uboot-boot cd $DST $K230_SDK_ROOT/tools/k230_priv_gzip -n8 -f -k Image sed -i -e "1s/\x08/\x09/" Image.gz cd - 3. Launch qemu (in sh file, modify ROOT and QEMU) ROOT=3Dk230-boot-assets QEMU=3Dqemu/build/qemu-system-riscv64 COMMON=3D$ROOT/common DST=3D$ROOT/buildroot/uboot-boot INITRD_END=3D$(printf "0x%x" $((0x0a100000 + $(stat -c %s "$DST/rootfs= .cpio.gz")))) echo "Use this U-Boot initrd end: $INITRD_END" $QEMU -M k230 \ -bios "$COMMON/u-boot" \ -device loader,file=3D"$COMMON/fw_jump.uImage",addr=3D0xc100000,f= orce-raw=3Don \ -device loader,file=3D"$DST/Image.gz",addr=3D0xd000000,force-raw= =3Don \ -device loader,file=3D"$DST/rootfs.cpio.gz",addr=3D0xa100000,forc= e-raw=3Don \ -device loader,file=3D"$DST/k230-qemu.dtb",addr=3D0xa000000,force= -raw=3Don \ -nographic -no-reboot \ -d guest_errors \ -D qemu.log 4. Input in uboot k230_unzip 0xd000000 0x6c354f 0x8200000 setenv bootargs console=3DttyS0,115200 earlycon=3Dsbi cma=3D0 fdt addr 0xa000000 fdt resize 8192 fdt set /chosen linux,initrd-start <0x0 0xa100000> fdt set /chosen linux,initrd-end <0x0 0xba2d5fe> bootm 0xc100000 - 0xa000000 hw/riscv/k230.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 7fd1ec4c25..ff834d6724 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -234,6 +234,9 @@ static void k230_soc_realize(DeviceState *dev, Error **= errp) qdev_get_gpio_in(DEVICE(&s->decomp_gzip), i)= ); } =20 + /* Noc stub, the k230 decomp_gzip driver in uboot will access this reg= ion */ + create_unimplemented_device("noc-stub", 0x91302000, 0x1000); + /* unimplemented devices */ create_unimplemented_device("kpu.l2-cache", memmap[K230_DEV_KPU_L2_CACHE].base, --=20 2.43.0