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