cxx_manager.cc revision 10458:64809024b924
110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2014 ARM Limited
310259SAndrew.Bardsley@arm.com * All rights reserved
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall
610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual
710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating
810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software
910259SAndrew.Bardsley@arm.com * licensed hereunder.  You may use the software subject to the license
1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated
1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software,
1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form.
1310259SAndrew.Bardsley@arm.com *
1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2410259SAndrew.Bardsley@arm.com *
2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610259SAndrew.Bardsley@arm.com *
3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley
3810259SAndrew.Bardsley@arm.com */
3910259SAndrew.Bardsley@arm.com
4010259SAndrew.Bardsley@arm.com#include <cstdlib>
4110259SAndrew.Bardsley@arm.com#include <sstream>
4210259SAndrew.Bardsley@arm.com
4310259SAndrew.Bardsley@arm.com#include "base/str.hh"
4410259SAndrew.Bardsley@arm.com#include "debug/CxxConfig.hh"
4510259SAndrew.Bardsley@arm.com#include "mem/mem_object.hh"
4610259SAndrew.Bardsley@arm.com#include "sim/cxx_manager.hh"
4710259SAndrew.Bardsley@arm.com#include "sim/serialize.hh"
4810259SAndrew.Bardsley@arm.com
4910259SAndrew.Bardsley@arm.comCxxConfigManager::CxxConfigManager(CxxConfigFileBase &configFile_) :
5010259SAndrew.Bardsley@arm.com    configFile(configFile_), flags(configFile_.getFlags()),
5110259SAndrew.Bardsley@arm.com    simObjectResolver(*this)
5210259SAndrew.Bardsley@arm.com{
5310259SAndrew.Bardsley@arm.com}
5410259SAndrew.Bardsley@arm.com
5510259SAndrew.Bardsley@arm.comconst CxxConfigDirectoryEntry &
5610259SAndrew.Bardsley@arm.comCxxConfigManager::findObjectType(const std::string &object_name,
5710259SAndrew.Bardsley@arm.com    std::string &object_type)
5810259SAndrew.Bardsley@arm.com{
5910259SAndrew.Bardsley@arm.com    if (!configFile.objectExists(object_name))
6010259SAndrew.Bardsley@arm.com        throw Exception(object_name, "Can't find sim object");
6110259SAndrew.Bardsley@arm.com
6210259SAndrew.Bardsley@arm.com    if (!configFile.getParam(object_name, "type", object_type))
6310259SAndrew.Bardsley@arm.com        throw Exception(object_name, "Sim object has no 'type' field");
6410259SAndrew.Bardsley@arm.com
6510259SAndrew.Bardsley@arm.com    if (cxx_config_directory.find(object_type) ==
6610259SAndrew.Bardsley@arm.com        cxx_config_directory.end())
6710259SAndrew.Bardsley@arm.com    {
6810259SAndrew.Bardsley@arm.com        throw Exception(object_name, csprintf(
6910259SAndrew.Bardsley@arm.com            "No sim object type %s is available", object_type));
7010259SAndrew.Bardsley@arm.com    }
7110259SAndrew.Bardsley@arm.com
7210259SAndrew.Bardsley@arm.com    const CxxConfigDirectoryEntry *entry = cxx_config_directory[object_type];
7310259SAndrew.Bardsley@arm.com
7410259SAndrew.Bardsley@arm.com    return *entry;
7510259SAndrew.Bardsley@arm.com}
7610259SAndrew.Bardsley@arm.com
7710259SAndrew.Bardsley@arm.comstd::string
7810259SAndrew.Bardsley@arm.comCxxConfigManager::rename(const std::string &from_name)
7910259SAndrew.Bardsley@arm.com{
8010259SAndrew.Bardsley@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
8110259SAndrew.Bardsley@arm.com        const Renaming &renaming = *i;
8210259SAndrew.Bardsley@arm.com
8310259SAndrew.Bardsley@arm.com        if (from_name.find(renaming.fromPrefix) == 0) {
8410259SAndrew.Bardsley@arm.com            return renaming.toPrefix +
8510259SAndrew.Bardsley@arm.com                from_name.substr(renaming.fromPrefix.length());
8610259SAndrew.Bardsley@arm.com        }
8710259SAndrew.Bardsley@arm.com    }
8810259SAndrew.Bardsley@arm.com
8910259SAndrew.Bardsley@arm.com    return from_name;
9010259SAndrew.Bardsley@arm.com}
9110259SAndrew.Bardsley@arm.com
9210259SAndrew.Bardsley@arm.comstd::string
9310259SAndrew.Bardsley@arm.comCxxConfigManager::unRename(const std::string &to_name)
9410259SAndrew.Bardsley@arm.com{
9510259SAndrew.Bardsley@arm.com    for (auto i = renamings.begin(); i != renamings.end(); ++ i) {
9610259SAndrew.Bardsley@arm.com        const Renaming &renaming = *i;
9710259SAndrew.Bardsley@arm.com
9810259SAndrew.Bardsley@arm.com        if (to_name.find(renaming.toPrefix) == 0) {
9910259SAndrew.Bardsley@arm.com            return renaming.fromPrefix +
10010259SAndrew.Bardsley@arm.com                to_name.substr(renaming.toPrefix.length());
10110259SAndrew.Bardsley@arm.com        }
10210259SAndrew.Bardsley@arm.com    }
10310259SAndrew.Bardsley@arm.com
10410259SAndrew.Bardsley@arm.com    return to_name;
10510259SAndrew.Bardsley@arm.com}
10610259SAndrew.Bardsley@arm.com
10710259SAndrew.Bardsley@arm.comstatic
10810259SAndrew.Bardsley@arm.comstd::string formatParamList(const std::vector<std::string> &param_values)
10910259SAndrew.Bardsley@arm.com{
11010259SAndrew.Bardsley@arm.com    std::ostringstream params;
11110259SAndrew.Bardsley@arm.com
11210259SAndrew.Bardsley@arm.com    auto i = param_values.begin();
11310259SAndrew.Bardsley@arm.com    auto end_i = param_values.end();
11410259SAndrew.Bardsley@arm.com
11510259SAndrew.Bardsley@arm.com    params << '[';
11610259SAndrew.Bardsley@arm.com    while (i != end_i) {
11710259SAndrew.Bardsley@arm.com        params << (*i);
11810259SAndrew.Bardsley@arm.com        ++i;
11910259SAndrew.Bardsley@arm.com
12010259SAndrew.Bardsley@arm.com        if (i != end_i)
12110259SAndrew.Bardsley@arm.com            params << ", ";
12210259SAndrew.Bardsley@arm.com    }
12310259SAndrew.Bardsley@arm.com    params << ']';
12410259SAndrew.Bardsley@arm.com
12510259SAndrew.Bardsley@arm.com    return params.str();
12610259SAndrew.Bardsley@arm.com}
12710259SAndrew.Bardsley@arm.com
12810259SAndrew.Bardsley@arm.comSimObject *
12910259SAndrew.Bardsley@arm.comCxxConfigManager::findObject(const std::string &object_name,
13010259SAndrew.Bardsley@arm.com    bool visit_children)
13110259SAndrew.Bardsley@arm.com{
13210259SAndrew.Bardsley@arm.com    std::string instance_name = rename(object_name);
13310259SAndrew.Bardsley@arm.com
13410259SAndrew.Bardsley@arm.com    if (object_name == "Null")
13510259SAndrew.Bardsley@arm.com        return NULL;
13610259SAndrew.Bardsley@arm.com
13710259SAndrew.Bardsley@arm.com    /* Already constructed */
13810259SAndrew.Bardsley@arm.com    if (objectsByName.find(instance_name) != objectsByName.end())
13910259SAndrew.Bardsley@arm.com        return objectsByName[instance_name];
14010259SAndrew.Bardsley@arm.com
14110259SAndrew.Bardsley@arm.com    if (inVisit.find(instance_name) != inVisit.end())
14210259SAndrew.Bardsley@arm.com        throw Exception(instance_name, "Cycle in configuration");
14310259SAndrew.Bardsley@arm.com
14410259SAndrew.Bardsley@arm.com    std::string object_type;
14510259SAndrew.Bardsley@arm.com    const CxxConfigDirectoryEntry &entry =
14610259SAndrew.Bardsley@arm.com        findObjectType(object_name, object_type);
14710259SAndrew.Bardsley@arm.com
14810259SAndrew.Bardsley@arm.com    SimObject *object = NULL;
14910259SAndrew.Bardsley@arm.com
15010259SAndrew.Bardsley@arm.com    CxxConfigParams *object_params = findObjectParams(object_name);
15110259SAndrew.Bardsley@arm.com
15210259SAndrew.Bardsley@arm.com    try {
15310259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Configuring sim object references for: %s"
15410259SAndrew.Bardsley@arm.com            " (%s from object %s)\n", instance_name, object_type,
15510259SAndrew.Bardsley@arm.com            object_name);
15610259SAndrew.Bardsley@arm.com
15710259SAndrew.Bardsley@arm.com        /* Remember the path back to the top of the recursion to detect
15810259SAndrew.Bardsley@arm.com         *  cycles */
15910259SAndrew.Bardsley@arm.com        inVisit.insert(instance_name);
16010259SAndrew.Bardsley@arm.com
16110259SAndrew.Bardsley@arm.com        /* Resolve pointed-to SimObjects by recursing into them */
16210259SAndrew.Bardsley@arm.com        for (auto i = entry.parameters.begin();
16310259SAndrew.Bardsley@arm.com            i != entry.parameters.end(); ++i)
16410259SAndrew.Bardsley@arm.com        {
16510259SAndrew.Bardsley@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
16610259SAndrew.Bardsley@arm.com
16710259SAndrew.Bardsley@arm.com            if (param->isSimObject) {
16810259SAndrew.Bardsley@arm.com                if (param->isVector) {
16910259SAndrew.Bardsley@arm.com                    std::vector<std::string> sub_object_names;
17010259SAndrew.Bardsley@arm.com
17110259SAndrew.Bardsley@arm.com                    if (!configFile.getParamVector(object_name, param->name,
17210259SAndrew.Bardsley@arm.com                        sub_object_names))
17310259SAndrew.Bardsley@arm.com                    {
17410259SAndrew.Bardsley@arm.com                        throw Exception(object_name, csprintf(
17510259SAndrew.Bardsley@arm.com                            "Element not found: %s", param->name));
17610259SAndrew.Bardsley@arm.com                    }
17710259SAndrew.Bardsley@arm.com
17810259SAndrew.Bardsley@arm.com                    std::vector<SimObject *> sub_objects;
17910259SAndrew.Bardsley@arm.com
18010259SAndrew.Bardsley@arm.com                    for (auto n = sub_object_names.begin();
18110259SAndrew.Bardsley@arm.com                        n != sub_object_names.end(); ++n)
18210259SAndrew.Bardsley@arm.com                    {
18310259SAndrew.Bardsley@arm.com                        SimObject *sub_object = findObject(*n,
18410259SAndrew.Bardsley@arm.com                            visit_children);
18510259SAndrew.Bardsley@arm.com
18610259SAndrew.Bardsley@arm.com                        if (sub_object)
18710259SAndrew.Bardsley@arm.com                            sub_objects.push_back(sub_object);
18810259SAndrew.Bardsley@arm.com                    }
18910259SAndrew.Bardsley@arm.com
19010259SAndrew.Bardsley@arm.com                    if (!object_params->setSimObjectVector(param->name,
19110259SAndrew.Bardsley@arm.com                        sub_objects))
19210259SAndrew.Bardsley@arm.com                    {
19310259SAndrew.Bardsley@arm.com                        throw Exception(object_name, csprintf(
19410259SAndrew.Bardsley@arm.com                            "Can't assign sim object element %s from \"%s\"",
19510259SAndrew.Bardsley@arm.com                            param->name, formatParamList(sub_object_names)));
19610259SAndrew.Bardsley@arm.com                    }
19710259SAndrew.Bardsley@arm.com
19810259SAndrew.Bardsley@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s): %s.%s=%s\n",
19910259SAndrew.Bardsley@arm.com                        object_name, param->name,
20010259SAndrew.Bardsley@arm.com                        formatParamList(sub_object_names));
20110259SAndrew.Bardsley@arm.com                } else {
20210259SAndrew.Bardsley@arm.com                    std::string sub_object_name;
20310259SAndrew.Bardsley@arm.com
20410259SAndrew.Bardsley@arm.com                    if (!configFile.getParam(object_name, param->name,
20510259SAndrew.Bardsley@arm.com                        sub_object_name))
20610259SAndrew.Bardsley@arm.com                    {
20710259SAndrew.Bardsley@arm.com                        throw Exception(object_name, csprintf(
20810259SAndrew.Bardsley@arm.com                            "Element not found: %s", param->name));
20910259SAndrew.Bardsley@arm.com                    }
21010259SAndrew.Bardsley@arm.com
21110259SAndrew.Bardsley@arm.com                    SimObject *sub_object = findObject(sub_object_name,
21210259SAndrew.Bardsley@arm.com                        visit_children);
21310259SAndrew.Bardsley@arm.com
21410259SAndrew.Bardsley@arm.com                    if (sub_object) {
21510259SAndrew.Bardsley@arm.com                        if (!object_params->setSimObject(param->name,
21610259SAndrew.Bardsley@arm.com                            sub_object))
21710259SAndrew.Bardsley@arm.com                        {
21810259SAndrew.Bardsley@arm.com                            throw Exception(object_name, csprintf(
21910259SAndrew.Bardsley@arm.com                                "Can't assign sim object element %s from"
22010259SAndrew.Bardsley@arm.com                                " \"%s\"", param->name, sub_object_name));
22110259SAndrew.Bardsley@arm.com                        }
22210259SAndrew.Bardsley@arm.com                    }
22310259SAndrew.Bardsley@arm.com
22410259SAndrew.Bardsley@arm.com                    DPRINTF(CxxConfig, "Setting sim object(s):"
22510259SAndrew.Bardsley@arm.com                        " %s.%s=%s\n", object_name, param->name,
22610259SAndrew.Bardsley@arm.com                        sub_object_name);
22710259SAndrew.Bardsley@arm.com                }
22810259SAndrew.Bardsley@arm.com            }
22910379Sandreas.hansson@arm.com        }
23010379Sandreas.hansson@arm.com
23110259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Creating SimObject: %s\n", instance_name);
23210259SAndrew.Bardsley@arm.com        object = object_params->simObjectCreate();
23310259SAndrew.Bardsley@arm.com
23410259SAndrew.Bardsley@arm.com        if (!object) {
23510259SAndrew.Bardsley@arm.com            throw Exception(object_name, csprintf("Couldn't create object of"
23610259SAndrew.Bardsley@arm.com                " type: %s", object_type));
23710259SAndrew.Bardsley@arm.com        }
23810259SAndrew.Bardsley@arm.com
23910259SAndrew.Bardsley@arm.com        objectsByName[instance_name] = object;
24010259SAndrew.Bardsley@arm.com        objectParamsByName[instance_name] = object_params;
24110259SAndrew.Bardsley@arm.com
24210259SAndrew.Bardsley@arm.com        if (visit_children) {
24310259SAndrew.Bardsley@arm.com            std::vector<std::string> children;
24410259SAndrew.Bardsley@arm.com            configFile.getObjectChildren(object_name, children, true);
24510259SAndrew.Bardsley@arm.com
24610259SAndrew.Bardsley@arm.com            /* Visit all your children */
24710259SAndrew.Bardsley@arm.com            for (auto i = children.begin(); i != children.end(); ++i)
24810259SAndrew.Bardsley@arm.com                findObject(*i, visit_children);
24910259SAndrew.Bardsley@arm.com        }
25010259SAndrew.Bardsley@arm.com    } catch (Exception &) {
25110259SAndrew.Bardsley@arm.com        delete object_params;
25210259SAndrew.Bardsley@arm.com        throw;
25310259SAndrew.Bardsley@arm.com    }
25410259SAndrew.Bardsley@arm.com
25510259SAndrew.Bardsley@arm.com    /* Mark that we've exited object
25610259SAndrew.Bardsley@arm.com     *  construction and so 'find'ing this object again won't be a
25710259SAndrew.Bardsley@arm.com     *  configuration loop */
25810259SAndrew.Bardsley@arm.com    inVisit.erase(object_name);
25910259SAndrew.Bardsley@arm.com    return object;
26010259SAndrew.Bardsley@arm.com}
26110259SAndrew.Bardsley@arm.com
26210259SAndrew.Bardsley@arm.comCxxConfigParams *
26310259SAndrew.Bardsley@arm.comCxxConfigManager::findObjectParams(const std::string &object_name)
26410259SAndrew.Bardsley@arm.com{
26510259SAndrew.Bardsley@arm.com    std::string instance_name = rename(object_name);
26610259SAndrew.Bardsley@arm.com
26710259SAndrew.Bardsley@arm.com    /* Already constructed */
26810259SAndrew.Bardsley@arm.com    if (objectParamsByName.find(instance_name) != objectParamsByName.end())
26910259SAndrew.Bardsley@arm.com        return objectParamsByName[instance_name];
27010259SAndrew.Bardsley@arm.com
27110259SAndrew.Bardsley@arm.com    std::string object_type;
27210259SAndrew.Bardsley@arm.com    const CxxConfigDirectoryEntry &entry =
27310259SAndrew.Bardsley@arm.com        findObjectType(object_name, object_type);
27410259SAndrew.Bardsley@arm.com
27510259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Configuring parameters of object: %s (%s)\n",
27610379Sandreas.hansson@arm.com        instance_name, object_type);
27710379Sandreas.hansson@arm.com
27810259SAndrew.Bardsley@arm.com    CxxConfigParams *object_params = entry.makeParamsObject();
27910259SAndrew.Bardsley@arm.com
28010259SAndrew.Bardsley@arm.com    try {
28110259SAndrew.Bardsley@arm.com        /* Fill in the implicit parameters that don't necessarily
28210259SAndrew.Bardsley@arm.com         *  appear in config files */
28310259SAndrew.Bardsley@arm.com        object_params->setName(instance_name);
28410259SAndrew.Bardsley@arm.com
28510259SAndrew.Bardsley@arm.com        /* Fill in parameters */
28610259SAndrew.Bardsley@arm.com        for (auto i = entry.parameters.begin();
28710259SAndrew.Bardsley@arm.com            i != entry.parameters.end(); ++i)
28810259SAndrew.Bardsley@arm.com        {
28910259SAndrew.Bardsley@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
29010259SAndrew.Bardsley@arm.com
29110259SAndrew.Bardsley@arm.com            if (!param->isSimObject) {
29210259SAndrew.Bardsley@arm.com                /* Only handle non-SimObject parameters here (see below) */
29310259SAndrew.Bardsley@arm.com
29410259SAndrew.Bardsley@arm.com                if (param->isVector) {
29510259SAndrew.Bardsley@arm.com                    std::vector<std::string> param_values;
29610259SAndrew.Bardsley@arm.com
29710259SAndrew.Bardsley@arm.com                    if (!configFile.getParamVector(object_name, param->name,
29810259SAndrew.Bardsley@arm.com                        param_values))
29910259SAndrew.Bardsley@arm.com                    {
30010259SAndrew.Bardsley@arm.com                        throw Exception(object_name, csprintf(
30110259SAndrew.Bardsley@arm.com                            "Element not found for parameter: %s",
30210259SAndrew.Bardsley@arm.com                            param->name));
30310259SAndrew.Bardsley@arm.com                    }
30410259SAndrew.Bardsley@arm.com
30510259SAndrew.Bardsley@arm.com                    if (!object_params->setParamVector(param->name,
30610259SAndrew.Bardsley@arm.com                        param_values, flags))
30710259SAndrew.Bardsley@arm.com                    {
30810259SAndrew.Bardsley@arm.com                        throw Exception(instance_name, csprintf(
30910259SAndrew.Bardsley@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
31010259SAndrew.Bardsley@arm.com                            param->name, formatParamList(param_values)));
31110259SAndrew.Bardsley@arm.com                    }
31210259SAndrew.Bardsley@arm.com
31310259SAndrew.Bardsley@arm.com                    DPRINTF(CxxConfig, "Setting parameter"
31410259SAndrew.Bardsley@arm.com                        " %s.%s=%s\n", instance_name, param->name,
31510259SAndrew.Bardsley@arm.com                        formatParamList(param_values));
31610259SAndrew.Bardsley@arm.com                } else {
31710259SAndrew.Bardsley@arm.com                    std::string param_value;
31810259SAndrew.Bardsley@arm.com
31910259SAndrew.Bardsley@arm.com                    if (!configFile.getParam(object_name, param->name,
32010259SAndrew.Bardsley@arm.com                        param_value))
32110259SAndrew.Bardsley@arm.com                    {
32210259SAndrew.Bardsley@arm.com                        throw Exception(object_name, csprintf(
32310259SAndrew.Bardsley@arm.com                            "Element not found for parameter: %s",
32410259SAndrew.Bardsley@arm.com                            param->name));
32510259SAndrew.Bardsley@arm.com                    }
32610259SAndrew.Bardsley@arm.com
32710259SAndrew.Bardsley@arm.com                    if (!object_params->setParam(param->name, param_value,
32810259SAndrew.Bardsley@arm.com                        flags))
32910259SAndrew.Bardsley@arm.com                    {
33010259SAndrew.Bardsley@arm.com                        throw Exception(instance_name, csprintf(
33110259SAndrew.Bardsley@arm.com                            "Bad parameter value: .%s=X=\"%s\"",
33210259SAndrew.Bardsley@arm.com                            param->name, param_value));
33310259SAndrew.Bardsley@arm.com                    }
33410259SAndrew.Bardsley@arm.com
33510259SAndrew.Bardsley@arm.com                    DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
33610259SAndrew.Bardsley@arm.com                        instance_name, param->name, param_value);
33710259SAndrew.Bardsley@arm.com                }
33810259SAndrew.Bardsley@arm.com            }
33910259SAndrew.Bardsley@arm.com        }
34010259SAndrew.Bardsley@arm.com
34110259SAndrew.Bardsley@arm.com        /* Find the number of ports that will need binding and set the
34210259SAndrew.Bardsley@arm.com         *  appropriate port_..._connection_count parameters */
34310259SAndrew.Bardsley@arm.com        for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
34410259SAndrew.Bardsley@arm.com            const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
34510259SAndrew.Bardsley@arm.com            std::vector<std::string> peers;
34610259SAndrew.Bardsley@arm.com
34710259SAndrew.Bardsley@arm.com            if (!configFile.getPortPeers(object_name, port->name, peers)) {
34810259SAndrew.Bardsley@arm.com                DPRINTF(CxxConfig, "Port not found: %s.%s,"
34910259SAndrew.Bardsley@arm.com                    " assuming there are no connections\n",
35010259SAndrew.Bardsley@arm.com                    instance_name, port->name);
35110259SAndrew.Bardsley@arm.com            }
35210259SAndrew.Bardsley@arm.com
35310259SAndrew.Bardsley@arm.com            unsigned int peer_count = peers.size();
35410259SAndrew.Bardsley@arm.com
35510259SAndrew.Bardsley@arm.com            /* It would be more efficient to split the peer list and
35610259SAndrew.Bardsley@arm.com             *  save the values for peer binding later but that would
35710259SAndrew.Bardsley@arm.com             *  require another annoying intermediate structure to
35810259SAndrew.Bardsley@arm.com             *  hold for little performance increase */
35910259SAndrew.Bardsley@arm.com
36010259SAndrew.Bardsley@arm.com            if (!object_params->setPortConnectionCount(port->name,
36110259SAndrew.Bardsley@arm.com                peer_count))
36210259SAndrew.Bardsley@arm.com            {
36310259SAndrew.Bardsley@arm.com                throw Exception(instance_name, csprintf(
36410259SAndrew.Bardsley@arm.com                    "Unconnected port: %s", port->name));
36510259SAndrew.Bardsley@arm.com            }
36610259SAndrew.Bardsley@arm.com
36710259SAndrew.Bardsley@arm.com            DPRINTF(CxxConfig, "Setting port connection count"
36810259SAndrew.Bardsley@arm.com                " for: %s.%s to %d\n",
36910259SAndrew.Bardsley@arm.com                instance_name, port->name, peer_count);
37010259SAndrew.Bardsley@arm.com        }
37110259SAndrew.Bardsley@arm.com
37210259SAndrew.Bardsley@arm.com        /* Set pointed-to SimObjects to NULL */
37310259SAndrew.Bardsley@arm.com        for (auto i = entry.parameters.begin();
37410259SAndrew.Bardsley@arm.com            i != entry.parameters.end(); ++i)
37510259SAndrew.Bardsley@arm.com        {
37610259SAndrew.Bardsley@arm.com            const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second;
37710259SAndrew.Bardsley@arm.com
37810259SAndrew.Bardsley@arm.com            if (param->isSimObject) {
37910259SAndrew.Bardsley@arm.com                bool ret;
38010259SAndrew.Bardsley@arm.com
38110259SAndrew.Bardsley@arm.com                DPRINTF(CxxConfig, "Nulling sim object reference: %s.%s\n",
38210259SAndrew.Bardsley@arm.com                    instance_name, param->name);
38310259SAndrew.Bardsley@arm.com
38410259SAndrew.Bardsley@arm.com                if (param->isVector) {
38510259SAndrew.Bardsley@arm.com                    /* Clear the reference list. */
38610259SAndrew.Bardsley@arm.com                    std::vector<SimObject *> empty;
38710259SAndrew.Bardsley@arm.com                    ret = object_params->setSimObjectVector(param->name,
38810259SAndrew.Bardsley@arm.com                        empty);
38910259SAndrew.Bardsley@arm.com                } else {
39010259SAndrew.Bardsley@arm.com                    ret = object_params->setSimObject(param->name, NULL);
39110259SAndrew.Bardsley@arm.com                }
39210259SAndrew.Bardsley@arm.com
39310259SAndrew.Bardsley@arm.com                if (!ret) {
39410259SAndrew.Bardsley@arm.com                    throw Exception(instance_name, csprintf(
39510259SAndrew.Bardsley@arm.com                        "Error nulling sim object reference(s): %s",
39610259SAndrew.Bardsley@arm.com                        param->name));
39710259SAndrew.Bardsley@arm.com                }
39810259SAndrew.Bardsley@arm.com            }
39910259SAndrew.Bardsley@arm.com        }
40010259SAndrew.Bardsley@arm.com    } catch (Exception &) {
40110259SAndrew.Bardsley@arm.com        delete object_params;
40210259SAndrew.Bardsley@arm.com        throw;
40310259SAndrew.Bardsley@arm.com    }
40410259SAndrew.Bardsley@arm.com
40510259SAndrew.Bardsley@arm.com    objectParamsByName[instance_name] = object_params;
40610259SAndrew.Bardsley@arm.com
40710259SAndrew.Bardsley@arm.com    return object_params;
40810259SAndrew.Bardsley@arm.com}
40910259SAndrew.Bardsley@arm.com
41010259SAndrew.Bardsley@arm.comvoid
41110259SAndrew.Bardsley@arm.comCxxConfigManager::findAllObjects()
41210259SAndrew.Bardsley@arm.com{
41310259SAndrew.Bardsley@arm.com    std::vector<std::string> objects;
41410259SAndrew.Bardsley@arm.com    configFile.getAllObjectNames(objects);
41510259SAndrew.Bardsley@arm.com
41610259SAndrew.Bardsley@arm.com    /* Sort the object names to get a consistent initialisation order
41710259SAndrew.Bardsley@arm.com     *  even with config file reorganisation */
41810259SAndrew.Bardsley@arm.com    std::sort(objects.begin(), objects.end());
41910259SAndrew.Bardsley@arm.com
42010259SAndrew.Bardsley@arm.com    for (auto i = objects.begin(); i != objects.end(); ++i)
42110259SAndrew.Bardsley@arm.com        findObject(*i);
42210259SAndrew.Bardsley@arm.com
42310259SAndrew.Bardsley@arm.com    /* Set the traversal order for further iterators */
42410259SAndrew.Bardsley@arm.com    objectsInOrder.clear();
42510259SAndrew.Bardsley@arm.com    findTraversalOrder("root");
42610259SAndrew.Bardsley@arm.com}
42710259SAndrew.Bardsley@arm.com
42810259SAndrew.Bardsley@arm.comvoid
42910259SAndrew.Bardsley@arm.comCxxConfigManager::findTraversalOrder(const std::string &object_name)
43010259SAndrew.Bardsley@arm.com{
43110259SAndrew.Bardsley@arm.com    SimObject *object = findObject(object_name);
43210259SAndrew.Bardsley@arm.com
43310259SAndrew.Bardsley@arm.com    if (object) {
43410259SAndrew.Bardsley@arm.com        objectsInOrder.push_back(object);
43510259SAndrew.Bardsley@arm.com
43610259SAndrew.Bardsley@arm.com        std::vector<std::string> children;
43710259SAndrew.Bardsley@arm.com        configFile.getObjectChildren(object_name, children, true);
43810259SAndrew.Bardsley@arm.com
43910259SAndrew.Bardsley@arm.com        /* Visit all your children */
44010259SAndrew.Bardsley@arm.com        for (auto i = children.begin(); i != children.end(); ++i)
44110259SAndrew.Bardsley@arm.com            findTraversalOrder(*i);
44210259SAndrew.Bardsley@arm.com    }
44310259SAndrew.Bardsley@arm.com}
44410259SAndrew.Bardsley@arm.com
44510259SAndrew.Bardsley@arm.comvoid
44610259SAndrew.Bardsley@arm.comCxxConfigManager::bindAllPorts()
44710259SAndrew.Bardsley@arm.com{
44810259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
44910259SAndrew.Bardsley@arm.com        bindObjectPorts(*i);
45010259SAndrew.Bardsley@arm.com}
45110259SAndrew.Bardsley@arm.com
45210259SAndrew.Bardsley@arm.comvoid
45310259SAndrew.Bardsley@arm.comCxxConfigManager::bindPort(
45410259SAndrew.Bardsley@arm.com    SimObject *master_object, const std::string &master_port_name,
45510259SAndrew.Bardsley@arm.com    PortID master_port_index,
45610259SAndrew.Bardsley@arm.com    SimObject *slave_object, const std::string &slave_port_name,
45710259SAndrew.Bardsley@arm.com    PortID slave_port_index)
45810259SAndrew.Bardsley@arm.com{
45910259SAndrew.Bardsley@arm.com    MemObject *master_mem_object = dynamic_cast<MemObject *>(master_object);
46010259SAndrew.Bardsley@arm.com    MemObject *slave_mem_object = dynamic_cast<MemObject *>(slave_object);
46110259SAndrew.Bardsley@arm.com
46210259SAndrew.Bardsley@arm.com    if (!master_mem_object) {
46310259SAndrew.Bardsley@arm.com        throw Exception(master_object->name(), csprintf(
46410259SAndrew.Bardsley@arm.com            "Object isn't a mem object and so can have master port:"
46510259SAndrew.Bardsley@arm.com            " %s[%d]", master_port_name, master_port_index));
46610259SAndrew.Bardsley@arm.com    }
46710259SAndrew.Bardsley@arm.com
46810259SAndrew.Bardsley@arm.com    if (!slave_mem_object) {
46910259SAndrew.Bardsley@arm.com        throw Exception(slave_object->name(), csprintf(
47010259SAndrew.Bardsley@arm.com            "Object isn't a mem object and so can have slave port:"
47110259SAndrew.Bardsley@arm.com            " %s[%d]", slave_port_name, slave_port_index));
47210259SAndrew.Bardsley@arm.com    }
47310259SAndrew.Bardsley@arm.com
47410259SAndrew.Bardsley@arm.com    /* FIXME, check slave_port_index against connection_count
47510259SAndrew.Bardsley@arm.com     *  defined for port, need getPortConnectionCount and a
47610259SAndrew.Bardsley@arm.com     *  getCxxConfigDirectoryEntry for each object. */
47710259SAndrew.Bardsley@arm.com
47810259SAndrew.Bardsley@arm.com    /* It would be nice to be able to catch the errors from these calls. */
47910368SAndrew.Bardsley@arm.com    BaseMasterPort &master_port = master_mem_object->getMasterPort(
48010368SAndrew.Bardsley@arm.com        master_port_name, master_port_index);
48110259SAndrew.Bardsley@arm.com    BaseSlavePort &slave_port = slave_mem_object->getSlavePort(
48210259SAndrew.Bardsley@arm.com        slave_port_name, slave_port_index);
48310259SAndrew.Bardsley@arm.com
48410259SAndrew.Bardsley@arm.com    if (master_port.isConnected()) {
48510259SAndrew.Bardsley@arm.com        throw Exception(master_object->name(), csprintf(
48610259SAndrew.Bardsley@arm.com            "Master port: %s[%d] is already connected\n", master_port_name,
48710259SAndrew.Bardsley@arm.com            master_port_index));
48810259SAndrew.Bardsley@arm.com    }
48910259SAndrew.Bardsley@arm.com
49010259SAndrew.Bardsley@arm.com    if (slave_port.isConnected()) {
49110259SAndrew.Bardsley@arm.com        throw Exception(slave_object->name(), csprintf(
49210259SAndrew.Bardsley@arm.com            "Slave port: %s[%d] is already connected\n", slave_port_name,
49310259SAndrew.Bardsley@arm.com            slave_port_index));
49410259SAndrew.Bardsley@arm.com    }
49510259SAndrew.Bardsley@arm.com
49610259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Binding port %s.%s[%d]"
49710259SAndrew.Bardsley@arm.com        " to %s:%s[%d]\n",
49810259SAndrew.Bardsley@arm.com        master_object->name(), master_port_name, master_port_index,
49910259SAndrew.Bardsley@arm.com        slave_object->name(), slave_port_name, slave_port_index);
50010259SAndrew.Bardsley@arm.com
50110259SAndrew.Bardsley@arm.com    master_port.bind(slave_port);
50210259SAndrew.Bardsley@arm.com}
50310259SAndrew.Bardsley@arm.com
50410259SAndrew.Bardsley@arm.comvoid
50510259SAndrew.Bardsley@arm.comCxxConfigManager::bindMasterPort(SimObject *object,
50610259SAndrew.Bardsley@arm.com    const CxxConfigDirectoryEntry::PortDesc &port,
50710259SAndrew.Bardsley@arm.com    const std::vector<std::string> &peers)
50810259SAndrew.Bardsley@arm.com{
50910259SAndrew.Bardsley@arm.com    unsigned int master_port_index = 0;
51010259SAndrew.Bardsley@arm.com
51110259SAndrew.Bardsley@arm.com    for (auto peer_i = peers.begin(); peer_i != peers.end();
51210259SAndrew.Bardsley@arm.com        ++peer_i)
51310259SAndrew.Bardsley@arm.com    {
51410259SAndrew.Bardsley@arm.com        const std::string &peer = *peer_i;
51510259SAndrew.Bardsley@arm.com        std::string slave_object_name;
51610259SAndrew.Bardsley@arm.com        std::string slave_port_name;
51710259SAndrew.Bardsley@arm.com        unsigned int slave_port_index;
51810259SAndrew.Bardsley@arm.com
51910259SAndrew.Bardsley@arm.com        parsePort(peer, slave_object_name, slave_port_name,
52010259SAndrew.Bardsley@arm.com            slave_port_index);
52110259SAndrew.Bardsley@arm.com
52210259SAndrew.Bardsley@arm.com        std::string slave_instance_name = rename(slave_object_name);
52310259SAndrew.Bardsley@arm.com
52410259SAndrew.Bardsley@arm.com        if (objectsByName.find(slave_instance_name) == objectsByName.end()) {
52510259SAndrew.Bardsley@arm.com            throw Exception(object->name(), csprintf(
52610259SAndrew.Bardsley@arm.com                "Can't find slave port object: %s", slave_instance_name));
52710259SAndrew.Bardsley@arm.com        }
52810259SAndrew.Bardsley@arm.com
52910259SAndrew.Bardsley@arm.com        SimObject *slave_object = objectsByName[slave_instance_name];
53010259SAndrew.Bardsley@arm.com
53110259SAndrew.Bardsley@arm.com        bindPort(object, port.name, master_port_index,
53210259SAndrew.Bardsley@arm.com            slave_object, slave_port_name, slave_port_index);
53310259SAndrew.Bardsley@arm.com
53410259SAndrew.Bardsley@arm.com        master_port_index++;
53510259SAndrew.Bardsley@arm.com    }
53610259SAndrew.Bardsley@arm.com}
53710259SAndrew.Bardsley@arm.com
53810259SAndrew.Bardsley@arm.comvoid
53910259SAndrew.Bardsley@arm.comCxxConfigManager::bindObjectPorts(SimObject *object)
54010259SAndrew.Bardsley@arm.com{
54110259SAndrew.Bardsley@arm.com    /* We may want to separate object->name() from the name in configuration
54210259SAndrew.Bardsley@arm.com     *  later to allow (for example) repetition of fragments of configs */
54310259SAndrew.Bardsley@arm.com    const std::string &instance_name = object->name();
54410259SAndrew.Bardsley@arm.com
54510259SAndrew.Bardsley@arm.com    std::string object_name = unRename(instance_name);
54610259SAndrew.Bardsley@arm.com
54710259SAndrew.Bardsley@arm.com    std::string object_type;
54810259SAndrew.Bardsley@arm.com    const CxxConfigDirectoryEntry &entry =
54910259SAndrew.Bardsley@arm.com        findObjectType(object_name, object_type);
55010259SAndrew.Bardsley@arm.com
55110259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Binding ports of object: %s (%s)\n",
55210259SAndrew.Bardsley@arm.com        instance_name, object_type);
55310259SAndrew.Bardsley@arm.com
55410259SAndrew.Bardsley@arm.com    for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) {
55510259SAndrew.Bardsley@arm.com        const CxxConfigDirectoryEntry::PortDesc *port = (*i).second;
55610259SAndrew.Bardsley@arm.com
55710259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Binding port: %s.%s\n", instance_name,
55810259SAndrew.Bardsley@arm.com            port->name);
55910259SAndrew.Bardsley@arm.com
56010259SAndrew.Bardsley@arm.com        std::vector<std::string> peers;
56110259SAndrew.Bardsley@arm.com        configFile.getPortPeers(object_name, port->name, peers);
56210259SAndrew.Bardsley@arm.com
56310259SAndrew.Bardsley@arm.com        /* Only handle master ports as binding only needs to happen once
56410259SAndrew.Bardsley@arm.com         *  for each observed pair of ports */
56510259SAndrew.Bardsley@arm.com        if (port->isMaster) {
56610259SAndrew.Bardsley@arm.com            if (!port->isVector && peers.size() > 1) {
56710259SAndrew.Bardsley@arm.com                throw Exception(instance_name, csprintf(
56810259SAndrew.Bardsley@arm.com                    "Too many connections to non-vector port %s (%d)\n",
56910259SAndrew.Bardsley@arm.com                    port->name, peers.size()));
57010259SAndrew.Bardsley@arm.com            }
57110259SAndrew.Bardsley@arm.com
57210259SAndrew.Bardsley@arm.com            bindMasterPort(object, *port, peers);
57310259SAndrew.Bardsley@arm.com        }
57410259SAndrew.Bardsley@arm.com    }
57510259SAndrew.Bardsley@arm.com}
57610259SAndrew.Bardsley@arm.com
57710259SAndrew.Bardsley@arm.comvoid
57810259SAndrew.Bardsley@arm.comCxxConfigManager::parsePort(const std::string &inp,
57910259SAndrew.Bardsley@arm.com    std::string &path, std::string &port, unsigned int &index)
58010259SAndrew.Bardsley@arm.com{
58110259SAndrew.Bardsley@arm.com    std::size_t dot_i = inp.rfind('.');
58210259SAndrew.Bardsley@arm.com    std::size_t open_square_i = inp.rfind('[');
58310259SAndrew.Bardsley@arm.com
58410259SAndrew.Bardsley@arm.com    if (dot_i == std::string::npos) {
58510259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Bad port string: %s\n", inp);
58610259SAndrew.Bardsley@arm.com        path = "";
58710259SAndrew.Bardsley@arm.com        port = "";
58810259SAndrew.Bardsley@arm.com        index = 0;
58910259SAndrew.Bardsley@arm.com    } else {
59010259SAndrew.Bardsley@arm.com        path = std::string(inp, 0, dot_i);
59110259SAndrew.Bardsley@arm.com
59210259SAndrew.Bardsley@arm.com        if (open_square_i == std::string::npos) {
59310259SAndrew.Bardsley@arm.com            /* Singleton port */
59410259SAndrew.Bardsley@arm.com            port = std::string(inp, dot_i + 1, inp.length() - dot_i);
59510259SAndrew.Bardsley@arm.com            index = 0;
59610259SAndrew.Bardsley@arm.com        } else {
59710259SAndrew.Bardsley@arm.com            /* Vectored port elemnt */
59810259SAndrew.Bardsley@arm.com            port = std::string(inp, dot_i + 1, (open_square_i - 1) - dot_i);
59910259SAndrew.Bardsley@arm.com            index = std::atoi(inp.c_str() + open_square_i + 1);
60010259SAndrew.Bardsley@arm.com        }
60110259SAndrew.Bardsley@arm.com    }
60210259SAndrew.Bardsley@arm.com}
60310259SAndrew.Bardsley@arm.com
60410259SAndrew.Bardsley@arm.comvoid
60510259SAndrew.Bardsley@arm.comCxxConfigManager::forEachObject(void (SimObject::*mem_func)())
60610259SAndrew.Bardsley@arm.com{
60710259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i)
60810259SAndrew.Bardsley@arm.com        ((*i)->*mem_func)();
60910259SAndrew.Bardsley@arm.com}
61010259SAndrew.Bardsley@arm.com
61110259SAndrew.Bardsley@arm.comvoid
61210259SAndrew.Bardsley@arm.comCxxConfigManager::instantiate(bool build_all)
61310259SAndrew.Bardsley@arm.com{
61410259SAndrew.Bardsley@arm.com    if (build_all) {
61510259SAndrew.Bardsley@arm.com        findAllObjects();
61610259SAndrew.Bardsley@arm.com        bindAllPorts();
61710259SAndrew.Bardsley@arm.com    }
61810259SAndrew.Bardsley@arm.com
61910259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Initialising all objects\n");
62010259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::init);
62110259SAndrew.Bardsley@arm.com
62210259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Registering stats\n");
62310259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::regStats);
62410259SAndrew.Bardsley@arm.com
62510259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Registering probe points\n");
62610259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::regProbePoints);
62710259SAndrew.Bardsley@arm.com
62810259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Connecting probe listeners\n");
62910259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::regProbeListeners);
63010259SAndrew.Bardsley@arm.com}
63110259SAndrew.Bardsley@arm.com
63210259SAndrew.Bardsley@arm.comvoid
63310259SAndrew.Bardsley@arm.comCxxConfigManager::initState()
63410259SAndrew.Bardsley@arm.com{
63510259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Calling initState on all objects\n");
63610259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::initState);
63710259SAndrew.Bardsley@arm.com}
63810259SAndrew.Bardsley@arm.com
63910259SAndrew.Bardsley@arm.comvoid
64010259SAndrew.Bardsley@arm.comCxxConfigManager::startup()
64110259SAndrew.Bardsley@arm.com{
64210259SAndrew.Bardsley@arm.com    DPRINTF(CxxConfig, "Starting up all objects\n");
64310259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::startup);
64410259SAndrew.Bardsley@arm.com}
64510259SAndrew.Bardsley@arm.com
64610259SAndrew.Bardsley@arm.comunsigned int
64710259SAndrew.Bardsley@arm.comCxxConfigManager::drain(DrainManager *drain_manager)
64810259SAndrew.Bardsley@arm.com{
64910259SAndrew.Bardsley@arm.com    unsigned int ret = 0;
65010259SAndrew.Bardsley@arm.com
65110259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i)
65210259SAndrew.Bardsley@arm.com        ret += (*i)->drain(drain_manager);
65310259SAndrew.Bardsley@arm.com
65410259SAndrew.Bardsley@arm.com    return ret;
65510259SAndrew.Bardsley@arm.com}
65610259SAndrew.Bardsley@arm.com
65710259SAndrew.Bardsley@arm.comvoid
65810259SAndrew.Bardsley@arm.comCxxConfigManager::drainResume()
65910259SAndrew.Bardsley@arm.com{
66010259SAndrew.Bardsley@arm.com    forEachObject(&SimObject::drainResume);
66110259SAndrew.Bardsley@arm.com}
66210259SAndrew.Bardsley@arm.com
66310259SAndrew.Bardsley@arm.comvoid
66410259SAndrew.Bardsley@arm.comCxxConfigManager::serialize(std::ostream &os)
66510259SAndrew.Bardsley@arm.com{
66610259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i) {
66710259SAndrew.Bardsley@arm.com        // (*i)->nameOut(os); FIXME, change access spec. for nameOut
66810259SAndrew.Bardsley@arm.com        os << '[' << (*i)->name() << "]\n";
66910259SAndrew.Bardsley@arm.com        (*i)->serialize(os);
67010259SAndrew.Bardsley@arm.com    }
67110259SAndrew.Bardsley@arm.com}
67210259SAndrew.Bardsley@arm.com
67310259SAndrew.Bardsley@arm.comvoid
67410259SAndrew.Bardsley@arm.comCxxConfigManager::loadState(Checkpoint *checkpoint)
67510259SAndrew.Bardsley@arm.com{
67610259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i)
67710259SAndrew.Bardsley@arm.com        (*i)->loadState(checkpoint);
67810259SAndrew.Bardsley@arm.com}
67910259SAndrew.Bardsley@arm.com
68010259SAndrew.Bardsley@arm.comvoid
68110259SAndrew.Bardsley@arm.comCxxConfigManager::deleteObjects()
68210259SAndrew.Bardsley@arm.com{
68310259SAndrew.Bardsley@arm.com    for (auto i = objectsInOrder.rbegin(); i != objectsInOrder.rend(); ++i) {
68410259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Freeing sim object: %s\n", (*i)->name());
68510259SAndrew.Bardsley@arm.com        delete *i;
68610259SAndrew.Bardsley@arm.com    }
68710259SAndrew.Bardsley@arm.com
68810259SAndrew.Bardsley@arm.com    for (auto i = objectParamsByName.rbegin();
68910259SAndrew.Bardsley@arm.com        i != objectParamsByName.rend(); ++i)
69010259SAndrew.Bardsley@arm.com    {
69110259SAndrew.Bardsley@arm.com        CxxConfigParams *params = (*i).second;
69210259SAndrew.Bardsley@arm.com
69310259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Freeing sim object params: %s\n",
69410259SAndrew.Bardsley@arm.com            params->getName());
69510259SAndrew.Bardsley@arm.com        delete params;
69610259SAndrew.Bardsley@arm.com    }
69710259SAndrew.Bardsley@arm.com
69810259SAndrew.Bardsley@arm.com    objectsInOrder.clear();
69910259SAndrew.Bardsley@arm.com    objectsByName.clear();
70010259SAndrew.Bardsley@arm.com}
70110259SAndrew.Bardsley@arm.com
70210259SAndrew.Bardsley@arm.comvoid
70310259SAndrew.Bardsley@arm.comCxxConfigManager::setParam(const std::string &object_name,
70410259SAndrew.Bardsley@arm.com    const std::string &param_name, const std::string &param_value)
70510259SAndrew.Bardsley@arm.com{
70610259SAndrew.Bardsley@arm.com    CxxConfigParams *params = findObjectParams(object_name);
70710259SAndrew.Bardsley@arm.com
70810259SAndrew.Bardsley@arm.com    if (!params->setParam(param_name, param_value, flags)) {
70910259SAndrew.Bardsley@arm.com        throw Exception(object_name, csprintf("Bad parameter value:"
71010259SAndrew.Bardsley@arm.com            " .%s=X=\"%s\"", param_name, param_value));
71110259SAndrew.Bardsley@arm.com    } else {
71210259SAndrew.Bardsley@arm.com        std::string instance_name = rename(object_name);
71310259SAndrew.Bardsley@arm.com
71410259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n",
71510259SAndrew.Bardsley@arm.com            instance_name, param_name, param_value);
71610259SAndrew.Bardsley@arm.com    }
71710259SAndrew.Bardsley@arm.com}
71810259SAndrew.Bardsley@arm.com
71910259SAndrew.Bardsley@arm.comvoid
72010259SAndrew.Bardsley@arm.comCxxConfigManager::setParamVector(const std::string &object_name,
72110259SAndrew.Bardsley@arm.com    const std::string &param_name,
72210259SAndrew.Bardsley@arm.com    const std::vector<std::string> &param_values)
72310259SAndrew.Bardsley@arm.com{
72410259SAndrew.Bardsley@arm.com    CxxConfigParams *params = findObjectParams(object_name);
72510259SAndrew.Bardsley@arm.com
72610259SAndrew.Bardsley@arm.com    if (!params->setParamVector(param_name, param_values, flags)) {
72710259SAndrew.Bardsley@arm.com        throw Exception(object_name, csprintf("Bad vector parameter value:"
72810259SAndrew.Bardsley@arm.com            " .%s=X=\"%s\"", param_name, formatParamList(param_values)));
72910259SAndrew.Bardsley@arm.com    } else {
73010259SAndrew.Bardsley@arm.com        std::string instance_name = rename(object_name);
73110259SAndrew.Bardsley@arm.com
73210259SAndrew.Bardsley@arm.com        DPRINTF(CxxConfig, "Setting parameter %s.%s=\"%s\"\n",
73310259SAndrew.Bardsley@arm.com            instance_name, param_name, formatParamList(param_values));
73410259SAndrew.Bardsley@arm.com    }
73510259SAndrew.Bardsley@arm.com}
73610259SAndrew.Bardsley@arm.com
73710259SAndrew.Bardsley@arm.comvoid CxxConfigManager::addRenaming(const Renaming &renaming)
73810259SAndrew.Bardsley@arm.com{
73910259SAndrew.Bardsley@arm.com    renamings.push_back(renaming);
74010259SAndrew.Bardsley@arm.com}
74110259SAndrew.Bardsley@arm.com