1de9707f9SLawrence Tang /** 2efe17e2cSLawrence Tang * Functions for generating pseudo-random CPER PCIe error sections. 3de9707f9SLawrence Tang * 4de9707f9SLawrence Tang * Author: Lawrence.Tang@arm.com 5de9707f9SLawrence Tang **/ 6de9707f9SLawrence Tang 7de9707f9SLawrence Tang #include <stdlib.h> 8de9707f9SLawrence Tang #include "../../edk/BaseTypes.h" 9de9707f9SLawrence Tang #include "../gen-utils.h" 108f977457SLawrence Tang #include "gen-section.h" 11de9707f9SLawrence Tang 12*f8fc7052SJohn Chung #define PCIE_PORT_TYPES \ 13*f8fc7052SJohn Chung (int[]) \ 14*f8fc7052SJohn Chung { \ 15*f8fc7052SJohn Chung 0, 1, 4, 5, 6, 7, 8, 9, 10 \ 16*f8fc7052SJohn Chung } 17de9707f9SLawrence Tang 18efe17e2cSLawrence Tang //Generates a single pseudo-random PCIe error section, saving the resulting address to the given 19de9707f9SLawrence Tang //location. Returns the size of the newly created section. 20de9707f9SLawrence Tang size_t generate_section_pcie(void **location) 21de9707f9SLawrence Tang { 22de9707f9SLawrence Tang //Create random bytes. 23de9707f9SLawrence Tang int size = 208; 24de9707f9SLawrence Tang UINT8 *bytes = generate_random_bytes(size); 25de9707f9SLawrence Tang 26de9707f9SLawrence Tang //Set reserved areas to zero. 27de9707f9SLawrence Tang UINT64 *validation = (UINT64 *)bytes; 28de9707f9SLawrence Tang *validation &= 0xFF; //Validation 8-63 29de9707f9SLawrence Tang UINT32 *version = (UINT32 *)(bytes + 12); 30de9707f9SLawrence Tang *version &= 0xFFFF; //Version bytes 2-3 31de9707f9SLawrence Tang UINT32 *reserved = (UINT32 *)(bytes + 20); 32de9707f9SLawrence Tang *reserved = 0; //Reserved bytes 20-24 33*f8fc7052SJohn Chung *(bytes + 37) &= ~0x7; //Device ID byte 13 bits 0-3 34de9707f9SLawrence Tang *(bytes + 39) = 0; //Device ID byte 15 35de9707f9SLawrence Tang 363ab351feSLawrence Tang //Set expected values. 373ab351feSLawrence Tang int minor = rand() % 128; 383ab351feSLawrence Tang int major = rand() % 128; 393ab351feSLawrence Tang *version = int_to_bcd(minor); 403ab351feSLawrence Tang *version |= int_to_bcd(major) << 8; 413ab351feSLawrence Tang 42de9707f9SLawrence Tang //Fix values that could be above range. 43de9707f9SLawrence Tang UINT32 *port_type = (UINT32 *)(bytes + 8); 44*f8fc7052SJohn Chung *port_type = PCIE_PORT_TYPES[rand() % 45*f8fc7052SJohn Chung (sizeof(PCIE_PORT_TYPES) / sizeof(int))]; 46de9707f9SLawrence Tang 47de9707f9SLawrence Tang //Set return values, exit. 48de9707f9SLawrence Tang *location = bytes; 49de9707f9SLawrence Tang return size; 50de9707f9SLawrence Tang } 51