1 /** 2 * Functions for generating psuedo-random CXL protocol error sections. 3 * 4 * Author: Lawrence.Tang@arm.com 5 **/ 6 7 #include <stdlib.h> 8 #include "../../edk/BaseTypes.h" 9 #include "../gen-utils.h" 10 #include "gen-sections.h" 11 12 //Generates a single psuedo-random CXL protocol error section, saving the resulting address to the given 13 //location. Returns the size of the newly created section. 14 size_t generate_section_cxl_protocol(void** location) 15 { 16 //Create a random length for the CXL DVSEC and CXL error log. 17 //The logs attached here do not necessarily conform to the specification, and are simply random. 18 int dvsec_len = rand() % 64; 19 int error_log_len = rand() % 64; 20 21 //Create random bytes. 22 int size = 116 + dvsec_len + error_log_len; 23 UINT8* bytes = generate_random_bytes(size); 24 25 //Set CXL agent type. 26 int cxl_agent_type = rand() % 2; 27 *(bytes + 8) = cxl_agent_type; 28 29 //Set reserved areas to zero. 30 UINT64* validation = (UINT64*)bytes; 31 *validation &= 0b111111; //Validation bits 6-63. 32 for (int i=0; i<7; i++) 33 *(bytes + 9 + i) = 0; //Reserved bytes 9-15. 34 35 //We only reserve bytes if it's a CXL 1.1 device, and not a host downstream port. 36 if (cxl_agent_type == 0) 37 { 38 for (int i=0; i<3; i++) 39 *(bytes + 20 + i) = 0; //CXL agent address bytes 5-7. 40 } 41 42 *(bytes + 34) &= ~0b111; //Device ID byte 10 bits 0-2. 43 UINT32* reserved = (UINT32*)(bytes + 36); 44 *reserved = 0; //Device ID bytes 12-15. 45 reserved = (UINT32*)(bytes + 112); 46 *reserved = 0; //Reserved bytes 112-115. 47 48 //If the device is a host downstream port, serial/capability structure is invalid. 49 if (cxl_agent_type != 0) 50 { 51 for (int i=0; i<68; i++) 52 *(bytes + 40 + i) = 0; //Device serial & capability structure. 53 } 54 55 //Set expected values. 56 UINT16* dvsec_length_field = (UINT16*)(bytes + 108); 57 UINT16* error_log_len_field = (UINT16*)(bytes + 110); 58 *dvsec_length_field = dvsec_len; 59 *error_log_len_field = error_log_len; 60 61 //Set return values, exit. 62 *location = bytes; 63 return size; 64 }