Skip to content

Commit 2ab7341

Browse files
committed
service: device-tree node vpd to d-bus hw id data
A daemon for transferring Viable Product Data (VPD) from device-tree nodes to D-Bus as described in the design doc @ https://gerrit.openbmc.org/c/openbmc/docs/+/66369 and discussed in this Technical Oversight Forum topic @ openbmc/technical-oversight-forum#38 Tested: Ensure 'model' and/or 'serial-number' nodes are populated in /proc/device-tree. Can be hardcoded into platform DTS via linux-kernel recipe if needed. ''' After OBMC boot, calling > busctl introspect xyz.openbmc_project.MachineContext /xyz/openbmc_project/MachineContext produces the following output: NAME TYPE SIGNATURE RESULT/VALUE FLAGS ... xyz.openbmc_project.Inventory.Decorator.Asset interface - - - .BuildDate property s "" emits-change writable .Manufacturer property s "" emits-change writable .Model property s "hpe,dl360" emits-change writable .PartNumber property s "" emits-change writable .SerialNumber property s "t5texpl" emits-change writable ... Note: Writing to one of these properties will update the property on D-Bus without affecting the underlying device-tree node. An 'updated' event will be fired, so Entity-Manager probes monitoring a given property would recognize the new value and key off it. ''' Change-Id: Id52d1fc3b26010c864c7e64d3dfdf0a2b5de9294 Signed-off-by: Chris Sides <[email protected]>
1 parent 28649a9 commit 2ab7341

10 files changed

+169
-2
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
build*/*
22
subprojects/*
33
!subprojects/*.wrap
4-
subprojects/phosphor-dbus-interfaces.wrap
54
!subprojects/.clang-tidy
65
!subprojects/.clang-format

meson.build

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ if get_option('fru-device')
3434
i2c = cpp.find_library('i2c')
3535
endif
3636

37+
if get_option('devicetree-vpd')
38+
phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces', include_type: 'system')
39+
endif
40+
3741
nlohmann_json_dep = dependency('nlohmann_json', include_type: 'system')
3842
sdbusplus = dependency('sdbusplus', include_type: 'system')
3943
phosphor_logging_dep = dependency('phosphor-logging')

meson_options.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ option(
22
'tests', type: 'feature', description: 'Build tests.',
33
)
44
option(
5-
'fru-device', type: 'boolean', description: 'Build fru-device.',
5+
'fru-device', type: 'boolean', description: 'Build fru-device VPD parser.',
66
)
77
option(
88
'fru-device-resizefru', value : false, type: 'boolean', description: 'Allow FruDevice to resize FRU areas.',
99
)
10+
option(
11+
'devicetree-vpd', type: 'boolean', description: 'Build device-tree VPD parser'
12+
)
1013
option(
1114
'validate-json', type: 'boolean', value: true, description: 'Run JSON schema validation during the build.',
1215
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[Unit]
2+
Description=Makes data from device-tree nodes avaliable thru D-Bus
3+
After=dbus.service
4+
5+
[Service]
6+
ExecStart=/usr/libexec/entity-manager/devicetree-vpd-parser
7+
Type=dbus
8+
BusName=xyz.openbmc_project.MachineContext
9+
10+
[Install]
11+
WantedBy=basic.target

service_files/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
unit_files = [
22
['xyz.openbmc_project.FruDevice.service', 'fru-device'],
33
['xyz.openbmc_project.EntityManager.service', ''],
4+
['devicetree-vpd-parser.service', 'devicetree-vpd'],
45
]
56

67
foreach u : unit_files

src/devicetree_vpd_parser.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "machine_context.hpp"
2+
3+
#include <memory>
4+
5+
int main()
6+
{
7+
static constexpr auto reqDBusPath = "/xyz/openbmc_project/MachineContext";
8+
static constexpr auto reqDBusName = "xyz.openbmc_project.MachineContext";
9+
10+
/*Note: OpenBMC convention typically has service name = bus name,
11+
where the bus name is representative of the underlying hardware.
12+
13+
In the case of MachineContext, the BMC is not gathering data from
14+
specific hardware, but is instead parsing device-tree nodes for
15+
context about the hardware OpenBMC is running on.
16+
17+
Because the VPD data being parsed is coming from device-tree,
18+
the daemon and matching service name reflect that.
19+
20+
Because the parsed data represents 'machine context' data,
21+
the bus name and associated path the daemon writes to
22+
reflects that instead.
23+
*/
24+
25+
sdbusplus::async::context ctx;
26+
sdbusplus::server::manager_t manager{ctx, reqDBusPath};
27+
28+
std::unique_ptr<MachineContext> mc = nullptr;
29+
if (MachineContext::keyNodeExists())
30+
{
31+
mc = std::make_unique<MachineContext>(ctx, reqDBusPath);
32+
mc->populateFromDeviceTree();
33+
}
34+
35+
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
36+
ctx.spawn([](sdbusplus::async::context& ctx) -> sdbusplus::async::task<> {
37+
ctx.request_name(reqDBusName);
38+
co_return;
39+
}(ctx));
40+
41+
ctx.run();
42+
43+
return 0;
44+
};

