diff options
author | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2014-10-15 16:56:03 +0100 |
---|---|---|
committer | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2014-10-21 10:16:44 +0100 |
commit | 2902b1ddf6101cd4c3cffc0443326bdea3bda0a6 (patch) | |
tree | 23b5dbde95529a519668c248198984d2d42f4308 | |
parent | 99565ab9d814d9c5844fbe2a4daba74848a95cc3 (diff) |
Restructure framework's directory hierarchy
This is a first, rough attempt at cleaning the framework's directory
hierarchy.
Basically, almost everything is moved to individual directories
under lib/. What's left under framework/ are the core features of
the framework, i.e. things that test cases won't ever need.
This patch also introduces some cleanups.
The following functions are removed:
- tftf_platform_get_time()
We'll need such a function in the future to measure tests execution
time but there's no reason for it to be platform-specific, we can
use the Generic Timer instead when we get to it.
Tracked by GENFW-506.
- tftf_platform_reset()
We'll need a function to reset the platform in the future but at
the moment it is not used.
Tracked by GENFW-500.
- tftf_platform_core_whoami()
Not needed. A CPU can just call read_mpidr_el1() to get its MPID,
then platform_get_core_pos() to get the corresponding linear ID.
See GENFW-483.
- tftf_is_core_enabled()
Superseded by plat_get_aff_state().
- tftf_core_participates_in_testcase()
Superseded by the platform API to query the platform topology.
Move the following defintions out of framework/helpers.c:
- Move mp_printf() in lib/utils/mp_printf.c
- Move MMU functions into plat_common.c as default implementations
of these platform functions.
What's left in helpers.c then are helper functions to write test
results into NVM so rename the file into nvm_results_helpers.c.
Remove bl_common.h as it contains only Trusted Firmware specific
definitions.
Rename tests_api.h into tftf_lib.h. Also move some of its
declarations into new header files: irq.h, systimer.h, sgi.h.
Remove tftf_common.h and move its declarations to tftf_lib.h.
Rename rt_services/ into runtime_services/.
The test cases' directory hierarchy needs to be restructured as well,
this will come in a subsequent patch.
Change-Id: I143c4c888586301594f6b6339d6e48cbbd817570
-rw-r--r-- | Makefile | 38 | ||||
-rw-r--r-- | framework/aarch64/entrypoint.S | 4 | ||||
-rw-r--r-- | framework/aarch64/tftf_asm_macros.S | 89 | ||||
-rw-r--r-- | framework/framework.mk | 64 | ||||
-rw-r--r-- | framework/helpers.c | 330 | ||||
-rw-r--r-- | framework/include/suspend.h | 38 | ||||
-rw-r--r-- | framework/include/tftf.h | 22 | ||||
-rw-r--r-- | framework/main.c | 3 | ||||
-rw-r--r-- | framework/nvm_results_helpers.c | 281 | ||||
-rw-r--r-- | framework/platform.c | 47 | ||||
-rw-r--r-- | include/common/asm_macros.S | 58 | ||||
-rw-r--r-- | include/common/bl_common.h | 221 | ||||
-rw-r--r-- | include/common/tftf_common.h | 50 | ||||
-rw-r--r-- | include/drivers/intel_p30_flash.h (renamed from include/common/intel_p30_flash.h) | 0 | ||||
-rw-r--r-- | include/lib/irq.h (renamed from framework/include/irq.h) | 10 | ||||
-rw-r--r-- | include/lib/power_management.h | 18 | ||||
-rw-r--r-- | include/lib/sgi.h | 53 | ||||
-rw-r--r-- | include/lib/status.h | 52 | ||||
-rw-r--r-- | include/lib/systimer.h | 42 | ||||
-rw-r--r-- | include/lib/tftf_lib.h (renamed from framework/include/tests_api.h) | 81 | ||||
-rw-r--r-- | include/plat/common/platform.h | 7 | ||||
-rw-r--r-- | include/runtime_services/psci.h (renamed from include/rt_services/psci.h) | 0 | ||||
-rw-r--r-- | include/runtime_services/secure_el1_payloads/tsp.h (renamed from include/secure_el1_payloads/tsp.h) | 0 | ||||
-rw-r--r-- | include/runtime_services/smc.h (renamed from include/rt_services/smc.h) | 0 | ||||
-rw-r--r-- | include/runtime_services/std_svc.h (renamed from include/rt_services/std_svc.h) | 0 | ||||
-rw-r--r-- | include/runtime_services/trusted_os.h (renamed from include/rt_services/trusted_os.h) | 0 | ||||
-rw-r--r-- | lib/aarch64/misc_helpers.S | 20 | ||||
-rw-r--r-- | lib/delay/delay.c (renamed from framework/delay.c) | 0 | ||||
-rw-r--r-- | lib/irq/irq.c (renamed from framework/irq.c) | 1 | ||||
-rw-r--r-- | lib/locks/spinlock.S (renamed from lib/locks/exclusive/spinlock.S) | 0 | ||||
-rw-r--r-- | lib/power_management/hotplug/hotplug.c | 2 | ||||
-rw-r--r-- | lib/power_management/suspend/asm_tftf_suspend.S (renamed from lib/suspend/asm_tftf_suspend.S) | 1 | ||||
-rw-r--r-- | lib/power_management/suspend/suspend_private.h (renamed from lib/suspend/suspend_private.h) | 0 | ||||
-rw-r--r-- | lib/power_management/suspend/tftf_suspend.c (renamed from lib/suspend/tftf_suspend.c) | 4 | ||||
-rw-r--r-- | lib/psci/psci.c (renamed from framework/psci.c) | 0 | ||||
-rw-r--r-- | lib/smc/asm_smc.S (renamed from framework/aarch64/asm_helpers.S) | 35 | ||||
-rw-r--r-- | lib/smc/smc.c (renamed from framework/smc.c) | 1 | ||||
-rw-r--r-- | lib/systimer/systimer.c (renamed from framework/systimer.c) | 3 | ||||
-rw-r--r-- | lib/trusted_os/trusted_os.c (renamed from framework/trusted_os.c) | 0 | ||||
-rw-r--r-- | lib/utils/mp_printf.c | 60 | ||||
-rw-r--r-- | plat/common/aarch64/plat_common.c | 63 | ||||
-rw-r--r-- | plat/common/tftf_nvm_accessors.c | 4 | ||||
-rw-r--r-- | plat/fvp/plat_setup.c | 2 | ||||
-rw-r--r-- | plat/juno/plat_setup.c | 2 | ||||
-rw-r--r-- | tests/test_dummy.c | 2 |
45 files changed, 755 insertions, 953 deletions
@@ -114,25 +114,25 @@ include plat/${PLAT}/platform.mk .PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch .SUFFIXES: -INCLUDES := -Iinclude \ - -Iinclude/common \ - -Iinclude/drivers \ - -Iinclude/drivers/arm \ - -Iinclude/drivers/io \ - -Iinclude/lib \ - -Iinclude/lib/aarch64 \ - -Iinclude/lib/utils \ - -Iinclude/plat/common \ - -Iinclude/rt_services/ \ - -Iinclude/secure_el1_payloads \ - -Iinclude/stdlib \ - -Iinclude/stdlib/sys \ - ${PLAT_INCLUDES} \ - ${FRAMEWORK_INCLUDES} - -SOURCES := ${FRAMEWORK_SOURCES} \ - ${TESTS_SOURCES} \ - ${PLAT_SOURCES} +INCLUDES := -Iinclude \ + -Iinclude/common \ + -Iinclude/drivers \ + -Iinclude/drivers/arm \ + -Iinclude/drivers/io \ + -Iinclude/lib \ + -Iinclude/lib/aarch64 \ + -Iinclude/lib/utils \ + -Iinclude/plat/common \ + -Iinclude/runtime_services \ + -Iinclude/runtime_services/secure_el1_payloads \ + -Iinclude/stdlib \ + -Iinclude/stdlib/sys \ + ${PLAT_INCLUDES} \ + ${FRAMEWORK_INCLUDES} + +SOURCES := ${FRAMEWORK_SOURCES} \ + ${TESTS_SOURCES} \ + ${PLAT_SOURCES} # Process DEBUG flag $(eval $(call assert_boolean,DEBUG)) diff --git a/framework/aarch64/entrypoint.S b/framework/aarch64/entrypoint.S index 33eae29..6cf7445 100644 --- a/framework/aarch64/entrypoint.S +++ b/framework/aarch64/entrypoint.S @@ -11,8 +11,8 @@ */ #include <arch.h> +#include <asm_macros.S> #include <tftf.h> -#include <tftf_asm_macros.S> .globl tftf_entrypoint .globl tftf_hotplug_entry @@ -118,7 +118,7 @@ tftf_hotplug_entry: * Enable the MMU * -------------------------------------------------------------------- */ - bl tftf_enable_mmu + bl tftf_plat_enable_mmu /* -------------------------------------------------------------------- * Give ourselves a stack in normal memory. diff --git a/framework/aarch64/tftf_asm_macros.S b/framework/aarch64/tftf_asm_macros.S deleted file mode 100644 index 08baf26..0000000 --- a/framework/aarch64/tftf_asm_macros.S +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <arch.h> - - .macro asm_read_sysreg_el1_or_el2 sysreg - mrs x0, CurrentEL - cmp x0, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq 1f - cmp x0, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq 2f - b dead -1: - mrs x0, \sysreg\()_el1 - b 3f -2: - mrs x0, \sysreg\()_el1 -3: - .endm - - .macro asm_write_sysreg_el1_or_el2 sysreg scratch_reg - mrs \scratch_reg, CurrentEL - cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq 1f - cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq 2f - b dead -1: - msr \sysreg\()_el1, x0 - b 3f -2: - msr \sysreg\()_el2, x0 -3: - .endm - - .macro asm_read_sctlr_el1_or_el2 - asm_read_sysreg_el1_or_el2 sctlr - .endm - - .macro asm_write_sctlr_el1_or_el2 scratch_reg - asm_write_sysreg_el1_or_el2 sctlr \scratch_reg - .endm - - .macro asm_write_vbar_el1_or_el2 scratch_reg - asm_write_sysreg_el1_or_el2 vbar \scratch_reg - .endm - -/* - * Depending on the current exception level, jump to 'label_el1' or 'label_el2'. - * If the current exception level is neither EL1 nor EL2, jump to an infinite - * loop instead. - * Provide the macro with a scratch 64-bit register to use, its contents prior - * to calling this function will be lost. - */ - .macro JUMP_EL1_OR_EL2 scratch_reg, label_el1, label_el2 - mrs \scratch_reg, CurrentEL - cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) - b.eq \label_el1 - cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) - b.eq \label_el2 - b dead - .endm diff --git a/framework/framework.mk b/framework/framework.mk index ab8d777..402ba43 100644 --- a/framework/framework.mk +++ b/framework/framework.mk @@ -30,40 +30,40 @@ AUTOGEN_DIR := $(BUILD_PLAT)/autogen -FRAMEWORK_INCLUDES := -Iframework/aarch64 \ - -Iframework/include \ +FRAMEWORK_INCLUDES := -Iframework/include \ + -Iinclude/common \ -I${AUTOGEN_DIR} -FRAMEWORK_SOURCES := ${AUTOGEN_DIR}/tests_list.c \ - framework/aarch64/arch.c \ - framework/aarch64/asm_helpers.S \ - framework/aarch64/asm_platform_weak.S \ - framework/aarch64/entrypoint.S \ - framework/aarch64/exceptions.S \ - framework/debug.c \ - framework/delay.c \ - framework/helpers.c \ - framework/irq.c \ - framework/main.c \ - framework/platform.c \ - framework/psci.c \ - framework/report.c \ - framework/smc.c \ - framework/systimer.c \ - framework/trusted_os.c \ - lib/aarch64/cache_helpers.S \ - lib/aarch64/misc_helpers.S \ - lib/aarch64/xlat_helpers.c \ - lib/aarch64/xlat_tables.c \ - lib/locks/exclusive/spinlock.S \ - lib/power_management/hotplug/hotplug.c \ - lib/stdlib/std.c \ - lib/suspend/tftf_suspend.c \ - lib/suspend/asm_tftf_suspend.S \ - lib/utils/uuid.c \ - plat/common/aarch64/plat_common.c \ - plat/common/aarch64/platform_helpers.S \ - plat/common/aarch64/platform_mp_stack.S \ +FRAMEWORK_SOURCES := ${AUTOGEN_DIR}/tests_list.c \ + framework/aarch64/arch.c \ + framework/aarch64/asm_platform_weak.S \ + framework/aarch64/entrypoint.S \ + framework/aarch64/exceptions.S \ + framework/debug.c \ + framework/main.c \ + framework/nvm_results_helpers.c \ + framework/report.c \ + lib/aarch64/cache_helpers.S \ + lib/aarch64/misc_helpers.S \ + lib/aarch64/xlat_helpers.c \ + lib/aarch64/xlat_tables.c \ + lib/delay/delay.c \ + lib/irq/irq.c \ + lib/locks/spinlock.S \ + lib/power_management/hotplug/hotplug.c \ + lib/power_management/suspend/asm_tftf_suspend.S \ + lib/power_management/suspend/tftf_suspend.c \ + lib/psci/psci.c \ + lib/smc/asm_smc.S \ + lib/smc/smc.c \ + lib/stdlib/std.c \ + lib/systimer/systimer.c \ + lib/trusted_os/trusted_os.c \ + lib/utils/mp_printf.c \ + lib/utils/uuid.c \ + plat/common/aarch64/plat_common.c \ + plat/common/aarch64/platform_helpers.S \ + plat/common/aarch64/platform_mp_stack.S \ plat/common/tftf_nvm_accessors.c TFTF_LINKERFILE := framework/tftf.ld.S 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(); -} diff --git a/framework/include/suspend.h b/framework/include/suspend.h deleted file mode 100644 index 18bb8b0..0000000 --- a/framework/include/suspend.h +++ /dev/null @@ -1,38 +0,0 @@ -/** @file -* -* Copyright (c) 2014, 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. -* -**/ - -#ifndef __SUSPEND_H__ -#define __SUSPEND_H__ - -#include <stdint.h> - -/* - * It is an Api used to enter a suspend state. It does the following: - * - Allocates space for saving architectural and non-architectural CPU state on - * stack - * - Saves architecture state of the CPU in the space allocated which consists: - * a. Callee registers - * b. System control registers. ex: MMU, SCTLR_EL1 - * - Sets context ID to the base of the stack allocated for saving context - * - Calls Secure Platform Firmware to enter suspend - * - If suspend fails, It restores the callee registers - * power state: PSCI power state to be sent via SMC - * Returns: PSCI_E_SUCCESS or PSCI_E_INVALID_PARAMS - * - * Note: This api might not test all use cases, as the context ID and resume - * entrypoint is in the control of the framework. - */ -unsigned int tftf_cpu_suspend(uint32_t power_state); - -#endif /* __SUSPEND_H__ */ diff --git a/framework/include/tftf.h b/framework/include/tftf.h index 02e6346..b423528 100644 --- a/framework/include/tftf.h +++ b/framework/include/tftf.h @@ -16,9 +16,9 @@ #define __TFTF_H__ #ifndef __ASSEMBLY__ +#include <status.h> #include <stddef.h> -#include <tests_api.h> -#include <tftf_common.h> +#include <tftf_lib.h> #define TFTF_WELCOME_STR "Booting trusted firmware test framework" @@ -29,6 +29,7 @@ #define TEST_REPORT_FORMAT_RAW 0 #define TEST_REPORT_FORMAT_JUNIT 1 +typedef unsigned TEST_REPORT_FORMAT; extern const char build_message[]; @@ -66,13 +67,6 @@ typedef struct { const TESTCASE *testcases; } TEST_SUITE; -/** -** @brief Write a string in the test output buffer. -** -** @note The test output buffer we are talking about here is a temporary buffer -** stored in RAM. This function doesn't write anything into NVM. -*/ -void tftf_testcase_output(const char* string); // The definition of this global variable is generated by the script 'tftf_generate_test_list' // during the build process @@ -109,8 +103,6 @@ STATUS tftf_testcase_set_result(const TESTCASE* testcase, TEST_RESULT result, co STATUS tftf_testcase_get_result(const TESTCASE* testcase, TESTCASE_RESULT *result, char *test_output); STATUS tftf_testcase_update_result(const TESTCASE* testcase, TEST_RESULT result); -typedef unsigned TEST_REPORT_FORMAT; - void tftf_report_generate(void); /* @@ -145,12 +137,8 @@ int tftf_systimer_setup(void); */ void __dead2 run_tests(void); -/* - * Prevent the compiler from optimising the access to a variable. - * Note that this only affects the compiler, this is NOT a run-time - * memory barrier. - */ -#define ACCESS(var) (*(volatile __typeof__(var) *)&(var)) +/* Entry point for a CPU that has just been powered up */ +void tftf_hotplug_entry(void); #endif /*__ASSEMBLY__*/ diff --git a/framework/main.c b/framework/main.c index ff0e4d7..9c43cdc 100644 --- a/framework/main.c +++ b/framework/main.c @@ -22,10 +22,11 @@ #include <platform_def.h> #include <power_management.h> #include <psci.h> +#include <sgi.h> #include <spinlock.h> #include <stdio.h> #include <string.h> -#include <tests_api.h> +#include <tftf_lib.h> #include <tftf.h> // Index of the current testsuite and the current testcase. diff --git a/framework/nvm_results_helpers.c b/framework/nvm_results_helpers.c new file mode 100644 index 0000000..dfa1822 --- /dev/null +++ b/framework/nvm_results_helpers.c @@ -0,0 +1,281 @@ +/** @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 <arch_helpers.h> +#include <assert.h> +#include <nvm.h> +#include <platform.h> +#include <string.h> + +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_fn) +{ + STATUS status; + unsigned testsuite_index, testcase_index; + + status = tftf_get_testcase_index(crashed_testcase_fn, &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); +} diff --git a/framework/platform.c b/framework/platform.c deleted file mode 100644 index 1fa16b3..0000000 --- a/framework/platform.c +++ /dev/null @@ -1,47 +0,0 @@ -/** @file -* -* Copyright (c) 2013-2014, 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 <tftf.h> -#include <psci.h> -#include <arch_helpers.h> -#include <platform.h> - -__attribute__((weak)) unsigned long long tftf_platform_get_time(void) { - return 0; -} - -__attribute__((weak)) void tftf_platform_end(void) { - -} - -__attribute__((weak)) void tftf_platform_reset(void) { - -} - -__attribute__((weak)) void tftf_platform_watchdog_set(void) { - -} - -__attribute__((weak)) void tftf_platform_watchdog_reset(void) { - -} - -__attribute__((weak)) unsigned tftf_platform_core_whoami(void) { - unsigned mpidr = read_mpidr(); - return platform_get_core_pos(mpidr); -} - -__attribute__((weak)) unsigned tftf_platform_core_pos_to_mpid(unsigned core_pos) { - return 0; -} diff --git a/include/common/asm_macros.S b/include/common/asm_macros.S index 238fa82..491ed60 100644 --- a/include/common/asm_macros.S +++ b/include/common/asm_macros.S @@ -195,3 +195,61 @@ wait_for_entrypoint: _mov_imm16 \_reg, (\_val), 48 .endif .endm + + .macro asm_read_sysreg_el1_or_el2 sysreg + mrs x0, CurrentEL + cmp x0, #(MODE_EL1 << MODE_EL_SHIFT) + b.eq 1f + cmp x0, #(MODE_EL2 << MODE_EL_SHIFT) + b.eq 2f + b dead +1: + mrs x0, \sysreg\()_el1 + b 3f +2: + mrs x0, \sysreg\()_el1 +3: + .endm + + .macro asm_write_sysreg_el1_or_el2 sysreg scratch_reg + mrs \scratch_reg, CurrentEL + cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) + b.eq 1f + cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) + b.eq 2f + b dead +1: + msr \sysreg\()_el1, x0 + b 3f +2: + msr \sysreg\()_el2, x0 +3: + .endm + + .macro asm_read_sctlr_el1_or_el2 + asm_read_sysreg_el1_or_el2 sctlr + .endm + + .macro asm_write_sctlr_el1_or_el2 scratch_reg + asm_write_sysreg_el1_or_el2 sctlr \scratch_reg + .endm + + .macro asm_write_vbar_el1_or_el2 scratch_reg + asm_write_sysreg_el1_or_el2 vbar \scratch_reg + .endm + +/* + * Depending on the current exception level, jump to 'label_el1' or 'label_el2'. + * If the current exception level is neither EL1 nor EL2, jump to an infinite + * loop instead. + * Provide the macro with a scratch 64-bit register to use, its contents prior + * to calling this function will be lost. + */ + .macro JUMP_EL1_OR_EL2 scratch_reg, label_el1, label_el2 + mrs \scratch_reg, CurrentEL + cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT) + b.eq \label_el1 + cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT) + b.eq \label_el2 + b dead + .endm diff --git a/include/common/bl_common.h b/include/common/bl_common.h deleted file mode 100644 index 9945e3a..0000000 --- a/include/common/bl_common.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __BL_COMMON_H__ -#define __BL_COMMON_H__ - -#define SECURE 0x0 -#define NON_SECURE 0x1 -#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE)) - -#define UP 1 -#define DOWN 0 - -/******************************************************************************* - * Constants to identify the location of a memory region in a given memory - * layout. -******************************************************************************/ -#define TOP 0x1 -#define BOTTOM !TOP - -/****************************************************************************** - * Opcode passed in x0 to tell next EL that we want to run an image. - * Corresponds to the function ID of the only SMC that the BL1 exception - * handlers service. That's why the chosen value is the first function ID of - * the ARM SMC64 range. - *****************************************************************************/ -#define RUN_IMAGE 0xC0000000 - -/******************************************************************************* - * Constants that allow assembler code to access members of and the - * 'entry_point_info' structure at their correct offsets. - ******************************************************************************/ -#define ENTRY_POINT_INFO_PC_OFFSET 0x08 -#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 - -#define PARAM_EP_SECURITY_MASK 0x1 -#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK) -#define SET_SECURITY_STATE(x, security) \ - ((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security)) - -#define EP_EE_MASK 0x2 -#define EP_EE_LITTLE 0x0 -#define EP_EE_BIG 0x2 -#define EP_GET_EE(x) (x & EP_EE_MASK) -#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee)) - -#define EP_ST_MASK 0x4 -#define EP_ST_DISABLE 0x0 -#define EP_ST_ENABLE 0x4 -#define EP_GET_ST(x) (x & EP_ST_MASK) -#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee)) - -#define PARAM_EP 0x01 -#define PARAM_IMAGE_BINARY 0x02 -#define PARAM_BL31 0x03 - -#define VERSION_1 0x01 - -#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \ - (_p)->h.type = (uint8_t)(_type); \ - (_p)->h.version = (uint8_t)(_ver); \ - (_p)->h.size = (uint16_t)sizeof(*_p); \ - (_p)->h.attr = (uint32_t)(_attr) ; \ - } while (0) - -#ifndef __ASSEMBLY__ -#include <cdefs.h> /* For __dead2 */ -#include <cassert.h> -#include <stdint.h> -#include <stddef.h> - -/******************************************************************************* - * Structure used for telling the next BL how much of a particular type of - * memory is available for its use and how much is already used. - ******************************************************************************/ -typedef struct meminfo { - uint64_t total_base; - size_t total_size; - uint64_t free_base; - size_t free_size; -} meminfo_t; - -typedef struct aapcs64_params { - unsigned long arg0; - unsigned long arg1; - unsigned long arg2; - unsigned long arg3; - unsigned long arg4; - unsigned long arg5; - unsigned long arg6; - unsigned long arg7; -} aapcs64_params_t; - -/*************************************************************************** - * This structure provides version information and the size of the - * structure, attributes for the structure it represents - ***************************************************************************/ -typedef struct param_header { - uint8_t type; /* type of the structure */ - uint8_t version; /* version of this structure */ - uint16_t size; /* size of this structure in bytes */ - uint32_t attr; /* attributes: unused bits SBZ */ -} param_header_t; - -/***************************************************************************** - * This structure represents the superset of information needed while - * switching exception levels. The only two mechanisms to do so are - * ERET & SMC. Security state is indicated using bit zero of header - * attribute - * NOTE: BL1 expects entrypoint followed by spsr while processing - * SMC to jump to BL31 from the start of entry_point_info - *****************************************************************************/ -typedef struct entry_point_info { - param_header_t h; - uintptr_t pc; - uint32_t spsr; - aapcs64_params_t args; -} entry_point_info_t; - -/***************************************************************************** - * Image info binary provides information from the image loader that - * can be used by the firmware to manage available trusted RAM. - * More advanced firmware image formats can provide additional - * information that enables optimization or greater flexibility in the - * common firmware code - *****************************************************************************/ -typedef struct image_info { - param_header_t h; - uintptr_t image_base; /* physical address of base of image */ - uint32_t image_size; /* bytes read from image file */ -} image_info_t; - -/******************************************************************************* - * This structure represents the superset of information that can be passed to - * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be - * populated only if BL2 detects its presence. A pointer to a structure of this - * type should be passed in X3 to BL31's cold boot entrypoint - * - * Use of this structure and the X3 parameter is not mandatory: the BL3-1 - * platform code can use other mechanisms to provide the necessary information - * about BL3-2 and BL3-3 to the common and SPD code. - * - * BL3-1 image information is mandatory if this structure is used. If either of - * the optional BL3-2 and BL3-3 image information is not provided, this is - * indicated by the respective image_info pointers being zero. - ******************************************************************************/ -typedef struct bl31_params { - param_header_t h; - image_info_t *bl31_image_info; - entry_point_info_t *bl32_ep_info; - image_info_t *bl32_image_info; - entry_point_info_t *bl33_ep_info; - image_info_t *bl33_image_info; -} bl31_params_t; - - -/* - * Compile time assertions related to the 'entry_point_info' structure to - * ensure that the assembler and the compiler view of the offsets of - * the structure members is the same. - */ -CASSERT(ENTRY_POINT_INFO_PC_OFFSET == - __builtin_offsetof(entry_point_info_t, pc), \ - assert_BL31_pc_offset_mismatch); - -CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \ - __builtin_offsetof(entry_point_info_t, args), \ - assert_BL31_args_offset_mismatch); - -CASSERT(sizeof(unsigned long) == - __builtin_offsetof(entry_point_info_t, spsr) - \ - __builtin_offsetof(entry_point_info_t, pc), \ - assert_entrypoint_and_spsr_should_be_adjacent); - -/******************************************************************************* - * Function & variable prototypes - ******************************************************************************/ -unsigned long page_align(unsigned long, unsigned); -void change_security_state(unsigned int); -unsigned long image_size(const char *); -int load_image(meminfo_t *mem_layout, - const char *image_name, - uint64_t image_base, - image_info_t *image_data, - entry_point_info_t *entry_point_info); -extern const char build_message[]; -extern const char version_string[]; - -void reserve_mem(uint64_t *free_base, size_t *free_size, - uint64_t addr, size_t size); - -#endif /*__ASSEMBLY__*/ - -#endif /* __BL_COMMON_H__ */ diff --git a/include/common/tftf_common.h b/include/common/tftf_common.h deleted file mode 100644 index 2abd0c2..0000000 --- a/include/common/tftf_common.h +++ /dev/null @@ -1,50 +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. -* -**/ - -#ifndef __TFTF_COMMON_H__ -#define __TFTF_COMMON_H__ - -#ifndef __ASSEMBLY__ -#include <stddef.h> - -/* Define bool type in the absence of stdbool.h */ -#define bool _Bool -#define false 0 -#define true 1 - -/* Status Code definitions */ -#define STATUS_SUCCESS 0x00 -#define STATUS_INVALID_PARAMETER 0x01 -#define STATUS_UNSUPPORTED 0x02 -#define STATUS_OUT_OF_RESOURCES 0x03 -#define STATUS_NOT_FOUND 0x04 -#define STATUS_ABORTED 0x05 -#define STATUS_LOAD_ERROR 0x06 -#define STATUS_NEVER_RETURN 0x07 -#define STATUS_BUSY 0x08 -#define STATUS_NOT_INIT 0x09 -#define STATUS_BUFFER_TOO_SMALL 0x0A -#define STATUS_COMPROMISED_DATA 0x0B -#define STATUS_ALREADY_LOADED 0x0C -#define STATUS_FAIL 0x0D - -typedef unsigned long long UINTN; -typedef unsigned int STATUS; - -/* Returns the presence of a core at position passed to it */ -bool tftf_platform_is_core_pos_present(unsigned int core_pos); - -#endif /* __ASSEMBLY__ */ - -#endif /* __TFTF_COMMMON_H__ */ diff --git a/include/common/intel_p30_flash.h b/include/drivers/intel_p30_flash.h index 762ac3c..762ac3c 100644 --- a/include/common/intel_p30_flash.h +++ b/include/drivers/intel_p30_flash.h diff --git a/framework/include/irq.h b/include/lib/irq.h index 181358d..ff0538a 100644 --- a/framework/include/irq.h +++ b/include/lib/irq.h @@ -36,23 +36,31 @@ #ifndef __ASSEMBLY__ -#include <tests_api.h> /* for irq_handler type */ +typedef int (*irq_handler)(void *data); typedef struct { unsigned int num; irq_handler handler; } irq_desc; + typedef irq_desc spi_desc; typedef union { irq_desc desc; unsigned char align[CACHE_WRITEBACK_GRANULE]; } ppi_desc; + typedef ppi_desc sgi_desc; void tftf_irq_setup(void); + int tftf_irq_handler(void); +/* + * Register an interrupt handler for a given interrupt number + */ +int tftf_irq_register(unsigned int num, irq_handler dev_irq_handler); + #endif /* __ASSEMBLY__ */ #endif /* __IRQ_H__ */ diff --git a/include/lib/power_management.h b/include/lib/power_management.h index 1c07a77..8328d26 100644 --- a/include/lib/power_management.h +++ b/include/lib/power_management.h @@ -63,6 +63,24 @@ int tftf_cpu_on(uint64_t target_cpu, */ int tftf_cpu_off(void); +/* + * It is an Api used to enter a suspend state. It does the following: + * - Allocates space for saving architectural and non-architectural CPU state on + * stack + * - Saves architecture state of the CPU in the space allocated which consists: + * a. Callee registers + * b. System control registers. ex: MMU, SCTLR_EL1 + * - Sets context ID to the base of the stack allocated for saving context + * - Calls Secure Platform Firmware to enter suspend + * - If suspend fails, It restores the callee registers + * power state: PSCI power state to be sent via SMC + * Returns: PSCI_E_SUCCESS or PSCI_E_INVALID_PARAMS + * + * Note: This api might not test all use cases, as the context ID and resume + * entrypoint is in the control of the framework. + */ +unsigned int tftf_cpu_suspend(uint32_t power_state); + /* ---------------------------------------------------------------------------- * The above APIs might not be suitable in all test scenarios. diff --git a/include/lib/sgi.h b/include/lib/sgi.h new file mode 100644 index 0000000..cc83d77 --- /dev/null +++ b/include/lib/sgi.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SGI_H__ +#define __SGI_H__ + +/* Data associated with the reception of an SGI */ +typedef struct { + /* Interrupt ID of the signaled interrupt */ + unsigned int irq_id; + /* Identifies the processor that requested the SGI */ + unsigned int cpu_id; +} sgi_data; + +/* Register an SGI for waking up the core from the lead CPU */ +void tftf_register_sgi_wake_interrupt(unsigned int core_pos); + +/* Handler for the SGI wakeup interrupt */ +int tftf_sgi_generic_wake_handler(void *data); + +/* + * Send an SGI to a given core. + */ +void tftf_send_sgi(unsigned int sgi_id, unsigned int core_pos); + +#endif /* __SGI_H__ */ diff --git a/include/lib/status.h b/include/lib/status.h new file mode 100644 index 0000000..c369c62 --- /dev/null +++ b/include/lib/status.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STATUS_H__ +#define __STATUS_H__ + +/* Status Code definitions */ +#define STATUS_SUCCESS 0x00 +#define STATUS_INVALID_PARAMETER 0x01 +#define STATUS_UNSUPPORTED 0x02 +#define STATUS_OUT_OF_RESOURCES 0x03 +#define STATUS_NOT_FOUND 0x04 +#define STATUS_ABORTED 0x05 +#define STATUS_LOAD_ERROR 0x06 +#define STATUS_NEVER_RETURN 0x07 +#define STATUS_BUSY 0x08 +#define STATUS_NOT_INIT 0x09 +#define STATUS_BUFFER_TOO_SMALL 0x0A +#define STATUS_COMPROMISED_DATA 0x0B +#define STATUS_ALREADY_LOADED 0x0C +#define STATUS_FAIL 0x0D + +typedef unsigned int STATUS; + +#endif /* __STATUS_H__ */ diff --git a/include/lib/systimer.h b/include/lib/systimer.h new file mode 100644 index 0000000..42497c2 --- /dev/null +++ b/include/lib/systimer.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SYSTIMER_H__ +#define __SYSTIMER_H__ + +/* + * Program the timer to fire in 'time_ms' milliseconds + */ +void tftf_systimer_fire_in(uint64_t time_ms); + +/* Handler for systimer */ +int tftf_systimer_handler(void *data); + +#endif /* __SYSTIMER_H__ */ diff --git a/framework/include/tests_api.h b/include/lib/tftf_lib.h index fe3c292..d1acad8 100644 --- a/framework/include/tests_api.h +++ b/include/lib/tftf_lib.h @@ -28,21 +28,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/***************************************************************************** - * This header file lists and documents all functions that a test function - * may use. - ****************************************************************************/ - -#ifndef __TESTS_API_H__ -#define __TESTS_API_H__ +#ifndef __TFTF_LIB_H__ +#define __TFTF_LIB_H__ #ifndef __ASSEMBLY__ #include <stdint.h> -#include <tftf_common.h> - -/* Number of iterations for repetitive tests */ -#define TFTF_LOOPS 1000 /* * Print a formatted string on the UART. @@ -63,40 +54,6 @@ __attribute__((format(printf, 1, 2))) void mp_printf(const char *fmt, ...); -typedef int (*irq_handler)(void *data); - -/* - * Register an interrupt handler for a given interrupt number - */ -int tftf_irq_register(unsigned int num, irq_handler dev_irq_handler); - -/* - * Program the timer to fire in 'time_ms' milliseconds - */ -void tftf_systimer_fire_in(uint64_t time_ms); - -/* Register an SGI for waking up the core from the lead CPU */ -void tftf_register_sgi_wake_interrupt(unsigned int core_pos); - -/* Handler for the SGI wakeup interrupt */ -int tftf_sgi_generic_wake_handler(void *data); - -/* Handler for systimer */ -int tftf_systimer_handler(void *data); - -/* Data associated with the reception of an SGI */ -typedef struct { - /* Interrupt ID of the signaled interrupt */ - unsigned int irq_id; - /* Identifies the processor that requested the SGI */ - unsigned int cpu_id; -} sgi_data; - -/* - * Send an SGI (Software Generated Interrupt) to a given core. - */ -void tftf_send_sgi(unsigned int sgi_id, unsigned int core_pos); - /* * Possible error codes for signaling the result of a test */ @@ -121,10 +78,6 @@ typedef enum { */ typedef TEST_RESULT (*TFTF_TASK)(unsigned core_pos, void *argument); -void tftf_hotplug_entry(void); - -bool tftf_is_core_enabled(unsigned int core_pos); - /* * PSCI Function Wrappers * @@ -137,9 +90,6 @@ uint32_t tftf_psci_cpu_off(void); void waitms(uint64_t ms); -bool tftf_core_participates_in_testcase(unsigned core_pos, - unsigned testcase_index); - /* * Write a string in the test output buffer. * The string will appear in the test report. @@ -170,6 +120,31 @@ typedef struct { */ smc64_ret_values tftf_smc64(const smc64_args *args); +/* + * Write a string in the test output buffer. + * + * Note: The test output buffer we are talking about here is a temporary buffer + * stored in RAM. This function doesn't write anything into NVM. + */ +void tftf_testcase_output(const char *string); + +/* + * Prevent the compiler from optimising the access to a variable. + * Note that this only affects the compiler, this is NOT a run-time + * memory barrier. + */ +#define ACCESS(var) (*(volatile __typeof__(var) *)&(var)) + +/* Define bool type in the absence of stdbool.h */ +#define bool _Bool +#define false 0 +#define true 1 + +typedef unsigned long long UINTN; + +/* Returns the presence of a core at position passed to it */ +bool tftf_platform_is_core_pos_present(unsigned int core_pos); + #endif /* __ASSEMBLY__ */ -#endif /* __TESTS_API_H__ */ +#endif /* __TFTF_LIB_H__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 9b56000..04a9a06 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -38,17 +38,14 @@ void tftf_plat_arch_setup(void); void tftf_early_platform_setup(void); void tftf_platform_setup(void); -void tftf_enable_mmu(void); -void tftf_configure_mmu(void); +void tftf_plat_enable_mmu(void); +void tftf_plat_configure_mmu(void); -unsigned long long tftf_platform_get_time(void); void tftf_platform_end(void); -void tftf_platform_reset(void); void tftf_platform_watchdog_set(void); void tftf_platform_watchdog_reset(void); unsigned int platform_get_primary_core_mpid(void); -unsigned tftf_platform_core_whoami(void); unsigned tftf_platform_core_pos_to_mpid(unsigned core_pos); diff --git a/include/rt_services/psci.h b/include/runtime_services/psci.h index a6160ce..a6160ce 100644 --- a/include/rt_services/psci.h +++ b/include/runtime_services/psci.h diff --git a/include/secure_el1_payloads/tsp.h b/include/runtime_services/secure_el1_payloads/tsp.h index c0e3612..c0e3612 100644 --- a/include/secure_el1_payloads/tsp.h +++ b/include/runtime_services/secure_el1_payloads/tsp.h diff --git a/include/rt_services/smc.h b/include/runtime_services/smc.h index 188de0e..188de0e 100644 --- a/include/rt_services/smc.h +++ b/include/runtime_services/smc.h diff --git a/include/rt_services/std_svc.h b/include/runtime_services/std_svc.h index 0e8b5f0..0e8b5f0 100644 --- a/include/rt_services/std_svc.h +++ b/include/runtime_services/std_svc.h diff --git a/include/rt_services/trusted_os.h b/include/runtime_services/trusted_os.h index 0f179cf..0f179cf 100644 --- a/include/rt_services/trusted_os.h +++ b/include/runtime_services/trusted_os.h diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index f605bf4..672d269 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.S @@ -45,6 +45,7 @@ #if SUPPORT_VFP .globl enable_vfp + .globl disable_fp_traps #endif func get_afflvl_shift @@ -67,7 +68,6 @@ func mpidr_mask_lower_afflvls func eret eret - func smc smc #0 @@ -169,4 +169,22 @@ func enable_vfp msr cptr_el3, x0 isb ret + +func disable_fp_traps + JUMP_EL1_OR_EL2 x0, _disable_fp_traps_el1, _disable_fp_traps_el2 +_disable_fp_traps_el1: + /* Read EL1 Coprocessor Access Control Register (CPACR) */ + mrs x0, cpacr_el1 + /* Disable trapping of instructions accessing FP regs */ + orr x0, x0, #CPACR_EL1_FPEN(3) + /* Write back EL1 Coprocessor Access Control Register (CPACR) */ + msr cpacr_el1, x0 + ret +_disable_fp_traps_el2: + mrs x0, cptr_el2 + mov x1, #TFP_BIT + bic x0, x0, x1 + msr cptr_el2, x0 + ret + #endif diff --git a/framework/delay.c b/lib/delay/delay.c index 055581c..055581c 100644 --- a/framework/delay.c +++ b/lib/delay/delay.c diff --git a/framework/irq.c b/lib/irq/irq.c index a5ad679..c50d006 100644 --- a/framework/irq.c +++ b/lib/irq/irq.c @@ -35,6 +35,7 @@ #include <irq.h> #include <platform.h> #include <platform_def.h> +#include <sgi.h> #include <string.h> #include <tftf.h> diff --git a/lib/locks/exclusive/spinlock.S b/lib/locks/spinlock.S index 5eae2b0..5eae2b0 100644 --- a/lib/locks/exclusive/spinlock.S +++ b/lib/locks/spinlock.S diff --git a/lib/power_management/hotplug/hotplug.c b/lib/power_management/hotplug/hotplug.c index fd4f7bf..1a87aed 100644 --- a/lib/power_management/hotplug/hotplug.c +++ b/lib/power_management/hotplug/hotplug.c @@ -33,10 +33,12 @@ #include <assert.h> #include <cdefs.h> /* For __dead2 */ #include <debug.h> +#include <irq.h> #include <platform.h> #include <platform_def.h> #include <power_management.h> #include <psci.h> +#include <sgi.h> #include <spinlock.h> #include <stdint.h> #include <tftf.h> diff --git a/lib/suspend/asm_tftf_suspend.S b/lib/power_management/suspend/asm_tftf_suspend.S index 9be437f..1a0d484 100644 --- a/lib/suspend/asm_tftf_suspend.S +++ b/lib/power_management/suspend/asm_tftf_suspend.S @@ -13,7 +13,6 @@ **/ #include <asm_macros.S> #include <psci.h> -#include <tftf_asm_macros.S> #include "suspend_private.h" .global __tftf_cpu_suspend diff --git a/lib/suspend/suspend_private.h b/lib/power_management/suspend/suspend_private.h index dc84d4e..dc84d4e 100644 --- a/lib/suspend/suspend_private.h +++ b/lib/power_management/suspend/suspend_private.h diff --git a/lib/suspend/tftf_suspend.c b/lib/power_management/suspend/tftf_suspend.c index 4942da0..8853451 100644 --- a/lib/suspend/tftf_suspend.c +++ b/lib/power_management/suspend/tftf_suspend.c @@ -15,10 +15,10 @@ #include <arch_helpers.h> #include <arm_gic.h> #include <platform.h> +#include <power_management.h> #include <psci.h> #include <stdint.h> -#include <suspend.h> -#include <tests_api.h> +#include <tftf_lib.h> #include "suspend_private.h" unsigned int tftf_enter_suspend(uint32_t power_state, diff --git a/framework/psci.c b/lib/psci/psci.c index 6334e06..6334e06 100644 --- a/framework/psci.c +++ b/lib/psci/psci.c diff --git a/framework/aarch64/asm_helpers.S b/lib/smc/asm_smc.S index a50d5ee..c5b24f5 100644 --- a/framework/aarch64/asm_helpers.S +++ b/lib/smc/asm_smc.S @@ -28,16 +28,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <tftf_asm_macros.S> +#include <asm_macros.S> .globl asm_tftf_smc64 -#if SUPPORT_VFP - .globl disable_fp_traps -#endif - .section .text, "ax" + .section .text, "ax" -/* ----------------------------------------------------------------------- + +/* --------------------------------------------------------------------------- * __noinline smc64_ret_values asm_tftf_smc64(uint64_t arg0, * uint64_t arg1, * uint64_t arg2, @@ -45,10 +43,9 @@ * uint64_t arg4, * uint64_t arg5, * uint64_t arg6); - * ----------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ -.type asm_tftf_smc64 STT_FUNC -asm_tftf_smc64: +func asm_tftf_smc64 /* * According to the AAPCS64, x8 is the indirect result location * register. It contains the address of the memory block that the caller @@ -71,23 +68,3 @@ asm_tftf_smc64: stp x0, x1, [x9, #0] stp x2, x3, [x9, #16] ret - -#if SUPPORT_VFP -disable_fp_traps: - JUMP_EL1_OR_EL2 x0, _disable_fp_traps_el1, _disable_fp_traps_el2 -_disable_fp_traps_el1: - mrs x0, cpacr_el1 // Read EL1 Coprocessor Access Control Register (CPACR) - orr x0, x0, #CPACR_EL1_FPEN(3) // Disable trapping of instructions accessing FP regs - msr cpacr_el1, x0 // Write back EL1 Coprocessor Access Control Register (CPACR) - ret -_disable_fp_traps_el2: - mrs x0, cptr_el2 - mov x1, #TFP_BIT - bic x0, x0, x1 - msr cptr_el2, x0 - ret - -#endif - -dead: - b dead diff --git a/framework/smc.c b/lib/smc/smc.c index 6cba7c3..13e682f 100644 --- a/framework/smc.c +++ b/lib/smc/smc.c @@ -32,7 +32,6 @@ #include <stdint.h> /* - * Defined in tftf_asm_helpers.S * Note: This function must not be inlined, otherwise we can't rely on the * AAPCS64. */ diff --git a/framework/systimer.c b/lib/systimer/systimer.c index 76f9cd2..80dc629 100644 --- a/framework/systimer.c +++ b/lib/systimer/systimer.c @@ -35,10 +35,11 @@ #include <platform.h> #include <mmio.h> #include <irq.h> +#include <sgi.h> #include <spinlock.h> #include <stdio.h> -static unsigned int systimer_init = 0; +static unsigned int systimer_init; /* Lock to avoid concurrent accesses to the send_sgis_cpu */ static spinlock_t sgi_dest_lock; diff --git a/framework/trusted_os.c b/lib/trusted_os/trusted_os.c index 3c9fcf1..3c9fcf1 100644 --- a/framework/trusted_os.c +++ b/lib/trusted_os/trusted_os.c diff --git a/lib/utils/mp_printf.c b/lib/utils/mp_printf.c new file mode 100644 index 0000000..3298431 --- /dev/null +++ b/lib/utils/mp_printf.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arch_helpers.h> +#include <spinlock.h> +#include <stdarg.h> +#include <stdio.h> + +/* Lock to avoid concurrent accesses to the serial console */ +static spinlock_t printf_lock; + +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_el1() & 0xFFFF); + printf("%s", str); + spin_unlock(&printf_lock); +} diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index 90574fd..eba3881 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -28,22 +28,67 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <arch_helpers.h> +#include <debug.h> +#include <platform.h> #include <xlat_tables.h> +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + /* - * The following 2 platform setup functions are weakly defined. They - * provide typical implementations that may be re-used by multiple - * platforms but may also be overridden by a platform if required. + * 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. */ -#pragma weak bl31_plat_enable_mmu -#pragma weak bl32_plat_enable_mmu +#define COH_START (unsigned long)(&__COHERENT_RAM_START__) +#define COH_LIMIT (unsigned long)(&__COHERENT_RAM_END__) -void bl31_plat_enable_mmu(uint32_t flags) +/* + * The following platform functions are all weakly defined. They provide typical + * implementations that may be re-used by multiple platforms but may also be + * overridden by a platform if required. + */ + +__attribute__((weak)) void tftf_platform_end(void) { - enable_mmu_el3(flags); + /* Placeholder function which should be redefined by each platform */ +} + +__attribute__((weak)) void tftf_platform_watchdog_set(void) +{ + /* Placeholder function which should be redefined by each platform */ +} + +__attribute__((weak)) void tftf_platform_watchdog_reset(void) +{ + /* Placeholder function which should be redefined by each platform */ +} + +__attribute__((weak)) unsigned int tftf_platform_core_pos_to_mpid(unsigned int core_pos) +{ + /* Placeholder function which should be redefined by each platform */ + return 0; +} + +__attribute__((weak)) void tftf_plat_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_plat_enable_mmu(); } -void bl32_plat_enable_mmu(uint32_t flags) +__attribute__((weak)) void tftf_plat_enable_mmu(void) { - enable_mmu_el1(flags); + if (IS_IN_EL1()) + enable_mmu_el1(0); + else if (IS_IN_EL2()) + enable_mmu_el2(0); + else + panic(); } diff --git a/plat/common/tftf_nvm_accessors.c b/plat/common/tftf_nvm_accessors.c index c0c740a..0022e57 100644 --- a/plat/common/tftf_nvm_accessors.c +++ b/plat/common/tftf_nvm_accessors.c @@ -27,12 +27,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + #include <assert.h> #include <io_storage.h> #include <platform.h> #include <platform_def.h> +#include <status.h> #include <string.h> -#include <tftf_common.h> +#include <tftf_lib.h> STATUS tftf_nvm_write(UINTN offset, const void *buffer, UINTN size) { diff --git a/plat/fvp/plat_setup.c b/plat/fvp/plat_setup.c index 99f2ef9..145b8bd 100644 --- a/plat/fvp/plat_setup.c +++ b/plat/fvp/plat_setup.c @@ -110,7 +110,7 @@ void tftf_early_platform_setup(void) void tftf_plat_arch_setup(void) { - tftf_configure_mmu(); + tftf_plat_configure_mmu(); } /* Terminate the model by sending EOT (End Of Transmission) on the UART */ diff --git a/plat/juno/plat_setup.c b/plat/juno/plat_setup.c index 3c450c5..50f3fa7 100644 --- a/plat/juno/plat_setup.c +++ b/plat/juno/plat_setup.c @@ -105,5 +105,5 @@ void tftf_early_platform_setup(void) void tftf_plat_arch_setup(void) { - tftf_configure_mmu(); + tftf_plat_configure_mmu(); } diff --git a/tests/test_dummy.c b/tests/test_dummy.c index 6d2b59d..3367675 100644 --- a/tests/test_dummy.c +++ b/tests/test_dummy.c @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <tests_api.h> +#include <tftf_lib.h> TEST_RESULT test_dummy(void) { |