@@ -4791,6 +4907,28 @@ void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState
*d, DeviceState *intf,
cxl_copy_cci_commands(cci, cxl_cmd_set_usp_mctp);
cci->d = d;
cci->intf = intf;
+ CXLUpstreamPort *pp;
+ int pn = 0;
cxl_init_cci(cci, payload_max);
cxl_set_phy_port_info(cci);
+ /* physical port control */
+ pp = CXL_USP(cci->d);
+ for (int byte_index = 0; byte_index < (CXL_MAX_PHY_PORTS / BITS_PER_BYTE);
+ byte_index++) {
+ unsigned char byte = pp->pports.active_port_bitmask[byte_index];
+
+ for (int bit_index = 0; bit_index < 8; bit_index++, pn++) {
+ if (((byte) & (1 << bit_index)) != 0) {
+ qemu_mutex_init(&pp->pports.perst[pn].lock);
+ pp->pports.perst[pn].issued_assert_perst = false;
+ /*
+ * Assert PERST involves physical port to be in
+ * hold reset phase for minimum 100ms. No other
+ * physcial port control requests are entertained
typo physcial -> physical
+ * until Deassert PERST command.
+ */
+ pp->pports.perst[pn].asrt_time = ASSERT_WAIT_TIME_MS;
+ }
+ }
+ }
}
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 9fc720ec10..033d9bf11a 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -130,6 +130,7 @@
(1 << 16))
#define CXL_MAX_PHY_PORTS 256
+#define ASSERT_WAIT_TIME_MS 100 /* Assert - Deassert PERST */
/* physical port control info - CXL r3.2 table 7-19 */
#define CXL_PORT_CONFIG_STATE_DISABLED 0x0
@@ -196,6 +197,14 @@ typedef struct CXLPhyPortInfo {
uint8_t supported_ld_count;
} QEMU_PACKED CXLPhyPortInfo;
+/* Assert - Deassert PERST */
+typedef struct CXLPhyPortPerst {
+ bool issued_assert_perst;
+ QemuMutex lock; /* protecting assert-deassert reset request */
+ uint64_t asrt_time;
+ QemuThread asrt_thread; /* thread for 100ms delay */
+} CXLPhyPortPerst;
+
/* CXL r3.1 Table 8-34: Command Return Codes */
typedef enum {
CXL_MBOX_SUCCESS = 0x0,
diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h
index 5c918c53a9..5c31023590 100644
--- a/include/hw/cxl/cxl_mailbox.h
+++ b/include/hw/cxl/cxl_mailbox.h
@@ -88,6 +88,7 @@ enum {
PHYSICAL_SWITCH = 0x51,
#define IDENTIFY_SWITCH_DEVICE 0x0
#define GET_PHYSICAL_PORT_STATE 0x1
+ #define PHYSICAL_PORT_CONTROL 0X2
use 0X2 -> 0x2
TUNNEL = 0x53,
#define MANAGEMENT_COMMAND 0x0
MHD = 0x55,
diff --git a/include/hw/pci-bridge/cxl_upstream_port.h
b/include/hw/pci-bridge/cxl_upstream_port.h
index 3b7e72bfe0..4b9da87d77 100644
--- a/include/hw/pci-bridge/cxl_upstream_port.h
+++ b/include/hw/pci-bridge/cxl_upstream_port.h
@@ -30,6 +30,7 @@ typedef struct CXLUpstreamPort {
uint8_t num_ports;
uint8_t active_port_bitmask[CXL_MAX_PHY_PORTS / BITS_PER_BYTE];
CXLPhyPortInfo pport_info[CXL_MAX_PHY_PORTS];
+ CXLPhyPortPerst perst[CXL_MAX_PHY_PORTS];
} pports;
} CXLUpstreamPort;
-- 2.34.1
Thanks,
Alok