xref: /openbmc/libcper/generator/sections/gen-section-dmar.c (revision ae8f6d9aaeaf37332e8924dd2c0b6f320335548c)
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.
generate_section_dmar_generic(void ** location,GEN_VALID_BITS_TEST_TYPE validBitsType)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) = rand() % 0xC;   //Fault reason.
29 	*(bytes + 5) = rand() % 2;     //Access type.
30 	*(bytes + 6) = rand() % 2;     //Address type.
31 	*(bytes + 7) = 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.
generate_section_dmar_vtd(void ** location,GEN_VALID_BITS_TEST_TYPE validBitsType)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.
generate_section_dmar_iommu(void ** location,GEN_VALID_BITS_TEST_TYPE validBitsType)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