cxx_manager.cc revision 11793
110458Sandreas.hansson@arm.com/*
210458Sandreas.hansson@arm.com * Copyright (c) 2014 ARM Limited
310458Sandreas.hansson@arm.com * All rights reserved
410458Sandreas.hansson@arm.com *
510458Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
610458Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
710458Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
810458Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
910458Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1010458Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1110458Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1210458Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1310458Sandreas.hansson@arm.com *
1410458Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
1510458Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
1610458Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
1710458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
1810458Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1910458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
2010458Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
2110458Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
2210458Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
2310458Sandreas.hansson@arm.com * this software without specific prior written permission.
2410458Sandreas.hansson@arm.com *
2510458Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610458Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710458Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810458Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910458Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010458Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110458Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210458Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310458Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410458Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510458Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610458Sandreas.hansson@arm.com *
3710458Sandreas.hansson@arm.com * Authors: Andrew Bardsley
3810458Sandreas.hansson@arm.com */
3910458Sandreas.hansson@arm.com
4011793Sbrandon.potter@amd.com#include "sim/cxx_manager.hh"
4111793Sbrandon.potter@amd.com
4210458Sandreas.hansson@arm.com#include <cstdlib>
4310458Sandreas.hansson@arm.com#include <sstream>
4410458Sandreas.hansson@arm.com
4510458Sandreas.hansson@arm.com#include "base/str.hh"
4610458Sandreas.hansson@arm.com#include "debug/CxxConfig.hh"
4710458Sandreas.hansson@arm.com#include "mem/mem_object.hh"
4810458Sandreas.hansson@arm.com#include "sim/serialize.hh"
4910458Sandreas.hansson@arm.com
5010458Sandreas.hansson@arm.comCxxConfigManager::CxxConfigManager(CxxConfigFileBase &configFile_) :
5110458Sandreas.hansson@arm.com    configFile(configFile_), flags(configFile_.getFlags()),
5210458Sandreas.hansson@arm.com    simObjectResolver(*this)
5310458Sandreas.hansson@arm.com{
5410458Sandreas.hansson@arm.com}
5510458Sandreas.hansson@arm.com
5610458Sandreas.hansson@arm.comconst CxxConfigDirectoryEntry &
5710458Sandreas.hansson@arm.comCxxConfigManager::findObjectType(const std::string &object_name,
5810458Sandreas.hansson@arm.com    std::string &object_type)
5910458Sandreas.hansson@arm.com{
6010458Sandreas.hansson@arm.com    if (!configFile.objectExists(object_name))
6110458Sandreas.hansson@arm.com        throw Exception(object_name, "Can't find sim object");
6210458Sandreas.hansson@arm.com
6310458Sandreas.hansson@arm.com    if (!configFile.getParam(object_name, "type", object_type))
6410458Sandreas.hansson@arm.com        throw Exception(object_name, "Sim object has no 'type' field");
6510458Sandreas.hansson@arm.com
6610458Sandreas.hansson@arm.com    if (cxx_config_directory.find(object_type) ==
6710458Sandreas.hansson@arm.com        cxx_config_directory.end())
6810458Sandreas.hansson@arm.com    {
6910458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf(
7010458Sandreas.hansson@arm.com            "No sim object type %s is available", object_type));
7110458Sandreas.hansson@arm.com    }
7210458Sandreas.hansson@arm.com
7310458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry *entry = cxx_config_directory[object_type];
7410458Sandreas.hansson@arm.com
7510458Sandreas.hansson@arm.com    return *entry;
7610458Sandreas.hansson@arm.com}
7710458Sandreas.hansson@arm.com
7810458Sandreas.hansson@arm.comstd::string
7910458Sandreas.hansson@arm.comCxxConfigManager::rename(const std::string &from_name)
8010458Sandreas.hansson@arm.com{
8110458Sandreas.hansson@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
8210458Sandreas.hansson@arm.com        const Renaming &renaming = *i;
8310458Sandreas.hansson@arm.com
8410458Sandreas.hansson@arm.com        if (from_name.find(renaming.fromPrefix) == 0) {
8510458Sandreas.hansson@arm.com            return renaming.toPrefix +
8610458Sandreas.hansson@arm.com                from_name.substr(renaming.fromPrefix.length());
8710458Sandreas.hansson@arm.com        }
8810458Sandreas.hansson@arm.com    }
8910458Sandreas.hansson@arm.com
9010458Sandreas.hansson@arm.com    return from_name;
9110458Sandreas.hansson@arm.com}
9210458Sandreas.hansson@arm.com
9310458Sandreas.hansson@arm.comstd::string
9410458Sandreas.hansson@arm.comCxxConfigManager::unRename(const std::string &to_name)
9510458Sandreas.hansson@arm.com{
9610458Sandreas.hansson@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
9710458Sandreas.hansson@arm.com        const Renaming &renaming = *i;
9810458Sandreas.hansson@arm.com
9910458Sandreas.hansson@arm.com        if (to_name.find(renaming.toPrefix) == 0) {
10010458Sandreas.hansson@arm.com            return renaming.fromPrefix +
10110458Sandreas.hansson@arm.com                to_name.substr(renaming.toPrefix.length());
10210458Sandreas.hansson@arm.com        }
10310458Sandreas.hansson@arm.com    }
10410458Sandreas.hansson@arm.com
10510458Sandreas.hansson@arm.com    return to_name;
10610458Sandreas.hansson@arm.com}
10710458Sandreas.hansson@arm.com
10810458Sandreas.hansson@arm.comstatic
10910458Sandreas.hansson@arm.comstd::string formatParamList(const std::vector<std::string> &param_values)
11010458Sandreas.hansson@arm.com{
11110458Sandreas.hansson@arm.com    std::ostringstream params;
11210458Sandreas.hansson@arm.com
11310458Sandreas.hansson@arm.com    auto i = param_values.begin();
11410458Sandreas.hansson@arm.com    auto end_i = param_values.end();
11510458Sandreas.hansson@arm.com
11610458Sandreas.hansson@arm.com    params << '[';
11710458Sandreas.hansson@arm.com    while (i != end_i) {
11810458Sandreas.hansson@arm.com        params << (*i);
11910458Sandreas.hansson@arm.com        ++i;
12010458Sandreas.hansson@arm.com
12110458Sandreas.hansson@arm.com        if (i != end_i)
12210458Sandreas.hansson@arm.com            params << ", ";
12310458Sandreas.hansson@arm.com    }
12410458Sandreas.hansson@arm.com    params << ']';
12510458Sandreas.hansson@arm.com
12610458Sandreas.hansson@arm.com    return params.str();
12710458Sandreas.hansson@arm.com}
12810458Sandreas.hansson@arm.com
12910458Sandreas.hansson@arm.comSimObject *
13010458Sandreas.hansson@arm.comCxxConfigManager::findObject(const std::string &object_name,
13110458Sandreas.hansson@arm.com    bool visit_children)
13210458Sandreas.hansson@arm.com{
13310458Sandreas.hansson@arm.com    std::string instance_name = rename(object_name);
13410458Sandreas.hansson@arm.com
13510458Sandreas.hansson@arm.com    if (object_name == "Null")
13610458Sandreas.hansson@arm.com        return NULL;
13710458Sandreas.hansson@arm.com
13810458Sandreas.hansson@arm.com    /* Already constructed */
13910458Sandreas.hansson@arm.com    if (objectsByName.find(instance_name) != objectsByName.end())
14010458Sandreas.hansson@arm.com        return objectsByName[instance_name];
14110458Sandreas.hansson@arm.com
14210458Sandreas.hansson@arm.com    if (inVisit.find(instance_name) != inVisit.end())
14310458Sandreas.hansson@arm.com        throw Exception(instance_name, "Cycle in configuration");
14410458Sandreas.hansson@arm.com
14510458Sandreas.hansson@arm.com    std::string object_type;
14610458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
14710458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
14810458Sandreas.hansson@arm.com
14910458Sandreas.hansson@arm.com    SimObject *object = NULL;
15010458Sandreas.hansson@arm.com
15110458Sandreas.hansson@arm.com    CxxConfigParams *object_params = findObjectParams(object_name);
15210458Sandreas.hansson@arm.com
15310458Sandreas.hansson@arm.com    try {
15410458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Configuring sim object references for: %s"
15510458Sandreas.hansson@arm.com            " (%s from object %s)\n", instance_name, object_type,
15610458Sandreas.hansson@arm.com            object_name);
15710458Sandreas.hansson@arm.com
15810458Sandreas.hansson@arm.com        /* Remember the path back to the top of the recursion to detect
15910458Sandreas.hansson@arm.com         *  cycles */
16010458Sandreas.hansson@arm.com        inVisit.insert(instance_name);
16110458Sandreas.hansson@arm.com
16210458Sandreas.hansson@arm.com        /* Resolve pointed-to SimObjects by recursing into them */
16310458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
16410458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
16510458Sandreas.hansson@arm.com        {
16610458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
16710458Sandreas.hansson@arm.com
16810458Sandreas.hansson@arm.com            if (param->isSimObject) {
16910458Sandreas.hansson@arm.com                if (param->isVector) {
17010458Sandreas.hansson@arm.com                    std::vector<std::string> sub_object_names;
17110458Sandreas.hansson@arm.com
17210458Sandreas.hansson@arm.com                    if (!configFile.getParamVector(object_name, param->name,
17310458Sandreas.hansson@arm.com                        sub_object_names))
17410458Sandreas.hansson@arm.com                    {
17510458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
17610458Sandreas.hansson@arm.com                            "Element not found: %s", param->name));
17710458Sandreas.hansson@arm.com                    }
17810458Sandreas.hansson@arm.com
17910458Sandreas.hansson@arm.com                    std::vector<SimObject *> sub_objects;
18010458Sandreas.hansson@arm.com
18110458Sandreas.hansson@arm.com                    for (auto n = sub_object_names.begin();
18210458Sandreas.hansson@arm.com                        n != sub_object_names.end(); ++n)
18310458Sandreas.hansson@arm.com                    {
18410458Sandreas.hansson@arm.com                        SimObject *sub_object = findObject(*n,
18510458Sandreas.hansson@arm.com                            visit_children);
18610458Sandreas.hansson@arm.com
18710458Sandreas.hansson@arm.com                        if (sub_object)
18810458Sandreas.hansson@arm.com                            sub_objects.push_back(sub_object);
18910458Sandreas.hansson@arm.com                    }
19010458Sandreas.hansson@arm.com
19110458Sandreas.hansson@arm.com                    if (!object_params->setSimObjectVector(param->name,
19210458Sandreas.hansson@arm.com                        sub_objects))
19310458Sandreas.hansson@arm.com                    {
19410458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
19510458Sandreas.hansson@arm.com                            "Can't assign sim object element %s from \"%s\"",
19610458Sandreas.hansson@arm.com                            param->name, formatParamList(sub_object_names)));
19710458Sandreas.hansson@arm.com                    }
19810458Sandreas.hansson@arm.com
19910458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s): %s.%s=%s\n",
20010458Sandreas.hansson@arm.com                        object_name, param->name,
20110458Sandreas.hansson@arm.com                        formatParamList(sub_object_names));
20210458Sandreas.hansson@arm.com                } else {
20310458Sandreas.hansson@arm.com                    std::string sub_object_name;
20410458Sandreas.hansson@arm.com
20510458Sandreas.hansson@arm.com                    if (!configFile.getParam(object_name, param->name,
20610458Sandreas.hansson@arm.com                        sub_object_name))
20710458Sandreas.hansson@arm.com                    {
20810458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
20910458Sandreas.hansson@arm.com                            "Element not found: %s", param->name));
21010458Sandreas.hansson@arm.com                    }
21110458Sandreas.hansson@arm.com
21210458Sandreas.hansson@arm.com                    SimObject *sub_object = findObject(sub_object_name,
21310458Sandreas.hansson@arm.com                        visit_children);
21410458Sandreas.hansson@arm.com
21510458Sandreas.hansson@arm.com                    if (sub_object) {
21610458Sandreas.hansson@arm.com                        if (!object_params->setSimObject(param->name,
21710458Sandreas.hansson@arm.com                            sub_object))
21810458Sandreas.hansson@arm.com                        {
21910458Sandreas.hansson@arm.com                            throw Exception(object_name, csprintf(
22010458Sandreas.hansson@arm.com                                "Can't assign sim object element %s from"
22110458Sandreas.hansson@arm.com                                " \"%s\"", param->name, sub_object_name));
22210458Sandreas.hansson@arm.com                        }
22310458Sandreas.hansson@arm.com                    }
22410458Sandreas.hansson@arm.com
22510458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s):"
22610458Sandreas.hansson@arm.com                        " %s.%s=%s\n", object_name, param->name,
22710458Sandreas.hansson@arm.com                        sub_object_name);
22810458Sandreas.hansson@arm.com                }
22910458Sandreas.hansson@arm.com            }
23010458Sandreas.hansson@arm.com        }
23110458Sandreas.hansson@arm.com
23210458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Creating SimObject: %s\n", instance_name);
23310458Sandreas.hansson@arm.com        object = object_params->simObjectCreate();
23410458Sandreas.hansson@arm.com
23510458Sandreas.hansson@arm.com        if (!object) {
23610458Sandreas.hansson@arm.com            throw Exception(object_name, csprintf("Couldn't create object of"
23710458Sandreas.hansson@arm.com                " type: %s", object_type));
23810458Sandreas.hansson@arm.com        }
23910458Sandreas.hansson@arm.com
24010458Sandreas.hansson@arm.com        objectsByName[instance_name] = object;
24110458Sandreas.hansson@arm.com        objectParamsByName[instance_name] = object_params;
24210458Sandreas.hansson@arm.com
24310458Sandreas.hansson@arm.com        if (visit_children) {
24410458Sandreas.hansson@arm.com            std::vector<std::string> children;
24510458Sandreas.hansson@arm.com            configFile.getObjectChildren(object_name, children, true);
24610458Sandreas.hansson@arm.com
24710458Sandreas.hansson@arm.com            /* Visit all your children */
24810458Sandreas.hansson@arm.com            for (auto i = children.begin(); i != children.end(); ++i)
24910458Sandreas.hansson@arm.com                findObject(*i, visit_children);
25010458Sandreas.hansson@arm.com        }
25110458Sandreas.hansson@arm.com    } catch (Exception &) {
25210458Sandreas.hansson@arm.com        delete object_params;
25310458Sandreas.hansson@arm.com        throw;
25410458Sandreas.hansson@arm.com    }
25510458Sandreas.hansson@arm.com
25610458Sandreas.hansson@arm.com    /* Mark that we've exited object
25710458Sandreas.hansson@arm.com     *  construction and so 'find'ing this object again won't be a
25810458Sandreas.hansson@arm.com     *  configuration loop */
25910458Sandreas.hansson@arm.com    inVisit.erase(object_name);
26010458Sandreas.hansson@arm.com    return object;
26110458Sandreas.hansson@arm.com}
26210458Sandreas.hansson@arm.com
26310458Sandreas.hansson@arm.comCxxConfigParams *
26410458Sandreas.hansson@arm.comCxxConfigManager::findObjectParams(const std::string &object_name)
26510458Sandreas.hansson@arm.com{
26610458Sandreas.hansson@arm.com    std::string instance_name = rename(object_name);
26710458Sandreas.hansson@arm.com
26810458Sandreas.hansson@arm.com    /* Already constructed */
26910458Sandreas.hansson@arm.com    if (objectParamsByName.find(instance_name) != objectParamsByName.end())
27010458Sandreas.hansson@arm.com        return objectParamsByName[instance_name];
27110458Sandreas.hansson@arm.com
27210458Sandreas.hansson@arm.com    std::string object_type;
27310458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
27410458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
27510458Sandreas.hansson@arm.com
27610458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Configuring parameters of object: %s (%s)\n",
27710458Sandreas.hansson@arm.com        instance_name, object_type);
27810458Sandreas.hansson@arm.com
27910458Sandreas.hansson@arm.com    CxxConfigParams *object_params = entry.makeParamsObject();
28010458Sandreas.hansson@arm.com
28110458Sandreas.hansson@arm.com    try {
28210458Sandreas.hansson@arm.com        /* Fill in the implicit parameters that don't necessarily
28310458Sandreas.hansson@arm.com         *  appear in config files */
28410458Sandreas.hansson@arm.com        object_params->setName(instance_name);
28510458Sandreas.hansson@arm.com
28610458Sandreas.hansson@arm.com        /* Fill in parameters */
28710458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
28810458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
28910458Sandreas.hansson@arm.com        {
29010458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
29110458Sandreas.hansson@arm.com
29210458Sandreas.hansson@arm.com            if (!param->isSimObject) {
29310458Sandreas.hansson@arm.com                /* Only handle non-SimObject parameters here (see below) */
29410458Sandreas.hansson@arm.com
29510458Sandreas.hansson@arm.com                if (param->isVector) {
29610458Sandreas.hansson@arm.com                    std::vector<std::string> param_values;
29710458Sandreas.hansson@arm.com
29810458Sandreas.hansson@arm.com                    if (!configFile.getParamVector(object_name, param->name,
29910458Sandreas.hansson@arm.com                        param_values))
30010458Sandreas.hansson@arm.com                    {
30110458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
30210458Sandreas.hansson@arm.com                            "Element not found for parameter: %s",
30310458Sandreas.hansson@arm.com                            param->name));
30410458Sandreas.hansson@arm.com                    }
30510458Sandreas.hansson@arm.com
30610458Sandreas.hansson@arm.com                    if (!object_params->setParamVector(param->name,
30710458Sandreas.hansson@arm.com                        param_values, flags))
30810458Sandreas.hansson@arm.com                    {
30910458Sandreas.hansson@arm.com                        throw Exception(instance_name, csprintf(
31010458Sandreas.hansson@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
31110458Sandreas.hansson@arm.com                            param->name, formatParamList(param_values)));
31210458Sandreas.hansson@arm.com                    }
31310458Sandreas.hansson@arm.com
31410458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting parameter"
31510458Sandreas.hansson@arm.com                        " %s.%s=%s\n", instance_name, param->name,
31610458Sandreas.hansson@arm.com                        formatParamList(param_values));
31710458Sandreas.hansson@arm.com                } else {
31810458Sandreas.hansson@arm.com                    std::string param_value;
31910458Sandreas.hansson@arm.com
32010458Sandreas.hansson@arm.com                    if (!configFile.getParam(object_name, param->name,
32110458Sandreas.hansson@arm.com                        param_value))
32210458Sandreas.hansson@arm.com                    {
32310458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
32410458Sandreas.hansson@arm.com                            "Element not found for parameter: %s",
32510458Sandreas.hansson@arm.com                            param->name));
32610458Sandreas.hansson@arm.com                    }
32710458Sandreas.hansson@arm.com
32810458Sandreas.hansson@arm.com                    if (!object_params->setParam(param->name, param_value,
32910458Sandreas.hansson@arm.com                        flags))
33010458Sandreas.hansson@arm.com                    {
33110458Sandreas.hansson@arm.com                        throw Exception(instance_name, csprintf(
33210458Sandreas.hansson@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
33310458Sandreas.hansson@arm.com                            param->name, param_value));
33410458Sandreas.hansson@arm.com                    }
33510458Sandreas.hansson@arm.com
33610458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
33710458Sandreas.hansson@arm.com                        instance_name, param->name, param_value);
33810458Sandreas.hansson@arm.com                }
33910458Sandreas.hansson@arm.com            }
34010458Sandreas.hansson@arm.com        }
34110458Sandreas.hansson@arm.com
34210458Sandreas.hansson@arm.com        /* Find the number of ports that will need binding and set the
34310458Sandreas.hansson@arm.com         *  appropriate port_..._connection_count parameters */
34410458Sandreas.hansson@arm.com        for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
34510458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
34610458Sandreas.hansson@arm.com            std::vector<std::string> peers;
34710458Sandreas.hansson@arm.com
34810458Sandreas.hansson@arm.com            if (!configFile.getPortPeers(object_name, port->name, peers)) {
34910458Sandreas.hansson@arm.com                DPRINTF(CxxConfig, "Port not found: %s.%s,"
35010458Sandreas.hansson@arm.com                    " assuming there are no connections\n",
35110458Sandreas.hansson@arm.com                    instance_name, port->name);
35210458Sandreas.hansson@arm.com            }
35310458Sandreas.hansson@arm.com
35410458Sandreas.hansson@arm.com            unsigned int peer_count = peers.size();
35510458Sandreas.hansson@arm.com
35610458Sandreas.hansson@arm.com            /* It would be more efficient to split the peer list and
35710458Sandreas.hansson@arm.com             *  save the values for peer binding later but that would
35810458Sandreas.hansson@arm.com             *  require another annoying intermediate structure to
35910458Sandreas.hansson@arm.com             *  hold for little performance increase */
36010458Sandreas.hansson@arm.com
36110458Sandreas.hansson@arm.com            if (!object_params->setPortConnectionCount(port->name,
36210458Sandreas.hansson@arm.com                peer_count))
36310458Sandreas.hansson@arm.com            {
36410458Sandreas.hansson@arm.com                throw Exception(instance_name, csprintf(
36510458Sandreas.hansson@arm.com                    "Unconnected port: %s", port->name));
36610458Sandreas.hansson@arm.com            }
36710458Sandreas.hansson@arm.com
36810458Sandreas.hansson@arm.com            DPRINTF(CxxConfig, "Setting port connection count"
36910458Sandreas.hansson@arm.com                " for: %s.%s to %d\n",
37010458Sandreas.hansson@arm.com                instance_name, port->name, peer_count);
37110458Sandreas.hansson@arm.com        }
37210458Sandreas.hansson@arm.com
37310458Sandreas.hansson@arm.com        /* Set pointed-to SimObjects to NULL */
37410458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
37510458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
37610458Sandreas.hansson@arm.com        {
37710458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
37810458Sandreas.hansson@arm.com
37910458Sandreas.hansson@arm.com            if (param->isSimObject) {
38010458Sandreas.hansson@arm.com                bool ret;
38110458Sandreas.hansson@arm.com
38210458Sandreas.hansson@arm.com                DPRINTF(CxxConfig, "Nulling sim object reference: %s.%s\n",
38310458Sandreas.hansson@arm.com                    instance_name, param->name);
38410458Sandreas.hansson@arm.com
38510458Sandreas.hansson@arm.com                if (param->isVector) {
38610458Sandreas.hansson@arm.com                    /* Clear the reference list. */
38710458Sandreas.hansson@arm.com                    std::vector<SimObject *> empty;
38810458Sandreas.hansson@arm.com                    ret = object_params->setSimObjectVector(param->name,
38910458Sandreas.hansson@arm.com                        empty);
39010458Sandreas.hansson@arm.com                } else {
39110458Sandreas.hansson@arm.com                    ret = object_params->setSimObject(param->name, NULL);
39210458Sandreas.hansson@arm.com                }
39310458Sandreas.hansson@arm.com
39410458Sandreas.hansson@arm.com                if (!ret) {
39510458Sandreas.hansson@arm.com                    throw Exception(instance_name, csprintf(
39610458Sandreas.hansson@arm.com                        "Error nulling sim object reference(s): %s",
39710458Sandreas.hansson@arm.com                        param->name));
39810458Sandreas.hansson@arm.com                }
39910458Sandreas.hansson@arm.com            }
40010458Sandreas.hansson@arm.com        }
40110458Sandreas.hansson@arm.com    } catch (Exception &) {
40210458Sandreas.hansson@arm.com        delete object_params;
40310458Sandreas.hansson@arm.com        throw;
40410458Sandreas.hansson@arm.com    }
40510458Sandreas.hansson@arm.com
40610458Sandreas.hansson@arm.com    objectParamsByName[instance_name] = object_params;
40710458Sandreas.hansson@arm.com
40810458Sandreas.hansson@arm.com    return object_params;
40910458Sandreas.hansson@arm.com}
41010458Sandreas.hansson@arm.com
41110458Sandreas.hansson@arm.comvoid
41210458Sandreas.hansson@arm.comCxxConfigManager::findAllObjects()
41310458Sandreas.hansson@arm.com{
41410458Sandreas.hansson@arm.com    std::vector<std::string> objects;
41510458Sandreas.hansson@arm.com    configFile.getAllObjectNames(objects);
41610458Sandreas.hansson@arm.com
41710458Sandreas.hansson@arm.com    /* Sort the object names to get a consistent initialisation order
41810458Sandreas.hansson@arm.com     *  even with config file reorganisation */
41910458Sandreas.hansson@arm.com    std::sort(objects.begin(), objects.end());
42010458Sandreas.hansson@arm.com
42110458Sandreas.hansson@arm.com    for (auto i = objects.begin(); i != objects.end(); ++i)
42210458Sandreas.hansson@arm.com        findObject(*i);
42310458Sandreas.hansson@arm.com
42410458Sandreas.hansson@arm.com    /* Set the traversal order for further iterators */
42510458Sandreas.hansson@arm.com    objectsInOrder.clear();
42610458Sandreas.hansson@arm.com    findTraversalOrder("root");
42710458Sandreas.hansson@arm.com}
42810458Sandreas.hansson@arm.com
42910458Sandreas.hansson@arm.comvoid
43010458Sandreas.hansson@arm.comCxxConfigManager::findTraversalOrder(const std::string &object_name)
43110458Sandreas.hansson@arm.com{
43210458Sandreas.hansson@arm.com    SimObject *object = findObject(object_name);
43310458Sandreas.hansson@arm.com
43410458Sandreas.hansson@arm.com    if (object) {
43510458Sandreas.hansson@arm.com        objectsInOrder.push_back(object);
43610458Sandreas.hansson@arm.com
43710458Sandreas.hansson@arm.com        std::vector<std::string> children;
43810458Sandreas.hansson@arm.com        configFile.getObjectChildren(object_name, children, true);
43910458Sandreas.hansson@arm.com
44010458Sandreas.hansson@arm.com        /* Visit all your children */
44110458Sandreas.hansson@arm.com        for (auto i = children.begin(); i != children.end(); ++i)
44210458Sandreas.hansson@arm.com            findTraversalOrder(*i);
44310458Sandreas.hansson@arm.com    }
44410458Sandreas.hansson@arm.com}
44510458Sandreas.hansson@arm.com
44610458Sandreas.hansson@arm.comvoid
44710458Sandreas.hansson@arm.comCxxConfigManager::bindAllPorts()
44810458Sandreas.hansson@arm.com{
44910458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
45010458Sandreas.hansson@arm.com        bindObjectPorts(*i);
45110458Sandreas.hansson@arm.com}
45210458Sandreas.hansson@arm.com
45310458Sandreas.hansson@arm.comvoid
45410458Sandreas.hansson@arm.comCxxConfigManager::bindPort(
45510458Sandreas.hansson@arm.com    SimObject *master_object, const std::string &master_port_name,
45610458Sandreas.hansson@arm.com    PortID master_port_index,
45710458Sandreas.hansson@arm.com    SimObject *slave_object, const std::string &slave_port_name,
45810458Sandreas.hansson@arm.com    PortID slave_port_index)
45910458Sandreas.hansson@arm.com{
46010458Sandreas.hansson@arm.com    MemObject *master_mem_object = dynamic_cast<MemObject *>(master_object);
46110458Sandreas.hansson@arm.com    MemObject *slave_mem_object = dynamic_cast<MemObject *>(slave_object);
46210458Sandreas.hansson@arm.com
46310458Sandreas.hansson@arm.com    if (!master_mem_object) {
46410458Sandreas.hansson@arm.com        throw Exception(master_object->name(), csprintf(
46510458Sandreas.hansson@arm.com            "Object isn't a mem object and so can have master port:"
46610458Sandreas.hansson@arm.com            " %s[%d]", master_port_name, master_port_index));
46710458Sandreas.hansson@arm.com    }
46810458Sandreas.hansson@arm.com
46910458Sandreas.hansson@arm.com    if (!slave_mem_object) {
47010458Sandreas.hansson@arm.com        throw Exception(slave_object->name(), csprintf(
47110458Sandreas.hansson@arm.com            "Object isn't a mem object and so can have slave port:"
47210458Sandreas.hansson@arm.com            " %s[%d]", slave_port_name, slave_port_index));
47310458Sandreas.hansson@arm.com    }
47410458Sandreas.hansson@arm.com
47510458Sandreas.hansson@arm.com    /* FIXME, check slave_port_index against connection_count
47610458Sandreas.hansson@arm.com     *  defined for port, need getPortConnectionCount and a
47710458Sandreas.hansson@arm.com     *  getCxxConfigDirectoryEntry for each object. */
47810458Sandreas.hansson@arm.com
47910458Sandreas.hansson@arm.com    /* It would be nice to be able to catch the errors from these calls. */
48010458Sandreas.hansson@arm.com    BaseMasterPort &master_port = master_mem_object->getMasterPort(
48110458Sandreas.hansson@arm.com        master_port_name, master_port_index);
48210458Sandreas.hansson@arm.com    BaseSlavePort &slave_port = slave_mem_object->getSlavePort(
48310458Sandreas.hansson@arm.com        slave_port_name, slave_port_index);
48410458Sandreas.hansson@arm.com
48510458Sandreas.hansson@arm.com    if (master_port.isConnected()) {
48610458Sandreas.hansson@arm.com        throw Exception(master_object->name(), csprintf(
48710458Sandreas.hansson@arm.com            "Master port: %s[%d] is already connected\n", master_port_name,
48810458Sandreas.hansson@arm.com            master_port_index));
48910458Sandreas.hansson@arm.com    }
49010458Sandreas.hansson@arm.com
49110458Sandreas.hansson@arm.com    if (slave_port.isConnected()) {
49210458Sandreas.hansson@arm.com        throw Exception(slave_object->name(), csprintf(
49310458Sandreas.hansson@arm.com            "Slave port: %s[%d] is already connected\n", slave_port_name,
49410458Sandreas.hansson@arm.com            slave_port_index));
49510458Sandreas.hansson@arm.com    }
49610458Sandreas.hansson@arm.com
49710458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Binding port %s.%s[%d]"
49810458Sandreas.hansson@arm.com        " to %s:%s[%d]\n",
49910458Sandreas.hansson@arm.com        master_object->name(), master_port_name, master_port_index,
50010458Sandreas.hansson@arm.com        slave_object->name(), slave_port_name, slave_port_index);
50110458Sandreas.hansson@arm.com
50210458Sandreas.hansson@arm.com    master_port.bind(slave_port);
50310458Sandreas.hansson@arm.com}
50410458Sandreas.hansson@arm.com
50510458Sandreas.hansson@arm.comvoid
50610458Sandreas.hansson@arm.comCxxConfigManager::bindMasterPort(SimObject *object,
50710458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry::PortDesc &port,
50810458Sandreas.hansson@arm.com    const std::vector<std::string> &peers)
50910458Sandreas.hansson@arm.com{
51010458Sandreas.hansson@arm.com    unsigned int master_port_index = 0;
51110458Sandreas.hansson@arm.com
51210458Sandreas.hansson@arm.com    for (auto peer_i = peers.begin(); peer_i != peers.end();
51310458Sandreas.hansson@arm.com        ++peer_i)
51410458Sandreas.hansson@arm.com    {
51510458Sandreas.hansson@arm.com        const std::string &peer = *peer_i;
51610458Sandreas.hansson@arm.com        std::string slave_object_name;
51710458Sandreas.hansson@arm.com        std::string slave_port_name;
51810458Sandreas.hansson@arm.com        unsigned int slave_port_index;
51910458Sandreas.hansson@arm.com
52010458Sandreas.hansson@arm.com        parsePort(peer, slave_object_name, slave_port_name,
52110458Sandreas.hansson@arm.com            slave_port_index);
52210458Sandreas.hansson@arm.com
52310458Sandreas.hansson@arm.com        std::string slave_instance_name = rename(slave_object_name);
52410458Sandreas.hansson@arm.com
52510458Sandreas.hansson@arm.com        if (objectsByName.find(slave_instance_name) == objectsByName.end()) {
52610458Sandreas.hansson@arm.com            throw Exception(object->name(), csprintf(
52710458Sandreas.hansson@arm.com                "Can't find slave port object: %s", slave_instance_name));
52810458Sandreas.hansson@arm.com        }
52910458Sandreas.hansson@arm.com
53010458Sandreas.hansson@arm.com        SimObject *slave_object = objectsByName[slave_instance_name];
53110458Sandreas.hansson@arm.com
53210458Sandreas.hansson@arm.com        bindPort(object, port.name, master_port_index,
53310458Sandreas.hansson@arm.com            slave_object, slave_port_name, slave_port_index);
53410458Sandreas.hansson@arm.com
53510458Sandreas.hansson@arm.com        master_port_index++;
53610458Sandreas.hansson@arm.com    }
53710458Sandreas.hansson@arm.com}
53810458Sandreas.hansson@arm.com
53910458Sandreas.hansson@arm.comvoid
54010458Sandreas.hansson@arm.comCxxConfigManager::bindObjectPorts(SimObject *object)
54110458Sandreas.hansson@arm.com{
54210458Sandreas.hansson@arm.com    /* We may want to separate object->name() from the name in configuration
54310458Sandreas.hansson@arm.com     *  later to allow (for example) repetition of fragments of configs */
54410458Sandreas.hansson@arm.com    const std::string &instance_name = object->name();
54510458Sandreas.hansson@arm.com
54610458Sandreas.hansson@arm.com    std::string object_name = unRename(instance_name);
54710458Sandreas.hansson@arm.com
54810458Sandreas.hansson@arm.com    std::string object_type;
54910458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
55010458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
55110458Sandreas.hansson@arm.com
55210458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Binding ports of object: %s (%s)\n",
55310458Sandreas.hansson@arm.com        instance_name, object_type);
55410458Sandreas.hansson@arm.com
55510458Sandreas.hansson@arm.com    for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
55610458Sandreas.hansson@arm.com        const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
55710458Sandreas.hansson@arm.com
55810458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Binding port: %s.%s\n", instance_name,
55910458Sandreas.hansson@arm.com            port->name);
56010458Sandreas.hansson@arm.com
56110458Sandreas.hansson@arm.com        std::vector<std::string> peers;
56210458Sandreas.hansson@arm.com        configFile.getPortPeers(object_name, port->name, peers);
56310458Sandreas.hansson@arm.com
56410458Sandreas.hansson@arm.com        /* Only handle master ports as binding only needs to happen once
56510458Sandreas.hansson@arm.com         *  for each observed pair of ports */
56610458Sandreas.hansson@arm.com        if (port->isMaster) {
56710458Sandreas.hansson@arm.com            if (!port->isVector && peers.size() > 1) {
56810458Sandreas.hansson@arm.com                throw Exception(instance_name, csprintf(
56910458Sandreas.hansson@arm.com                    "Too many connections to non-vector port %s (%d)\n",
57010458Sandreas.hansson@arm.com                    port->name, peers.size()));
57110458Sandreas.hansson@arm.com            }
57210458Sandreas.hansson@arm.com
57310458Sandreas.hansson@arm.com            bindMasterPort(object, *port, peers);
57410458Sandreas.hansson@arm.com        }
57510458Sandreas.hansson@arm.com    }
57610458Sandreas.hansson@arm.com}
57710458Sandreas.hansson@arm.com
57810458Sandreas.hansson@arm.comvoid
57910458Sandreas.hansson@arm.comCxxConfigManager::parsePort(const std::string &inp,
58010458Sandreas.hansson@arm.com    std::string &path, std::string &port, unsigned int &index)
58110458Sandreas.hansson@arm.com{
58210458Sandreas.hansson@arm.com    std::size_t dot_i = inp.rfind('.');
58310458Sandreas.hansson@arm.com    std::size_t open_square_i = inp.rfind('[');
58410458Sandreas.hansson@arm.com
58510458Sandreas.hansson@arm.com    if (dot_i == std::string::npos) {
58610458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Bad port string: %s\n", inp);
58710458Sandreas.hansson@arm.com        path = "";
58810458Sandreas.hansson@arm.com        port = "";
58910458Sandreas.hansson@arm.com        index = 0;
59010458Sandreas.hansson@arm.com    } else {
59110458Sandreas.hansson@arm.com        path = std::string(inp, 0, dot_i);
59210458Sandreas.hansson@arm.com
59310458Sandreas.hansson@arm.com        if (open_square_i == std::string::npos) {
59410458Sandreas.hansson@arm.com            /* Singleton port */
59510458Sandreas.hansson@arm.com            port = std::string(inp, dot_i + 1, inp.length() - dot_i);
59610458Sandreas.hansson@arm.com            index = 0;
59710458Sandreas.hansson@arm.com        } else {
59810458Sandreas.hansson@arm.com            /* Vectored port elemnt */
59910458Sandreas.hansson@arm.com            port = std::string(inp, dot_i + 1, (open_square_i - 1) - dot_i);
60010458Sandreas.hansson@arm.com            index = std::atoi(inp.c_str() + open_square_i + 1);
60110458Sandreas.hansson@arm.com        }
60210458Sandreas.hansson@arm.com    }
60310458Sandreas.hansson@arm.com}
60410458Sandreas.hansson@arm.com
60510458Sandreas.hansson@arm.comvoid
60610458Sandreas.hansson@arm.comCxxConfigManager::forEachObject(void (SimObject::*mem_func)())
60710458Sandreas.hansson@arm.com{
60810458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
60910458Sandreas.hansson@arm.com        ((*i)->*mem_func)();
61010458Sandreas.hansson@arm.com}
61110458Sandreas.hansson@arm.com
61210458Sandreas.hansson@arm.comvoid
61310458Sandreas.hansson@arm.comCxxConfigManager::instantiate(bool build_all)
61410458Sandreas.hansson@arm.com{
61510458Sandreas.hansson@arm.com    if (build_all) {
61610458Sandreas.hansson@arm.com        findAllObjects();
61710458Sandreas.hansson@arm.com        bindAllPorts();
61810458Sandreas.hansson@arm.com    }
61910458Sandreas.hansson@arm.com
62010458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Initialising all objects\n");
62110458Sandreas.hansson@arm.com    forEachObject(&SimObject::init);
62210458Sandreas.hansson@arm.com
62310458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Registering stats\n");
62410458Sandreas.hansson@arm.com    forEachObject(&SimObject::regStats);
62510458Sandreas.hansson@arm.com
62610458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Registering probe points\n");
62710458Sandreas.hansson@arm.com    forEachObject(&SimObject::regProbePoints);
62810458Sandreas.hansson@arm.com
62910458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Connecting probe listeners\n");
63010458Sandreas.hansson@arm.com    forEachObject(&SimObject::regProbeListeners);
63110458Sandreas.hansson@arm.com}
63210458Sandreas.hansson@arm.com
63310458Sandreas.hansson@arm.comvoid
63410458Sandreas.hansson@arm.comCxxConfigManager::initState()
63510458Sandreas.hansson@arm.com{
63610458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Calling initState on all objects\n");
63710458Sandreas.hansson@arm.com    forEachObject(&SimObject::initState);
63810458Sandreas.hansson@arm.com}
63910458Sandreas.hansson@arm.com
64010458Sandreas.hansson@arm.comvoid
64110458Sandreas.hansson@arm.comCxxConfigManager::startup()
64210458Sandreas.hansson@arm.com{
64310458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Starting up all objects\n");
64410458Sandreas.hansson@arm.com    forEachObject(&SimObject::startup);
64510458Sandreas.hansson@arm.com}
64610458Sandreas.hansson@arm.com
64710458Sandreas.hansson@arm.comunsigned int
64810912Sandreas.sandberg@arm.comCxxConfigManager::drain()
64910458Sandreas.hansson@arm.com{
65010912Sandreas.sandberg@arm.com    return DrainManager::instance().tryDrain() ? 0 : 1;
65110458Sandreas.hansson@arm.com}
65210458Sandreas.hansson@arm.com
65310458Sandreas.hansson@arm.comvoid
65410458Sandreas.hansson@arm.comCxxConfigManager::drainResume()
65510458Sandreas.hansson@arm.com{
65610912Sandreas.sandberg@arm.com    DrainManager::instance().resume();
65710458Sandreas.hansson@arm.com}
65810458Sandreas.hansson@arm.com
65910458Sandreas.hansson@arm.comvoid
66010458Sandreas.hansson@arm.comCxxConfigManager::serialize(std::ostream &os)
66110458Sandreas.hansson@arm.com{
66210458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i) {
66310458Sandreas.hansson@arm.com        // (*i)->nameOut(os); FIXME, change access spec. for nameOut
66410458Sandreas.hansson@arm.com        os << '[' << (*i)->name() << "]\n";
66510458Sandreas.hansson@arm.com        (*i)->serialize(os);
66610458Sandreas.hansson@arm.com    }
66710458Sandreas.hansson@arm.com}
66810458Sandreas.hansson@arm.com
66910458Sandreas.hansson@arm.comvoid
67010905Sandreas.sandberg@arm.comCxxConfigManager::loadState(CheckpointIn &checkpoint)
67110458Sandreas.hansson@arm.com{
67210458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i)
67310458Sandreas.hansson@arm.com        (*i)->loadState(checkpoint);
67410458Sandreas.hansson@arm.com}
67510458Sandreas.hansson@arm.com
67610458Sandreas.hansson@arm.comvoid
67710458Sandreas.hansson@arm.comCxxConfigManager::deleteObjects()
67810458Sandreas.hansson@arm.com{
67910458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.rbegin(); i != objectsInOrder.rend(); ++i) {
68010458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Freeing sim object: %s\n", (*i)->name());
68110458Sandreas.hansson@arm.com        delete *i;
68210458Sandreas.hansson@arm.com    }
68310458Sandreas.hansson@arm.com
68410458Sandreas.hansson@arm.com    for (auto i = objectParamsByName.rbegin();
68510458Sandreas.hansson@arm.com        i != objectParamsByName.rend(); ++i)
68610458Sandreas.hansson@arm.com    {
68710458Sandreas.hansson@arm.com        CxxConfigParams *params = (*i).second;
68810458Sandreas.hansson@arm.com
68910458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Freeing sim object params: %s\n",
69010458Sandreas.hansson@arm.com            params->getName());
69110458Sandreas.hansson@arm.com        delete params;
69210458Sandreas.hansson@arm.com    }
69310458Sandreas.hansson@arm.com
69410458Sandreas.hansson@arm.com    objectsInOrder.clear();
69510458Sandreas.hansson@arm.com    objectsByName.clear();
69610458Sandreas.hansson@arm.com}
69710458Sandreas.hansson@arm.com
69810458Sandreas.hansson@arm.comvoid
69910458Sandreas.hansson@arm.comCxxConfigManager::setParam(const std::string &object_name,
70010458Sandreas.hansson@arm.com    const std::string &param_name, const std::string &param_value)
70110458Sandreas.hansson@arm.com{
70210458Sandreas.hansson@arm.com    CxxConfigParams *params = findObjectParams(object_name);
70310458Sandreas.hansson@arm.com
70410458Sandreas.hansson@arm.com    if (!params->setParam(param_name, param_value, flags)) {
70510458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf("Bad parameter value:"
70610458Sandreas.hansson@arm.com            " .%s=X=\"%s\"", param_name, param_value));
70710458Sandreas.hansson@arm.com    } else {
70810458Sandreas.hansson@arm.com        std::string instance_name = rename(object_name);
70910458Sandreas.hansson@arm.com
71010458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
71110458Sandreas.hansson@arm.com            instance_name, param_name, param_value);
71210458Sandreas.hansson@arm.com    }
71310458Sandreas.hansson@arm.com}
71410458Sandreas.hansson@arm.com
71510458Sandreas.hansson@arm.comvoid
71610458Sandreas.hansson@arm.comCxxConfigManager::setParamVector(const std::string &object_name,
71710458Sandreas.hansson@arm.com    const std::string &param_name,
71810458Sandreas.hansson@arm.com    const std::vector<std::string> &param_values)
71910458Sandreas.hansson@arm.com{
72010458Sandreas.hansson@arm.com    CxxConfigParams *params = findObjectParams(object_name);
72110458Sandreas.hansson@arm.com
72210458Sandreas.hansson@arm.com    if (!params->setParamVector(param_name, param_values, flags)) {
72310458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf("Bad vector parameter value:"
72410458Sandreas.hansson@arm.com            " .%s=X=\"%s\"", param_name, formatParamList(param_values)));
72510458Sandreas.hansson@arm.com    } else {
72610458Sandreas.hansson@arm.com        std::string instance_name = rename(object_name);
72710458Sandreas.hansson@arm.com
72810458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=\"%s\"\n",
72910458Sandreas.hansson@arm.com            instance_name, param_name, formatParamList(param_values));
73010458Sandreas.hansson@arm.com    }
73110458Sandreas.hansson@arm.com}
73210458Sandreas.hansson@arm.com
73310458Sandreas.hansson@arm.comvoid CxxConfigManager::addRenaming(const Renaming &renaming)
73410458Sandreas.hansson@arm.com{
73510458Sandreas.hansson@arm.com    renamings.push_back(renaming);
73610458Sandreas.hansson@arm.com}
737