All of lore.kernel.org
 help / color / mirror / Atom feed
From: Drew Fustini <fustini@kernel.org>
To: "Radim Krčmář" <rkrcmar@ventanamicro.com>
Cc: qemu-devel@nongnu.org, "Palmer Dabbelt" <palmer@dabbelt.com>,
	"Alistair Francis" <Alistair.Francis@wdc.com>,
	"Weiwei Li" <liwei1518@gmail.com>,
	"Daniel Henrique Barboza" <dbarboza@ventanamicro.com>,
	"Liu Zhiwei" <zhiwei_liu@linux.alibaba.com>,
	qemu-riscv@nongnu.org, "Paolo Bonzini" <pbonzini@redhat.com>,
	"Nicolas Pitre" <npitre@baylibre.com>,
	"Kornel Dulęba" <mindal@semihalf.com>,
	"Atish Kumar Patra" <atishp@rivosinc.com>,
	"Atish Patra" <atish.patra@linux.dev>,
	"Vasudevan Srinivasan" <vasu@rivosinc.com>,
	"yunhui cui" <cuiyunhui@bytedance.com>,
	"Chen Pei" <cp0613@linux.alibaba.com>,
	guo.wenjia23@zte.com.cn, liu.qingtao2@zte.com.cn,
	qemu-riscv-bounces+qemu-riscv=archiver.kernel.org@nongnu.org
Subject: Re: [PATCH 3/7] hw/riscv: implement CBQRI capacity controller
Date: Fri, 21 Nov 2025 11:50:50 -0800	[thread overview]
Message-ID: <aSDCmrvONUgvzqbV@x1> (raw)
In-Reply-To: <DEDROLF9I9YQ.2MQIEGB7I4BKH@ventanamicro.com>

