1# To Build 2Need `meson` and `ninja`. Alternatively, source an OpenBMC ARM/x86 SDK. 3``` 4meson build && ninja -C build 5``` 6## To run unit tests 7The simplest way of running the tests is as described by the meson man page: 8``` 9meson builddir && meson test -C builddir 10``` 11 12Alternatively, tests can be run in the OpenBMC CI docker container, or with an 13OpenBMC x86 sdk(see below for x86 steps). 14``` 15meson -Doe-sdk=enabled build 16ninja -C build test 17``` 18 19# Code Organization 20At a high-level, code in this repository belongs to one of the following three 21components. 22 23## libpldm 24This is a library which deals with the encoding and decoding of PLDM messages. 25It should be possible to use this library by projects other than OpenBMC, and 26hence certain constraints apply to it: 27- keeping it light weight 28- implementation in C 29- minimal dynamic memory allocations 30- endian-safe 31- no OpenBMC specific dependencies 32 33Source files are named according to the PLDM Type, for eg base.[h/c], fru.[h/c], 34etc. 35 36Given a PLDM command "foo", the library will provide the following API: 37For the Requester function: 38``` 39encode_foo_req() - encode a foo request 40decode_foo_resp() - decode a response to foo 41``` 42For the Responder function: 43``` 44decode_foo_req() - decode a foo request 45encode_foo_resp() - encode a response to foo 46``` 47The library also provides API to pack and unpack PLDM headers. 48 49## libpldmresponder 50This library provides handlers for incoming PLDM request messages. It provides 51for a registration as well as a plug-in mechanism. The library is implemented in 52modern C++, and handles OpenBMC's platform specifics. 53 54The handlers are of the form 55``` 56Response handler(Request payload, size_t payloadLen) 57``` 58 59Source files are named according to the PLDM Type, for eg base.[hpp/cpp], 60fru.[hpp/cpp], etc. 61 62 63## OEM/vendor-specific functions 64This will support OEM or vendor-specific functions and semantic information. 65Following directory structure has to be used: 66``` 67 pldm repo 68 |---- oem 69 |----<oem_name> 70 |----libpldm 71 |----<oem based encoding and decoding files> 72 |----libpldmresponder 73 |---<oem based handler files> 74 75``` 76<oem_name> - This folder must be created with the name of the OEM/vendor 77in lower case. Folders named libpldm and libpldmresponder must be created under 78the folder <oem_name> 79 80Files having the oem functionality for the libpldm library should be placed 81under the folder oem/<oem_name>/libpldm. They must be adhering to the rules 82mentioned under the libpldm section above. 83 84Files having the oem functionality for the libpldmresponder library should be 85placed under the folder oem/<oem_name>/libpldmresponder. They must be adhering 86to the rules mentioned under the libpldmresponder section above. 87 88Once the above is done a meson option has to be created in 89`pldm/meson_options.txt` with its mapped compiler flag to enable conditional 90compilation. 91 92For consistency would recommend using "oem-<oem_name>". 93 94The `pldm/meson.build` and the corresponding source file(s) will need to 95incorporate the logic of adding its mapped compiler flag to allow conditional 96compilation of the code. 97 98## pldmtool 99For more information on pldmtool please refer to plmdtool/README.md. 100 101## TODO 102Consider hosting libpldm above in a repo of its own, probably even outside the 103OpenBMC project? A separate repo would enable something like git submodule. 104 105# Flows 106This section documents important code flow paths. 107 108## BMC as PLDM responder 109a) PLDM daemon receives PLDM request message from underlying transport (MCTP). 110 111b) PLDM daemon routes message to message handler, based on the PLDM command. 112 113c) Message handler decodes request payload into various field(s) of the request 114 message. It can make use of a decode_foo_req() API, and doesn't have to 115 perform deserialization of the request payload by itself. 116 117d) Message handler works with the request field(s) and generates response 118 field(s). 119 120e) Message handler prepares a response message. It can make use of an 121 encode_foo_resp() API, and doesn't have to perform the serialization of the 122 response field(s) by itself. 123 124f) The PLDM daemon sends the response message prepared at step e) to the remote 125 PLDM device. 126 127## BMC as PLDM requester 128a) A BMC PLDM requester app prepares a PLDM request message. There would be 129 several requester apps (based on functionality/PLDM remote device). Each of 130 them needn't bother with the serialization of request field(s), and can 131 instead make use of an encode_foo_req() API. 132 133b) BMC requester app requests PLDM daemon to send the request message to remote 134 PLDM device. 135 136c) Once the PLDM daemon receives a corresponding response message, it notifies 137 the requester app. 138 139d) The requester app has to work with the response field(s). It can make use of 140 a decode_foo_resp() API to deserialize the response message. 141 142# PDR Implementation 143While PLDM Platform Descriptor Records (PDRs) are mostly static information, 144they can vary across platforms and systems. For this reason, platform specific 145PDR information is encoded in platform specific JSON files. JSON files must be 146named based on the PDR type number. For example a state effecter PDR JSON file 147will be named 11.json. The JSON files may also include information to enable 148additional processing (apart from PDR creation) for specific PDR types, for eg 149mapping an effecter id to a D-Bus object. 150 151The PLDM responder implementation finds and parses PDR JSON files to create the 152PDR repository. Platform specific PDR modifications would likely just result in 153JSON updates. New PDR type support would require JSON updates as well as PDR 154generation code. The PDR generator is a map of PDR Type -> C++ lambda to create 155PDR entries for that type based on the JSON, and to update the central PDR repo. 156