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 Musteastatic 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 MusteaTEE_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 MusteaTEE_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