uboot/test/optee/cmd_ut_optee.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
   4 */
   5
   6#include <common.h>
   7#include <command.h>
   8#include <errno.h>
   9#include <fdt_support.h>
  10#include <log.h>
  11#include <malloc.h>
  12#include <tee/optee.h>
  13
  14#include <linux/sizes.h>
  15
  16#include <test/ut.h>
  17#include <test/optee.h>
  18#include <test/suites.h>
  19
  20/* 4k ought to be enough for anybody */
  21#define FDT_COPY_SIZE   (4 * SZ_1K)
  22
  23extern u32 __dtb_test_optee_base_begin;
  24extern u32 __dtb_test_optee_optee_begin;
  25extern u32 __dtb_test_optee_no_optee_begin;
  26
  27static void *fdt;
  28static bool expect_success;
  29
  30static int optee_fdt_firmware(struct unit_test_state *uts)
  31{
  32        const void *prop;
  33        int offs, len;
  34
  35        offs = fdt_path_offset(fdt, "/firmware/optee");
  36        ut_assert(expect_success ? offs >= 0 : offs < 0);
  37
  38        /* only continue if we have an optee node */
  39        if (offs < 0)
  40                return CMD_RET_SUCCESS;
  41
  42        prop = fdt_getprop(fdt, offs, "compatible", &len);
  43        ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
  44
  45        prop = fdt_getprop(fdt, offs, "method", &len);
  46        ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
  47
  48        return CMD_RET_SUCCESS;
  49}
  50OPTEE_TEST(optee_fdt_firmware, 0);
  51
  52static int optee_fdt_protected_memory(struct unit_test_state *uts)
  53{
  54        int offs, subnode;
  55        bool found;
  56
  57        offs = fdt_path_offset(fdt, "/firmware/optee");
  58        ut_assert(expect_success ? offs >= 0 : offs < 0);
  59
  60        /* only continue if we have an optee node */
  61        if (offs < 0)
  62                return CMD_RET_SUCCESS;
  63
  64        /* optee inserts its memory regions as reserved-memory nodes */
  65        offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
  66        ut_assert(offs >= 0);
  67
  68        subnode = fdt_first_subnode(fdt, offs);
  69        ut_assert(subnode);
  70
  71        found = 0;
  72        while (subnode >= 0) {
  73                const char *name = fdt_get_name(fdt, subnode, NULL);
  74                struct fdt_resource res;
  75
  76                ut_assert(name);
  77
  78                /* only handle optee reservations */
  79                if (strncmp(name, "optee", 5))
  80                        continue;
  81
  82                found = true;
  83
  84                /* check if this subnode has a reg property */
  85                ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
  86                subnode = fdt_next_subnode(fdt, subnode);
  87        }
  88
  89        ut_assert(found);
  90
  91        return CMD_RET_SUCCESS;
  92}
  93OPTEE_TEST(optee_fdt_protected_memory, 0);
  94
  95int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  96{
  97        struct unit_test *tests = UNIT_TEST_SUITE_START(optee_test);
  98        const int n_ents = UNIT_TEST_SUITE_COUNT(optee_test);
  99        struct unit_test_state *uts;
 100        void *fdt_optee = &__dtb_test_optee_optee_begin;
 101        void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
 102        void *fdt_base = &__dtb_test_optee_base_begin;
 103        int ret = -ENOMEM;
 104
 105        uts = calloc(1, sizeof(*uts));
 106        if (!uts)
 107                return -ENOMEM;
 108
 109        ut_assertok(fdt_check_header(fdt_base));
 110        ut_assertok(fdt_check_header(fdt_optee));
 111        ut_assertok(fdt_check_header(fdt_no_optee));
 112
 113        fdt = malloc(FDT_COPY_SIZE);
 114        if (!fdt)
 115                return ret;
 116
 117        /*
 118         * Resize the FDT to 4k so that we have room to operate on
 119         *
 120         * (and relocate it since the memory might be mapped
 121         * read-only)
 122         */
 123        ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
 124
 125        /*
 126         * (1) Try to copy optee nodes from empty dt.
 127         * This should still run successfully.
 128         */
 129        ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
 130
 131        expect_success = false;
 132        ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 133
 134        /* (2) Try to copy optee nodes from prefilled dt */
 135        ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
 136
 137        expect_success = true;
 138        ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 139
 140        /* (3) Try to copy OP-TEE nodes into a already filled DT */
 141        ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
 142        ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
 143
 144        expect_success = true;
 145        ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 146
 147        free(fdt);
 148        return ret;
 149}
 150