src/machine_context.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
// Copyright (c) 2024 Hewlett Packard Enterprise
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
*/
16+
17+
#include "machine_context.hpp"
18+
19+
#include <filesystem>
20+
#include <fstream>
21+
22+
void MachineContext::populateFromDeviceTree()
23+
{
24+
std::string nodeVal;
25+
std::ifstream vpdStream(nodeBasePath + std::string("model"));
26+
if (vpdStream && std::getline(vpdStream, nodeVal))
27+
{
28+
MachineContext::Asset::model(nodeVal);
29+
vpdStream.close();
30+
}
31+
32+
vpdStream.open(nodeBasePath + std::string("serial-number"));
33+
if (vpdStream && std::getline(vpdStream, nodeVal))
34+
{
35+
MachineContext::Asset::serial_number(nodeVal);
36+
vpdStream.close();
37+
}
38+
};
39+
40+
bool MachineContext::keyNodeExists()
41+
{
42+
std::filesystem::path nodePath{nodeBasePath + std::string("model")};
43+
44+
return std::filesystem::exists(nodePath);
45+
};

src/machine_context.hpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
// Copyright (c) 2024 Hewlett Packard Enterprise
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <sdbusplus/async.hpp>
20+
#include <xyz/openbmc_project/Inventory/Decorator/Asset/aserver.hpp>
21+
22+
class MachineContext :
23+
public sdbusplus::aserver::xyz::openbmc_project::inventory::decorator::
24+
Asset<MachineContext>
25+
{
26+
public:
27+
explicit MachineContext(sdbusplus::async::context& ctx, auto path) :
28+
sdbusplus::aserver::xyz::openbmc_project::inventory::decorator::Asset<
29+
MachineContext>(ctx, path) {};
30+
31+
void populateFromDeviceTree();
32+
33+
static bool keyNodeExists();
34+
35+
private:
36+
static constexpr auto nodeBasePath = "/proc/device-tree/";
37+
};

src/meson.build

+16
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,19 @@ if get_option('fru-device')
4949
install_dir: installdir,
5050
)
5151
endif
52+
53+
if get_option('devicetree-vpd')
54+
cpp_args_fd = cpp_args
55+
executable(
56+
'devicetree-vpd-parser',
57+
'machine_context.cpp',
58+
'devicetree_vpd_parser.cpp',
59+
cpp_args: cpp_args_fd,
60+
dependencies: [
61+
sdbusplus,
62+
phosphor_dbus_interfaces_dep,
63+
],
64+
install: true,
65+
install_dir: installdir,
66+
)
67+
endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
[wrap-git]
3+
url = https://github.com/openbmc/phosphor-dbus-interfaces.git
4+
revision = HEAD
5+
6+
[provide]
7+
phosphor-dbus-interfaces = phosphor_dbus_interfaces_dep

0 commit comments

Comments
 (0)