@@ -226,8 +226,10 @@ void cxl_component_create_dvsec(CXLComponentState *cxl_cstate,
uint16_t type, uint8_t rev, uint8_t *body);
int cxl_decoder_count_enc(int count);
+int cxl_decoder_count_dec(int enc_cnt);
uint8_t cxl_interleave_ways_enc(int iw, Error **errp);
+int cxl_interleave_ways_dec(uint8_t iw_enc, Error **errp);
uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp);
hwaddr cxl_decode_ig(int ig);
@@ -13,15 +13,45 @@
#include "hw/pci/pci.h"
#include "hw/cxl/cxl.h"
+/* CXL r3.0 Section 8.2.4.19.1 CXL HDM Decoder Capability Register */
int cxl_decoder_count_enc(int count)
{
switch (count) {
- case 1: return 0;
- case 2: return 1;
- case 4: return 2;
- case 6: return 3;
- case 8: return 4;
- case 10: return 5;
+ case 1: return 0x0;
+ case 2: return 0x1;
+ case 4: return 0x2;
+ case 6: return 0x3;
+ case 8: return 0x4;
+ case 10: return 0x5;
+ /* Switches and Host Bridges may have more than 10 decoders */
+ case 12: return 0x6;
+ case 14: return 0x7;
+ case 16: return 0x8;
+ case 20: return 0x9;
+ case 24: return 0xa;
+ case 28: return 0xb;
+ case 32: return 0xc;
+ }
+ return 0;
+}
+
+int cxl_decoder_count_dec(int enc_cnt)
+{
+ switch (enc_cnt) {
+ case 0x0: return 1;
+ case 0x1: return 2;
+ case 0x2: return 4;
+ case 0x3: return 6;
+ case 0x4: return 8;
+ case 0x5: return 10;
+ /* Switches and Host Bridges may have more than 10 decoders */
+ case 0x6: return 12;
+ case 0x7: return 14;
+ case 0x8: return 16;
+ case 0x9: return 20;
+ case 0xa: return 24;
+ case 0xb: return 28;
+ case 0xc: return 32;
}
return 0;
}
@@ -393,6 +423,7 @@ void cxl_component_create_dvsec(CXLComponentState *cxl,
cxl->dvsec_offset += length;
}
+/* CXL r3.0 Section 8.2.4.19.7 CXL HDM Decoder n Control Register */
uint8_t cxl_interleave_ways_enc(int iw, Error **errp)
{
switch (iw) {
@@ -410,6 +441,23 @@ uint8_t cxl_interleave_ways_enc(int iw, Error **errp)
}
}
+int cxl_interleave_ways_dec(uint8_t iw_enc, Error **errp)
+{
+ switch (iw_enc) {
+ case 0x0: return 1;
+ case 0x1: return 2;
+ case 0x2: return 4;
+ case 0x3: return 8;
+ case 0x4: return 16;
+ case 0x8: return 3;
+ case 0x9: return 6;
+ case 0xa: return 12;
+ default:
+ error_setg(errp, "Encoded interleave ways: %d not supported", iw_enc);
+ return 0;
+ }
+}
+
uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp)
{
switch (gran) {