diff options
Diffstat (limited to 'framework/helpers.c')
-rw-r--r-- | framework/helpers.c | 330 |
1 files changed, 0 insertions, 330 deletions
diff --git a/framework/helpers.c b/framework/helpers.c deleted file mode 100644 index e3daf24..0000000 --- a/framework/helpers.c +++ /dev/null @@ -1,330 +0,0 @@ -/** @file -* -* Copyright (c) 2013, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include <arm_gic.h> -#include <string.h> -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> - -#include <arch_helpers.h> -#include <platform.h> -#include <tftf.h> -#include <xlat_tables.h> -#include <spinlock.h> -#include <debug.h> -#include <psci.h> -#include <nvm.h> - -extern unsigned long __COHERENT_RAM_START__; -extern unsigned long __COHERENT_RAM_END__; - -/* - * The next 2 constants identify the extents of the coherent memory region. - * These addresses are used by the MMU setup code and therefore they must be - * page-aligned. It is the responsibility of the linker script to ensure that - * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols - * refer to page-aligned addresses. - */ -#define COH_START (unsigned long)(&__COHERENT_RAM_START__) -#define COH_LIMIT (unsigned long)(&__COHERENT_RAM_END__) - -/* Lock to avoid concurrent accesses to the serial console */ -static spinlock_t printf_lock; - -static const TEST_NVM nvm_init_state = { - TESTS_MAGIC_VALUE, // magic - NULL, // current_testcase - NULL, // next_testcase - { 0 }, // testcase_buffer - { { // testcase_results - TEST_NOT_RUN, /* testcase_results.result */ - 0, // testcase_results.duration - 0, // testcase_results.output_offset - 0, // testcase_results.output_size - } }, - 0, // result_buffer_size - NULL, // result_buffer -}; - -STATUS tftf_init_nvm(void) { - STATUS status; - unsigned magic; - - // Check if NVM needs to be initialized. - // NVM needs to be initialized when the magic number stored in NVM doesn't - // have the expected value. - // Note: this method isn't perfect and will sometimes lead to false results: - // NVM could be uninitialised but happen to have the expected magic value, - // which will make TFTF think it is already initialised. But we'll consider - // that's good enough. - status = tftf_nvm_read(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - - if (magic != TESTS_MAGIC_VALUE) { - status = tftf_nvm_write(0, &nvm_init_state, sizeof(nvm_init_state)); - if (status != STATUS_SUCCESS) { - return status; - } - } - - return STATUS_SUCCESS; -} - -STATUS tftf_clean_nvm(void) { - unsigned magic = 0xDEADC0DE; - - // Invalidate magic number. - // This will cause TFTF to re-initialise its data structures next time it runs. - return tftf_nvm_write(TEST_NVM_MAGIC_OFFSET, &magic, sizeof(unsigned)); -} - -void tftf_set_current_testcase(TESTCASE_FUNC testcase_function) { - tftf_nvm_write(TEST_NVM_CURRENT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_get_current_testcase(TESTCASE_FUNC* testcase_function) { - return tftf_nvm_read(TEST_NVM_CURRENT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); -} - -void tftf_set_next_testcase(TESTCASE_FUNC testcase_function) { - tftf_nvm_write(TEST_NVM_NEXT_TESTCASE_OFFSET, &testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_get_next_testcase(TESTCASE_FUNC* testcase_function) { - return tftf_nvm_read(TEST_NVM_NEXT_TESTCASE_OFFSET, testcase_function, sizeof(TESTCASE_FUNC)); -} - -STATUS tftf_testcase_set_result(const TESTCASE* testcase, TEST_RESULT result, const char* output, - unsigned long long duration) -{ - STATUS status; - unsigned result_buffer_size = 0; - TESTCASE_RESULT test_result; - - assert(testcase != NULL); - - // Initialize Test case result. - test_result.result = result; - test_result.duration = duration; - test_result.output_offset = 0; - test_result.output_size = output ? strlen(output) : 0; - - // Does the test have an output? - if (test_result.output_size != 0) { - // Get the size of the buffer containing all tests outputs. - status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, &result_buffer_size, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - - // Write the output buffer at the end of the string buffer in NVM. - test_result.output_offset = result_buffer_size; - status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_OFFSET + result_buffer_size, - output, test_result.output_size + 1); - if (status != STATUS_SUCCESS) { - return status; - } - - // And update the buffer size into NVM - result_buffer_size += test_result.output_size + 1; - status = tftf_nvm_write(TEST_NVM_RESULT_BUFFER_SIZE_OFFSET, - &result_buffer_size, sizeof(unsigned)); - if (status != STATUS_SUCCESS) { - return status; - } - } - - // Write the test result into NVM. - return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); -} - -STATUS tftf_testcase_update_result(const TESTCASE* testcase, TEST_RESULT result) { - STATUS status; - TESTCASE_RESULT test_result; - - // Read the test result from NVM - status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); - if (status != STATUS_SUCCESS) { - return status; - } - - // Update Test case result - test_result.result = result; - - // Write back the test result into NVM - return tftf_nvm_write(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - &test_result, sizeof(TESTCASE_RESULT)); -} - -STATUS tftf_testcase_get_result(const TESTCASE* testcase, TESTCASE_RESULT *result, - char *test_output) { - STATUS status; - unsigned output_size; - - assert(testcase != NULL); - assert(result != NULL); - assert(test_output != NULL); - - status = tftf_nvm_read(TEST_NVM_TESTCASE_RESULTS_OFFSET + (testcase->index * sizeof(TESTCASE_RESULT)), - result, sizeof(TESTCASE_RESULT)); - if (status != STATUS_SUCCESS) { - return status; - } - - output_size = result->output_size; - - if (output_size != 0) { - status = tftf_nvm_read(TEST_NVM_RESULT_BUFFER_OFFSET + result->output_offset, - test_output, output_size); - if (status != STATUS_SUCCESS) { - return status; - } - } - - test_output[output_size] = 0; - - return STATUS_SUCCESS; -} - -STATUS tftf_get_testcase_index(TESTCASE_FUNC testcase_function, unsigned *testsuite_index, unsigned *testcase_index, - unsigned get_next) -{ - unsigned i, j; - - if (!testcase_function || !testsuite_index || !testcase_index) { - return STATUS_INVALID_PARAMETER; - } - - for (i = 0; testsuites[i].name != NULL; i++) { - for (j = 0; testsuites[i].testcases[j].name != NULL; j++) { - if (testcase_function == testsuites[i].testcases[j].test) { - // Find the next testcase - if (get_next) { - if (testsuites[i].testcases[j+1].name != NULL) { - *testsuite_index = i; - *testcase_index = j+1; - } else if (testsuites[i+1].testcases != NULL) { - *testsuite_index = i+1; - *testcase_index = 0; - } else { - return STATUS_NOT_FOUND; - } - } else { - *testsuite_index = i; - *testcase_index = j; - } - return STATUS_SUCCESS; - } - } - } - return STATUS_NOT_FOUND; -} - -STATUS test_set_passed_and_next(TESTCASE_FUNC testcase_function) { - STATUS status; - unsigned testsuite_index, testcase_index; - unsigned next_testsuite_index, next_testcase_index; - - status = tftf_get_testcase_index(testcase_function, &testsuite_index, &testcase_index, 0); - if (status != STATUS_SUCCESS) { - return status; - } - status = tftf_get_testcase_index(testcase_function, &next_testsuite_index, &next_testcase_index, 1); - if (status != STATUS_SUCCESS) { - return status; - } - - // Set the NVM to resume the test execution - tftf_set_next_testcase(testsuites[next_testsuite_index].testcases[next_testcase_index].test); - tftf_set_current_testcase(NULL); - - // Assume the test has passed - if it fails then we will overwrite the result - return tftf_testcase_set_result(&testsuites[testsuite_index].testcases[testcase_index], - TEST_RESULT_SUCCESS, NULL, 0); -} - -STATUS tftf_testcase_set_result_as_crashed(TESTCASE_FUNC crashed_testcase_function) { - STATUS status; - unsigned testsuite_index, testcase_index; - - status = tftf_get_testcase_index(crashed_testcase_function, &testsuite_index, &testcase_index, 0); - if (status != STATUS_SUCCESS) { - return status; - } - - return tftf_testcase_update_result(&testsuites[testsuite_index].testcases[testcase_index], TEST_RESULT_CRASHED); -} - - -void mp_printf(const char *fmt, ...) -{ - va_list ap; - char str[256]; - - /* - * TODO: It would be simpler to use vprintf() instead of - * vsnprintf() + printf(), we wouldn't need to declare a static buffer - * for storing the product of vsnprintf(). Unfortunately our C library - * doesn't provide vprintf() at the moment. - * Import vprintf() code from FreeBSD C library to our local C library. - */ - va_start(ap, fmt); - vsnprintf(str, sizeof(str), fmt, ap); - str[sizeof(str) - 1] = 0; - va_end(ap); - - spin_lock(&printf_lock); - printf("[cpu 0x%.4x] ", read_mpidr() & 0xFFFF); - printf("%s", str); - spin_unlock(&printf_lock); -} - -bool tftf_is_core_enabled(unsigned int core_pos) -{ - smc64_ret_values core_state; - smc64_args aff_info_args = { - PSCI_AFFINITY_INFO_AARCH64, - tftf_platform_core_pos_to_mpid(core_pos), - 0 /* affinity level */ - }; - - core_state = tftf_smc64(&aff_info_args); - - return core_state.ret0 == PSCI_STATE_ON; -} - -void tftf_configure_mmu(void) -{ - mmap_add_region(COH_START, COH_START, COH_LIMIT - COH_START, - MT_DEVICE | MT_RW | MT_NS); - mmap_add(tftf_platform_get_mmap()); - init_xlat_tables(); - - tftf_enable_mmu(); -} - -void tftf_enable_mmu(void) -{ - if (IS_IN_EL1()) - enable_mmu_el1(0); - else if (IS_IN_EL2()) - enable_mmu_el2(0); - else - panic(); -} |