summaryrefslogtreecommitdiff
path: root/libqmrom/include/qmrom.h
blob: c403ed12313b550d13f9635118c7387e7d7ff3e3 (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
/*
 * Copyright 2021 Qorvo US, Inc.
 *
 */

#ifndef __QMROM_H__
#define __QMROM_H__

#ifndef __KERNEL__
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <byteswap.h>
#include <inttypes.h>
#else
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#define bswap_16 be16_to_cpu
#define PRIu32 "u"
#endif

#include <qmrom_error.h>

#undef CHECK_STCS

#define PEG_ERR_TIMEOUT PEG_ERR_BASE - 1
#define PEG_ERR_ROM_NOT_READY PEG_ERR_BASE - 2
#define PEG_ERR_SEND_CERT_WRITE PEG_ERR_BASE - 3
#define PEG_ERR_WRONG_REVISION PEG_ERR_BASE - 4
#define PEG_ERR_FIRST_KEY_CERT_OR_FW_VER PEG_ERR_BASE - 5

enum chip_revision_e {
	CHIP_REVISION_A0 = 0xA0,
	CHIP_REVISION_B0 = 0xB0,
	CHIP_REVISION_C0 = 0xC0,
	CHIP_REVISION_UNKNOWN = 0xFF
};

#define HBK_LOC 12
typedef enum {
	HBK_2E_ICV = 0,
	HBK_2E_OEM = 1,
	HBK_1E_ICV_OEM = 2,
} hbk_t;

#define ROM_VERSION_A0 0x01a0
#define ROM_VERSION_B0 0xb000

#define ROM_SOC_ID_LEN 0x20
#define ROM_UUID_LEN 0x10

/* Life cycle state definitions. */

/*! Defines the CM life-cycle state value. */
#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0
/*! Defines the DM life-cycle state value. */
#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1
/*! Defines the Secure life-cycle state value. */
#define CC_BSV_SECURE_LCS 0x5
/*! Defines the RMA life-cycle state value. */
#define CC_BSV_RMA_LCS 0x7

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"

struct qmrom_handle;

struct unstitched_firmware {
	struct firmware *fw_img;
	struct firmware *fw_crt;
	struct firmware *key1_crt;
	struct firmware *key2_crt;
};

#define SSTC2UINT32(handle, offset)                                      \
	({                                                               \
		uint32_t tmp = 0xbeefdeed;                               \
		if ((handle)->sstc->len >= (offset) + sizeof(tmp))       \
			memcpy(&tmp, &(handle)->sstc->payload[(offset)], \
			       sizeof(tmp));                             \
		tmp;                                                     \
	})

#define SSTC2UINT16(handle, offset)                                      \
	({                                                               \
		uint16_t tmp = 0xbeed;                                   \
		if ((handle)->sstc->len >= (offset) + sizeof(tmp))       \
			memcpy(&tmp, &(handle)->sstc->payload[(offset)], \
			       sizeof(tmp));                             \
		tmp;                                                     \
	})

/* Those functions allow the libqmrom to call
 * revision specific functions
 */
typedef int (*flash_fw_fn)(struct qmrom_handle *handle,
			   const struct firmware *fw);
typedef int (*flash_unstitched_fw_fn)(struct qmrom_handle *handle,
				      const struct unstitched_firmware *fw);
typedef int (*flash_debug_cert_fn)(struct qmrom_handle *handle,
				   struct firmware *dbg_cert);
typedef int (*erase_debug_cert_fn)(struct qmrom_handle *handle);

struct rom_code_ops {
	flash_fw_fn flash_fw;
	flash_unstitched_fw_fn flash_unstitched_fw;
	flash_debug_cert_fn flash_debug_cert;
	erase_debug_cert_fn erase_debug_cert;
};

/* Those functions allow the libqmrom to call
 * device specific functions
 */
typedef int (*reset_device_fn)(void *handle);

struct device_ops {
	reset_device_fn reset;
};

struct qmrom_handle {
	void *spi_handle;
	void *reset_handle;
	void *ss_rdy_handle;
	int comms_retries;
	enum chip_revision_e chip_rev;
	uint16_t device_version;
	struct device_ops dev_ops;
	struct rom_code_ops rom_ops;
	uint32_t lcs_state;
	struct stc *hstc;
	struct stc *sstc;
	uint8_t soc_id[ROM_SOC_ID_LEN];
	uint8_t uuid[ROM_UUID_LEN];
	bool is_be;
};

int qmrom_unstitch_fw(const struct firmware *fw,
		      struct unstitched_firmware *unstitched_fw,
		      enum chip_revision_e revision);
struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
				void *ss_rdy_handle, int comms_retries,
				reset_device_fn reset);
void qmrom_deinit(struct qmrom_handle *handle);
int qmrom_reboot_bootloader(struct qmrom_handle *handle);
int qmrom_flash_dbg_cert(struct qmrom_handle *handle,
			 struct firmware *dbg_cert);
int qmrom_erase_dbg_cert(struct qmrom_handle *handle);
int qmrom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw);
int qmrom_flash_unstitched_fw(struct qmrom_handle *handle,
			      const struct unstitched_firmware *fw);

int qmrom_pre_read(struct qmrom_handle *handle);
int qmrom_read(struct qmrom_handle *handle);
int qmrom_write_cmd(struct qmrom_handle *handle, uint8_t cmd);
int qmrom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd);
int qmrom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
			 uint16_t data_size, const char *data);
int qmrom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
			   uint16_t data_size, const char *data);

#ifdef CHECK_STCS
void check_stcs(const char *func, int line, struct qmrom_handle *h);
#else
#define check_stcs(f, l, h)
#endif
#endif /* __QMROM_H__ */