1*de9707f9SLawrence Tang /**
2*de9707f9SLawrence Tang  * Functions for generating psuedo-random CPER DMAr error sections.
3*de9707f9SLawrence Tang  *
4*de9707f9SLawrence Tang  * Author: Lawrence.Tang@arm.com
5*de9707f9SLawrence Tang  **/
6*de9707f9SLawrence Tang 
7*de9707f9SLawrence Tang #include <stdlib.h>
8*de9707f9SLawrence Tang #include "../../edk/BaseTypes.h"
9*de9707f9SLawrence Tang #include "../gen-utils.h"
10*de9707f9SLawrence Tang #include "gen-sections.h"
11*de9707f9SLawrence Tang 
12*de9707f9SLawrence Tang //Generates a single psuedo-random generic DMAr error section, saving the resulting address to the given
13*de9707f9SLawrence Tang //location. Returns the size of the newly created section.
14*de9707f9SLawrence Tang size_t generate_section_dmar_generic(void** location)
15*de9707f9SLawrence Tang {
16*de9707f9SLawrence Tang     //Create random bytes.
17*de9707f9SLawrence Tang     int size = 32;
18*de9707f9SLawrence Tang     UINT8* bytes = generate_random_bytes(size);
19*de9707f9SLawrence Tang 
20*de9707f9SLawrence Tang     //Set reserved areas to zero.
21*de9707f9SLawrence Tang     UINT64* reserved = (UINT64*)(bytes + 16);
22*de9707f9SLawrence Tang     *reserved = 0;
23*de9707f9SLawrence Tang     *(reserved + 1) = 0;
24*de9707f9SLawrence Tang 
25*de9707f9SLawrence Tang     //Set expected values.
26*de9707f9SLawrence Tang     *(bytes + 4) = rand() % 0xC; //Fault reason.
27*de9707f9SLawrence Tang     *(bytes + 5) = rand() % 2; //Access type.
28*de9707f9SLawrence Tang     *(bytes + 6) = rand() % 2; //Address type.
29*de9707f9SLawrence Tang     *(bytes + 7) = rand() % 2 + 1; //Architecture type.
30*de9707f9SLawrence Tang 
31*de9707f9SLawrence Tang     //Set return values, exit.
32*de9707f9SLawrence Tang     *location = bytes;
33*de9707f9SLawrence Tang     return size;
34*de9707f9SLawrence Tang }
35*de9707f9SLawrence Tang 
36*de9707f9SLawrence Tang //Generates a single psuedo-random VT-d DMAr error section, saving the resulting address to the given
37*de9707f9SLawrence Tang //location. Returns the size of the newly created section.
38*de9707f9SLawrence Tang size_t generate_section_dmar_vtd(void** location)
39*de9707f9SLawrence Tang {
40*de9707f9SLawrence Tang     //Create random bytes.
41*de9707f9SLawrence Tang     int size = 144;
42*de9707f9SLawrence Tang     UINT8* bytes = generate_random_bytes(size);
43*de9707f9SLawrence Tang 
44*de9707f9SLawrence Tang     //Set reserved areas to zero.
45*de9707f9SLawrence Tang     for (int i=0; i<12; i++)
46*de9707f9SLawrence Tang         *(bytes + 36 + i) = 0; //Reserved bytes 36-47.
47*de9707f9SLawrence Tang 
48*de9707f9SLawrence Tang     //Set return values, exit.
49*de9707f9SLawrence Tang     *location = bytes;
50*de9707f9SLawrence Tang     return size;
51*de9707f9SLawrence Tang }
52*de9707f9SLawrence Tang 
53*de9707f9SLawrence Tang //Generates a single psuedo-random IOMMU DMAr error section, saving the resulting address to the given
54*de9707f9SLawrence Tang //location. Returns the size of the newly created section.
55*de9707f9SLawrence Tang size_t generate_section_dmar_iommu(void** location)
56*de9707f9SLawrence Tang {
57*de9707f9SLawrence Tang     //Create random bytes.
58*de9707f9SLawrence Tang     int size = 144;
59*de9707f9SLawrence Tang     UINT8* bytes = generate_random_bytes(size);
60*de9707f9SLawrence Tang 
61*de9707f9SLawrence Tang     //Set reserved areas to zero.
62*de9707f9SLawrence Tang     for (int i=0; i<7; i++)
63*de9707f9SLawrence Tang         *(bytes + 1 + i) + 0; //Reserved bytes 1 to 7.
64*de9707f9SLawrence Tang     UINT64* reserved = (UINT64*)(bytes + 24);
65*de9707f9SLawrence Tang     *reserved = 0; //Reserved bytes 24-31.
66*de9707f9SLawrence Tang     for (int i=0; i<16; i++)
67*de9707f9SLawrence Tang         *(bytes + 48 + i) = 0; //Reserved bytes 48-63.
68*de9707f9SLawrence Tang 
69*de9707f9SLawrence Tang     //Set return values, exit.
70*de9707f9SLawrence Tang     *location = bytes;
71*de9707f9SLawrence Tang     return size;
72*de9707f9SLawrence Tang }