|
| 1 | +// Copyright (c) 2021 Intel Corporation |
| 2 | +// |
| 3 | +// SPDX-License-Identifier: BSD-2-Clause-Patent |
| 4 | + |
| 5 | +#![no_std] |
| 6 | +#![no_main] |
| 7 | +#![allow(unused)] |
| 8 | +#![feature(alloc_error_handler)] |
| 9 | +#[macro_use] |
| 10 | + |
| 11 | +mod lib; |
| 12 | +mod testiorw32; |
| 13 | +mod testiorw8; |
| 14 | +mod testtdinfo; |
| 15 | +mod testtdreport; |
| 16 | + |
| 17 | +extern crate alloc; |
| 18 | +use alloc::boxed::Box; |
| 19 | +use alloc::string::String; |
| 20 | +use alloc::string::ToString; |
| 21 | +use alloc::vec::Vec; |
| 22 | +use core::ffi::c_void; |
| 23 | +use core::panic::PanicInfo; |
| 24 | +use linked_list_allocator::LockedHeap; |
| 25 | +use td_layout::memslice; |
| 26 | + |
| 27 | +use crate::lib::{TestResult, TestSuite}; |
| 28 | +use crate::testiorw32::Tdiorw32; |
| 29 | +use crate::testiorw8::Tdiorw8; |
| 30 | +use crate::testtdinfo::Tdinfo; |
| 31 | +use crate::testtdreport::Tdreport; |
| 32 | + |
| 33 | +use r_efi::efi::Guid; |
| 34 | +use serde::{Deserialize, Serialize}; |
| 35 | +use serde_json::{Result, Value}; |
| 36 | +use td_uefi_pi::{fv, hob, pi}; |
| 37 | + |
| 38 | +#[derive(Debug, Serialize, Deserialize)] |
| 39 | +// The test cases' data structure corresponds to the test config json data structure |
| 40 | +pub struct TestCases { |
| 41 | + pub tcs001: Tdinfo, |
| 42 | + pub tcs002: Tdinfo, |
| 43 | + pub tcs003: Tdinfo, |
| 44 | + pub tcs004: Tdreport, |
| 45 | + pub tcs005: Tdiorw8, |
| 46 | + pub tcs006: Tdiorw32, |
| 47 | +} |
| 48 | + |
| 49 | +pub const CFV_FFS_HEADER_TEST_CONFIG_GUID: Guid = Guid::from_fields( |
| 50 | + 0xf10e684e, |
| 51 | + 0x3abd, |
| 52 | + 0x20e4, |
| 53 | + 0x59, |
| 54 | + 0x32, |
| 55 | + &[0x8f, 0x97, 0x3c, 0x35, 0x5e, 0x57], |
| 56 | +); // {F10E684E-3ABD-20E4-5932-8F973C355E57} |
| 57 | + |
| 58 | +#[cfg(not(test))] |
| 59 | +#[panic_handler] |
| 60 | +#[allow(clippy::empty_loop)] |
| 61 | +fn panic(_info: &PanicInfo) -> ! { |
| 62 | + log::info!("panic ... {:?}\n", _info); |
| 63 | + loop {} |
| 64 | +} |
| 65 | + |
| 66 | +#[alloc_error_handler] |
| 67 | +#[allow(clippy::empty_loop)] |
| 68 | +fn alloc_error(_info: core::alloc::Layout) -> ! { |
| 69 | + log::info!("alloc_error ... {:?}\n", _info); |
| 70 | + panic!("deadloop"); |
| 71 | +} |
| 72 | + |
| 73 | +#[cfg(not(test))] |
| 74 | +#[global_allocator] |
| 75 | +static ALLOCATOR: LockedHeap = LockedHeap::empty(); |
| 76 | + |
| 77 | +#[cfg(not(test))] |
| 78 | +fn init_heap(heap_start: usize, heap_size: usize) { |
| 79 | + unsafe { |
| 80 | + ALLOCATOR.lock().init(heap_start, heap_size); |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +#[cfg(not(test))] |
| 85 | +fn build_testcases() -> TestCases { |
| 86 | + log::info!("Starting get test data from cfv and parse json data\n"); |
| 87 | + let cfv = memslice::get_mem_slice(memslice::SliceType::Config); |
| 88 | + let json_data = fv::get_file_from_fv( |
| 89 | + cfv, |
| 90 | + pi::fv::FV_FILETYPE_RAW, |
| 91 | + CFV_FFS_HEADER_TEST_CONFIG_GUID, |
| 92 | + ) |
| 93 | + .unwrap(); |
| 94 | + let json_string = String::from_utf8_lossy(json_data).to_string(); |
| 95 | + // trim zero in json string |
| 96 | + let json_config = json_string.trim_matches(char::from(0)); |
| 97 | + |
| 98 | + serde_json::from_str(json_config).unwrap() |
| 99 | +} |
| 100 | + |
| 101 | +#[cfg(not(test))] |
| 102 | +#[no_mangle] |
| 103 | +#[cfg_attr(target_os = "uefi", export_name = "efi_main")] |
| 104 | +extern "win64" fn _start(hob: *const c_void) -> ! { |
| 105 | + use td_layout::runtime::*; |
| 106 | + |
| 107 | + td_logger::init(); |
| 108 | + log::info!("Starting rust-tdcall-payload hob - {:p}\n", hob); |
| 109 | + |
| 110 | + // init heap so that we can allocate memory |
| 111 | + let hob_buffer = unsafe { |
| 112 | + memslice::get_dynamic_mem_slice_mut(memslice::SliceType::PayloadHob, hob as usize) |
| 113 | + }; |
| 114 | + |
| 115 | + let hob_size = hob::get_hob_total_size(hob_buffer).unwrap(); |
| 116 | + let hob_list = &hob_buffer[..hob_size]; |
| 117 | + |
| 118 | + init_heap( |
| 119 | + (hob::get_system_memory_size_below_4gb(hob_list).unwrap() as usize |
| 120 | + - (TD_PAYLOAD_HOB_SIZE |
| 121 | + + TD_PAYLOAD_STACK_SIZE |
| 122 | + + TD_PAYLOAD_SHADOW_STACK_SIZE |
| 123 | + + TD_PAYLOAD_ACPI_SIZE |
| 124 | + + TD_PAYLOAD_EVENT_LOG_SIZE) as usize |
| 125 | + - TD_PAYLOAD_HEAP_SIZE as usize), |
| 126 | + TD_PAYLOAD_HEAP_SIZE as usize, |
| 127 | + ); |
| 128 | + |
| 129 | + // create TestSuite to hold the test cases |
| 130 | + let mut ts = TestSuite { |
| 131 | + testsuite: Vec::new(), |
| 132 | + passed_cases: 0, |
| 133 | + failed_cases: 0, |
| 134 | + }; |
| 135 | + |
| 136 | + // build test cases with test configuration data in CFV |
| 137 | + let tcs = build_testcases(); |
| 138 | + |
| 139 | + // Add test cases in ts.testsuite |
| 140 | + if tcs.tcs001.run { |
| 141 | + ts.testsuite.push(Box::new(tcs.tcs001)); |
| 142 | + } |
| 143 | + |
| 144 | + if tcs.tcs002.run { |
| 145 | + ts.testsuite.push(Box::new(tcs.tcs002)); |
| 146 | + } |
| 147 | + |
| 148 | + if tcs.tcs003.run { |
| 149 | + ts.testsuite.push(Box::new(tcs.tcs003)); |
| 150 | + } |
| 151 | + |
| 152 | + if tcs.tcs004.run { |
| 153 | + ts.testsuite.push(Box::new(tcs.tcs004)); |
| 154 | + } |
| 155 | + |
| 156 | + if tcs.tcs005.run { |
| 157 | + ts.testsuite.push(Box::new(tcs.tcs005)); |
| 158 | + } |
| 159 | + |
| 160 | + if tcs.tcs006.run { |
| 161 | + ts.testsuite.push(Box::new(tcs.tcs006)); |
| 162 | + } |
| 163 | + |
| 164 | + // run the TestSuite which contains the test cases |
| 165 | + log::info!("---------------------------------------------\n"); |
| 166 | + log::info!("Start to run tests.\n"); |
| 167 | + log::info!("---------------------------------------------\n"); |
| 168 | + ts.run(); |
| 169 | + log::info!( |
| 170 | + "Test Result: Total run {0} tests; {1} passed; {2} failed\n", |
| 171 | + ts.testsuite.len(), |
| 172 | + ts.passed_cases, |
| 173 | + ts.failed_cases |
| 174 | + ); |
| 175 | + |
| 176 | + panic!("deadloop"); |
| 177 | +} |
0 commit comments