blob: e171c7fa894857995448edff3f36fa834cda913a [file] [log] [blame]
Lawrence Tangde9707f2022-07-19 10:54:31 +01001/**
Lawrence Tangefe17e22022-08-08 09:16:23 +01002 * Functions for generating pseudo-random CXL protocol error sections.
Ed Tanousfedd4572024-07-12 13:56:00 -07003 *
Lawrence Tangde9707f2022-07-19 10:54:31 +01004 * Author: Lawrence.Tang@arm.com
5 **/
6
7#include <stdlib.h>
Thu Nguyene42fb482024-10-15 14:43:11 +00008#include <libcper/BaseTypes.h>
9#include <libcper/generator/gen-utils.h>
10#include <libcper/generator/sections/gen-section.h>
Lawrence Tangde9707f2022-07-19 10:54:31 +010011
Lawrence Tangefe17e22022-08-08 09:16:23 +010012//Generates a single pseudo-random CXL protocol error section, saving the resulting address to the given
Lawrence Tangde9707f2022-07-19 10:54:31 +010013//location. Returns the size of the newly created section.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080014size_t generate_section_cxl_protocol(void **location,
15 GEN_VALID_BITS_TEST_TYPE validBitsType)
Lawrence Tangde9707f2022-07-19 10:54:31 +010016{
John Chungf8fc7052024-05-03 20:05:29 +080017 //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.
Ed Tanous2d4d3b62025-03-11 10:34:29 -070019 int dvsec_len = cper_rand() % 64;
20 int error_log_len = cper_rand() % 64;
Lawrence Tangde9707f2022-07-19 10:54:31 +010021
John Chungf8fc7052024-05-03 20:05:29 +080022 //Create random bytes.
23 int size = 116 + dvsec_len + error_log_len;
24 UINT8 *bytes = generate_random_bytes(size);
Lawrence Tangde9707f2022-07-19 10:54:31 +010025
John Chungf8fc7052024-05-03 20:05:29 +080026 //Set CXL agent type.
Ed Tanous2d4d3b62025-03-11 10:34:29 -070027 int cxl_agent_type = cper_rand() % 2;
John Chungf8fc7052024-05-03 20:05:29 +080028 *(bytes + 8) = cxl_agent_type;
Lawrence Tangde9707f2022-07-19 10:54:31 +010029
John Chungf8fc7052024-05-03 20:05:29 +080030 //Set reserved areas to zero.
31 UINT64 *validation = (UINT64 *)bytes;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080032 *validation &= 0x67;
33 if (validBitsType == ALL_VALID) {
34 *validation = 0x67;
35 } else if (validBitsType == SOME_VALID) {
36 *validation = 0x25;
37 }
John Chungf8fc7052024-05-03 20:05:29 +080038 for (int i = 0; i < 7; i++) {
39 *(bytes + 9 + i) = 0; //Reserved bytes 9-15.
40 }
Lawrence Tangde9707f2022-07-19 10:54:31 +010041
John Chungf8fc7052024-05-03 20:05:29 +080042 //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 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080047 *validation |=
48 0x18; //Device Serial Number depends on agent type
John Chungf8fc7052024-05-03 20:05:29 +080049 }
Lawrence Tang0a4b3f22022-07-21 10:40:10 +010050
John Chungf8fc7052024-05-03 20:05:29 +080051 *(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.
Lawrence Tangde9707f2022-07-19 10:54:31 +010056
John Chungf8fc7052024-05-03 20:05:29 +080057 //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}