summaryrefslogtreecommitdiffstats
path: root/src/lib/occlib/ipc_init.c
blob: a322eb41bfd353bb770d3451f3a35893f00f6a8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/lib/occlib/ipc_init.c $                                   */
/*                                                                        */
/* OpenPOWER OnChipController Project                                     */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/// \file ipc_init.c
/// \brief Implementation of IPC (InterProcessor Communication) routines for
///        Setting up the IPC function tables, messages and message queues.
///
/// NOTE: The functions that these interfaces peform can all be done statically.
/// This code will not be included in an image if none of the functions are
/// referenced.

#include "ipc_api.h"
#include "ipc_ping.h"

///////////////////////////////////////////////////////////////////////////////
/// Associate an IPC function ID with a handler function
///
int ipc_set_handler(uint32_t            function_id,
                    ipc_msg_handler_t   handler,
                    void*               callback_arg)
{
    ipc_func_table_entry_t* func_table;
    uint32_t                table_limit;
    int                     rc = IPC_RC_SUCCESS;
    ipc_func_id_t           func_id = {{0}};

    do
    {
        func_id.word32 = function_id;

        //setup for multi-target commands
        if(func_id.multi_target_flag)
        {
            table_limit = IPC_MT_NUM_FUNCIDS;
            func_table = G_ipc_mt_handlers;
        }
        //setup for single-target commands
        else
        {
            //make sure the function id targets this processor
            if(func_id.target_id != OCCHW_INST_ID_SELF)
            {
                rc = IPC_RC_INVALID_TARGET_ID;
                break;
            }

            table_limit = IPC_ST_NUM_FUNCIDS;
            func_table = G_ipc_st_handlers;
        }

        //make sure the function id is valid
        if((func_id.table_index >= table_limit) || !func_id.valid_flag)
        {
            rc = IPC_RC_INVALID_FUNC_ID;
            break;
        }

        if(!handler)
        {
            rc = IPC_RC_INVALID_ARG;
            break;
        }

        func_table[func_id.table_index].handler = handler;
        func_table[func_id.table_index].arg = callback_arg;
    }
    while(0);

    return rc;
}

///////////////////////////////////////////////////////////////////////////////
/// Initialize an IPC command message
///
void ipc_init_msg(ipc_msg_t* msg,
                  uint32_t func_id,
                  ipc_msg_handler_t resp_callback,
                  void* callback_arg)
{
    KERN_DEQUE_ELEMENT_CREATE(&msg->node);
    msg->func_id.word32 = func_id;
    msg->ipc_rc = IPC_RC_SUCCESS;
    msg->resp_callback = resp_callback;
    msg->callback_arg = callback_arg;
#ifdef GPE_IPC_TIMERS
    msg->begin_time = 0;
    msg->end_time = 0;
#endif
}

///////////////////////////////////////////////////////////////////////////////
/// Initialize an IPC message queue.
///
void ipc_init_msgq(ipc_msgq_t* msgq)
{
    KERN_DEQUE_SENTINEL_CREATE(&msgq->msg_head);

    //set the initial count to 0 with no max count
    KERN_SEMAPHORE_CREATE(&msgq->msg_sem, 0, 0);
}

///////////////////////////////////////////////////////////////////////////////
/// Initialize an IPC message and associate it with an IPC message queue
///
void ipc_init_msgq_msg(ipc_msg_t* msg, uint32_t func_id, ipc_msgq_t* msgq)
{
    ipc_init_msg(msg, func_id, ipc_msgq_handler, msgq);
}


///////////////////////////////////////////////////////////////////////////////
/// Initialize an IPC ping command message
///
#ifdef IPC_ENABLE_PING
int ipc_ping_cmd_init(ipc_ping_cmd_t* ping_cmd)
{
    int rc;

    do
    {
        //initialize the message
        ipc_init_msg(&ping_cmd->msg, IPC_MT_PING, ipc_ping_response, 0);

        //initialize the semaphore count to 0 and set the max count to 1
        rc = KERN_SEMAPHORE_CREATE(&ping_cmd->sem, 0, 1);

        if(rc)
        {
            break;
        }
    }
    while(0);

    return rc;
}
#endif /*IPC_ENABLE_PING*/
OpenPOWER on IntegriCloud