xref: /optee_os/core/drivers/ls_sec_mon.c (revision a5d5bbc82de95f531512fafa76a42c879e81b4c4)
13a340005SAndrew Mustea // SPDX-License-Identifier: BSD-2-Clause
23a340005SAndrew Mustea /*
33a340005SAndrew Mustea  * Copyright 2022 Microsoft
43a340005SAndrew Mustea  *
53a340005SAndrew Mustea  * Driver for the NXP LX2160A-series Security Monitor (SecMon).
63a340005SAndrew Mustea  */
73a340005SAndrew Mustea 
83a340005SAndrew Mustea #include <drivers/ls_sec_mon.h>
93a340005SAndrew Mustea #include <io.h>
103a340005SAndrew Mustea #include <kernel/boot.h>
113a340005SAndrew Mustea #include <kernel/dt.h>
123a340005SAndrew Mustea #include <libfdt.h>
133a340005SAndrew Mustea #include <mm/core_memprot.h>
143a340005SAndrew Mustea #include <util.h>
153a340005SAndrew Mustea 
163a340005SAndrew Mustea /**
173a340005SAndrew Mustea  * struct ls_sec_mon_registers - Memory map of the SecMon registers.
183a340005SAndrew Mustea  * hplr;		HP Lock Register.
193a340005SAndrew Mustea  * @hpcomr:		HP Command Register.
203a340005SAndrew Mustea  * @rsvd0:		Reserved.
213a340005SAndrew Mustea  * @hpsicr:		HP Security Interrupt Control Register.
223a340005SAndrew Mustea  * @hpsvcr:		HP Security Violation Control Register.
233a340005SAndrew Mustea  * @hpsr:		HP Status Register.
243a340005SAndrew Mustea  * @hpsvsr:		HP Security Violation Status Register.
253a340005SAndrew Mustea  * @hphacivr:		HP High Assurance Counter IV Register.
263a340005SAndrew Mustea  * @hphacr:		HP High Assurance Counter Register.
273a340005SAndrew Mustea  * @rsvd1[0x4]:		Reserved.
283a340005SAndrew Mustea  * @lplr:		LP Lock Register.
293a340005SAndrew Mustea  * @lpcr:		LP Control Register.
303a340005SAndrew Mustea  * @lpmkcr:		LP Master Key Control Register.
313a340005SAndrew Mustea  * @lpsvcr:		LP Security Violation Control Register.
323a340005SAndrew Mustea  * @rsvd2:		Reserved.
333a340005SAndrew Mustea  * @lptdcr:		LP Tamper Detectors Configuration.
343a340005SAndrew Mustea  * @lpsr:		LP Status Register.
353a340005SAndrew Mustea  * @rsvd3[0x3]:		Reserved.
363a340005SAndrew Mustea  * @lpsmcmr:		LP Secure Monotonic Counter MSB Register.
373a340005SAndrew Mustea  * @lpsmclr:		LP Secure Monotonic Counter LSB Register.
383a340005SAndrew Mustea  * @lppgdr:		LP Power Glitch Detector Register.
393a340005SAndrew Mustea  * @rsvd4:		Reserved.
403a340005SAndrew Mustea  * @lpzmkr[0x8]:	LP Zeroizable Master Key Registers.
413a340005SAndrew Mustea  * @lpgpr[0x4]:		LP General Purpose Registers.
423a340005SAndrew Mustea  * @rsvd5[0x2d2]:	Reserved.
433a340005SAndrew Mustea  * @hpvidr1:		HP Version ID Register 1.
443a340005SAndrew Mustea  * @hpvidr2:		HP Version ID Register 2.
453a340005SAndrew Mustea  */
463a340005SAndrew Mustea static struct ls_sec_mon_registers {
473a340005SAndrew Mustea 	uint32_t hplr;			/* 0x000 */
483a340005SAndrew Mustea 	uint32_t hpcomr;		/* 0x004 */
493a340005SAndrew Mustea 	uint32_t rsvd0;			/* 0x008 */
503a340005SAndrew Mustea 	uint32_t hpsicr;		/* 0x00C */
513a340005SAndrew Mustea 	uint32_t hpsvcr;		/* 0x010 */
523a340005SAndrew Mustea 	uint32_t hpsr;			/* 0x014 */
533a340005SAndrew Mustea 	uint32_t hpsvsr;		/* 0x018 */
543a340005SAndrew Mustea 	uint32_t hphacivr;		/* 0x01C */
553a340005SAndrew Mustea 	uint32_t hphacr;		/* 0x020 */
563a340005SAndrew Mustea 	uint32_t rsvd1[0x4];		/* 0x024 */
573a340005SAndrew Mustea 	uint32_t lplr;			/* 0x034 */
583a340005SAndrew Mustea 	uint32_t lpcr;			/* 0x038 */
593a340005SAndrew Mustea 	uint32_t lpmkcr;		/* 0x03C */
603a340005SAndrew Mustea 	uint32_t lpsvcr;		/* 0x040 */
613a340005SAndrew Mustea 	uint32_t rsvd2;			/* 0x044 */
623a340005SAndrew Mustea 	uint32_t lptdcr;		/* 0x048 */
633a340005SAndrew Mustea 	uint32_t lpsr;			/* 0x04C */
643a340005SAndrew Mustea 	uint32_t rsvd3[0x3];		/* 0x050 */
653a340005SAndrew Mustea 	uint32_t lpsmcmr;		/* 0x05C */
663a340005SAndrew Mustea 	uint32_t lpsmclr;		/* 0x060 */
673a340005SAndrew Mustea 	uint32_t lppgdr;		/* 0x064 */
683a340005SAndrew Mustea 	uint32_t rsvd4;			/* 0x068 */
693a340005SAndrew Mustea 	uint32_t lpzmkr[0x8];		/* 0x06C */
703a340005SAndrew Mustea 	uint32_t lpgpr[0x4];		/* 0x090 */
713a340005SAndrew Mustea 	uint32_t rsvd5[0x2d2];		/* 0x0B0 */
723a340005SAndrew Mustea 	uint32_t hpvidr1;		/* 0xBF8 */
733a340005SAndrew Mustea 	uint32_t hpvidr2;		/* 0xBFC */
743a340005SAndrew Mustea } *sec_mon_regs;
753a340005SAndrew Mustea 
763a340005SAndrew Mustea /**
773a340005SAndrew Mustea  * ls_sec_mon_init() - Initialize the SecMon driver and assign the sec_mon_regs
783a340005SAndrew Mustea  *		       pointer to the SecMon base address detailed in the device
793a340005SAndrew Mustea  *		       tree.
803a340005SAndrew Mustea  *
813a340005SAndrew Mustea  * Return:	0 if successful or > 0 on error.
823a340005SAndrew Mustea  */
ls_sec_mon_init(void)833a340005SAndrew Mustea static TEE_Result ls_sec_mon_init(void)
843a340005SAndrew Mustea {
853a340005SAndrew Mustea 	void *fdt = NULL;
863a340005SAndrew Mustea 	size_t size = 0;
873a340005SAndrew Mustea 	uint32_t node = 0;
883a340005SAndrew Mustea 	vaddr_t ctrl_base = 0;
893a340005SAndrew Mustea 
903a340005SAndrew Mustea 	fdt = get_embedded_dt();
913a340005SAndrew Mustea 	if (!fdt) {
923a340005SAndrew Mustea 		EMSG("Unable to find the device tree");
933a340005SAndrew Mustea 		return TEE_ERROR_ITEM_NOT_FOUND;
943a340005SAndrew Mustea 	}
953a340005SAndrew Mustea 
963a340005SAndrew Mustea 	node = fdt_node_offset_by_compatible(fdt, node, "fsl,lx2160a-sec-mon");
973a340005SAndrew Mustea 	if (node <= 0) {
983a340005SAndrew Mustea 		EMSG("Unable to find the SecMon device tree node");
993a340005SAndrew Mustea 		return TEE_ERROR_ITEM_NOT_FOUND;
1003a340005SAndrew Mustea 	}
1013a340005SAndrew Mustea 
102*a5d5bbc8SVesa Jääskeläinen 	if (dt_map_dev(fdt, node, &ctrl_base, &size, DT_MAP_AUTO) < 0) {
1033a340005SAndrew Mustea 		EMSG("Unable to get the SecMon virtual address");
1043a340005SAndrew Mustea 		return TEE_ERROR_GENERIC;
1053a340005SAndrew Mustea 	}
1063a340005SAndrew Mustea 
1073a340005SAndrew Mustea 	sec_mon_regs = (struct ls_sec_mon_registers *)ctrl_base;
1083a340005SAndrew Mustea 
1093a340005SAndrew Mustea 	return TEE_SUCCESS;
1103a340005SAndrew Mustea }
1113a340005SAndrew Mustea 
ls_sec_mon_read(struct ls_sec_mon_data * data)1123a340005SAndrew Mustea TEE_Result ls_sec_mon_read(struct ls_sec_mon_data *data)
1133a340005SAndrew Mustea {
1143a340005SAndrew Mustea 	if (!sec_mon_regs) {
1153a340005SAndrew Mustea 		EMSG("SecMon driver is not initialized");
1163a340005SAndrew Mustea 		return TEE_ERROR_GENERIC;
1173a340005SAndrew Mustea 	}
1183a340005SAndrew Mustea 
1193a340005SAndrew Mustea 	if (!data) {
1203a340005SAndrew Mustea 		EMSG("Given buffer is uninitialized");
1213a340005SAndrew Mustea 		return TEE_ERROR_BAD_PARAMETERS;
1223a340005SAndrew Mustea 	}
1233a340005SAndrew Mustea 
1243a340005SAndrew Mustea 	data->hplr = io_read32((vaddr_t)&sec_mon_regs->hplr);
1253a340005SAndrew Mustea 	data->hpcomr = io_read32((vaddr_t)&sec_mon_regs->hpcomr);
1263a340005SAndrew Mustea 	data->hpsicr = io_read32((vaddr_t)&sec_mon_regs->hpsicr);
1273a340005SAndrew Mustea 	data->hpsvcr = io_read32((vaddr_t)&sec_mon_regs->hpsvcr);
1283a340005SAndrew Mustea 	data->hpsr = io_read32((vaddr_t)&sec_mon_regs->hpsr);
1293a340005SAndrew Mustea 	data->hpsvsr = io_read32((vaddr_t)&sec_mon_regs->hpsvsr);
1303a340005SAndrew Mustea 	data->hphacivr = io_read32((vaddr_t)&sec_mon_regs->hphacivr);
1313a340005SAndrew Mustea 	data->hphacr = io_read32((vaddr_t)&sec_mon_regs->hphacr);
1323a340005SAndrew Mustea 	data->lplr = io_read32((vaddr_t)&sec_mon_regs->lplr);
1333a340005SAndrew Mustea 	data->lpcr = io_read32((vaddr_t)&sec_mon_regs->lpcr);
1343a340005SAndrew Mustea 	data->lpmkcr = io_read32((vaddr_t)&sec_mon_regs->lpmkcr);
1353a340005SAndrew Mustea 	data->lpsvcr = io_read32((vaddr_t)&sec_mon_regs->lpsvcr);
1363a340005SAndrew Mustea 	data->lptdcr = io_read32((vaddr_t)&sec_mon_regs->lptdcr);
1373a340005SAndrew Mustea 	data->lpsr = io_read32((vaddr_t)&sec_mon_regs->lpsr);
1383a340005SAndrew Mustea 	data->lpsmcmr = io_read32((vaddr_t)&sec_mon_regs->lpsmcmr);
1393a340005SAndrew Mustea 	data->lpsmclr = io_read32((vaddr_t)&sec_mon_regs->lpsmclr);
1403a340005SAndrew Mustea 	data->lppgdr = io_read32((vaddr_t)&sec_mon_regs->lppgdr);
1413a340005SAndrew Mustea 	data->hpvidr1 = io_read32((vaddr_t)&sec_mon_regs->hpvidr1);
1423a340005SAndrew Mustea 	data->hpvidr2 = io_read32((vaddr_t)&sec_mon_regs->hpvidr2);
1433a340005SAndrew Mustea 
1443a340005SAndrew Mustea 	for (uint32_t i = 0; i < ARRAY_SIZE(data->lpzmkr); ++i)
1453a340005SAndrew Mustea 		data->lpzmkr[i] = io_read32((vaddr_t)&sec_mon_regs->lpzmkr[i]);
1463a340005SAndrew Mustea 
1473a340005SAndrew Mustea 	for (uint32_t i = 0; i < ARRAY_SIZE(data->lpgpr); ++i)
1483a340005SAndrew Mustea 		data->lpgpr[i] = io_read32((vaddr_t)&sec_mon_regs->lpgpr[i]);
1493a340005SAndrew Mustea 
1503a340005SAndrew Mustea 	return TEE_SUCCESS;
1513a340005SAndrew Mustea }
1523a340005SAndrew Mustea 
ls_sec_mon_status(void)1533a340005SAndrew Mustea TEE_Result ls_sec_mon_status(void)
1543a340005SAndrew Mustea {
1553a340005SAndrew Mustea 	if (!sec_mon_regs)
1563a340005SAndrew Mustea 		return TEE_ERROR_GENERIC;
1573a340005SAndrew Mustea 
1583a340005SAndrew Mustea 	return TEE_SUCCESS;
1593a340005SAndrew Mustea }
1603a340005SAndrew Mustea 
1613a340005SAndrew Mustea driver_init(ls_sec_mon_init);
162