blob: 3959008336407127a2e678795e2c5b7262e0d9aa [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
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +00006#include <assert.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +00007#include <debug.h>
8#include <errno.h>
9#include <host_defs.h>
10#include <host_utils.h>
11#include <plat_common.h>
12#include <string.h>
13#include <xlat_tables.h>
14
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000015static struct sysreg_data sysregs[SYSREG_MAX_CBS];
Soby Mathewb4c6df42022-11-09 11:13:29 +000016static unsigned int installed_cb_idx;
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000017static unsigned int current_cpuid;
Soby Mathewb4c6df42022-11-09 11:13:29 +000018
19/*
20 * Allocate memory to emulate physical memory to initialize the
21 * granule library.
22 */
23static unsigned char granules_buffer[HOST_MEM_SIZE] __aligned(GRANULE_SIZE);
24
25/*
26 * Generic callback to access a sysreg for reading.
27 */
28static u_register_t sysreg_rd_cb(u_register_t *reg)
29{
30 return *reg;
31}
32
33/*
34 * Generic callback to access a sysreg for writing.
35 */
36static void sysreg_wr_cb(u_register_t val, u_register_t *reg)
37{
38 *reg = val;
39}
40
41struct sysreg_cb *host_util_get_sysreg_cb(char *name)
42{
43 for (unsigned int i = 0U; i < SYSREG_MAX_CBS; i++) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000044 if (strncmp(name, &sysregs[i].name[0],
Soby Mathewb4c6df42022-11-09 11:13:29 +000045 MAX_SYSREG_NAME_LEN) == 0) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000046
47 /*
48 * Get a pointer to the register value for the
49 * current CPU.
50 */
51 sysregs[i].callbacks.reg =
52 &(sysregs[i].value[current_cpuid]);
53 return &sysregs[i].callbacks;
Soby Mathewb4c6df42022-11-09 11:13:29 +000054 }
55 }
56
57 return (struct sysreg_cb *)NULL;
58}
59
60int host_util_set_sysreg_cb(char *name, rd_cb_t rd_cb, wr_cb_t wr_cb,
61 u_register_t init)
62{
63 if (installed_cb_idx < SYSREG_MAX_CBS) {
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000064 sysregs[installed_cb_idx].callbacks.rd_cb = rd_cb;
65 sysregs[installed_cb_idx].callbacks.wr_cb = wr_cb;
66 sysregs[installed_cb_idx].callbacks.reg =
67 (u_register_t *)NULL;
Soby Mathewb4c6df42022-11-09 11:13:29 +000068
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000069 for (unsigned int i = 0U; i < MAX_CPUS; i++) {
70 sysregs[installed_cb_idx].value[i] = init;
71 }
72
73 (void)strncpy(&(sysregs[installed_cb_idx].name[0]),
Soby Mathewb4c6df42022-11-09 11:13:29 +000074 &name[0], MAX_SYSREG_NAME_LEN);
75
76 /*
77 * Add a string termination character in case the
78 * name were truncated.
79 */
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000080 sysregs[installed_cb_idx].name[MAX_SYSREG_NAME_LEN] = '\0';
Soby Mathewb4c6df42022-11-09 11:13:29 +000081
82 ++installed_cb_idx;
83
84 return 0;
85 }
86
87 return -ENOMEM;
88}
89
90void host_util_reset_all_sysreg_cb(void)
91{
92
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +000093 (void)memset((void *)sysregs, 0,
94 sizeof(struct sysreg_data) * SYSREG_MAX_CBS);
Soby Mathewb4c6df42022-11-09 11:13:29 +000095
96 installed_cb_idx = 0U;
97}
98
99int host_util_set_default_sysreg_cb(char *name, u_register_t init)
100{
101 return host_util_set_sysreg_cb(name, &sysreg_rd_cb,
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +0000102 &sysreg_wr_cb, init);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000103}
104
105unsigned long host_util_get_granule_base(void)
106{
107 return (unsigned long)granules_buffer;
108}
Javier Almansa Sobrino9929a792022-11-22 16:11:13 +0000109
110void host_util_set_cpuid(unsigned int cpuid)
111{
112 assert(cpuid < MAX_CPUS);
113
114 current_cpuid = cpuid;
115}