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