From: Arpit Kumar <arpit1.kumar@samsung.com>
To: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: qemu-devel@nongnu.org, gost.dev@samsung.com,
linux-cxl@vger.kernel.org, nifan.cxl@gmail.com,
dave@stgolabs.net, vishak.g@samsung.com, krish.reddy@samsung.com,
a.manzanares@samsung.com, alok.rathore@samsung.com
Subject: Re: [PATCH 3/3] hw/cxl: Add Physical Port Control (Opcode 5102h)
Date: Tue, 17 Jun 2025 15:41:36 +0530 [thread overview]
Message-ID: <20250617101136.z4ityaayhuglrvqu@test-PowerEdge-R740xd> (raw)
In-Reply-To: <20250610154501.0000213b@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 8087 bytes --]
On 10/06/25 03:45PM, Jonathan Cameron wrote:
>On Mon, 2 Jun 2025 19:29:42 +0530
>Arpit Kumar <arpit1.kumar@samsung.com> wrote:
>
>
>Very interesting to see support for this. It will enable a load
>of additional test cases.
>
>> added assert-deassert PERST implementation, reset PPB
>> for physical port.
>Added
okay
>
>Please also include some details of testing done and what happens.
>Given I know we have some issues with reset that we haven't resolved
>I'm curious if you see them here.
>
sure, I have tested this command using libcxl-mi. will share the details in the
next iteration (V2) of the patch series.
>>
>> Signed-off-by: Arpit Kumar <arpit1.kumar@samsung.com>
>
>> +/* Assert - Deassert PERST */
>> +#define ASSERT_WAIT_TIME_MS 100
>> +
>> /* link state flags */
>> #define LINK_STATE_FLAG_LANE_REVERSED (1 << 0)
>> #define LINK_STATE_FLAG_PERST_ASSERTED (1 << 1)
>> @@ -662,6 +666,114 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
>> return CXL_MBOX_SUCCESS;
>> }
>>
>> +static struct PCIDevice *cxl_find_port_dev(uint8_t ppb_id, PCIBus *bus)
>> +{
>> + PCIDevice *d;
>> + int devfn;
>> +
>> + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
>
>As in patch one, maybe use the for_each_pci_... Though with the callback
>needed it may end up slightly more complex that this.
>
right, will use the same.
>
>> + d = bus->devices[devfn];
>> + if (d) {
>> + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_DSP)) {
>> + uint8_t port = PCIE_PORT(d)->port;
>I'd not bother with the local variable for this one.
>
okay
> if (PCIE_PORT(d)->port == ppb_id) {
> return d;
> }
>
>> + if (port == ppb_id) {
>> + return d;
>> + }
>> + }
>> + }
>> + }
>> + return NULL;
>> +}
>> +
>> +static CXLRetCode deassert_PERST(Object *obj, ResetType type, uint8_t pn, CXLCCI *cci)
>> +{
>> + ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
>> + ResettableState *s = rc->get_state(obj);
>> +
>> + if (cci->pports.perst[pn].issued_assert_PERST) {
>> + if (cci->pports.perst[pn].asrt_time == -1 && !s->hold_phase_pending) {
>
>I'd flip the logic as then can return early in error case and reduce
>indent of the rest.
>
okay, will update in V2.
>
>> + qemu_mutex_lock(&cci->pports.perst[pn].lock);
>
> QEMU_LOCK_GUARD(&cci->pports.prst[pn].lock);
>
>> + resettable_release_reset(obj, type);
>> + cci->pports.perst[pn].issued_assert_PERST = false;
>> + cci->pports.pport_info[pn].link_state_flags &=
>> + ~LINK_STATE_FLAG_PERST_ASSERTED;
>> + cci->pports.perst[pn].asrt_time = ASSERT_WAIT_TIME_MS;
>> + qemu_mutex_unlock(&cci->pports.perst[pn].lock);
>and drop explicit unlock.
got it
>> + } else {
>> + return CXL_MBOX_INTERNAL_ERROR;
>> + }
>> + } else {
>> + return CXL_MBOX_INTERNAL_ERROR;
>> + }
>> + return CXL_MBOX_SUCCESS;
>> +}
>> +
>> +static CXLRetCode assert_PERST(Object *obj, ResetType type, uint8_t pn, CXLCCI *cci)
>> +{
>> + ResettableClass *rc = RESETTABLE_GET_CLASS(ocpgs@samsung.combj);
>> + ResettableState *s = rc->get_state(obj);
>> +
>> + if (cci->pports.perst[pn].issued_assert_PERST || s->exit_phase_in_progress) {
>> + return CXL_MBOX_INTERNAL_ERROR;
>> + }
>> +
>
>WITH_QEMU_LOCK_GUARD() perhaps
okay
>
>> + qemu_mutex_lock(&cci->pports.perst[pn].lock);
>> + cci->pports.perst[pn].issued_assert_PERST = true;
>> + cci->pports.pport_info[pn].link_state_flags |=
>> + LINK_STATE_FLAG_PERST_ASSERTED;
>> + resettable_assert_reset(obj, type);
>> + qemu_mutex_unlock(&cci->pports.perst[pn].lock);
>> +
>> + /* holding reset phase for 100ms */
>> + while (cci->pports.perst[pn].asrt_time--) {
>> + usleep(1000);
>Is this happening synchronously? I'd kind of expect it to be a background thing
>where we'd just check it had finished.
okay, will update it in V2 of patch series.
>> + }
>> + return CXL_MBOX_SUCCESS;
>> +}
>> +
>> +/*CXL r3.2 Section 7.6.7.1.3: Get Physical Port Control (Opcode 5102h)*/
>> +static CXLRetCode cmd_physical_port_control(const struct cxl_cmd *cmd,
>> + uint8_t *payload_in,
>> + size_t len_in,
>> + uint8_t *payload_out,
>> + size_t *len_out,
>> + CXLCCI *cci)
>> +{
>> + PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
>> + PCIDevice *dev;
>> + struct cxl_fmapi_get_physical_port_control_req_pl {
>> + uint8_t PPB_ID;
>> + uint8_t Ports_Op;
>> + } QEMU_PACKED *in;
>> +
>> + in = (struct cxl_fmapi_get_physical_port_control_req_pl *)payload_in;
>
>Often we cheat on these where the type is locally defined and do
>
> struct cxl_fmapi_get_physical_port_control_req_pl {
> uint8_t ppb_id;
> uint8_t ports_op;
> } QEMU_PACKED *in = (void *)payload_in;
>
>Given it's all together the type isn't confusing or ambiguous even
>though we use a void * instead of the more specific cast.
>
>Note also that it is better to stick to local style and use lower_case
>style for structure element naming etc.
>
got it
>> +
>> + if (len_in < sizeof(*in)) {
>> + return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
>> + }
>> +
>> + uint8_t pn = in->PPB_ID;
>> + dev = cxl_find_port_dev(pn, bus);
>> + if (!dev) {
>> + return CXL_MBOX_INTERNAL_ERROR;
>> + }
>> +
>> + switch (in->Ports_Op) {
>> + case 0:
>> + assert_PERST(OBJECT(&dev->qdev), RESET_TYPE_COLD, pn, cci);
>
>Even for these probably
>
>assert_perst()
>
okay
>> + break;
>return CXL_MBOX_SUCESS;
>> + case 1:
>> + deassert_PERST(OBJECT(&dev->qdev), RESET_TYPE_COLD, pn, cci);
>> + break;
>> + case 2:
>> + device_cold_reset(&dev->qdev);
>> + break;
>> + default:
>> + return CXL_MBOX_INVALID_INPUT;
>> + }
>> + return CXL_MBOX_SUCCESS;
>> +}
>> +
>
>> @@ -3878,4 +3995,15 @@ void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
>> cci->intf = intf;
>> cxl_init_cci(cci, payload_max);
>> cxl_set_phy_port_info(cci); /* store port info */
>> + /* physical port control */
>> + for (int i = 0; i < PCI_DEVFN_MAX; i++) {
>> + qemu_mutex_init(&cci->pports.perst[i].lock);
>
>perst is definitely port wise - not linked to CCI so that stuff should be
>in the port structures themselves.
>
>> + cci->pports.perst[i].issued_assert_PERST = false;
>> + /* Assert PERST involves physical port to be in
>wrap at 80 chars.
okay
>> + * hold reset phase for minimum 100ms. No other calls
>> + * are entertained until Deassert PERST command.
>> + * https://patchwork.ozlabs.org/project/linux-pci/patch/20190523194409.17718-1-niklas.cassel@linaro.org/#2178369
>
>Blocking other commands is fine but we should lock up emulation of other stuff
>in the system and I think you currently do.
>
got it. I think you meant 'we should *not lock up..'
>> + */
>> + cci->pports.perst[i].asrt_time = ASSERT_WAIT_TIME_MS;
>> + }
>> }
>> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
>> index 9eb128a1e8..f877d60b39 100644
>> --- a/include/hw/cxl/cxl_device.h
>> +++ b/include/hw/cxl/cxl_device.h
>> @@ -146,10 +146,18 @@ struct cxl_phy_port_info {
>> uint8_t supported_ld_count;
>> } QEMU_PACKED;
>>
>> +/* assert-deassert PERST */
>> +struct pperst {
>> + bool issued_assert_PERST;
>> + int asrt_time;
>> + QemuMutex lock;
>> +};
>> +
>> struct phy_port {
>> uint8_t num_ports;
>> uint8_t active_port_bitmask[0x20];
>> struct cxl_phy_port_info pport_info[PCI_DEVFN_MAX];
>> + struct pperst perst[PCI_DEVFN_MAX];
>> };
>>
>> /* CXL r3.1 Table 8-34: Command Return Codes */
>
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
next prev parent reply other threads:[~2025-06-17 10:21 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20250602140008epcas5p25fce01492de105da3cdc0aaa533f6ebc@epcas5p2.samsung.com>
2025-06-02 13:59 ` [PATCH 0/3] FM-API Physical switch command set update Arpit Kumar
2025-06-02 13:59 ` [PATCH 1/3] hw/cxl: Storing physical ports info during enumeration Arpit Kumar
2025-06-10 14:21 ` Jonathan Cameron
2025-06-10 14:21 ` Jonathan Cameron via
2025-06-17 9:46 ` Arpit Kumar
2025-06-18 11:31 ` Jonathan Cameron
2025-06-18 11:31 ` Jonathan Cameron via
2025-06-02 13:59 ` [PATCH 2/3] hw/cxl: Simplified Identify Switch Device & Get Physical Port State Arpit Kumar
2025-06-10 14:29 ` Jonathan Cameron
2025-06-10 14:29 ` Jonathan Cameron via
2025-06-17 10:01 ` Arpit Kumar
2025-06-02 13:59 ` [PATCH 3/3] hw/cxl: Add Physical Port Control (Opcode 5102h) Arpit Kumar
2025-06-10 14:45 ` Jonathan Cameron
2025-06-10 14:45 ` Jonathan Cameron via
2025-06-17 10:11 ` Arpit Kumar [this message]
2025-06-18 11:32 ` Jonathan Cameron
2025-06-18 11:32 ` Jonathan Cameron via
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=20250617101136.z4ityaayhuglrvqu@test-PowerEdge-R740xd \
--to=arpit1.kumar@samsung.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=a.manzanares@samsung.com \
--cc=alok.rathore@samsung.com \
--cc=dave@stgolabs.net \
--cc=gost.dev@samsung.com \
--cc=krish.reddy@samsung.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nifan.cxl@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=vishak.g@samsung.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.