On Thu, Nov 20, 2025 at 08:25:44PM +0100, Radim Krčmář wrote:
> 2025-11-19T16:42:19-08:00, Drew Fustini <fustini@kernel.org>:
> > From: Nicolas Pitre <npitre@baylibre.com>
> >
> > Implement a capacity controller according to the Capacity and Bandwidth
> > QoS Register Interface (CBQRI) which supports these capabilities:
> >
> >   - Number of access types: 2 (code and data)
> >   - Usage monitoring operations: CONFIG_EVENT, READ_COUNTER
> >   - Event IDs supported: None, Occupancy
> >   - Capacity allocation ops: CONFIG_LIMIT, READ_LIMIT, FLUSH_RCID
> >
> > Link: https://github.com/riscv-non-isa/riscv-cbqri/blob/main/riscv-cbqri.pdf
> > Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
> > [fustini: add fields introduced in the ratified spec: cunits, rpfx, p]
> > Signed-off-by: Drew Fustini <fustini@kernel.org>
> > ---
> > diff --git a/hw/riscv/cbqri_capacity.c b/hw/riscv/cbqri_capacity.c
> > [...]
> > +static void riscv_cbqri_cc_write_alloc_ctl(RiscvCbqriCapacityState *cc,
> > +                                           uint64_t value)
> > +{
> >[...]
> > +    if (rcid >= cc->nb_rcids) {
> > +        status = CC_ALLOC_STATUS_INVAL_RCID;
> > +    } else if (atv && !is_valid_at(cc, at)) {
> > +        status = CC_ALLOC_STATUS_INVAL_AT;
> > +    } else if (op == CC_ALLOC_OP_CONFIG_LIMIT &&
> > +               cc->supports_alloc_op_config_limit) {
> > +        status = alloc_blockmask_config(cc, rcid, at, &busy);
> > +    } else if (op == CC_ALLOC_OP_READ_LIMIT &&
> > +               cc->supports_alloc_op_read_limit) {
> > +        status = alloc_blockmask_read(cc, rcid, at, &busy);
> > +    } else if (op == CC_ALLOC_OP_FLUSH_RCID &&
> > +               cc->supports_alloc_op_flush_rcid) {
> > +        status = alloc_blockmask_init(cc, rcid, at, false, &busy);
> 
> The spec says the following about flush:
> 
>   "The configured capacity block allocation or the capacity unit limit
>    is not changed by this operation."
> 
> Limits are not implemented, so I think it's supposed to be a nop.

Thanks, that makes sense. I'll change it for the next revision.

> > [...]
> > +static uint64_t riscv_cbqri_cc_read(void *opaque, hwaddr addr, unsigned size)
> > +{
> > +    RiscvCbqriCapacityState *cc = opaque;
> > +    uint64_t value = 0;
> > +
> > +    assert((addr % 8) == 0);
> > +    assert(size == 8);
> 
> Is there a plan to extend support for 32 bit operations?
> 
>   "The CBQRI registers are defined so that software can perform two
>    individual 4 byte accesses."

Good question. Daniel also commented about the asserts for size == 8
while your MemoryRegionOps has .valid.min_access_size = 4. It does seem
like from the spec that these CBQRI controllers do need to support 4
byte accesses.

However, I need to understand better how to accomplish that. I'm
uncertain if I need to add code to the read and write hooks for that, or
if something in MemoryRegionOps can handle it automatically.

> > [...]
> > +    case A_CC_BLOCK_MASK:
> > +        if (cc->ncblks == 0) {
> > +            break;
> > +        }
> > +        /* fallthrough */
> > +    default:
> > +        unsigned int blkmask_slot = (addr - A_CC_BLOCK_MASK) / 8;
> > +        if (blkmask_slot >= (cc->ncblks + 63) / 64) {
> > +            qemu_log_mask(LOG_GUEST_ERROR,
> > +                          "%s: out of bounds (addr=0x%x)",
> > +                          __func__, (uint32_t)addr);
> > +            break;
> > +        }
> > +        value = cc->alloc_blockmasks[blkmask_slot];
> 
> There is supposed to be a cc_cunits registers after the cc_block_mask.

Good point, I need to update the code to account for cc_units.

> > [...]
> > +static void riscv_cbqri_cc_realize(DeviceState *dev, Error **errp)
> > +{
> > +    RiscvCbqriCapacityState *cc = RISCV_CBQRI_CC(dev);
> > +
> > +    if (!cc->mmio_base) {
> > +        error_setg(errp, "mmio_base property not set");
> > +        return;
> > +    }
> > +
> > +    assert(cc->mon_counters == NULL);
> > +    cc->mon_counters = g_new0(MonitorCounter, cc->nb_mcids);
> > +
> > +    assert(cc->alloc_blockmasks == NULL);
> > +    uint64_t *end = get_blockmask_location(cc, cc->nb_rcids, 0);
> > +    unsigned int blockmasks_size = end - cc->alloc_blockmasks;
> > +    cc->alloc_blockmasks = g_new0(uint64_t, blockmasks_size);
> > +
> > +    memory_region_init_io(&cc->mmio, OBJECT(dev), &riscv_cbqri_cc_ops,
> > +                          cc, TYPE_RISCV_CBQRI_CC".mmio", 4 * 1024);
> 
> Shouldn't the region size take cc->ncblks into account?
> (A bitmask for 2^16 ids is 8kB.)

cc_block_mask field is BMW / 8. In the case of NCBLKS of 12 and NCBLKS
of 16, both end up with a BMW of 64 which would be 8 bytes. I think the
the only reason the allocation is 4KB is that is meant to be aligned to
the page size. Otherwise, the capacity controller register layout is
pretty small.

> > +    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &cc->mmio);
> > +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, cc->mmio_base);
> > +}
> > +
> > +static void riscv_cbqri_cc_reset(DeviceState *dev)
> > +{
> > +    RiscvCbqriCapacityState *cc = RISCV_CBQRI_CC(dev);
> > +
> > +    cc->cc_mon_ctl = 0;
> > +    cc->cc_alloc_ctl = 0;
> 
> Only the busy field must be reset to 0.  I think the decision warrants a
> comment that we're zeroing more to have simpler code.

Okay, will do.

> > +
> > +    /* assign all capacity only to rcid0 */
> > +    for (unsigned int rcid = 0; rcid < cc->nb_rcids; rcid++) {
> 
> rcid != 0 are unspecified on reset, so I would prefer not to touch them.

Okay, that is a good point that the spec does state that. I'll fix this
in the next rev.

> > +        bool any_at = false;
> > +
> > +        if (cc->supports_at_data) {
> > +            alloc_blockmask_init(cc, rcid, CC_AT_DATA,
> > +                                 rcid == 0, NULL);
> > +            any_at = true;
> > +        }
> > +        if (cc->supports_at_code) {
> > +            alloc_blockmask_init(cc, rcid, CC_AT_CODE,
> > +                                 rcid == 0, NULL);
> > +            any_at = true;
> > +        }
> > +        if (!any_at) {
> > +            alloc_blockmask_init(cc, rcid, 0,
> > +                                 rcid == 0, NULL);
> > +        }
> > +    }
> 
> I think it looks a bit better if AT values were expressed as a bitfield
> of size 8: (untested)
> 
>     unsigned long at = find_next_bit(&cc->supported_at_mask, 8, 0);
> 
>     do {
>         alloc_blockmask_init(cc, rcid, at < 8 ? at : 0, rcid == 0, NULL);
>         at = find_next_bit(&cc->supported_at_mask, 8, at + 1);
>     } while (at < 8);

Thanks for the suggestion. I will give that a try.

Drew


  reply	other threads:[~2025-11-22  2:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-20  0:42 [PATCH 0/7] riscv: implement Ssqosid extension and CBQRI controllers Drew Fustini
2025-11-20  0:42 ` [PATCH 1/7] riscv: implement Ssqosid extension and srmcfg CSR Drew Fustini
2025-11-20 11:30   ` Daniel Henrique Barboza
2025-11-20 21:34     ` Drew Fustini
2025-11-20 16:07   ` Radim Krčmář
2025-11-20 20:46     ` Drew Fustini
2025-11-24 16:54       ` Radim Krčmář
2025-11-20  0:42 ` [PATCH 2/7] hw/riscv: define capabilities of CBQRI controllers Drew Fustini
2025-11-20 11:59   ` Daniel Henrique Barboza
2025-11-20  0:42 ` [PATCH 3/7] hw/riscv: implement CBQRI capacity controller Drew Fustini
2025-11-20 11:47   ` Daniel Henrique Barboza
2025-11-21 18:57     ` Drew Fustini
2025-11-20 19:25   ` Radim Krčmář
2025-11-21 19:50     ` Drew Fustini [this message]
2025-11-24 17:02       ` Radim Krčmář
2025-11-24 18:37         ` Drew Fustini
2025-11-25 11:55           ` Radim Krčmář
2025-11-20  0:42 ` [PATCH 4/7] hw/riscv: implement CBQRI bandwidth controller Drew Fustini
2025-11-20 11:51   ` Daniel Henrique Barboza
2025-11-24 17:06   ` Radim Krčmář
2025-11-24 18:45     ` Drew Fustini
2025-11-20  0:42 ` [PATCH 5/7] hw/riscv: Kconfig: add CBQRI options Drew Fustini
2025-11-20  0:42 ` [PATCH 6/7] hw/riscv: meson: add CBQRI controllers to the build Drew Fustini
2025-11-20 12:01   ` Daniel Henrique Barboza
2025-11-20 20:56     ` Drew Fustini
2025-11-20  0:42 ` [PATCH 7/7] hw/riscv: add CBQRI controllers to virt machine Drew Fustini
2025-11-20 12:01   ` Daniel Henrique Barboza

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aSDCmrvONUgvzqbV@x1 \
    --to=fustini@kernel.org \
    --cc=Alistair.Francis@wdc.com \
    --cc=atish.patra@linux.dev \
    --cc=atishp@rivosinc.com \
    --cc=cp0613@linux.alibaba.com \
    --cc=cuiyunhui@bytedance.com \
    --cc=dbarboza@ventanamicro.com \
    --cc=guo.wenjia23@zte.com.cn \
    --cc=liu.qingtao2@zte.com.cn \
    --cc=liwei1518@gmail.com \
    --cc=mindal@semihalf.com \
    --cc=npitre@baylibre.com \
    --cc=palmer@dabbelt.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv-bounces+qemu-riscv=archiver.kernel.org@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=rkrcmar@ventanamicro.com \
    --cc=vasu@rivosinc.com \
    --cc=zhiwei_liu@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.