1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/*
* Copyright (C) ST-Ericsson SA 2011
*
* Author: Jens Wiklander <jens.wiklander@stericsson.com>
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
* Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
*
* License terms: GNU General Public License (GPL) version 2
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/tee.h>
#include <linux/module.h>
#include <mach/hardware.h>
#define STATIC_TEE_TA_START_LOW 0xBC765EDE
#define STATIC_TEE_TA_START_MID 0x6724
#define STATIC_TEE_TA_START_HIGH 0x11DF
#define STATIC_TEE_TA_START_CLOCKSEQ \
{0x8E, 0x12, 0xEC, 0xDB, 0xDF, 0xD7, 0x20, 0x85}
#define U5500_PRCMU_DBG_PWRCTRL (U5500_PRCMU_BASE + 0x4AC)
#define PRCMU_DBG_PWRCTRL_A9DBGCLKEN (1 << 4)
static struct tee_product_config product_config;
bool ux500_jtag_enabled(void)
{
#ifdef CONFIG_UX500_DEBUG_NO_LAUTERBACH
return false;
#else
if (cpu_is_u5500())
return readl_relaxed(__io_address(U5500_PRCMU_DBG_PWRCTRL))
& PRCMU_DBG_PWRCTRL_A9DBGCLKEN;
if (cpu_is_u8500())
return (product_config.rt_flags & TEE_RT_FLAGS_JTAG_ENABLED) ==
TEE_RT_FLAGS_JTAG_ENABLED;
return true;
#endif
}
static int __init product_detect(void)
{
int err;
int origin_err;
struct tee_operation operation = { { { 0 } } };
struct tee_context context;
struct tee_session session;
/* Selects trustzone application needed for the job. */
struct tee_uuid static_uuid = {
STATIC_TEE_TA_START_LOW,
STATIC_TEE_TA_START_MID,
STATIC_TEE_TA_START_HIGH,
STATIC_TEE_TA_START_CLOCKSEQ,
};
if (cpu_is_u5500())
return -ENODEV;
err = teec_initialize_context(NULL, &context);
if (err) {
pr_err("ux500-product: unable to initialize tee context,"
" err = %d\n", err);
err = -EINVAL;
goto error0;
}
err = teec_open_session(&context, &session, &static_uuid,
TEEC_LOGIN_PUBLIC, NULL, NULL, &origin_err);
if (err) {
pr_err("ux500-product: unable to open tee session,"
" tee error = %d, origin error = %d\n",
err, origin_err);
err = -EINVAL;
goto error1;
}
operation.shm[0].buffer = &product_config;
operation.shm[0].size = sizeof(product_config);
operation.shm[0].flags = TEEC_MEM_OUTPUT;
operation.flags = TEEC_MEMREF_0_USED;
err = teec_invoke_command(&session,
TEE_STA_GET_PRODUCT_CONFIG,
&operation, &origin_err);
if (err) {
pr_err("ux500-product: fetching product settings failed, err=%d",
err);
err = -EINVAL;
goto error1;
}
pr_info("ux500-product: JTAG is %s\n",
ux500_jtag_enabled()? "enabled" : "disabled");
error1:
(void) teec_finalize_context(&context);
error0:
return err;
}
device_initcall(product_detect);
|