| /** @file |
| * Copyright (c) 2018-2020, Arm Limited or its affiliates. All rights reserved. |
| * SPDX-License-Identifier : Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| **/ |
| |
| #include "val_driver_service_apis.h" |
| |
| #define DATA_VALUE 0x1111 |
| #define BUFFER_SIZE 4 |
| |
| uint32_t g_psa_rot_data = DATA_VALUE; |
| |
| int32_t driver_test_psa_eoi_with_non_intr_signal(void); |
| int32_t driver_test_psa_eoi_with_unasserted_signal(void); |
| int32_t driver_test_psa_eoi_with_multiple_signals(void); |
| int32_t driver_test_irq_routing(void); |
| void driver_test_isolation_psa_rot_data_rd(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_data_wr(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_stack_rd(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_stack_wr(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_heap_rd(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_heap_wr(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_mmio_rd(psa_msg_t *msg); |
| void driver_test_isolation_psa_rot_mmio_wr(psa_msg_t *msg); |
| |
| void driver_main(void) |
| { |
| psa_signal_t signals = 0; |
| psa_msg_t msg = {0}; |
| int32_t data = 0; |
| uart_fn_type_t uart_fn; |
| nvmem_param_t nvmem_param; |
| driver_test_fn_id_t driver_test_fn_id; |
| char string[256] = {0}; |
| uint8_t buffer[256] = {0}; |
| wd_param_t wd_param; |
| addr_t uart_base; |
| |
| /* Initialised driver mmio space */ |
| if (val_init_driver_memory()) |
| TEST_PANIC(); |
| |
| while (1) |
| { |
| val_status_t fn_status = VAL_STATUS_SUCCESS; |
| signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK); |
| |
| /* Service Print functionality */ |
| if (signals & DRIVER_UART_SIGNAL) |
| { |
| psa_get(DRIVER_UART_SIGNAL, &msg); |
| switch (msg.type) |
| { |
| case PSA_IPC_CONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| case PSA_IPC_CALL: |
| if ((msg.in_size[0] > sizeof(uart_fn)) |
| && (msg.in_size[1] > sizeof(string)) |
| && (msg.in_size[2] > sizeof(data))) |
| { |
| /* buffer overflow */ |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| break; |
| } |
| else |
| { |
| psa_read(msg.handle, 0, &uart_fn, msg.in_size[0]); |
| } |
| |
| if (uart_fn == UART_INIT) |
| { |
| /* arg2=uart_base */ |
| psa_read(msg.handle, 1, &uart_base, msg.in_size[1]); |
| fn_status = val_uart_init_sf(uart_base); |
| } |
| else |
| { |
| /* arg2=string, arg3=DATA */ |
| psa_read(msg.handle, 1, &string, msg.in_size[1]); |
| psa_read(msg.handle, 2, &data, msg.in_size[2]); |
| fn_status = val_print_sf(string, data); |
| } |
| if (VAL_ERROR(fn_status)) |
| { |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| } |
| else |
| { |
| psa_reply(msg.handle, PSA_SUCCESS); |
| } |
| break; |
| case PSA_IPC_DISCONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| } |
| } |
| |
| /* Service Watchdog functionality */ |
| else if (signals & DRIVER_WATCHDOG_SIGNAL) |
| { |
| psa_get(DRIVER_WATCHDOG_SIGNAL, &msg); |
| switch (msg.type) |
| { |
| case PSA_IPC_CALL: |
| if (msg.in_size[0] > sizeof(wd_param)) |
| { |
| /* buffer overflow */ |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| val_print_sf("msg.in_size[0] buffer overflow\n", 0); |
| break; |
| } |
| else |
| { |
| psa_read(msg.handle, 0, &wd_param, msg.in_size[0]); |
| } |
| |
| if (wd_param.wd_fn_type == WD_INIT_SEQ) |
| { |
| fn_status = val_wd_timer_init_sf(wd_param.wd_base_addr, |
| wd_param.wd_time_us, |
| wd_param.wd_timer_tick_us); |
| } |
| else if (wd_param.wd_fn_type == WD_ENABLE_SEQ) |
| { |
| fn_status = val_wd_timer_enable_sf(wd_param.wd_base_addr); |
| } |
| else if (wd_param.wd_fn_type == WD_DISABLE_SEQ) |
| { |
| fn_status = val_wd_timer_disable_sf(wd_param.wd_base_addr); |
| } |
| else if (wd_param.wd_fn_type == WD_STATUS_SEQ) |
| { |
| fn_status = val_is_wd_timer_enabled_sf(wd_param.wd_base_addr); |
| } |
| if (fn_status == VAL_STATUS_SUCCESS) |
| { |
| psa_reply(msg.handle, PSA_SUCCESS); |
| } |
| else |
| { |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| } |
| break; |
| case PSA_IPC_CONNECT: |
| case PSA_IPC_DISCONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| } |
| } |
| |
| /* Service NVMEM functionality */ |
| else if (signals & DRIVER_NVMEM_SIGNAL) |
| { |
| psa_get(DRIVER_NVMEM_SIGNAL, &msg); |
| switch (msg.type) |
| { |
| case PSA_IPC_CALL: |
| if (msg.in_size[0] > sizeof(nvmem_param)) |
| { |
| /* buffer overflow */ |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| val_print_sf("msg.in_size[0] buffer overflow\n", 0); |
| break; |
| } |
| else |
| { |
| psa_read(msg.handle, 0, &nvmem_param, msg.in_size[0]); |
| } |
| |
| if (nvmem_param.nvmem_fn_type == NVMEM_READ) |
| { |
| fn_status = val_nvmem_read_sf(nvmem_param.base, |
| nvmem_param.offset, |
| buffer, |
| nvmem_param.size); |
| psa_write(msg.handle, 0, (const void*) buffer, msg.out_size[0]); |
| } |
| else |
| { |
| if (msg.in_size[1] > sizeof(buffer)) |
| { |
| /* buffer overflow */ |
| fn_status = VAL_STATUS_ERROR; |
| val_print_sf("msg.in_size[1] buffer overflow\n", 0); |
| } |
| else |
| { |
| psa_read(msg.handle, 1, (void*) buffer, msg.in_size[1]); |
| fn_status = val_nvmem_write_sf(nvmem_param.base, |
| nvmem_param.offset, |
| buffer, |
| nvmem_param.size); |
| } |
| } |
| if (fn_status == VAL_STATUS_SUCCESS) |
| { |
| psa_reply(msg.handle, PSA_SUCCESS); |
| } |
| else |
| { |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| } |
| break; |
| case PSA_IPC_CONNECT: |
| case PSA_IPC_DISCONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| } |
| } |
| /* SID reserved for Driver test functions */ |
| else if (signals & DRIVER_TEST_SIGNAL) |
| { |
| psa_get(DRIVER_TEST_SIGNAL, &msg); |
| switch (msg.type) |
| { |
| case PSA_IPC_CALL: |
| if (msg.in_size[0] > sizeof(driver_test_fn_id_t)) |
| { |
| /* buffer overflow */ |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| val_print_sf("msg.in_size[0] buffer overflow\n", 0); |
| break; |
| } |
| else |
| { |
| psa_read(msg.handle, 0, &driver_test_fn_id, msg.in_size[0]); |
| } |
| |
| switch (driver_test_fn_id) |
| { |
| case TEST_PSA_EOI_WITH_NON_INTR_SIGNAL: |
| driver_test_psa_eoi_with_non_intr_signal(); |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| break; |
| case TEST_PSA_EOI_WITH_UNASSERTED_SIGNAL: |
| driver_test_psa_eoi_with_unasserted_signal(); |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| break; |
| case TEST_PSA_EOI_WITH_MULTIPLE_SIGNALS: |
| driver_test_psa_eoi_with_multiple_signals(); |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| break; |
| case TEST_INTR_SERVICE: |
| if (driver_test_irq_routing() != VAL_STATUS_SUCCESS) |
| psa_reply(msg.handle, VAL_STATUS_ERROR); |
| else |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| case TEST_ISOLATION_PSA_ROT_DATA_RD: |
| driver_test_isolation_psa_rot_data_rd(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_DATA_WR: |
| driver_test_isolation_psa_rot_data_wr(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_STACK_RD: |
| driver_test_isolation_psa_rot_stack_rd(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_STACK_WR: |
| driver_test_isolation_psa_rot_stack_wr(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_HEAP_RD: |
| driver_test_isolation_psa_rot_heap_rd(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_HEAP_WR: |
| driver_test_isolation_psa_rot_heap_wr(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_MMIO_RD: |
| driver_test_isolation_psa_rot_mmio_rd(&msg); |
| break; |
| case TEST_ISOLATION_PSA_ROT_MMIO_WR: |
| driver_test_isolation_psa_rot_mmio_wr(&msg); |
| break; |
| } |
| break; |
| case PSA_IPC_CONNECT: |
| case PSA_IPC_DISCONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| } |
| } |
| else |
| { |
| val_print_sf("Unexpected signal value=0x%x. Entering into infinite loop\n", |
| signals); |
| TEST_PANIC(); |
| } |
| } |
| } |
| |
| int32_t driver_test_psa_eoi_with_non_intr_signal(void) |
| { |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_NS)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| /* psa_eoi should panic as signal is non-interrupt signal*/ |
| psa_eoi(PSA_DOORBELL); |
| |
| /* Control shouldn't have reached here */ |
| val_print_sf("\tCheck for psa_eoi(non_intr_sig) failed\n", 0); |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| int32_t driver_test_psa_eoi_with_unasserted_signal(void) |
| { |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_NS)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| /* psa_eoi should panic as DRIVER_UART_INTR_SIG is unasserted */ |
| psa_eoi(DRIVER_UART_INTR_SIG); |
| |
| /* Control shouldn't have reached here */ |
| val_print_sf("\tCheck for psa_eoi(multiple_signals) failed\n", 0); |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| int32_t driver_test_psa_eoi_with_multiple_signals(void) |
| { |
| /* |
| * To test psa_eoi for multiple signals, one of signal should asserted first. |
| * Otherwise, check can false pass with psa_eoi_with_unasserted_signal. |
| * Assert interrupt signal assigned to driver partition |
| */ |
| val_generate_interrupt(); |
| |
| /* Wait for DRIVER_UART_INTR_SIG signal */ |
| if (psa_wait(DRIVER_UART_INTR_SIG, PSA_BLOCK) & DRIVER_UART_INTR_SIG) |
| { |
| /* Received DRIVER_UART_INTR_SIG signal, now process it */ |
| val_disable_interrupt(); |
| } |
| else |
| { |
| /* didn't receive DRIVER_UART_INTR_SIG signal, however process it */ |
| val_disable_interrupt(); |
| val_print_sf("\tFailed to receive irq signal\n", 0); |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_NS)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| /* psa_eoi should panic as irq_signal is provided with multiple signals */ |
| psa_eoi(DRIVER_UART_INTR_SIG|DRIVER_TEST_SIGNAL); |
| |
| /* Control shouldn't have reached here */ |
| val_print_sf("\tCheck for psa_eoi(multiple_signals) failed\n", 0); |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| return VAL_STATUS_ERROR; |
| } |
| |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| int32_t driver_test_irq_routing(void) |
| { |
| psa_signal_t signals = 0; |
| |
| /* Assert interrupt signal assigned to driver partition */ |
| val_generate_interrupt(); |
| |
| /* Wait for DRIVER_UART_INTR_SIG signal */ |
| signals = psa_wait(DRIVER_UART_INTR_SIG, PSA_BLOCK); |
| |
| if (signals & DRIVER_UART_INTR_SIG) |
| { |
| /* Received DRIVER_UART_INTR_SIG signal, now process it */ |
| val_disable_interrupt(); |
| |
| /* A signal remains active until it is processed by psa_eoi */ |
| if ((psa_wait(DRIVER_UART_INTR_SIG, PSA_BLOCK) & DRIVER_UART_INTR_SIG) == 0) |
| { |
| val_print_sf("\tIrq signal got de-activate before psa_eoi()\n", 0); |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| /* Perform end of interrupt */ |
| psa_eoi(DRIVER_UART_INTR_SIG); |
| |
| /* Irq signal should be de-activated now */ |
| if (psa_wait(DRIVER_UART_INTR_SIG, PSA_POLL) & DRIVER_UART_INTR_SIG) |
| { |
| val_print_sf("\tIrq signal didn't get de-activate after psa_eoi()\n", 0); |
| return VAL_STATUS_SPM_FAILED; |
| } |
| |
| return VAL_STATUS_SUCCESS; |
| } |
| else |
| { |
| /* didn't receive DRIVER_UART_INTR_SIG signal, however process it */ |
| val_disable_interrupt(); |
| val_print_sf("\tFailed to receive irq signal, signals=0x%x\n", signals); |
| return VAL_STATUS_SPM_FAILED; |
| } |
| } |
| |
| static int32_t process_call_request(psa_signal_t sig, psa_msg_t *msg) |
| { |
| val_status_t res = VAL_STATUS_ERROR; |
| psa_signal_t signals; |
| |
| wait: |
| signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK); |
| if (signals & sig) |
| { |
| if (psa_get(sig, msg) != PSA_SUCCESS) |
| { |
| goto wait; |
| } |
| |
| if ((msg->type < PSA_IPC_CALL) || (msg->handle <= 0)) |
| { |
| val_print_sf("\tpsa_get failed for request message\n", 0); |
| res = VAL_STATUS_ERROR; |
| } |
| else |
| { |
| res = VAL_STATUS_SUCCESS; |
| } |
| } |
| else |
| { |
| val_print_sf("\tpsa_wait returned with invalid signal value = 0x%x\n", signals); |
| res = VAL_STATUS_ERROR; |
| } |
| return res; |
| } |
| |
| void driver_test_isolation_psa_rot_data_rd(psa_msg_t *msg) |
| { |
| uint32_t *addr = &g_psa_rot_data; |
| |
| /* Send PSA RoT data address - global variable */ |
| psa_write(msg->handle, 0, (void *) &addr, sizeof(addr_t)); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| |
| void driver_test_isolation_psa_rot_data_wr(psa_msg_t *msg) |
| { |
| uint32_t *addr = &g_psa_rot_data; |
| |
| /* Send PSA RoT data address - global variable */ |
| psa_write(msg->handle, 0, (void *) &addr, sizeof(addr_t)); |
| |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_S)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| psa_reply(msg->handle, PSA_SUCCESS); |
| |
| /* Process second call request */ |
| if (VAL_ERROR(process_call_request(DRIVER_TEST_SIGNAL, msg))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Reached here means there could be write succeed or ignored */ |
| if (g_psa_rot_data == DATA_VALUE) |
| { |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| else |
| { |
| val_print_sf("\tExpected write to fault but it didn't\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| } |
| |
| void driver_test_isolation_psa_rot_stack_rd(psa_msg_t *msg) |
| { |
| uint32_t l_psa_rot_data = DATA_VALUE; |
| uint32_t *addr = &l_psa_rot_data; |
| |
| /* Send PSA RoT stack address - local variable */ |
| psa_write(msg->handle, 0, (void *) &addr, sizeof(addr_t)); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| |
| /* Dummy print to avoid compiler optimisation on local variable */ |
| val_print_sf("\tStack data 0x%x\n", (int)l_psa_rot_data); |
| } |
| |
| void driver_test_isolation_psa_rot_stack_wr(psa_msg_t *msg) |
| { |
| uint32_t l_psa_rot_data = DATA_VALUE; |
| uint32_t *addr = &l_psa_rot_data; |
| |
| /* Send PSA RoT stack address - local variable */ |
| psa_write(msg->handle, 0, (void *) &addr, sizeof(addr_t)); |
| |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_S)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| psa_reply(msg->handle, PSA_SUCCESS); |
| |
| /* Process second call request */ |
| if (VAL_ERROR(process_call_request(DRIVER_TEST_SIGNAL, msg))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Reached here means there could be write succeed or ignored */ |
| if (l_psa_rot_data == DATA_VALUE) |
| { |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| else |
| { |
| val_print_sf("\tExpected write to fault but it didn't\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| } |
| |
| void driver_test_isolation_psa_rot_heap_rd(psa_msg_t *msg) |
| { |
| #ifdef SP_HEAP_MEM_SUPP |
| uint8_t *buffer; |
| |
| buffer = (uint8_t *)malloc(sizeof(uint8_t) * BUFFER_SIZE); |
| memset((uint8_t *)buffer, (uint8_t)DATA_VALUE, BUFFER_SIZE); |
| |
| /* Send PSA RoT heap address */ |
| psa_write(msg->handle, 0, (void *) &buffer, BUFFER_SIZE); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| free(buffer); |
| #else |
| (void)msg; |
| #endif |
| } |
| |
| void driver_test_isolation_psa_rot_heap_wr(psa_msg_t *msg) |
| { |
| #ifdef SP_HEAP_MEM_SUPP |
| uint8_t *buffer; |
| |
| buffer = (uint8_t *)malloc(sizeof(uint8_t) * BUFFER_SIZE); |
| memset((uint8_t *)buffer, (uint8_t)DATA_VALUE, BUFFER_SIZE); |
| |
| /* Send PSA RoT heap address */ |
| psa_write(msg->handle, 0, (void *) &buffer, BUFFER_SIZE); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_S)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| |
| /* Process second call request */ |
| if (VAL_ERROR(process_call_request(DRIVER_TEST_SIGNAL, msg))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Reached here means there could be write succeed or ignored */ |
| if (buffer[0] == (uint8_t)DATA_VALUE) |
| { |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| else |
| { |
| val_print_sf("\tExpected write to fault but it didn't\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| free(buffer); |
| #else |
| (void)msg; |
| #endif |
| } |
| |
| void driver_test_isolation_psa_rot_mmio_rd(psa_msg_t *msg) |
| { |
| addr_t psa_rot_mmio_addr; |
| |
| if (VAL_ERROR(val_get_driver_mmio_addr(&psa_rot_mmio_addr))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Send PSA RoT mmio address */ |
| memset((uint8_t *)&psa_rot_mmio_addr, (uint8_t)DATA_VALUE, sizeof(addr_t)); |
| psa_write(msg->handle, 0, (void *) &psa_rot_mmio_addr, sizeof(addr_t)); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| |
| void driver_test_isolation_psa_rot_mmio_wr(psa_msg_t *msg) |
| { |
| addr_t psa_rot_mmio_addr; |
| |
| if (VAL_ERROR(val_get_driver_mmio_addr(&psa_rot_mmio_addr))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Send PSA RoT mmio address */ |
| memset((uint8_t *)&psa_rot_mmio_addr, (uint8_t)DATA_VALUE, sizeof(addr_t)); |
| psa_write(msg->handle, 0, (void *) &psa_rot_mmio_addr, sizeof(addr_t)); |
| psa_reply(msg->handle, PSA_SUCCESS); |
| |
| /* Setting boot.state before test check */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_S)) |
| { |
| val_print_sf("\tFailed to set boot flag before check\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| |
| /* Process second call request */ |
| if (VAL_ERROR(process_call_request(DRIVER_TEST_SIGNAL, msg))) |
| { |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Resetting boot.state to catch unwanted reboot */ |
| if (val_driver_private_set_boot_flag_fn(BOOT_EXPECTED_BUT_FAILED)) |
| { |
| val_print_sf("\tFailed to set boot flag after check\n", 0); |
| psa_reply(msg->handle, -2); |
| return; |
| } |
| |
| /* Reached here means there could be write succeed or ignored */ |
| if (*(uint32_t *)psa_rot_mmio_addr == (uint32_t)DATA_VALUE) |
| { |
| psa_reply(msg->handle, PSA_SUCCESS); |
| } |
| else |
| { |
| val_print_sf("\tExpected write to fault but it didn't\n", 0); |
| psa_reply(msg->handle, -2); |
| } |
| } |