| Lawrence Tang | de9707f | 2022-07-19 10:54:31 +0100 | [diff] [blame^] | 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 | //Set expected values. | 
|  | 49 | UINT16* dvsec_length_field = (UINT16*)(bytes + 108); | 
|  | 50 | UINT16* error_log_len_field = (UINT16*)(bytes + 110); | 
|  | 51 | *dvsec_length_field = dvsec_len; | 
|  | 52 | *error_log_len_field = error_log_len; | 
|  | 53 |  | 
|  | 54 | //Set return values, exit. | 
|  | 55 | *location = bytes; | 
|  | 56 | return size; | 
|  | 57 | } |