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"
4611800Sbrandon.potter@amd.com#include "base/trace.hh"
4710458Sandreas.hansson@arm.com#include "debug/CxxConfig.hh"
4810458Sandreas.hansson@arm.com#include "sim/serialize.hh"
4913892Sgabeblack@google.com#include "sim/sim_object.hh"
5010458Sandreas.hansson@arm.com
5110458Sandreas.hansson@arm.comCxxConfigManager::CxxConfigManager(CxxConfigFileBase &configFile_) :
5210458Sandreas.hansson@arm.com    configFile(configFile_), flags(configFile_.getFlags()),
5310458Sandreas.hansson@arm.com    simObjectResolver(*this)
5410458Sandreas.hansson@arm.com{
5510458Sandreas.hansson@arm.com}
5610458Sandreas.hansson@arm.com
5710458Sandreas.hansson@arm.comconst CxxConfigDirectoryEntry &
5810458Sandreas.hansson@arm.comCxxConfigManager::findObjectType(const std::string &object_name,
5910458Sandreas.hansson@arm.com    std::string &object_type)
6010458Sandreas.hansson@arm.com{
6110458Sandreas.hansson@arm.com    if (!configFile.objectExists(object_name))
6210458Sandreas.hansson@arm.com        throw Exception(object_name, "Can't find sim object");
6310458Sandreas.hansson@arm.com
6410458Sandreas.hansson@arm.com    if (!configFile.getParam(object_name, "type", object_type))
6510458Sandreas.hansson@arm.com        throw Exception(object_name, "Sim object has no 'type' field");
6610458Sandreas.hansson@arm.com
6710458Sandreas.hansson@arm.com    if (cxx_config_directory.find(object_type) ==
6810458Sandreas.hansson@arm.com        cxx_config_directory.end())
6910458Sandreas.hansson@arm.com    {
7010458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf(
7110458Sandreas.hansson@arm.com            "No sim object type %s is available", object_type));
7210458Sandreas.hansson@arm.com    }
7310458Sandreas.hansson@arm.com
7410458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry *entry = cxx_config_directory[object_type];
7510458Sandreas.hansson@arm.com
7610458Sandreas.hansson@arm.com    return *entry;
7710458Sandreas.hansson@arm.com}
7810458Sandreas.hansson@arm.com
7910458Sandreas.hansson@arm.comstd::string
8010458Sandreas.hansson@arm.comCxxConfigManager::rename(const std::string &from_name)
8110458Sandreas.hansson@arm.com{
8210458Sandreas.hansson@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
8310458Sandreas.hansson@arm.com        const Renaming &renaming = *i;
8410458Sandreas.hansson@arm.com
8510458Sandreas.hansson@arm.com        if (from_name.find(renaming.fromPrefix) == 0) {
8610458Sandreas.hansson@arm.com            return renaming.toPrefix +
8710458Sandreas.hansson@arm.com                from_name.substr(renaming.fromPrefix.length());
8810458Sandreas.hansson@arm.com        }
8910458Sandreas.hansson@arm.com    }
9010458Sandreas.hansson@arm.com
9110458Sandreas.hansson@arm.com    return from_name;
9210458Sandreas.hansson@arm.com}
9310458Sandreas.hansson@arm.com
9410458Sandreas.hansson@arm.comstd::string
9510458Sandreas.hansson@arm.comCxxConfigManager::unRename(const std::string &to_name)
9610458Sandreas.hansson@arm.com{
9710458Sandreas.hansson@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
9810458Sandreas.hansson@arm.com        const Renaming &renaming = *i;
9910458Sandreas.hansson@arm.com
10010458Sandreas.hansson@arm.com        if (to_name.find(renaming.toPrefix) == 0) {
10110458Sandreas.hansson@arm.com            return renaming.fromPrefix +
10210458Sandreas.hansson@arm.com                to_name.substr(renaming.toPrefix.length());
10310458Sandreas.hansson@arm.com        }
10410458Sandreas.hansson@arm.com    }
10510458Sandreas.hansson@arm.com
10610458Sandreas.hansson@arm.com    return to_name;
10710458Sandreas.hansson@arm.com}
10810458Sandreas.hansson@arm.com
10910458Sandreas.hansson@arm.comstatic
11010458Sandreas.hansson@arm.comstd::string formatParamList(const std::vector<std::string> &param_values)
11110458Sandreas.hansson@arm.com{
11210458Sandreas.hansson@arm.com    std::ostringstream params;
11310458Sandreas.hansson@arm.com
11410458Sandreas.hansson@arm.com    auto i = param_values.begin();
11510458Sandreas.hansson@arm.com    auto end_i = param_values.end();
11610458Sandreas.hansson@arm.com
11710458Sandreas.hansson@arm.com    params << '[';
11810458Sandreas.hansson@arm.com    while (i != end_i) {
11910458Sandreas.hansson@arm.com        params << (*i);
12010458Sandreas.hansson@arm.com        ++i;
12110458Sandreas.hansson@arm.com
12210458Sandreas.hansson@arm.com        if (i != end_i)
12310458Sandreas.hansson@arm.com            params << ", ";
12410458Sandreas.hansson@arm.com    }
12510458Sandreas.hansson@arm.com    params << ']';
12610458Sandreas.hansson@arm.com
12710458Sandreas.hansson@arm.com    return params.str();
12810458Sandreas.hansson@arm.com}
12910458Sandreas.hansson@arm.com
13010458Sandreas.hansson@arm.comSimObject *
13110458Sandreas.hansson@arm.comCxxConfigManager::findObject(const std::string &object_name,
13210458Sandreas.hansson@arm.com    bool visit_children)
13310458Sandreas.hansson@arm.com{
13410458Sandreas.hansson@arm.com    std::string instance_name = rename(object_name);
13510458Sandreas.hansson@arm.com
13610458Sandreas.hansson@arm.com    if (object_name == "Null")
13710458Sandreas.hansson@arm.com        return NULL;
13810458Sandreas.hansson@arm.com
13910458Sandreas.hansson@arm.com    /* Already constructed */
14010458Sandreas.hansson@arm.com    if (objectsByName.find(instance_name) != objectsByName.end())
14110458Sandreas.hansson@arm.com        return objectsByName[instance_name];
14210458Sandreas.hansson@arm.com
14310458Sandreas.hansson@arm.com    if (inVisit.find(instance_name) != inVisit.end())
14410458Sandreas.hansson@arm.com        throw Exception(instance_name, "Cycle in configuration");
14510458Sandreas.hansson@arm.com
14610458Sandreas.hansson@arm.com    std::string object_type;
14710458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
14810458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
14910458Sandreas.hansson@arm.com
15010458Sandreas.hansson@arm.com    SimObject *object = NULL;
15110458Sandreas.hansson@arm.com
15210458Sandreas.hansson@arm.com    CxxConfigParams *object_params = findObjectParams(object_name);
15310458Sandreas.hansson@arm.com
15410458Sandreas.hansson@arm.com    try {
15510458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Configuring sim object references for: %s"
15610458Sandreas.hansson@arm.com            " (%s from object %s)\n", instance_name, object_type,
15710458Sandreas.hansson@arm.com            object_name);
15810458Sandreas.hansson@arm.com
15910458Sandreas.hansson@arm.com        /* Remember the path back to the top of the recursion to detect
16010458Sandreas.hansson@arm.com         *  cycles */
16110458Sandreas.hansson@arm.com        inVisit.insert(instance_name);
16210458Sandreas.hansson@arm.com
16310458Sandreas.hansson@arm.com        /* Resolve pointed-to SimObjects by recursing into them */
16410458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
16510458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
16610458Sandreas.hansson@arm.com        {
16710458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
16810458Sandreas.hansson@arm.com
16910458Sandreas.hansson@arm.com            if (param->isSimObject) {
17010458Sandreas.hansson@arm.com                if (param->isVector) {
17110458Sandreas.hansson@arm.com                    std::vector<std::string> sub_object_names;
17210458Sandreas.hansson@arm.com
17310458Sandreas.hansson@arm.com                    if (!configFile.getParamVector(object_name, param->name,
17410458Sandreas.hansson@arm.com                        sub_object_names))
17510458Sandreas.hansson@arm.com                    {
17610458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
17710458Sandreas.hansson@arm.com                            "Element not found: %s", param->name));
17810458Sandreas.hansson@arm.com                    }
17910458Sandreas.hansson@arm.com
18010458Sandreas.hansson@arm.com                    std::vector<SimObject *> sub_objects;
18110458Sandreas.hansson@arm.com
18210458Sandreas.hansson@arm.com                    for (auto n = sub_object_names.begin();
18310458Sandreas.hansson@arm.com                        n != sub_object_names.end(); ++n)
18410458Sandreas.hansson@arm.com                    {
18510458Sandreas.hansson@arm.com                        SimObject *sub_object = findObject(*n,
18610458Sandreas.hansson@arm.com                            visit_children);
18710458Sandreas.hansson@arm.com
18810458Sandreas.hansson@arm.com                        if (sub_object)
18910458Sandreas.hansson@arm.com                            sub_objects.push_back(sub_object);
19010458Sandreas.hansson@arm.com                    }
19110458Sandreas.hansson@arm.com
19210458Sandreas.hansson@arm.com                    if (!object_params->setSimObjectVector(param->name,
19310458Sandreas.hansson@arm.com                        sub_objects))
19410458Sandreas.hansson@arm.com                    {
19510458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
19610458Sandreas.hansson@arm.com                            "Can't assign sim object element %s from \"%s\"",
19710458Sandreas.hansson@arm.com                            param->name, formatParamList(sub_object_names)));
19810458Sandreas.hansson@arm.com                    }
19910458Sandreas.hansson@arm.com
20010458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s): %s.%s=%s\n",
20110458Sandreas.hansson@arm.com                        object_name, param->name,
20210458Sandreas.hansson@arm.com                        formatParamList(sub_object_names));
20310458Sandreas.hansson@arm.com                } else {
20410458Sandreas.hansson@arm.com                    std::string sub_object_name;
20510458Sandreas.hansson@arm.com
20610458Sandreas.hansson@arm.com                    if (!configFile.getParam(object_name, param->name,
20710458Sandreas.hansson@arm.com                        sub_object_name))
20810458Sandreas.hansson@arm.com                    {
20910458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
21010458Sandreas.hansson@arm.com                            "Element not found: %s", param->name));
21110458Sandreas.hansson@arm.com                    }
21210458Sandreas.hansson@arm.com
21310458Sandreas.hansson@arm.com                    SimObject *sub_object = findObject(sub_object_name,
21410458Sandreas.hansson@arm.com                        visit_children);
21510458Sandreas.hansson@arm.com
21610458Sandreas.hansson@arm.com                    if (sub_object) {
21710458Sandreas.hansson@arm.com                        if (!object_params->setSimObject(param->name,
21810458Sandreas.hansson@arm.com                            sub_object))
21910458Sandreas.hansson@arm.com                        {
22010458Sandreas.hansson@arm.com                            throw Exception(object_name, csprintf(
22110458Sandreas.hansson@arm.com                                "Can't assign sim object element %s from"
22210458Sandreas.hansson@arm.com                                " \"%s\"", param->name, sub_object_name));
22310458Sandreas.hansson@arm.com                        }
22410458Sandreas.hansson@arm.com                    }
22510458Sandreas.hansson@arm.com
22610458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s):"
22710458Sandreas.hansson@arm.com                        " %s.%s=%s\n", object_name, param->name,
22810458Sandreas.hansson@arm.com                        sub_object_name);
22910458Sandreas.hansson@arm.com                }
23010458Sandreas.hansson@arm.com            }
23110458Sandreas.hansson@arm.com        }
23210458Sandreas.hansson@arm.com
23310458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Creating SimObject: %s\n", instance_name);
23410458Sandreas.hansson@arm.com        object = object_params->simObjectCreate();
23510458Sandreas.hansson@arm.com
23610458Sandreas.hansson@arm.com        if (!object) {
23710458Sandreas.hansson@arm.com            throw Exception(object_name, csprintf("Couldn't create object of"
23810458Sandreas.hansson@arm.com                " type: %s", object_type));
23910458Sandreas.hansson@arm.com        }
24010458Sandreas.hansson@arm.com
24110458Sandreas.hansson@arm.com        objectsByName[instance_name] = object;
24210458Sandreas.hansson@arm.com        objectParamsByName[instance_name] = object_params;
24310458Sandreas.hansson@arm.com
24410458Sandreas.hansson@arm.com        if (visit_children) {
24510458Sandreas.hansson@arm.com            std::vector<std::string> children;
24610458Sandreas.hansson@arm.com            configFile.getObjectChildren(object_name, children, true);
24710458Sandreas.hansson@arm.com
24810458Sandreas.hansson@arm.com            /* Visit all your children */
24910458Sandreas.hansson@arm.com            for (auto i = children.begin(); i != children.end(); ++i)
25010458Sandreas.hansson@arm.com                findObject(*i, visit_children);
25110458Sandreas.hansson@arm.com        }
25210458Sandreas.hansson@arm.com    } catch (Exception &) {
25310458Sandreas.hansson@arm.com        delete object_params;
25410458Sandreas.hansson@arm.com        throw;
25510458Sandreas.hansson@arm.com    }
25610458Sandreas.hansson@arm.com
25710458Sandreas.hansson@arm.com    /* Mark that we've exited object
25810458Sandreas.hansson@arm.com     *  construction and so 'find'ing this object again won't be a
25910458Sandreas.hansson@arm.com     *  configuration loop */
26010458Sandreas.hansson@arm.com    inVisit.erase(object_name);
26110458Sandreas.hansson@arm.com    return object;
26210458Sandreas.hansson@arm.com}
26310458Sandreas.hansson@arm.com
26410458Sandreas.hansson@arm.comCxxConfigParams *
26510458Sandreas.hansson@arm.comCxxConfigManager::findObjectParams(const std::string &object_name)
26610458Sandreas.hansson@arm.com{
26710458Sandreas.hansson@arm.com    std::string instance_name = rename(object_name);
26810458Sandreas.hansson@arm.com
26910458Sandreas.hansson@arm.com    /* Already constructed */
27010458Sandreas.hansson@arm.com    if (objectParamsByName.find(instance_name) != objectParamsByName.end())
27110458Sandreas.hansson@arm.com        return objectParamsByName[instance_name];
27210458Sandreas.hansson@arm.com
27310458Sandreas.hansson@arm.com    std::string object_type;
27410458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
27510458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
27610458Sandreas.hansson@arm.com
27710458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Configuring parameters of object: %s (%s)\n",
27810458Sandreas.hansson@arm.com        instance_name, object_type);
27910458Sandreas.hansson@arm.com
28010458Sandreas.hansson@arm.com    CxxConfigParams *object_params = entry.makeParamsObject();
28110458Sandreas.hansson@arm.com
28210458Sandreas.hansson@arm.com    try {
28310458Sandreas.hansson@arm.com        /* Fill in the implicit parameters that don't necessarily
28410458Sandreas.hansson@arm.com         *  appear in config files */
28510458Sandreas.hansson@arm.com        object_params->setName(instance_name);
28610458Sandreas.hansson@arm.com
28710458Sandreas.hansson@arm.com        /* Fill in parameters */
28810458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
28910458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
29010458Sandreas.hansson@arm.com        {
29110458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
29210458Sandreas.hansson@arm.com
29310458Sandreas.hansson@arm.com            if (!param->isSimObject) {
29410458Sandreas.hansson@arm.com                /* Only handle non-SimObject parameters here (see below) */
29510458Sandreas.hansson@arm.com
29610458Sandreas.hansson@arm.com                if (param->isVector) {
29710458Sandreas.hansson@arm.com                    std::vector<std::string> param_values;
29810458Sandreas.hansson@arm.com
29910458Sandreas.hansson@arm.com                    if (!configFile.getParamVector(object_name, param->name,
30010458Sandreas.hansson@arm.com                        param_values))
30110458Sandreas.hansson@arm.com                    {
30210458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
30310458Sandreas.hansson@arm.com                            "Element not found for parameter: %s",
30410458Sandreas.hansson@arm.com                            param->name));
30510458Sandreas.hansson@arm.com                    }
30610458Sandreas.hansson@arm.com
30710458Sandreas.hansson@arm.com                    if (!object_params->setParamVector(param->name,
30810458Sandreas.hansson@arm.com                        param_values, flags))
30910458Sandreas.hansson@arm.com                    {
31010458Sandreas.hansson@arm.com                        throw Exception(instance_name, csprintf(
31110458Sandreas.hansson@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
31210458Sandreas.hansson@arm.com                            param->name, formatParamList(param_values)));
31310458Sandreas.hansson@arm.com                    }
31410458Sandreas.hansson@arm.com
31510458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting parameter"
31610458Sandreas.hansson@arm.com                        " %s.%s=%s\n", instance_name, param->name,
31710458Sandreas.hansson@arm.com                        formatParamList(param_values));
31810458Sandreas.hansson@arm.com                } else {
31910458Sandreas.hansson@arm.com                    std::string param_value;
32010458Sandreas.hansson@arm.com
32110458Sandreas.hansson@arm.com                    if (!configFile.getParam(object_name, param->name,
32210458Sandreas.hansson@arm.com                        param_value))
32310458Sandreas.hansson@arm.com                    {
32410458Sandreas.hansson@arm.com                        throw Exception(object_name, csprintf(
32510458Sandreas.hansson@arm.com                            "Element not found for parameter: %s",
32610458Sandreas.hansson@arm.com                            param->name));
32710458Sandreas.hansson@arm.com                    }
32810458Sandreas.hansson@arm.com
32910458Sandreas.hansson@arm.com                    if (!object_params->setParam(param->name, param_value,
33010458Sandreas.hansson@arm.com                        flags))
33110458Sandreas.hansson@arm.com                    {
33210458Sandreas.hansson@arm.com                        throw Exception(instance_name, csprintf(
33310458Sandreas.hansson@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
33410458Sandreas.hansson@arm.com                            param->name, param_value));
33510458Sandreas.hansson@arm.com                    }
33610458Sandreas.hansson@arm.com
33710458Sandreas.hansson@arm.com                    DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
33810458Sandreas.hansson@arm.com                        instance_name, param->name, param_value);
33910458Sandreas.hansson@arm.com                }
34010458Sandreas.hansson@arm.com            }
34110458Sandreas.hansson@arm.com        }
34210458Sandreas.hansson@arm.com
34310458Sandreas.hansson@arm.com        /* Find the number of ports that will need binding and set the
34410458Sandreas.hansson@arm.com         *  appropriate port_..._connection_count parameters */
34510458Sandreas.hansson@arm.com        for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
34610458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
34710458Sandreas.hansson@arm.com            std::vector<std::string> peers;
34810458Sandreas.hansson@arm.com
34910458Sandreas.hansson@arm.com            if (!configFile.getPortPeers(object_name, port->name, peers)) {
35010458Sandreas.hansson@arm.com                DPRINTF(CxxConfig, "Port not found: %s.%s,"
35110458Sandreas.hansson@arm.com                    " assuming there are no connections\n",
35210458Sandreas.hansson@arm.com                    instance_name, port->name);
35310458Sandreas.hansson@arm.com            }
35410458Sandreas.hansson@arm.com
35510458Sandreas.hansson@arm.com            unsigned int peer_count = peers.size();
35610458Sandreas.hansson@arm.com
35710458Sandreas.hansson@arm.com            /* It would be more efficient to split the peer list and
35810458Sandreas.hansson@arm.com             *  save the values for peer binding later but that would
35910458Sandreas.hansson@arm.com             *  require another annoying intermediate structure to
36010458Sandreas.hansson@arm.com             *  hold for little performance increase */
36110458Sandreas.hansson@arm.com
36210458Sandreas.hansson@arm.com            if (!object_params->setPortConnectionCount(port->name,
36310458Sandreas.hansson@arm.com                peer_count))
36410458Sandreas.hansson@arm.com            {
36510458Sandreas.hansson@arm.com                throw Exception(instance_name, csprintf(
36610458Sandreas.hansson@arm.com                    "Unconnected port: %s", port->name));
36710458Sandreas.hansson@arm.com            }
36810458Sandreas.hansson@arm.com
36910458Sandreas.hansson@arm.com            DPRINTF(CxxConfig, "Setting port connection count"
37010458Sandreas.hansson@arm.com                " for: %s.%s to %d\n",
37110458Sandreas.hansson@arm.com                instance_name, port->name, peer_count);
37210458Sandreas.hansson@arm.com        }
37310458Sandreas.hansson@arm.com
37410458Sandreas.hansson@arm.com        /* Set pointed-to SimObjects to NULL */
37510458Sandreas.hansson@arm.com        for (auto i = entry.parameters.begin();
37610458Sandreas.hansson@arm.com            i != entry.parameters.end(); ++i)
37710458Sandreas.hansson@arm.com        {
37810458Sandreas.hansson@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
37910458Sandreas.hansson@arm.com
38010458Sandreas.hansson@arm.com            if (param->isSimObject) {
38110458Sandreas.hansson@arm.com                bool ret;
38210458Sandreas.hansson@arm.com
38310458Sandreas.hansson@arm.com                DPRINTF(CxxConfig, "Nulling sim object reference: %s.%s\n",
38410458Sandreas.hansson@arm.com                    instance_name, param->name);
38510458Sandreas.hansson@arm.com
38610458Sandreas.hansson@arm.com                if (param->isVector) {
38710458Sandreas.hansson@arm.com                    /* Clear the reference list. */
38810458Sandreas.hansson@arm.com                    std::vector<SimObject *> empty;
38910458Sandreas.hansson@arm.com                    ret = object_params->setSimObjectVector(param->name,
39010458Sandreas.hansson@arm.com                        empty);
39110458Sandreas.hansson@arm.com                } else {
39210458Sandreas.hansson@arm.com                    ret = object_params->setSimObject(param->name, NULL);
39310458Sandreas.hansson@arm.com                }
39410458Sandreas.hansson@arm.com
39510458Sandreas.hansson@arm.com                if (!ret) {
39610458Sandreas.hansson@arm.com                    throw Exception(instance_name, csprintf(
39710458Sandreas.hansson@arm.com                        "Error nulling sim object reference(s): %s",
39810458Sandreas.hansson@arm.com                        param->name));
39910458Sandreas.hansson@arm.com                }
40010458Sandreas.hansson@arm.com            }
40110458Sandreas.hansson@arm.com        }
40210458Sandreas.hansson@arm.com    } catch (Exception &) {
40310458Sandreas.hansson@arm.com        delete object_params;
40410458Sandreas.hansson@arm.com        throw;
40510458Sandreas.hansson@arm.com    }
40610458Sandreas.hansson@arm.com
40710458Sandreas.hansson@arm.com    objectParamsByName[instance_name] = object_params;
40810458Sandreas.hansson@arm.com
40910458Sandreas.hansson@arm.com    return object_params;
41010458Sandreas.hansson@arm.com}
41110458Sandreas.hansson@arm.com
41210458Sandreas.hansson@arm.comvoid
41310458Sandreas.hansson@arm.comCxxConfigManager::findAllObjects()
41410458Sandreas.hansson@arm.com{
41510458Sandreas.hansson@arm.com    std::vector<std::string> objects;
41610458Sandreas.hansson@arm.com    configFile.getAllObjectNames(objects);
41710458Sandreas.hansson@arm.com
41810458Sandreas.hansson@arm.com    /* Set the traversal order for further iterators */
41910458Sandreas.hansson@arm.com    objectsInOrder.clear();
42010458Sandreas.hansson@arm.com    findTraversalOrder("root");
42110458Sandreas.hansson@arm.com}
42210458Sandreas.hansson@arm.com
42310458Sandreas.hansson@arm.comvoid
42410458Sandreas.hansson@arm.comCxxConfigManager::findTraversalOrder(const std::string &object_name)
42510458Sandreas.hansson@arm.com{
42610458Sandreas.hansson@arm.com    SimObject *object = findObject(object_name);
42710458Sandreas.hansson@arm.com
42810458Sandreas.hansson@arm.com    if (object) {
42910458Sandreas.hansson@arm.com        objectsInOrder.push_back(object);
43010458Sandreas.hansson@arm.com
43110458Sandreas.hansson@arm.com        std::vector<std::string> children;
43210458Sandreas.hansson@arm.com        configFile.getObjectChildren(object_name, children, true);
43310458Sandreas.hansson@arm.com
43410458Sandreas.hansson@arm.com        /* Visit all your children */
43510458Sandreas.hansson@arm.com        for (auto i = children.begin(); i != children.end(); ++i)
43610458Sandreas.hansson@arm.com            findTraversalOrder(*i);
43710458Sandreas.hansson@arm.com    }
43810458Sandreas.hansson@arm.com}
43910458Sandreas.hansson@arm.com
44010458Sandreas.hansson@arm.comvoid
44110458Sandreas.hansson@arm.comCxxConfigManager::bindAllPorts()
44210458Sandreas.hansson@arm.com{
44310458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
44410458Sandreas.hansson@arm.com        bindObjectPorts(*i);
44510458Sandreas.hansson@arm.com}
44610458Sandreas.hansson@arm.com
44710458Sandreas.hansson@arm.comvoid
44810458Sandreas.hansson@arm.comCxxConfigManager::bindPort(
44910458Sandreas.hansson@arm.com    SimObject *master_object, const std::string &master_port_name,
45010458Sandreas.hansson@arm.com    PortID master_port_index,
45110458Sandreas.hansson@arm.com    SimObject *slave_object, const std::string &slave_port_name,
45210458Sandreas.hansson@arm.com    PortID slave_port_index)
45310458Sandreas.hansson@arm.com{
45410458Sandreas.hansson@arm.com    /* FIXME, check slave_port_index against connection_count
45510458Sandreas.hansson@arm.com     *  defined for port, need getPortConnectionCount and a
45610458Sandreas.hansson@arm.com     *  getCxxConfigDirectoryEntry for each object. */
45710458Sandreas.hansson@arm.com
45810458Sandreas.hansson@arm.com    /* It would be nice to be able to catch the errors from these calls. */
45913892Sgabeblack@google.com    Port &master_port = master_object->getPort(
46010458Sandreas.hansson@arm.com        master_port_name, master_port_index);
46113892Sgabeblack@google.com    Port &slave_port = slave_object->getPort(
46210458Sandreas.hansson@arm.com        slave_port_name, slave_port_index);
46310458Sandreas.hansson@arm.com
46410458Sandreas.hansson@arm.com    if (master_port.isConnected()) {
46510458Sandreas.hansson@arm.com        throw Exception(master_object->name(), csprintf(
46610458Sandreas.hansson@arm.com            "Master port: %s[%d] is already connected\n", master_port_name,
46710458Sandreas.hansson@arm.com            master_port_index));
46810458Sandreas.hansson@arm.com    }
46910458Sandreas.hansson@arm.com
47010458Sandreas.hansson@arm.com    if (slave_port.isConnected()) {
47110458Sandreas.hansson@arm.com        throw Exception(slave_object->name(), csprintf(
47210458Sandreas.hansson@arm.com            "Slave port: %s[%d] is already connected\n", slave_port_name,
47310458Sandreas.hansson@arm.com            slave_port_index));
47410458Sandreas.hansson@arm.com    }
47510458Sandreas.hansson@arm.com
47610458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Binding port %s.%s[%d]"
47710458Sandreas.hansson@arm.com        " to %s:%s[%d]\n",
47810458Sandreas.hansson@arm.com        master_object->name(), master_port_name, master_port_index,
47910458Sandreas.hansson@arm.com        slave_object->name(), slave_port_name, slave_port_index);
48010458Sandreas.hansson@arm.com
48110458Sandreas.hansson@arm.com    master_port.bind(slave_port);
48210458Sandreas.hansson@arm.com}
48310458Sandreas.hansson@arm.com
48410458Sandreas.hansson@arm.comvoid
48510458Sandreas.hansson@arm.comCxxConfigManager::bindMasterPort(SimObject *object,
48610458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry::PortDesc &port,
48710458Sandreas.hansson@arm.com    const std::vector<std::string> &peers)
48810458Sandreas.hansson@arm.com{
48910458Sandreas.hansson@arm.com    unsigned int master_port_index = 0;
49010458Sandreas.hansson@arm.com
49110458Sandreas.hansson@arm.com    for (auto peer_i = peers.begin(); peer_i != peers.end();
49210458Sandreas.hansson@arm.com        ++peer_i)
49310458Sandreas.hansson@arm.com    {
49410458Sandreas.hansson@arm.com        const std::string &peer = *peer_i;
49510458Sandreas.hansson@arm.com        std::string slave_object_name;
49610458Sandreas.hansson@arm.com        std::string slave_port_name;
49710458Sandreas.hansson@arm.com        unsigned int slave_port_index;
49810458Sandreas.hansson@arm.com
49910458Sandreas.hansson@arm.com        parsePort(peer, slave_object_name, slave_port_name,
50010458Sandreas.hansson@arm.com            slave_port_index);
50110458Sandreas.hansson@arm.com
50210458Sandreas.hansson@arm.com        std::string slave_instance_name = rename(slave_object_name);
50310458Sandreas.hansson@arm.com
50410458Sandreas.hansson@arm.com        if (objectsByName.find(slave_instance_name) == objectsByName.end()) {
50510458Sandreas.hansson@arm.com            throw Exception(object->name(), csprintf(
50610458Sandreas.hansson@arm.com                "Can't find slave port object: %s", slave_instance_name));
50710458Sandreas.hansson@arm.com        }
50810458Sandreas.hansson@arm.com
50910458Sandreas.hansson@arm.com        SimObject *slave_object = objectsByName[slave_instance_name];
51010458Sandreas.hansson@arm.com
51110458Sandreas.hansson@arm.com        bindPort(object, port.name, master_port_index,
51210458Sandreas.hansson@arm.com            slave_object, slave_port_name, slave_port_index);
51310458Sandreas.hansson@arm.com
51410458Sandreas.hansson@arm.com        master_port_index++;
51510458Sandreas.hansson@arm.com    }
51610458Sandreas.hansson@arm.com}
51710458Sandreas.hansson@arm.com
51810458Sandreas.hansson@arm.comvoid
51910458Sandreas.hansson@arm.comCxxConfigManager::bindObjectPorts(SimObject *object)
52010458Sandreas.hansson@arm.com{
52110458Sandreas.hansson@arm.com    /* We may want to separate object->name() from the name in configuration
52210458Sandreas.hansson@arm.com     *  later to allow (for example) repetition of fragments of configs */
52310458Sandreas.hansson@arm.com    const std::string &instance_name = object->name();
52410458Sandreas.hansson@arm.com
52510458Sandreas.hansson@arm.com    std::string object_name = unRename(instance_name);
52610458Sandreas.hansson@arm.com
52710458Sandreas.hansson@arm.com    std::string object_type;
52810458Sandreas.hansson@arm.com    const CxxConfigDirectoryEntry &entry =
52910458Sandreas.hansson@arm.com        findObjectType(object_name, object_type);
53010458Sandreas.hansson@arm.com
53110458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Binding ports of object: %s (%s)\n",
53210458Sandreas.hansson@arm.com        instance_name, object_type);
53310458Sandreas.hansson@arm.com
53410458Sandreas.hansson@arm.com    for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
53510458Sandreas.hansson@arm.com        const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
53610458Sandreas.hansson@arm.com
53710458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Binding port: %s.%s\n", instance_name,
53810458Sandreas.hansson@arm.com            port->name);
53910458Sandreas.hansson@arm.com
54010458Sandreas.hansson@arm.com        std::vector<std::string> peers;
54110458Sandreas.hansson@arm.com        configFile.getPortPeers(object_name, port->name, peers);
54210458Sandreas.hansson@arm.com
54310458Sandreas.hansson@arm.com        /* Only handle master ports as binding only needs to happen once
54410458Sandreas.hansson@arm.com         *  for each observed pair of ports */
54510458Sandreas.hansson@arm.com        if (port->isMaster) {
54610458Sandreas.hansson@arm.com            if (!port->isVector && peers.size() > 1) {
54710458Sandreas.hansson@arm.com                throw Exception(instance_name, csprintf(
54810458Sandreas.hansson@arm.com                    "Too many connections to non-vector port %s (%d)\n",
54910458Sandreas.hansson@arm.com                    port->name, peers.size()));
55010458Sandreas.hansson@arm.com            }
55110458Sandreas.hansson@arm.com
55210458Sandreas.hansson@arm.com            bindMasterPort(object, *port, peers);
55310458Sandreas.hansson@arm.com        }
55410458Sandreas.hansson@arm.com    }
55510458Sandreas.hansson@arm.com}
55610458Sandreas.hansson@arm.com
55710458Sandreas.hansson@arm.comvoid
55810458Sandreas.hansson@arm.comCxxConfigManager::parsePort(const std::string &inp,
55910458Sandreas.hansson@arm.com    std::string &path, std::string &port, unsigned int &index)
56010458Sandreas.hansson@arm.com{
56110458Sandreas.hansson@arm.com    std::size_t dot_i = inp.rfind('.');
56210458Sandreas.hansson@arm.com    std::size_t open_square_i = inp.rfind('[');
56310458Sandreas.hansson@arm.com
56410458Sandreas.hansson@arm.com    if (dot_i == std::string::npos) {
56510458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Bad port string: %s\n", inp);
56610458Sandreas.hansson@arm.com        path = "";
56710458Sandreas.hansson@arm.com        port = "";
56810458Sandreas.hansson@arm.com        index = 0;
56910458Sandreas.hansson@arm.com    } else {
57010458Sandreas.hansson@arm.com        path = std::string(inp, 0, dot_i);
57110458Sandreas.hansson@arm.com
57210458Sandreas.hansson@arm.com        if (open_square_i == std::string::npos) {
57310458Sandreas.hansson@arm.com            /* Singleton port */
57410458Sandreas.hansson@arm.com            port = std::string(inp, dot_i + 1, inp.length() - dot_i);
57510458Sandreas.hansson@arm.com            index = 0;
57610458Sandreas.hansson@arm.com        } else {
57710458Sandreas.hansson@arm.com            /* Vectored port elemnt */
57810458Sandreas.hansson@arm.com            port = std::string(inp, dot_i + 1, (open_square_i - 1) - dot_i);
57910458Sandreas.hansson@arm.com            index = std::atoi(inp.c_str() + open_square_i + 1);
58010458Sandreas.hansson@arm.com        }
58110458Sandreas.hansson@arm.com    }
58210458Sandreas.hansson@arm.com}
58310458Sandreas.hansson@arm.com
58410458Sandreas.hansson@arm.comvoid
58510458Sandreas.hansson@arm.comCxxConfigManager::forEachObject(void (SimObject::*mem_func)())
58610458Sandreas.hansson@arm.com{
58710458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
58810458Sandreas.hansson@arm.com        ((*i)->*mem_func)();
58910458Sandreas.hansson@arm.com}
59010458Sandreas.hansson@arm.com
59110458Sandreas.hansson@arm.comvoid
59210458Sandreas.hansson@arm.comCxxConfigManager::instantiate(bool build_all)
59310458Sandreas.hansson@arm.com{
59410458Sandreas.hansson@arm.com    if (build_all) {
59510458Sandreas.hansson@arm.com        findAllObjects();
59610458Sandreas.hansson@arm.com        bindAllPorts();
59710458Sandreas.hansson@arm.com    }
59810458Sandreas.hansson@arm.com
59910458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Initialising all objects\n");
60010458Sandreas.hansson@arm.com    forEachObject(&SimObject::init);
60110458Sandreas.hansson@arm.com
60210458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Registering stats\n");
60310458Sandreas.hansson@arm.com    forEachObject(&SimObject::regStats);
60410458Sandreas.hansson@arm.com
60510458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Registering probe points\n");
60610458Sandreas.hansson@arm.com    forEachObject(&SimObject::regProbePoints);
60710458Sandreas.hansson@arm.com
60810458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Connecting probe listeners\n");
60910458Sandreas.hansson@arm.com    forEachObject(&SimObject::regProbeListeners);
61010458Sandreas.hansson@arm.com}
61110458Sandreas.hansson@arm.com
61210458Sandreas.hansson@arm.comvoid
61310458Sandreas.hansson@arm.comCxxConfigManager::initState()
61410458Sandreas.hansson@arm.com{
61510458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Calling initState on all objects\n");
61610458Sandreas.hansson@arm.com    forEachObject(&SimObject::initState);
61710458Sandreas.hansson@arm.com}
61810458Sandreas.hansson@arm.com
61910458Sandreas.hansson@arm.comvoid
62010458Sandreas.hansson@arm.comCxxConfigManager::startup()
62110458Sandreas.hansson@arm.com{
62210458Sandreas.hansson@arm.com    DPRINTF(CxxConfig, "Starting up all objects\n");
62310458Sandreas.hansson@arm.com    forEachObject(&SimObject::startup);
62410458Sandreas.hansson@arm.com}
62510458Sandreas.hansson@arm.com
62610458Sandreas.hansson@arm.comunsigned int
62710912Sandreas.sandberg@arm.comCxxConfigManager::drain()
62810458Sandreas.hansson@arm.com{
62910912Sandreas.sandberg@arm.com    return DrainManager::instance().tryDrain() ? 0 : 1;
63010458Sandreas.hansson@arm.com}
63110458Sandreas.hansson@arm.com
63210458Sandreas.hansson@arm.comvoid
63310458Sandreas.hansson@arm.comCxxConfigManager::drainResume()
63410458Sandreas.hansson@arm.com{
63510912Sandreas.sandberg@arm.com    DrainManager::instance().resume();
63610458Sandreas.hansson@arm.com}
63710458Sandreas.hansson@arm.com
63810458Sandreas.hansson@arm.comvoid
63910458Sandreas.hansson@arm.comCxxConfigManager::serialize(std::ostream &os)
64010458Sandreas.hansson@arm.com{
64110458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i) {
64210458Sandreas.hansson@arm.com        // (*i)->nameOut(os); FIXME, change access spec. for nameOut
64310458Sandreas.hansson@arm.com        os << '[' << (*i)->name() << "]\n";
64410458Sandreas.hansson@arm.com        (*i)->serialize(os);
64510458Sandreas.hansson@arm.com    }
64610458Sandreas.hansson@arm.com}
64710458Sandreas.hansson@arm.com
64810458Sandreas.hansson@arm.comvoid
64910905Sandreas.sandberg@arm.comCxxConfigManager::loadState(CheckpointIn &checkpoint)
65010458Sandreas.hansson@arm.com{
65110458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i)
65210458Sandreas.hansson@arm.com        (*i)->loadState(checkpoint);
65310458Sandreas.hansson@arm.com}
65410458Sandreas.hansson@arm.com
65510458Sandreas.hansson@arm.comvoid
65610458Sandreas.hansson@arm.comCxxConfigManager::deleteObjects()
65710458Sandreas.hansson@arm.com{
65810458Sandreas.hansson@arm.com    for (auto i = objectsInOrder.rbegin(); i != objectsInOrder.rend(); ++i) {
65910458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Freeing sim object: %s\n", (*i)->name());
66010458Sandreas.hansson@arm.com        delete *i;
66110458Sandreas.hansson@arm.com    }
66210458Sandreas.hansson@arm.com
66310458Sandreas.hansson@arm.com    for (auto i = objectParamsByName.rbegin();
66410458Sandreas.hansson@arm.com        i != objectParamsByName.rend(); ++i)
66510458Sandreas.hansson@arm.com    {
66610458Sandreas.hansson@arm.com        CxxConfigParams *params = (*i).second;
66710458Sandreas.hansson@arm.com
66810458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Freeing sim object params: %s\n",
66910458Sandreas.hansson@arm.com            params->getName());
67010458Sandreas.hansson@arm.com        delete params;
67110458Sandreas.hansson@arm.com    }
67210458Sandreas.hansson@arm.com
67310458Sandreas.hansson@arm.com    objectsInOrder.clear();
67410458Sandreas.hansson@arm.com    objectsByName.clear();
67510458Sandreas.hansson@arm.com}
67610458Sandreas.hansson@arm.com
67710458Sandreas.hansson@arm.comvoid
67810458Sandreas.hansson@arm.comCxxConfigManager::setParam(const std::string &object_name,
67910458Sandreas.hansson@arm.com    const std::string &param_name, const std::string &param_value)
68010458Sandreas.hansson@arm.com{
68110458Sandreas.hansson@arm.com    CxxConfigParams *params = findObjectParams(object_name);
68210458Sandreas.hansson@arm.com
68310458Sandreas.hansson@arm.com    if (!params->setParam(param_name, param_value, flags)) {
68410458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf("Bad parameter value:"
68510458Sandreas.hansson@arm.com            " .%s=X=\"%s\"", param_name, param_value));
68610458Sandreas.hansson@arm.com    } else {
68710458Sandreas.hansson@arm.com        std::string instance_name = rename(object_name);
68810458Sandreas.hansson@arm.com
68910458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
69010458Sandreas.hansson@arm.com            instance_name, param_name, param_value);
69110458Sandreas.hansson@arm.com    }
69210458Sandreas.hansson@arm.com}
69310458Sandreas.hansson@arm.com
69410458Sandreas.hansson@arm.comvoid
69510458Sandreas.hansson@arm.comCxxConfigManager::setParamVector(const std::string &object_name,
69610458Sandreas.hansson@arm.com    const std::string &param_name,
69710458Sandreas.hansson@arm.com    const std::vector<std::string> &param_values)
69810458Sandreas.hansson@arm.com{
69910458Sandreas.hansson@arm.com    CxxConfigParams *params = findObjectParams(object_name);
70010458Sandreas.hansson@arm.com
70110458Sandreas.hansson@arm.com    if (!params->setParamVector(param_name, param_values, flags)) {
70210458Sandreas.hansson@arm.com        throw Exception(object_name, csprintf("Bad vector parameter value:"
70310458Sandreas.hansson@arm.com            " .%s=X=\"%s\"", param_name, formatParamList(param_values)));
70410458Sandreas.hansson@arm.com    } else {
70510458Sandreas.hansson@arm.com        std::string instance_name = rename(object_name);
70610458Sandreas.hansson@arm.com
70710458Sandreas.hansson@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=\"%s\"\n",
70810458Sandreas.hansson@arm.com            instance_name, param_name, formatParamList(param_values));
70910458Sandreas.hansson@arm.com    }
71010458Sandreas.hansson@arm.com}
71110458Sandreas.hansson@arm.com
71210458Sandreas.hansson@arm.comvoid CxxConfigManager::addRenaming(const Renaming &renaming)
71310458Sandreas.hansson@arm.com{
71410458Sandreas.hansson@arm.com    renamings.push_back(renaming);
71510458Sandreas.hansson@arm.com}
716