|
@@ -13,15 +13,45 @@
|
|
#include "hw/pci/pci.h"
|
|
#include "hw/pci/pci.h"
|
|
#include "hw/cxl/cxl.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)
|
|
int cxl_decoder_count_enc(int count)
|
|
{
|
|
{
|
|
switch (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;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -393,6 +423,7 @@ void cxl_component_create_dvsec(CXLComponentState *cxl,
|
|
cxl->dvsec_offset += length;
|
|
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)
|
|
uint8_t cxl_interleave_ways_enc(int iw, Error **errp)
|
|
{
|
|
{
|
|
switch (iw) {
|
|
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)
|
|
uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp)
|
|
{
|
|
{
|
|
switch (gran) {
|
|
switch (gran) {
|