blob: 082f24ffae07bdcc36ab71510f2e1909db19b6b4 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <debug.h>
7#include <errno.h>
8#include <host_defs.h>
9#include <host_utils.h>
10#include <plat_common.h>
11#include <string.h>
12#include <xlat_tables.h>
13
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000014static struct sysreg_data sysregs[SYSREG_MAX_CBS];
Soby Mathewb4c6df42022-11-09 11:13:29 +000015static unsigned int installed_cb_idx;
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000016static unsigned int current_cpuid;
Soby Mathewb4c6df42022-11-09 11:13:29 +000017
18/*
19 * Allocate memory to emulate physical memory to initialize the
20 * granule library.
21 */
22static unsigned char granules_buffer[HOST_MEM_SIZE] __aligned(GRANULE_SIZE);
23
24/*
25 * Generic callback to access a sysreg for reading.
26 */
27static u_register_t sysreg_rd_cb(u_register_t *reg)
28{
29 return *reg;
30}
31
32/*
33 * Generic callback to access a sysreg for writing.
34 */
35static void sysreg_wr_cb(u_register_t val, u_register_t *reg)
36{
37 *reg = val;
38}
39
40struct sysreg_cb *host_util_get_sysreg_cb(char *name)
41{
42 for (unsigned int i = 0U; i < SYSREG_MAX_CBS; i++) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000043 if (strncmp(name, &sysregs[i].name[0],
Soby Mathewb4c6df42022-11-09 11:13:29 +000044 MAX_SYSREG_NAME_LEN) == 0) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000045
46 /*
47 * Get a pointer to the register value for the
48 * current CPU.
49 */
50 sysregs[i].callbacks.reg =
51 &(sysregs[i].value[current_cpuid]);
52 return &sysregs[i].callbacks;
Soby Mathewb4c6df42022-11-09 11:13:29 +000053 }
54 }
55
56 return (struct sysreg_cb *)NULL;
57}
58
59int host_util_set_sysreg_cb(char *name, rd_cb_t rd_cb, wr_cb_t wr_cb,
60 u_register_t init)
61{
62 if (installed_cb_idx < SYSREG_MAX_CBS) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000063 sysregs[installed_cb_idx].callbacks.rd_cb = rd_cb;
64 sysregs[installed_cb_idx].callbacks.wr_cb = wr_cb;
65 sysregs[installed_cb_idx].callbacks.reg =
66 (u_register_t *)NULL;
Soby Mathewb4c6df42022-11-09 11:13:29 +000067
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000068 for (unsigned int i = 0U; i < MAX_CPUS; i++) {
69 sysregs[installed_cb_idx].value[i] = init;
70 }
71
72 (void)strncpy(&(sysregs[installed_cb_idx].name[0]),
Soby Mathewb4c6df42022-11-09 11:13:29 +000073 &name[0], MAX_SYSREG_NAME_LEN);
74
75 /*
76 * Add a string termination character in case the
77 * name were truncated.
78 */
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000079 sysregs[installed_cb_idx].name[MAX_SYSREG_NAME_LEN] = '\0';
Soby Mathewb4c6df42022-11-09 11:13:29 +000080
81 ++installed_cb_idx;
82
83 return 0;
84 }
85
86 return -ENOMEM;
87}
88
89void host_util_reset_all_sysreg_cb(void)
90{
91
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000092 (void)memset((void *)sysregs, 0,
93 sizeof(struct sysreg_data) * SYSREG_MAX_CBS);
Soby Mathewb4c6df42022-11-09 11:13:29 +000094
95 installed_cb_idx = 0U;
96}
97
98int host_util_set_default_sysreg_cb(char *name, u_register_t init)
99{
100 return host_util_set_sysreg_cb(name, &sysreg_rd_cb,
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +0000101 &sysreg_wr_cb, init);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102}
103
104unsigned long host_util_get_granule_base(void)
105{
106 return (unsigned long)granules_buffer;
107}
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +0000108
109void host_util_set_cpuid(unsigned int cpuid)
110{
111 assert(cpuid < MAX_CPUS);
112
113 current_cpuid = cpuid;
114}