1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include <mod_apcontext.h>
9 #include <mod_clock.h>
10
11 #include <fwk_assert.h>
12 #include <fwk_event.h>
13 #include <fwk_id.h>
14 #include <fwk_log.h>
15 #include <fwk_module.h>
16 #include <fwk_module_idx.h>
17 #include <fwk_notification.h>
18 #include <fwk_status.h>
19
20 #include <inttypes.h>
21 #include <string.h>
22
23 #define MODULE_NAME "[APContext]"
24
apcontext_zero(void)25 static void apcontext_zero(void)
26 {
27 const struct mod_apcontext_config *config;
28
29 config = fwk_module_get_data(fwk_module_id_apcontext);
30
31 FWK_LOG_INFO(
32 MODULE_NAME " Zeroing AP context area [0x%" PRIxPTR " - 0x%" PRIxPTR
33 "]",
34 config->base,
35 config->base + config->size);
36
37 memset((void *)config->base, 0, config->size);
38 }
39
40 /*
41 * Framework handlers
42 */
43
apcontext_init(fwk_id_t module_id,unsigned int element_count,const void * data)44 static int apcontext_init(fwk_id_t module_id, unsigned int element_count,
45 const void *data)
46 {
47 const struct mod_apcontext_config *config = data;
48
49 /* This module does not support elements */
50 if (element_count != 0)
51 return FWK_E_PARAM;
52
53 if (config->base == 0)
54 return FWK_E_DATA;
55
56 if (config->size == 0)
57 return FWK_E_DATA;
58
59 return FWK_SUCCESS;
60 }
61
apcontext_start(fwk_id_t id)62 static int apcontext_start(fwk_id_t id)
63 {
64 const struct mod_apcontext_config *config =
65 fwk_module_get_data(fwk_module_id_apcontext);
66
67 if (fwk_id_is_equal(config->clock_id, FWK_ID_NONE)) {
68 apcontext_zero();
69 return FWK_SUCCESS;
70 }
71
72 /* Register the module for clock state notifications */
73 return fwk_notification_subscribe(
74 mod_clock_notification_id_state_changed,
75 config->clock_id,
76 id);
77 }
78
apcontext_process_notification(const struct fwk_event * event,struct fwk_event * resp_event)79 static int apcontext_process_notification(const struct fwk_event *event,
80 struct fwk_event *resp_event)
81 {
82 struct clock_notification_params *params;
83
84 fwk_assert(
85 fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed));
86 fwk_assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE));
87
88 params = (struct clock_notification_params *)event->params;
89
90 /*
91 * Zero AP context area when the system is initialized for the first time
92 * only
93 */
94 if (params->new_state == MOD_CLOCK_STATE_RUNNING) {
95 apcontext_zero();
96
97 /* Unsubscribe to the notification */
98 return fwk_notification_unsubscribe(event->id, event->source_id,
99 event->target_id);
100 }
101
102 return FWK_SUCCESS;
103 }
104
105 const struct fwk_module module_apcontext = {
106 .type = FWK_MODULE_TYPE_SERVICE,
107 .init = apcontext_init,
108 .start = apcontext_start,
109 .process_notification = apcontext_process_notification,
110 };
111