1 /** 2 * Functions for generating pseudo-random CPER DMAr 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 generic DMAr error section, saving the resulting address to the given 13 //location. Returns the size of the newly created section. 14 size_t generate_section_dmar_generic(void **location, 15 GEN_VALID_BITS_TEST_TYPE validBitsType) 16 { 17 (void)validBitsType; 18 //Create random bytes. 19 int size = 32; 20 UINT8 *bytes = generate_random_bytes(size); 21 22 //Set reserved areas to zero. 23 UINT64 *reserved = (UINT64 *)(bytes + 16); 24 *reserved = 0; 25 *(reserved + 1) = 0; 26 27 //Set expected values. 28 *(bytes + 4) = cper_rand() % 0xC; //Fault reason. 29 *(bytes + 5) = cper_rand() % 2; //Access type. 30 *(bytes + 6) = cper_rand() % 2; //Address type. 31 *(bytes + 7) = cper_rand() % 2 + 1; //Architecture type. 32 33 //Set return values, exit. 34 *location = bytes; 35 return size; 36 } 37 38 //Generates a single pseudo-random VT-d DMAr error section, saving the resulting address to the given 39 //location. Returns the size of the newly created section. 40 size_t generate_section_dmar_vtd(void **location, 41 GEN_VALID_BITS_TEST_TYPE validBitsType) 42 { 43 (void)validBitsType; 44 //Create random bytes. 45 int size = 144; 46 UINT8 *bytes = generate_random_bytes(size); 47 48 //Set reserved areas to zero. 49 for (int i = 0; i < 12; i++) { 50 *(bytes + 36 + i) = 0; //Reserved bytes 36-47. 51 } 52 UINT8 *fault_record = bytes + 48; 53 UINT32 *reserved = (UINT32 *)(fault_record); 54 *reserved &= ~0xFFF; //First 12 bits of fault record. 55 reserved = (UINT32 *)(fault_record + 8); 56 *reserved &= ~0x1FFF0000; //Bits 80-92 of fault record. 57 *(fault_record + 15) &= 0x7; //Very last bit of fault record. 58 59 //Set return values, exit. 60 *location = bytes; 61 return size; 62 } 63 64 //Generates a single pseudo-random IOMMU DMAr error section, saving the resulting address to the given 65 //location. Returns the size of the newly created section. 66 size_t generate_section_dmar_iommu(void **location, 67 GEN_VALID_BITS_TEST_TYPE validBitsType) 68 { 69 (void)validBitsType; 70 //Create random bytes. 71 int size = 144; 72 UINT8 *bytes = generate_random_bytes(size); 73 74 //Set reserved areas to zero. 75 for (int i = 0; i < 7; i++) { 76 *(bytes + 1 + i) = 0; //Reserved bytes 1 to 7. 77 } 78 UINT64 *reserved = (UINT64 *)(bytes + 24); 79 *reserved = 0; //Reserved bytes 24-31. 80 for (int i = 0; i < 16; i++) { 81 *(bytes + 48 + i) = 0; //Reserved bytes 48-63. 82 } 83 84 //Set return values, exit. 85 *location = bytes; 86 return size; 87 } 88