blob: 513900581fa73e11e4432366f1aa0205240b2060 [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.
John Chungf8fc7052024-05-03 20:05:29 +080014size_t generate_section_cxl_protocol(void **location)
Lawrence Tangde9707f2022-07-19 10:54:31 +010015{
John Chungf8fc7052024-05-03 20:05:29 +080016 //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;
Lawrence Tangde9707f2022-07-19 10:54:31 +010020
John Chungf8fc7052024-05-03 20:05:29 +080021 //Create random bytes.
22 int size = 116 + dvsec_len + error_log_len;
23 UINT8 *bytes = generate_random_bytes(size);
Lawrence Tangde9707f2022-07-19 10:54:31 +010024
John Chungf8fc7052024-05-03 20:05:29 +080025 //Set CXL agent type.
26 int cxl_agent_type = rand() % 2;
27 *(bytes + 8) = cxl_agent_type;
Lawrence Tangde9707f2022-07-19 10:54:31 +010028
John Chungf8fc7052024-05-03 20:05:29 +080029 //Set reserved areas to zero.
30 UINT64 *validation = (UINT64 *)bytes;
31 *validation &= 0x3F; //Validation bits 6-63.
32 for (int i = 0; i < 7; i++) {
33 *(bytes + 9 + i) = 0; //Reserved bytes 9-15.
34 }
Lawrence Tangde9707f2022-07-19 10:54:31 +010035
John Chungf8fc7052024-05-03 20:05:29 +080036 //We only reserve bytes if it's a CXL 1.1 device, and not a host downstream port.
37 if (cxl_agent_type == 0) {
38 for (int i = 0; i < 3; i++) {
39 *(bytes + 21 + i) = 0; //CXL agent address bytes 5-7.
40 }
41 }
Lawrence Tang0a4b3f22022-07-21 10:40:10 +010042
John Chungf8fc7052024-05-03 20:05:29 +080043 *(bytes + 34) &= ~0x7; //Device ID byte 10 bits 0-2.
44 UINT32 *reserved = (UINT32 *)(bytes + 36);
45 *reserved = 0; //Device ID bytes 12-15.
46 reserved = (UINT32 *)(bytes + 112);
47 *reserved = 0; //Reserved bytes 112-115.
Lawrence Tangde9707f2022-07-19 10:54:31 +010048
John Chungf8fc7052024-05-03 20:05:29 +080049 //If the device is a host downstream port, serial/capability structure is invalid.
50 if (cxl_agent_type != 0) {
51 for (int i = 0; i < 68; i++) {
52 *(bytes + 40 + i) =
53 0; //Device serial & capability structure.
54 }
55 }
56
57 //Set expected values.
58 UINT16 *dvsec_length_field = (UINT16 *)(bytes + 108);
59 UINT16 *error_log_len_field = (UINT16 *)(bytes + 110);
60 *dvsec_length_field = dvsec_len;
61 *error_log_len_field = error_log_len;
62
63 //Set return values, exit.
64 *location = bytes;
65 return size;
66}