xref: /openbmc/fb-ipmi-oem/src/usb-dbg.cpp (revision 3add478ba5b825e2d800a5b6b8a98d409110e42e)
1e7d23d0eSVijay Khemka /*
2e7d23d0eSVijay Khemka  * Copyright (c)  2018-present Facebook. All Rights Reserved.
3e7d23d0eSVijay Khemka  *
4e7d23d0eSVijay Khemka  * Licensed under the Apache License, Version 2.0 (the "License");
5e7d23d0eSVijay Khemka  * you may not use this file except in compliance with the License.
6e7d23d0eSVijay Khemka  * You may obtain a copy of the License at
7e7d23d0eSVijay Khemka  *
8e7d23d0eSVijay Khemka  *      http://www.apache.org/licenses/LICENSE-2.0
9e7d23d0eSVijay Khemka  *
10e7d23d0eSVijay Khemka  * Unless required by applicable law or agreed to in writing, software
11e7d23d0eSVijay Khemka  * distributed under the License is distributed on an "AS IS" BASIS,
12e7d23d0eSVijay Khemka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e7d23d0eSVijay Khemka  * See the License for the specific language governing permissions and
14e7d23d0eSVijay Khemka  * limitations under the License.
15e7d23d0eSVijay Khemka  */
16e7d23d0eSVijay Khemka 
174ec80567SJayashree Dhanapal #include <commandutils.hpp>
182405ae98SPatrick Williams #include <usb-dbg.hpp>
19e7d23d0eSVijay Khemka 
20e7d23d0eSVijay Khemka namespace ipmi
21e7d23d0eSVijay Khemka {
22e7d23d0eSVijay Khemka 
23e7d23d0eSVijay Khemka ipmi_ret_t getNetworkData(uint8_t lan_param, char* data);
24d8d95a3dSDaniel Hsu std::string getMotherBoardFruName();
25e7d23d0eSVijay Khemka int8_t getFruData(std::string& serial, std::string& name);
2610ff3d86SKarthikeyan Pasupathi int8_t sysConfig(std::vector<std::string>& data, size_t pos);
27d532fecaSKarthikeyan Pasupathi int8_t procInfo(std::string& result, size_t pos);
28e7d23d0eSVijay Khemka 
2939836ffaSKarthikeyan Pasupathi bool isMultiHostPlatform();
3039836ffaSKarthikeyan Pasupathi 
3139836ffaSKarthikeyan Pasupathi /* Declare Host Selector interface and path */
3239836ffaSKarthikeyan Pasupathi namespace selector
3339836ffaSKarthikeyan Pasupathi {
3439836ffaSKarthikeyan Pasupathi const std::string path = "/xyz/openbmc_project/Chassis/Buttons/HostSelector";
3539836ffaSKarthikeyan Pasupathi const std::string interface =
36cff150e3SPotin Lai     "xyz.openbmc_project.Chassis.Buttons.HostSelector";
3739836ffaSKarthikeyan Pasupathi } // namespace selector
3839836ffaSKarthikeyan Pasupathi 
39427b2762SVijay Khemka /* Declare storage functions used here */
40427b2762SVijay Khemka namespace storage
41427b2762SVijay Khemka {
42427b2762SVijay Khemka int getSensorValue(std::string&, double&);
4358bd5d84SVijay Khemka int getSensorUnit(std::string&, std::string&);
442ca4aa0eSDelphine CC Chiu int getSensorThreshold(std::string&, std::string&);
4558bd5d84SVijay Khemka } // namespace storage
46427b2762SVijay Khemka 
477bb4592aSDelphine CC Chiu namespace boot
487bb4592aSDelphine CC Chiu {
497bb4592aSDelphine CC Chiu std::tuple<std::string, std::string> objPath(size_t id);
507bb4592aSDelphine CC Chiu void setBootOrder(std::string bootObjPath, const std::vector<uint8_t>& bootSeq,
517bb4592aSDelphine CC Chiu                   std::string hostName);
527bb4592aSDelphine CC Chiu void getBootOrder(std::string bootObjPath, std::vector<uint8_t>& bootSeq,
537bb4592aSDelphine CC Chiu                   std::string hostName);
547bb4592aSDelphine CC Chiu } // namespace boot
557bb4592aSDelphine CC Chiu 
getMaxHostPosition(size_t & maxPosition)56e1ff81faSKarthikeyan Pasupathi void getMaxHostPosition(size_t& maxPosition)
57f24c78e8SPotin Lai {
58f24c78e8SPotin Lai     try
59f24c78e8SPotin Lai     {
60f24c78e8SPotin Lai         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
61010dee04SPatrick Williams         std::string service =
62010dee04SPatrick Williams             getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
63010dee04SPatrick Williams         Value variant =
64010dee04SPatrick Williams             getDbusProperty(*dbus, service, ipmi::selector::path,
65010dee04SPatrick Williams                             ipmi::selector::interface, "MaxPosition");
66e1ff81faSKarthikeyan Pasupathi         maxPosition = std::get<size_t>(variant);
67f24c78e8SPotin Lai     }
68e1ff81faSKarthikeyan Pasupathi     catch (const std::exception& e)
69f24c78e8SPotin Lai     {
70e1ff81faSKarthikeyan Pasupathi         lg2::error("Unable to get max host position - {MAXPOSITION}",
71e1ff81faSKarthikeyan Pasupathi                    "MAXPOSITION", maxPosition);
72e1ff81faSKarthikeyan Pasupathi         throw e;
73e1ff81faSKarthikeyan Pasupathi     }
74f24c78e8SPotin Lai }
75f24c78e8SPotin Lai 
getSelectorPosition(size_t & hostPosition)76e1ff81faSKarthikeyan Pasupathi void getSelectorPosition(size_t& hostPosition)
77e1ff81faSKarthikeyan Pasupathi {
78e1ff81faSKarthikeyan Pasupathi     try
7939836ffaSKarthikeyan Pasupathi     {
8039836ffaSKarthikeyan Pasupathi         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
81010dee04SPatrick Williams         std::string service =
82010dee04SPatrick Williams             getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
8339836ffaSKarthikeyan Pasupathi         Value variant = getDbusProperty(*dbus, service, ipmi::selector::path,
84e1ff81faSKarthikeyan Pasupathi                                         ipmi::selector::interface, "Position");
85e1ff81faSKarthikeyan Pasupathi         hostPosition = std::get<size_t>(variant);
86e1ff81faSKarthikeyan Pasupathi     }
87e1ff81faSKarthikeyan Pasupathi     catch (const std::exception& e)
88e1ff81faSKarthikeyan Pasupathi     {
89e1ff81faSKarthikeyan Pasupathi         lg2::error("Unable to get host position - {POSITION}", "POSITION",
90e1ff81faSKarthikeyan Pasupathi                    hostPosition);
91e1ff81faSKarthikeyan Pasupathi         throw e;
92e1ff81faSKarthikeyan Pasupathi     }
9339836ffaSKarthikeyan Pasupathi }
9439836ffaSKarthikeyan Pasupathi 
95e7d23d0eSVijay Khemka static int panelNum = (sizeof(panels) / sizeof(struct ctrl_panel)) - 1;
96e7d23d0eSVijay Khemka 
97e7d23d0eSVijay Khemka /* Returns the FRU the hand-switch is switched to. If it is switched to BMC
98e7d23d0eSVijay Khemka  * it returns FRU_ALL. Note, if in err, it returns FRU_ALL */
plat_get_fru_sel()9939836ffaSKarthikeyan Pasupathi static size_t plat_get_fru_sel()
10039836ffaSKarthikeyan Pasupathi {
10139836ffaSKarthikeyan Pasupathi     size_t position;
10239836ffaSKarthikeyan Pasupathi     bool platform = isMultiHostPlatform();
10339836ffaSKarthikeyan Pasupathi     if (platform == true)
10439836ffaSKarthikeyan Pasupathi     {
105e1ff81faSKarthikeyan Pasupathi         getSelectorPosition(position);
10639836ffaSKarthikeyan Pasupathi         if (position == BMC_POSITION)
10739836ffaSKarthikeyan Pasupathi         {
10839836ffaSKarthikeyan Pasupathi             return FRU_ALL;
10939836ffaSKarthikeyan Pasupathi         }
11039836ffaSKarthikeyan Pasupathi     }
11139836ffaSKarthikeyan Pasupathi     else
112e7d23d0eSVijay Khemka     {
113e1ff81faSKarthikeyan Pasupathi         /* For Tiogapass it just return 1,
114e1ff81faSKarthikeyan Pasupathi          *  can modify to support more platform */
11539836ffaSKarthikeyan Pasupathi         position = 1;
11639836ffaSKarthikeyan Pasupathi     }
11739836ffaSKarthikeyan Pasupathi     return position;
118e7d23d0eSVijay Khemka }
119e7d23d0eSVijay Khemka 
120e7d23d0eSVijay Khemka // return 0 on seccuess
init(size_t size)12113ce3793SPatrick Williams void frame::init(size_t size)
122e7d23d0eSVijay Khemka {
123e7d23d0eSVijay Khemka     // Reset status
124e7d23d0eSVijay Khemka     idx_head = idx_tail = 0;
125e7d23d0eSVijay Khemka     lines = 0;
126e7d23d0eSVijay Khemka     esc_sts = 0;
127e7d23d0eSVijay Khemka     pages = 1;
128e7d23d0eSVijay Khemka 
12913ce3793SPatrick Williams     if (buf != nullptr && max_size == size)
130e7d23d0eSVijay Khemka     {
13113ce3793SPatrick Williams         return;
132e7d23d0eSVijay Khemka     }
133e7d23d0eSVijay Khemka 
13413ce3793SPatrick Williams     if (buf != nullptr && max_size != size)
135e7d23d0eSVijay Khemka     {
136e7d23d0eSVijay Khemka         delete[] buf;
137e7d23d0eSVijay Khemka     }
138e7d23d0eSVijay Khemka     // Initialize Configuration
139e7d23d0eSVijay Khemka     title[0] = '\0';
140e7d23d0eSVijay Khemka     buf = new char[size];
141e7d23d0eSVijay Khemka     max_size = size;
142e7d23d0eSVijay Khemka     max_page = size;
143e7d23d0eSVijay Khemka     line_per_page = 7;
144e7d23d0eSVijay Khemka     line_width = 16;
14513ce3793SPatrick Williams     overwrite = false;
146e7d23d0eSVijay Khemka 
14713ce3793SPatrick Williams     return;
148e7d23d0eSVijay Khemka }
149e7d23d0eSVijay Khemka 
150e7d23d0eSVijay Khemka // return 0 on seccuess
append(const std::string & str,size_t indent)15113ce3793SPatrick Williams void frame::append(const std::string& str, size_t indent)
152e7d23d0eSVijay Khemka {
15313ce3793SPatrick Williams     for (auto ch : parse(str, indent))
154e7d23d0eSVijay Khemka     {
155e7d23d0eSVijay Khemka         if (isFull())
156e7d23d0eSVijay Khemka         {
157e7d23d0eSVijay Khemka             if (overwrite)
158e7d23d0eSVijay Khemka             {
159e7d23d0eSVijay Khemka                 if (buf[idx_head] == LINE_DELIMITER)
160e7d23d0eSVijay Khemka                     lines--;
161e7d23d0eSVijay Khemka                 idx_head = (idx_head + 1) % max_size;
162e7d23d0eSVijay Khemka             }
163e7d23d0eSVijay Khemka             else
16413ce3793SPatrick Williams             {
16513ce3793SPatrick Williams                 throw std::overflow_error("No room in buffer");
16613ce3793SPatrick Williams             }
167e7d23d0eSVijay Khemka         }
168e7d23d0eSVijay Khemka 
16913ce3793SPatrick Williams         buf[idx_tail] = ch;
17013ce3793SPatrick Williams         if (ch == LINE_DELIMITER)
171e7d23d0eSVijay Khemka             lines++;
172e7d23d0eSVijay Khemka 
173e7d23d0eSVijay Khemka         idx_tail = (idx_tail + 1) % max_size;
174e7d23d0eSVijay Khemka     }
175e7d23d0eSVijay Khemka 
176e7d23d0eSVijay Khemka     pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
177e7d23d0eSVijay Khemka 
178e7d23d0eSVijay Khemka     if (pages > max_page)
179e7d23d0eSVijay Khemka         pages = max_page;
180e7d23d0eSVijay Khemka 
18113ce3793SPatrick Williams     return;
182e7d23d0eSVijay Khemka }
183e7d23d0eSVijay Khemka 
184e7d23d0eSVijay Khemka // return page size
getPage(size_t page,char * page_buf,size_t page_buf_size)18513ce3793SPatrick Williams int frame::getPage(size_t page, char* page_buf, size_t page_buf_size)
186e7d23d0eSVijay Khemka {
187e7d23d0eSVijay Khemka     int ret;
188e7d23d0eSVijay Khemka     uint16_t line = 0;
189e7d23d0eSVijay Khemka     uint16_t idx, len;
190e7d23d0eSVijay Khemka 
19113ce3793SPatrick Williams     if (buf == nullptr)
192e7d23d0eSVijay Khemka         return -1;
193e7d23d0eSVijay Khemka 
194e7d23d0eSVijay Khemka     // 1-based page
195e7d23d0eSVijay Khemka     if (page > pages || page < 1)
196e7d23d0eSVijay Khemka         return -1;
197e7d23d0eSVijay Khemka 
19813ce3793SPatrick Williams     if (page_buf == nullptr || page_buf_size == 0)
199e7d23d0eSVijay Khemka         return -1;
200e7d23d0eSVijay Khemka 
20113ce3793SPatrick Williams     ret = snprintf(page_buf, 17, "%-10s %02zd/%02zd", title, page, pages);
202e7d23d0eSVijay Khemka     len = strlen(page_buf);
203e7d23d0eSVijay Khemka     if (ret < 0)
204e7d23d0eSVijay Khemka         return -1;
205e7d23d0eSVijay Khemka 
206e7d23d0eSVijay Khemka     line = 0;
207e7d23d0eSVijay Khemka     idx = idx_head;
208e7d23d0eSVijay Khemka     while (line < ((page - 1) * line_per_page) && idx != idx_tail)
209e7d23d0eSVijay Khemka     {
210e7d23d0eSVijay Khemka         if (buf[idx] == LINE_DELIMITER)
211e7d23d0eSVijay Khemka             line++;
212e7d23d0eSVijay Khemka         idx = (idx + 1) % max_size;
213e7d23d0eSVijay Khemka     }
214e7d23d0eSVijay Khemka 
215e7d23d0eSVijay Khemka     while (line < ((page)*line_per_page) && idx != idx_tail)
216e7d23d0eSVijay Khemka     {
217e7d23d0eSVijay Khemka         if (buf[idx] == LINE_DELIMITER)
218e7d23d0eSVijay Khemka         {
219e7d23d0eSVijay Khemka             line++;
220e7d23d0eSVijay Khemka         }
221e7d23d0eSVijay Khemka         else
222e7d23d0eSVijay Khemka         {
223e7d23d0eSVijay Khemka             page_buf[len++] = buf[idx];
224e7d23d0eSVijay Khemka             if (len == (page_buf_size - 1))
225e7d23d0eSVijay Khemka             {
226e7d23d0eSVijay Khemka                 break;
227e7d23d0eSVijay Khemka             }
228e7d23d0eSVijay Khemka         }
229e7d23d0eSVijay Khemka         idx = (idx + 1) % max_size;
230e7d23d0eSVijay Khemka     }
231e7d23d0eSVijay Khemka 
232e7d23d0eSVijay Khemka     return len;
233e7d23d0eSVijay Khemka }
234e7d23d0eSVijay Khemka 
isFull() const23513ce3793SPatrick Williams bool frame::isFull() const
236e7d23d0eSVijay Khemka {
23713ce3793SPatrick Williams     if (buf == nullptr)
23813ce3793SPatrick Williams         return true;
239e7d23d0eSVijay Khemka 
240e7d23d0eSVijay Khemka     if ((idx_tail + 1) % max_size == idx_head)
24113ce3793SPatrick Williams         return true;
242e7d23d0eSVijay Khemka     else
24313ce3793SPatrick Williams         return false;
244e7d23d0eSVijay Khemka }
245e7d23d0eSVijay Khemka 
246e7d23d0eSVijay Khemka // return 1 for Escape Sequence
isEscSeq(char chr)24713ce3793SPatrick Williams bool frame::isEscSeq(char chr)
248e7d23d0eSVijay Khemka {
249e7d23d0eSVijay Khemka     uint8_t curr_sts = esc_sts;
250e7d23d0eSVijay Khemka 
251e7d23d0eSVijay Khemka     if (esc_sts == 0 && (chr == 0x1b))
252e7d23d0eSVijay Khemka         esc_sts = 1; // Escape Sequence
253e7d23d0eSVijay Khemka     else if (esc_sts == 1 && (chr == 0x5b))
254e7d23d0eSVijay Khemka         esc_sts = 2; // Control Sequence Introducer(CSI)
255e7d23d0eSVijay Khemka     else if (esc_sts == 1 && (chr != 0x5b))
256e7d23d0eSVijay Khemka         esc_sts = 0;
257e7d23d0eSVijay Khemka     else if (esc_sts == 2 && (chr >= 0x40 && chr <= 0x7e))
258e7d23d0eSVijay Khemka         esc_sts = 0;
259e7d23d0eSVijay Khemka 
260e7d23d0eSVijay Khemka     if (curr_sts || esc_sts)
26113ce3793SPatrick Williams         return true;
262e7d23d0eSVijay Khemka     else
26313ce3793SPatrick Williams         return false;
264e7d23d0eSVijay Khemka }
265e7d23d0eSVijay Khemka 
266e7d23d0eSVijay Khemka // return 0 on success
parse(const std::string & input,size_t indent)26713ce3793SPatrick Williams auto frame::parse(const std::string& input, size_t indent) -> std::string
268e7d23d0eSVijay Khemka {
26913ce3793SPatrick Williams     if (indent > line_width)
27013ce3793SPatrick Williams         return {};
271e7d23d0eSVijay Khemka 
27213ce3793SPatrick Williams     std::string result;
27313ce3793SPatrick Williams     size_t linepos = 0;
274e7d23d0eSVijay Khemka 
27513ce3793SPatrick Williams     for (auto ch : input)
276e7d23d0eSVijay Khemka     {
2776c02bfb1SCosmo Chou         if (linepos == 0)
278e7d23d0eSVijay Khemka         {
27913ce3793SPatrick Williams             result.append(indent, ' ');
28013ce3793SPatrick Williams             linepos = indent;
281e7d23d0eSVijay Khemka         }
282e7d23d0eSVijay Khemka 
28313ce3793SPatrick Williams         // Insert character.
28413ce3793SPatrick Williams         result.push_back(ch);
2856c02bfb1SCosmo Chou 
2866c02bfb1SCosmo Chou         if (!isEscSeq(ch))
2876c02bfb1SCosmo Chou         {
2886c02bfb1SCosmo Chou             // Check if new line is needed.
2896c02bfb1SCosmo Chou             if (++linepos == line_width)
2906c02bfb1SCosmo Chou             {
2916c02bfb1SCosmo Chou                 result.push_back(LINE_DELIMITER);
2926c02bfb1SCosmo Chou                 linepos = 0;
2936c02bfb1SCosmo Chou             }
2946c02bfb1SCosmo Chou         }
295e7d23d0eSVijay Khemka     }
296e7d23d0eSVijay Khemka 
29713ce3793SPatrick Williams     // Fill out remaining line.
29813ce3793SPatrick Williams     result.append(line_width - linepos, ' ');
29913ce3793SPatrick Williams     result.push_back(LINE_DELIMITER);
300e7d23d0eSVijay Khemka 
30113ce3793SPatrick Williams     return result;
302e7d23d0eSVijay Khemka }
303e7d23d0eSVijay Khemka 
chk_cri_sel_update(uint8_t * cri_sel_up)304e7d23d0eSVijay Khemka static int chk_cri_sel_update(uint8_t* cri_sel_up)
305e7d23d0eSVijay Khemka {
306e7d23d0eSVijay Khemka     FILE* fp;
307e7d23d0eSVijay Khemka     struct stat file_stat;
30839836ffaSKarthikeyan Pasupathi     size_t pos = plat_get_fru_sel();
309e7d23d0eSVijay Khemka     static uint8_t pre_pos = 0xff;
310e7d23d0eSVijay Khemka 
311e7d23d0eSVijay Khemka     fp = fopen("/mnt/data/cri_sel", "r");
312e7d23d0eSVijay Khemka     if (fp)
313e7d23d0eSVijay Khemka     {
314e7d23d0eSVijay Khemka         if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
315e7d23d0eSVijay Khemka             (file_stat.st_mtime != frame_sel.mtime || pre_pos != pos))
316e7d23d0eSVijay Khemka         {
317e7d23d0eSVijay Khemka             *cri_sel_up = 1;
318e7d23d0eSVijay Khemka         }
319e7d23d0eSVijay Khemka         else
320e7d23d0eSVijay Khemka         {
321e7d23d0eSVijay Khemka             *cri_sel_up = 0;
322e7d23d0eSVijay Khemka         }
323e7d23d0eSVijay Khemka         fclose(fp);
324e7d23d0eSVijay Khemka     }
325e7d23d0eSVijay Khemka     else
326e7d23d0eSVijay Khemka     {
32713ce3793SPatrick Williams         if (frame_sel.buf == nullptr || frame_sel.lines != 0 || pre_pos != pos)
328e7d23d0eSVijay Khemka         {
329e7d23d0eSVijay Khemka             *cri_sel_up = 1;
330e7d23d0eSVijay Khemka         }
331e7d23d0eSVijay Khemka         else
332e7d23d0eSVijay Khemka         {
333e7d23d0eSVijay Khemka             *cri_sel_up = 0;
334e7d23d0eSVijay Khemka         }
335e7d23d0eSVijay Khemka     }
336e7d23d0eSVijay Khemka     pre_pos = pos;
337e7d23d0eSVijay Khemka     return 0;
338e7d23d0eSVijay Khemka }
339e7d23d0eSVijay Khemka 
plat_udbg_get_frame_info(uint8_t * num)340e7d23d0eSVijay Khemka int plat_udbg_get_frame_info(uint8_t* num)
341e7d23d0eSVijay Khemka {
342e7d23d0eSVijay Khemka     *num = 3;
343e7d23d0eSVijay Khemka     return 0;
344e7d23d0eSVijay Khemka }
345e7d23d0eSVijay Khemka 
plat_udbg_get_updated_frames(uint8_t * count,uint8_t * buffer)346e7d23d0eSVijay Khemka int plat_udbg_get_updated_frames(uint8_t* count, uint8_t* buffer)
347e7d23d0eSVijay Khemka {
348e7d23d0eSVijay Khemka     uint8_t cri_sel_up = 0;
349e7d23d0eSVijay Khemka     uint8_t info_page_up = 1;
350e7d23d0eSVijay Khemka 
351e7d23d0eSVijay Khemka     *count = 0;
352e7d23d0eSVijay Khemka 
353e7d23d0eSVijay Khemka     // info page update
354e7d23d0eSVijay Khemka     if (info_page_up == 1)
355e7d23d0eSVijay Khemka     {
356e7d23d0eSVijay Khemka         buffer[*count] = 1;
357e7d23d0eSVijay Khemka         *count += 1;
358e7d23d0eSVijay Khemka     }
359e7d23d0eSVijay Khemka 
360e7d23d0eSVijay Khemka     // cri sel update
361e7d23d0eSVijay Khemka     chk_cri_sel_update(&cri_sel_up);
362e7d23d0eSVijay Khemka     if (cri_sel_up == 1)
363e7d23d0eSVijay Khemka     {
364e7d23d0eSVijay Khemka         buffer[*count] = 2;
365e7d23d0eSVijay Khemka         *count += 1;
366e7d23d0eSVijay Khemka     }
367e7d23d0eSVijay Khemka 
368e7d23d0eSVijay Khemka     // cri sensor update
369e7d23d0eSVijay Khemka     buffer[*count] = 3;
370e7d23d0eSVijay Khemka     *count += 1;
371e7d23d0eSVijay Khemka 
372e7d23d0eSVijay Khemka     return 0;
373e7d23d0eSVijay Khemka }
374e7d23d0eSVijay Khemka 
plat_udbg_get_post_desc(uint8_t index,uint8_t * next,uint8_t phase,uint8_t * end,uint8_t * length,uint8_t * buffer)375e7d23d0eSVijay Khemka int plat_udbg_get_post_desc(uint8_t index, uint8_t* next, uint8_t phase,
376e7d23d0eSVijay Khemka                             uint8_t* end, uint8_t* length, uint8_t* buffer)
377e7d23d0eSVijay Khemka {
378cc0d6d92SVijay Khemka     nlohmann::json postObj;
379cc0d6d92SVijay Khemka     std::string postCode;
380e7d23d0eSVijay Khemka 
381cc0d6d92SVijay Khemka     /* Get post description data stored in json file */
382cc0d6d92SVijay Khemka     std::ifstream file(JSON_POST_DATA_FILE);
383cc0d6d92SVijay Khemka     if (file)
384cc0d6d92SVijay Khemka     {
385cc0d6d92SVijay Khemka         file >> postObj;
386cc0d6d92SVijay Khemka         file.close();
387cc0d6d92SVijay Khemka     }
388cc0d6d92SVijay Khemka     else
389cc0d6d92SVijay Khemka     {
390cc0d6d92SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
391cc0d6d92SVijay Khemka             "Post code description file not found",
392cc0d6d92SVijay Khemka             phosphor::logging::entry("POST_CODE_FILE=%s", JSON_POST_DATA_FILE));
393cc0d6d92SVijay Khemka         return -1;
394cc0d6d92SVijay Khemka     }
395cc0d6d92SVijay Khemka 
396cc0d6d92SVijay Khemka     std::string phaseStr = "PhaseAny";
397cc0d6d92SVijay Khemka     if (postObj.find(phaseStr) == postObj.end())
398cc0d6d92SVijay Khemka     {
399cc0d6d92SVijay Khemka         phaseStr = "Phase" + std::to_string(phase);
400cc0d6d92SVijay Khemka     }
401cc0d6d92SVijay Khemka 
402cc0d6d92SVijay Khemka     if (postObj.find(phaseStr) == postObj.end())
403cc0d6d92SVijay Khemka     {
404cc0d6d92SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
405cc0d6d92SVijay Khemka             "Post code phase not available",
406cc0d6d92SVijay Khemka             phosphor::logging::entry("PHASE=%d", phase));
407cc0d6d92SVijay Khemka         return -1;
408cc0d6d92SVijay Khemka     }
409cc0d6d92SVijay Khemka 
410cc0d6d92SVijay Khemka     auto phaseObj = postObj[phaseStr];
411cc0d6d92SVijay Khemka     int phaseSize = phaseObj.size();
412cc0d6d92SVijay Khemka 
413cc0d6d92SVijay Khemka     for (int i = 0; i < phaseSize; i++)
414cc0d6d92SVijay Khemka     {
415cc0d6d92SVijay Khemka         postCode = phaseObj[i][0];
416cc0d6d92SVijay Khemka         if (index == stoul(postCode, nullptr, 16))
417cc0d6d92SVijay Khemka         {
418cc0d6d92SVijay Khemka             std::string postDesc = phaseObj[i][1];
419cc0d6d92SVijay Khemka             *length = postDesc.size();
420cc0d6d92SVijay Khemka             memcpy(buffer, postDesc.data(), *length);
421cc0d6d92SVijay Khemka             buffer[*length] = '\0';
422cc0d6d92SVijay Khemka 
423cc0d6d92SVijay Khemka             if (phaseSize != i + 1)
424cc0d6d92SVijay Khemka             {
425cc0d6d92SVijay Khemka                 postCode = phaseObj[i + 1][0];
426cc0d6d92SVijay Khemka                 *next = stoul(postCode, nullptr, 16);
427cc0d6d92SVijay Khemka                 *end = 0;
428cc0d6d92SVijay Khemka             }
429cc0d6d92SVijay Khemka             else
430cc0d6d92SVijay Khemka             {
431cc0d6d92SVijay Khemka                 if (postObj.size() != phase)
432cc0d6d92SVijay Khemka                 {
433010dee04SPatrick Williams                     std::string nextPhaseStr =
434010dee04SPatrick Williams                         "Phase" + std::to_string(phase + 1);
435cc0d6d92SVijay Khemka                     postCode = postObj[nextPhaseStr][0][0];
436cc0d6d92SVijay Khemka                     *next = stoul(postCode, nullptr, 16);
437cc0d6d92SVijay Khemka                     *end = 0;
438cc0d6d92SVijay Khemka                 }
439cc0d6d92SVijay Khemka                 else
440cc0d6d92SVijay Khemka                 {
441e7d23d0eSVijay Khemka                     *next = 0xff;
442cc0d6d92SVijay Khemka                     *end = 1;
443cc0d6d92SVijay Khemka                 }
444cc0d6d92SVijay Khemka             }
445cc0d6d92SVijay Khemka 
446e7d23d0eSVijay Khemka             return 0;
447e7d23d0eSVijay Khemka         }
448cc0d6d92SVijay Khemka     }
449cc0d6d92SVijay Khemka 
450cc0d6d92SVijay Khemka     phosphor::logging::log<phosphor::logging::level::ERR>(
451cc0d6d92SVijay Khemka         "Post code description data not available",
452cc0d6d92SVijay Khemka         phosphor::logging::entry("PHASE_CODE=%d_0x%x", phase, index));
453cc0d6d92SVijay Khemka     return -1;
454cc0d6d92SVijay Khemka }
455e7d23d0eSVijay Khemka 
plat_udbg_get_gpio_desc(uint8_t index,uint8_t * next,uint8_t * level,uint8_t * def,uint8_t * length,uint8_t * buffer)456e7d23d0eSVijay Khemka int plat_udbg_get_gpio_desc(uint8_t index, uint8_t* next, uint8_t* level,
45738183d66SVijay Khemka                             uint8_t* def, uint8_t* length, uint8_t* buffer)
458e7d23d0eSVijay Khemka {
45938183d66SVijay Khemka     nlohmann::json gpioObj;
46038183d66SVijay Khemka     std::string gpioPin;
46138183d66SVijay Khemka 
46238183d66SVijay Khemka     /* Get gpio data stored in json file */
46338183d66SVijay Khemka     std::ifstream file(JSON_GPIO_DATA_FILE);
46438183d66SVijay Khemka     if (file)
46538183d66SVijay Khemka     {
46638183d66SVijay Khemka         file >> gpioObj;
46738183d66SVijay Khemka         file.close();
46838183d66SVijay Khemka     }
46938183d66SVijay Khemka     else
47038183d66SVijay Khemka     {
47138183d66SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
47238183d66SVijay Khemka             "GPIO pin description file not found",
47338183d66SVijay Khemka             phosphor::logging::entry("GPIO_PIN_DETAILS_FILE=%s",
47438183d66SVijay Khemka                                      JSON_GPIO_DATA_FILE));
47538183d66SVijay Khemka         return -1;
47638183d66SVijay Khemka     }
47738183d66SVijay Khemka 
47838183d66SVijay Khemka     if (gpioObj.find(DEBUG_GPIO_KEY) == gpioObj.end())
47938183d66SVijay Khemka     {
48038183d66SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
48138183d66SVijay Khemka             "GPIO pin details not available",
48238183d66SVijay Khemka             phosphor::logging::entry("GPIO_JSON_KEY=%d", DEBUG_GPIO_KEY));
48338183d66SVijay Khemka         return -1;
48438183d66SVijay Khemka     }
48538183d66SVijay Khemka 
48638183d66SVijay Khemka     auto obj = gpioObj[DEBUG_GPIO_KEY];
48738183d66SVijay Khemka     int objSize = obj.size();
48838183d66SVijay Khemka 
48938183d66SVijay Khemka     for (int i = 0; i < objSize; i++)
49038183d66SVijay Khemka     {
49138183d66SVijay Khemka         if (obj[i].size() != GPIO_ARRAY_SIZE)
49238183d66SVijay Khemka         {
49338183d66SVijay Khemka             phosphor::logging::log<phosphor::logging::level::ERR>(
49438183d66SVijay Khemka                 "Size of gpio array is incorrect",
49538183d66SVijay Khemka                 phosphor::logging::entry("EXPECTED_SIZE=%d", GPIO_ARRAY_SIZE));
49638183d66SVijay Khemka             return -1;
49738183d66SVijay Khemka         }
49838183d66SVijay Khemka 
49938183d66SVijay Khemka         gpioPin = obj[i][GPIO_PIN_INDEX];
50038183d66SVijay Khemka         if (index == stoul(gpioPin, nullptr, 16))
50138183d66SVijay Khemka         {
50238183d66SVijay Khemka             if (objSize != i + 1)
50338183d66SVijay Khemka             {
50438183d66SVijay Khemka                 gpioPin = obj[i + 1][GPIO_PIN_INDEX];
50538183d66SVijay Khemka                 *next = stoul(gpioPin, nullptr, 16);
50638183d66SVijay Khemka             }
50738183d66SVijay Khemka             else
50838183d66SVijay Khemka             {
50938183d66SVijay Khemka                 *next = 0xff;
51038183d66SVijay Khemka             }
51138183d66SVijay Khemka 
51238183d66SVijay Khemka             *level = obj[i][GPIO_LEVEL_INDEX];
51338183d66SVijay Khemka             *def = obj[i][GPIO_DEF_INDEX];
51438183d66SVijay Khemka             std::string gpioDesc = obj[i][GPIO_DESC_INDEX];
51538183d66SVijay Khemka             *length = gpioDesc.size();
51638183d66SVijay Khemka             memcpy(buffer, gpioDesc.data(), *length);
51738183d66SVijay Khemka             buffer[*length] = '\0';
51838183d66SVijay Khemka 
519e7d23d0eSVijay Khemka             return 0;
520e7d23d0eSVijay Khemka         }
52138183d66SVijay Khemka     }
52238183d66SVijay Khemka 
52338183d66SVijay Khemka     phosphor::logging::log<phosphor::logging::level::ERR>(
52438183d66SVijay Khemka         "GPIO pin description data not available",
52538183d66SVijay Khemka         phosphor::logging::entry("GPIO_PIN=0x%x", index));
52638183d66SVijay Khemka     return -1;
52738183d66SVijay Khemka }
528e7d23d0eSVijay Khemka 
getBiosVer(std::string & ver,size_t hostPosition)529e9baaff1SBonnie Lo static int getBiosVer(std::string& ver, size_t hostPosition)
53088884b85SVijay Khemka {
53188884b85SVijay Khemka     nlohmann::json appObj;
53288884b85SVijay Khemka 
53388884b85SVijay Khemka     std::ifstream file(JSON_APP_DATA_FILE);
53488884b85SVijay Khemka     if (file)
53588884b85SVijay Khemka     {
53688884b85SVijay Khemka         file >> appObj;
53788884b85SVijay Khemka         file.close();
538e9baaff1SBonnie Lo         std::string version_key = KEY_SYSFW_VER + std::to_string(hostPosition);
539e9baaff1SBonnie Lo 
540e9baaff1SBonnie Lo         if (appObj.find(version_key) != appObj.end())
54188884b85SVijay Khemka         {
542e9baaff1SBonnie Lo             ver = appObj[version_key].get<std::string>();
54388884b85SVijay Khemka             return 0;
54488884b85SVijay Khemka         }
54588884b85SVijay Khemka     }
54688884b85SVijay Khemka 
54788884b85SVijay Khemka     return -1;
54888884b85SVijay Khemka }
54988884b85SVijay Khemka 
sendBicCmd(uint8_t netFn,uint8_t cmd,uint8_t bicAddr,std::vector<uint8_t> & cmdData,std::vector<uint8_t> & respData)5505f8e3435SManikandan Elumalai int sendBicCmd(uint8_t netFn, uint8_t cmd, uint8_t bicAddr,
5515f8e3435SManikandan Elumalai                std::vector<uint8_t>& cmdData, std::vector<uint8_t>& respData)
5525f8e3435SManikandan Elumalai {
5535f8e3435SManikandan Elumalai     static constexpr uint8_t lun = 0;
5545f8e3435SManikandan Elumalai 
5555f8e3435SManikandan Elumalai     auto bus = getSdBus();
5565f8e3435SManikandan Elumalai 
5575f8e3435SManikandan Elumalai     auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
5585f8e3435SManikandan Elumalai                                        "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
5595f8e3435SManikandan Elumalai                                        "org.openbmc.Ipmb", "sendRequest");
5605f8e3435SManikandan Elumalai     method.append(bicAddr, netFn, lun, cmd, cmdData);
5615f8e3435SManikandan Elumalai 
5625f8e3435SManikandan Elumalai     auto reply = bus->call(method);
5635f8e3435SManikandan Elumalai     if (reply.is_method_error())
5645f8e3435SManikandan Elumalai     {
5655f8e3435SManikandan Elumalai         phosphor::logging::log<phosphor::logging::level::ERR>(
5665f8e3435SManikandan Elumalai             "Error reading from BIC");
5675f8e3435SManikandan Elumalai         return -1;
5685f8e3435SManikandan Elumalai     }
5695f8e3435SManikandan Elumalai 
5705f8e3435SManikandan Elumalai     IpmbMethodType resp;
5715f8e3435SManikandan Elumalai     reply.read(resp);
5725f8e3435SManikandan Elumalai 
5735f8e3435SManikandan Elumalai     respData =
5745f8e3435SManikandan Elumalai         std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
5755f8e3435SManikandan Elumalai 
5765f8e3435SManikandan Elumalai     return 0;
5775f8e3435SManikandan Elumalai }
5785f8e3435SManikandan Elumalai 
sendMeCmd(uint8_t netFn,uint8_t cmd,std::vector<uint8_t> & cmdData,std::vector<uint8_t> & respData)579dd14c0f7SVijay Khemka int sendMeCmd(uint8_t netFn, uint8_t cmd, std::vector<uint8_t>& cmdData,
580dd14c0f7SVijay Khemka               std::vector<uint8_t>& respData)
581dd14c0f7SVijay Khemka {
582dd14c0f7SVijay Khemka     auto bus = getSdBus();
583dd14c0f7SVijay Khemka 
584dd14c0f7SVijay Khemka     if (DEBUG)
585dd14c0f7SVijay Khemka     {
586dd14c0f7SVijay Khemka         std::cout << "ME NetFn:cmd " << (int)netFn << ":" << (int)cmd << "\n";
587dd14c0f7SVijay Khemka         std::cout << "ME req data: ";
588dd14c0f7SVijay Khemka         for (auto d : cmdData)
589dd14c0f7SVijay Khemka         {
590dd14c0f7SVijay Khemka             std::cout << d << " ";
591dd14c0f7SVijay Khemka         }
592dd14c0f7SVijay Khemka         std::cout << "\n";
593dd14c0f7SVijay Khemka     }
594dd14c0f7SVijay Khemka 
595dd14c0f7SVijay Khemka     auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
596dd14c0f7SVijay Khemka                                        "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
597dd14c0f7SVijay Khemka                                        "org.openbmc.Ipmb", "sendRequest");
598dd14c0f7SVijay Khemka     method.append(meAddress, netFn, lun, cmd, cmdData);
599dd14c0f7SVijay Khemka 
600dd14c0f7SVijay Khemka     auto reply = bus->call(method);
601dd14c0f7SVijay Khemka     if (reply.is_method_error())
602dd14c0f7SVijay Khemka     {
603dd14c0f7SVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
604dd14c0f7SVijay Khemka             "Error reading from ME");
605dd14c0f7SVijay Khemka         return -1;
606dd14c0f7SVijay Khemka     }
607dd14c0f7SVijay Khemka 
608dd14c0f7SVijay Khemka     IpmbMethodType resp;
609dd14c0f7SVijay Khemka     reply.read(resp);
610dd14c0f7SVijay Khemka 
611dd14c0f7SVijay Khemka     respData =
612dd14c0f7SVijay Khemka         std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
613dd14c0f7SVijay Khemka 
614dd14c0f7SVijay Khemka     if (DEBUG)
615dd14c0f7SVijay Khemka     {
616dd14c0f7SVijay Khemka         std::cout << "ME resp data: ";
617dd14c0f7SVijay Khemka         for (auto d : respData)
618dd14c0f7SVijay Khemka         {
619dd14c0f7SVijay Khemka             std::cout << d << " ";
620dd14c0f7SVijay Khemka         }
621dd14c0f7SVijay Khemka         std::cout << "\n";
622dd14c0f7SVijay Khemka     }
623dd14c0f7SVijay Khemka 
624dd14c0f7SVijay Khemka     return 0;
625dd14c0f7SVijay Khemka }
626dd14c0f7SVijay Khemka 
udbg_get_info_page(uint8_t,uint8_t page,uint8_t * next,uint8_t * count,uint8_t * buffer)627e39f9393SWilly Tu static int udbg_get_info_page(uint8_t, uint8_t page, uint8_t* next,
628e7d23d0eSVijay Khemka                               uint8_t* count, uint8_t* buffer)
629e7d23d0eSVijay Khemka {
630e39f9393SWilly Tu     char line_buff[1000];
631e39f9393SWilly Tu     [[maybe_unused]] char* pres_dev = line_buff;
632e39f9393SWilly Tu     [[maybe_unused]] size_t pos = plat_get_fru_sel();
633e7d23d0eSVijay Khemka     int ret;
63498aabdb1SKarthikeyan Pasupathi     std::string serialName = "SerialNumber";
63598aabdb1SKarthikeyan Pasupathi     std::string partName = "PartNumber";
636e7d23d0eSVijay Khemka     std::string verDel = "VERSION=";
637e7d23d0eSVijay Khemka     std::string verPath = "/etc/os-release";
63821a79235SBonnieLo-wiwynn     size_t hostPosition = 0;
639e1ff81faSKarthikeyan Pasupathi     size_t maxPosition;
640e7d23d0eSVijay Khemka 
641e7d23d0eSVijay Khemka     if (page == 1)
642e7d23d0eSVijay Khemka     {
643e7d23d0eSVijay Khemka         // Only update frame data while getting page 1
644e7d23d0eSVijay Khemka 
645e7d23d0eSVijay Khemka         // initialize and clear frame
64613ce3793SPatrick Williams         frame_info.init();
647e7d23d0eSVijay Khemka         snprintf(frame_info.title, 32, "SYS_Info");
648e7d23d0eSVijay Khemka 
64998aabdb1SKarthikeyan Pasupathi         bool platform = isMultiHostPlatform();
65098aabdb1SKarthikeyan Pasupathi         if (platform == true)
65198aabdb1SKarthikeyan Pasupathi         {
652e1ff81faSKarthikeyan Pasupathi             hostPosition = plat_get_fru_sel();
65398aabdb1SKarthikeyan Pasupathi         }
65498aabdb1SKarthikeyan Pasupathi 
655e1ff81faSKarthikeyan Pasupathi         getMaxHostPosition(maxPosition);
6564ec80567SJayashree Dhanapal         if (hostPosition == BMC_POSITION || hostInstances == "0")
65798aabdb1SKarthikeyan Pasupathi         {
658d8d95a3dSDaniel Hsu             std::string data = "FRU:" + getMotherBoardFruName();
659d8d95a3dSDaniel Hsu             frame_info.append(data);
66098aabdb1SKarthikeyan Pasupathi         }
661e1ff81faSKarthikeyan Pasupathi         else if (hostPosition != BMC_POSITION && hostPosition <= maxPosition)
66298aabdb1SKarthikeyan Pasupathi         {
66398aabdb1SKarthikeyan Pasupathi             std::string data = "FRU:slot" + std::to_string(hostPosition);
66413ce3793SPatrick Williams             frame_info.append(data);
66598aabdb1SKarthikeyan Pasupathi         }
66698aabdb1SKarthikeyan Pasupathi 
66798aabdb1SKarthikeyan Pasupathi         // FRU
668e7d23d0eSVijay Khemka         std::string data;
66913ce3793SPatrick Williams         frame_info.append("SN:");
670e7d23d0eSVijay Khemka         if (getFruData(data, serialName) != 0)
671e7d23d0eSVijay Khemka         {
672e7d23d0eSVijay Khemka             data = "Not Found";
673e7d23d0eSVijay Khemka         }
67413ce3793SPatrick Williams         frame_info.append(data, 1);
67513ce3793SPatrick Williams         frame_info.append("PN:");
676e7d23d0eSVijay Khemka         if (getFruData(data, partName) != 0)
677e7d23d0eSVijay Khemka         {
678e7d23d0eSVijay Khemka             data = "Not Found";
679e7d23d0eSVijay Khemka         }
68013ce3793SPatrick Williams         frame_info.append(data, 1);
681e7d23d0eSVijay Khemka 
682e7d23d0eSVijay Khemka         // LAN
683e7d23d0eSVijay Khemka         getNetworkData(3, line_buff);
68413ce3793SPatrick Williams         frame_info.append("BMC_IP:");
685e7d23d0eSVijay Khemka         frame_info.append(line_buff, 1);
686e7d23d0eSVijay Khemka         getNetworkData(59, line_buff);
68713ce3793SPatrick Williams         frame_info.append("BMC_IPv6:");
688e7d23d0eSVijay Khemka         frame_info.append(line_buff, 1);
689e7d23d0eSVijay Khemka 
690e7d23d0eSVijay Khemka         // BMC ver
691e7d23d0eSVijay Khemka         std::ifstream file(verPath);
692e7d23d0eSVijay Khemka         if (file)
693e7d23d0eSVijay Khemka         {
694e7d23d0eSVijay Khemka             std::string line;
695e7d23d0eSVijay Khemka             while (std::getline(file, line))
696e7d23d0eSVijay Khemka             {
697e7d23d0eSVijay Khemka                 if (line.find(verDel) != std::string::npos)
698e7d23d0eSVijay Khemka                 {
699e7d23d0eSVijay Khemka                     std::string bmcVer = line.substr(verDel.size());
70013ce3793SPatrick Williams                     frame_info.append("BMC_FW_ver:");
70113ce3793SPatrick Williams                     frame_info.append(bmcVer, 1);
702e7d23d0eSVijay Khemka                     break;
703e7d23d0eSVijay Khemka                 }
704e7d23d0eSVijay Khemka             }
705e7d23d0eSVijay Khemka         }
706e7d23d0eSVijay Khemka 
707*3add478bSDaniel Hsu         if (hostPosition != BMC_POSITION || hostInstances == "0")
70898aabdb1SKarthikeyan Pasupathi         {
709e7d23d0eSVijay Khemka             // BIOS ver
71088884b85SVijay Khemka             std::string biosVer;
711e9baaff1SBonnie Lo             if (getBiosVer(biosVer, hostPosition) == 0)
71288884b85SVijay Khemka             {
71313ce3793SPatrick Williams                 frame_info.append("BIOS_FW_ver:");
71413ce3793SPatrick Williams                 frame_info.append(biosVer, 1);
71588884b85SVijay Khemka             }
71698aabdb1SKarthikeyan Pasupathi         }
717e7d23d0eSVijay Khemka 
718317999d3SVijay Khemka         /* TBD: Board ID needs implementation */
719e7d23d0eSVijay Khemka         // Board ID
720e7d23d0eSVijay Khemka 
721e7d23d0eSVijay Khemka         // Battery - Use Escape sequence
72213ce3793SPatrick Williams         frame_info.append("Battery:");
723e7d23d0eSVijay Khemka         frame_info.append(ESC_BAT "     ", 1);
724e7d23d0eSVijay Khemka         // frame_info.append(&frame_info, esc_bat, 1);
725e7d23d0eSVijay Khemka 
726e7d23d0eSVijay Khemka         // MCU Version - Use Escape sequence
72713ce3793SPatrick Williams         frame_info.append("MCUbl_ver:");
728e7d23d0eSVijay Khemka         frame_info.append(ESC_MCU_BL_VER, 1);
72913ce3793SPatrick Williams         frame_info.append("MCU_ver:");
730e7d23d0eSVijay Khemka         frame_info.append(ESC_MCU_RUN_VER, 1);
731e7d23d0eSVijay Khemka 
732e7d23d0eSVijay Khemka         // Sys config present device
73310ff3d86SKarthikeyan Pasupathi         if (hostPosition != BMC_POSITION)
73410ff3d86SKarthikeyan Pasupathi         {
73513ce3793SPatrick Williams             frame_info.append("Sys Conf. info:");
73610ff3d86SKarthikeyan Pasupathi 
73710ff3d86SKarthikeyan Pasupathi             // Dimm info
73810ff3d86SKarthikeyan Pasupathi             std::vector<std::string> data;
739e1ff81faSKarthikeyan Pasupathi             if (sysConfig(data, pos) == 0)
740e1ff81faSKarthikeyan Pasupathi             {
74110ff3d86SKarthikeyan Pasupathi                 for (auto& info : data)
74210ff3d86SKarthikeyan Pasupathi                 {
74313ce3793SPatrick Williams                     frame_info.append(info, 1);
74410ff3d86SKarthikeyan Pasupathi                 }
745e1ff81faSKarthikeyan Pasupathi             }
746e1ff81faSKarthikeyan Pasupathi             else
747e1ff81faSKarthikeyan Pasupathi             {
748e1ff81faSKarthikeyan Pasupathi                 frame_info.append("Not Found", 1);
749e1ff81faSKarthikeyan Pasupathi             }
750d532fecaSKarthikeyan Pasupathi 
751d532fecaSKarthikeyan Pasupathi             // Processor info
752d532fecaSKarthikeyan Pasupathi             std::string result;
753e1ff81faSKarthikeyan Pasupathi             if (procInfo(result, pos) != 0)
754e1ff81faSKarthikeyan Pasupathi             {
755e1ff81faSKarthikeyan Pasupathi                 result = "Not Found";
756e1ff81faSKarthikeyan Pasupathi             }
75713ce3793SPatrick Williams             frame_info.append(result, 1);
75810ff3d86SKarthikeyan Pasupathi         }
759e7d23d0eSVijay Khemka 
760e7d23d0eSVijay Khemka     } // End of update frame
761e7d23d0eSVijay Khemka 
762e7d23d0eSVijay Khemka     if (page > frame_info.pages)
763e7d23d0eSVijay Khemka     {
764e7d23d0eSVijay Khemka         return -1;
765e7d23d0eSVijay Khemka     }
766e7d23d0eSVijay Khemka 
767e7d23d0eSVijay Khemka     ret = frame_info.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
768e7d23d0eSVijay Khemka     if (ret < 0)
769e7d23d0eSVijay Khemka     {
770e7d23d0eSVijay Khemka         *count = 0;
771e7d23d0eSVijay Khemka         return -1;
772e7d23d0eSVijay Khemka     }
773e7d23d0eSVijay Khemka     *count = (uint8_t)ret;
774e7d23d0eSVijay Khemka 
775e7d23d0eSVijay Khemka     if (page < frame_info.pages)
776e7d23d0eSVijay Khemka         *next = page + 1;
777e7d23d0eSVijay Khemka     else
778e7d23d0eSVijay Khemka         *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
779e7d23d0eSVijay Khemka                       // last page
780e7d23d0eSVijay Khemka 
781e7d23d0eSVijay Khemka     return 0;
782e7d23d0eSVijay Khemka }
783e7d23d0eSVijay Khemka 
udbg_get_postcode(uint8_t,uint8_t page,uint8_t * next,uint8_t * count,uint8_t * buffer)784b340aa28SPeter Yin static int udbg_get_postcode(uint8_t, uint8_t page, uint8_t* next,
785b340aa28SPeter Yin                              uint8_t* count, uint8_t* buffer)
786b340aa28SPeter Yin {
7875a6917dbSCosmo Chou     // up to 70 codes can be displayed on 10 pages
7885a6917dbSCosmo Chou     static constexpr size_t maxPostcodes = 70;
7895a6917dbSCosmo Chou 
790b340aa28SPeter Yin     if (page == 1)
791b340aa28SPeter Yin     {
792b340aa28SPeter Yin         // Initialize and clear frame (example initialization)
79313ce3793SPatrick Williams         frame_postcode.init();
7945a6917dbSCosmo Chou         snprintf(frame_postcode.title, 32, "POST CODE");
7955a6917dbSCosmo Chou         frame_postcode.max_page = 10;
796b340aa28SPeter Yin 
797b340aa28SPeter Yin         // Synchronously get D-Bus connection
798b340aa28SPeter Yin         auto bus = sdbusplus::bus::new_default();
799b340aa28SPeter Yin 
800b340aa28SPeter Yin         // Build D-Bus method call
801b340aa28SPeter Yin         auto method = bus.new_method_call(
802b340aa28SPeter Yin             "xyz.openbmc_project.State.Boot.PostCode0",  // Target service name
803b340aa28SPeter Yin             "/xyz/openbmc_project/State/Boot/PostCode0", // Object path
804b340aa28SPeter Yin             "xyz.openbmc_project.State.Boot.PostCode",   // Interface name
805b340aa28SPeter Yin             "GetPostCodes");                             // Method name
806b340aa28SPeter Yin 
807b340aa28SPeter Yin         method.append(uint16_t(1)); // Add method parameter, assuming it's page
808b340aa28SPeter Yin 
809b340aa28SPeter Yin         try
810b340aa28SPeter Yin         {
811b340aa28SPeter Yin             auto reply = bus.call(method); // Send synchronous method call
812b340aa28SPeter Yin 
813b340aa28SPeter Yin             // Read postcode value
8145e18a70eSCosmo Chou             std::vector<std::tuple<std::vector<uint8_t>, std::vector<uint8_t>>>
8155e18a70eSCosmo Chou                 postcodes;
816b340aa28SPeter Yin             reply.read(postcodes);
817b340aa28SPeter Yin 
8185a6917dbSCosmo Chou             // retrieve the latest postcodes
8195a6917dbSCosmo Chou             size_t numEntries = std::min(maxPostcodes, postcodes.size());
8205e18a70eSCosmo Chou             auto range = std::ranges::subrange(postcodes.rbegin(),
8215e18a70eSCosmo Chou                                                postcodes.rbegin() + numEntries);
8225e18a70eSCosmo Chou             for (const auto& [code, extra] : range)
823b340aa28SPeter Yin             {
8245e18a70eSCosmo Chou                 std::string result;
8255e18a70eSCosmo Chou                 result.reserve(2 * code.size());
8265e18a70eSCosmo Chou                 for (const auto& byte : code)
8273c9f5b60SPotin Lai                 {
8285a6917dbSCosmo Chou                     result += std::format("{:02X}", byte);
8293c9f5b60SPotin Lai                 }
8305a6917dbSCosmo Chou 
83113ce3793SPatrick Williams                 frame_postcode.append(result);
8325a6917dbSCosmo Chou                 if (frame_postcode.lines >= maxPostcodes)
8335a6917dbSCosmo Chou                 {
8345a6917dbSCosmo Chou                     break;
8355a6917dbSCosmo Chou                 }
836b340aa28SPeter Yin             }
837b340aa28SPeter Yin         }
838b340aa28SPeter Yin         catch (const std::exception& e)
839b340aa28SPeter Yin         {
840b340aa28SPeter Yin             // Handle exceptions
841b340aa28SPeter Yin             std::cerr << "Error retrieving postcodes: " << e.what()
842b340aa28SPeter Yin                       << std::endl;
843b340aa28SPeter Yin             return -1;
844b340aa28SPeter Yin         }
845b340aa28SPeter Yin     }
846b340aa28SPeter Yin 
847b340aa28SPeter Yin     if (page > frame_postcode.pages)
848b340aa28SPeter Yin     {
849b340aa28SPeter Yin         return -1;
850b340aa28SPeter Yin     }
851b340aa28SPeter Yin 
852b340aa28SPeter Yin     int ret = frame_postcode.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
853b340aa28SPeter Yin     if (ret < 0)
854b340aa28SPeter Yin     {
855b340aa28SPeter Yin         *count = 0;
856b340aa28SPeter Yin         return -1;
857b340aa28SPeter Yin     }
858b340aa28SPeter Yin     *count = (uint8_t)ret;
859b340aa28SPeter Yin 
860b340aa28SPeter Yin     if (page < frame_postcode.pages)
861b340aa28SPeter Yin         *next = page + 1;
862b340aa28SPeter Yin     else
863b340aa28SPeter Yin         *next = 0xFF; // Set next to 0xFF to indicate last page
864b340aa28SPeter Yin     return 0;
865b340aa28SPeter Yin }
866b340aa28SPeter Yin 
plat_udbg_get_frame_data(uint8_t frame,uint8_t page,uint8_t * next,uint8_t * count,uint8_t * buffer)867e7d23d0eSVijay Khemka int plat_udbg_get_frame_data(uint8_t frame, uint8_t page, uint8_t* next,
868e7d23d0eSVijay Khemka                              uint8_t* count, uint8_t* buffer)
869e7d23d0eSVijay Khemka {
870e7d23d0eSVijay Khemka     switch (frame)
871e7d23d0eSVijay Khemka     {
872e7d23d0eSVijay Khemka         case 1: // info_page
873e7d23d0eSVijay Khemka             return udbg_get_info_page(frame, page, next, count, buffer);
874b340aa28SPeter Yin         case 2: // Extra Post Code
875b340aa28SPeter Yin             return udbg_get_postcode(frame, page, next, count, buffer);
876e7d23d0eSVijay Khemka         default:
877e7d23d0eSVijay Khemka             return -1;
878e7d23d0eSVijay Khemka     }
879e7d23d0eSVijay Khemka }
880e7d23d0eSVijay Khemka 
panel_main(size_t item)881a758d0a4SPatrick Williams static panel panel_main(size_t item)
882e7d23d0eSVijay Khemka {
883e7d23d0eSVijay Khemka     // Update item list when select item 0
884e7d23d0eSVijay Khemka     switch (item)
885e7d23d0eSVijay Khemka     {
886e7d23d0eSVijay Khemka         case 1:
887a758d0a4SPatrick Williams             return panels[std::to_underlying(panel::BOOT_ORDER)].select(0);
888e7d23d0eSVijay Khemka         case 2:
889a758d0a4SPatrick Williams             return panels[std::to_underlying(panel::POWER_POLICY)].select(0);
890e7d23d0eSVijay Khemka         default:
891a758d0a4SPatrick Williams             return panel::MAIN;
892e7d23d0eSVijay Khemka     }
893e7d23d0eSVijay Khemka }
894e7d23d0eSVijay Khemka 
panel_boot_order(size_t selectedItemIndex)895a758d0a4SPatrick Williams static panel panel_boot_order(size_t selectedItemIndex)
896e7d23d0eSVijay Khemka {
8977bb4592aSDelphine CC Chiu     static constexpr size_t sizeBootOrder = 6;
8987bb4592aSDelphine CC Chiu     static constexpr size_t bootValid = 0x80;
8997bb4592aSDelphine CC Chiu 
9007bb4592aSDelphine CC Chiu     std::vector<uint8_t> bootSeq;
9017bb4592aSDelphine CC Chiu 
902a758d0a4SPatrick Williams     ctrl_panel& bootOrderPanel = panels[std::to_underlying(panel::BOOT_ORDER)];
9037bb4592aSDelphine CC Chiu 
90439836ffaSKarthikeyan Pasupathi     size_t pos = plat_get_fru_sel();
9057bb4592aSDelphine CC Chiu 
9067bb4592aSDelphine CC Chiu     if (pos == FRU_ALL)
907e7d23d0eSVijay Khemka     {
9087bb4592aSDelphine CC Chiu         bootOrderPanel.item_num = 0;
909a758d0a4SPatrick Williams         return panel::BOOT_ORDER;
910e7d23d0eSVijay Khemka     }
9117bb4592aSDelphine CC Chiu 
9127bb4592aSDelphine CC Chiu     auto [bootObjPath, hostName] = ipmi::boot::objPath(pos);
9137bb4592aSDelphine CC Chiu     ipmi::boot::getBootOrder(bootObjPath, bootSeq, hostName);
9147bb4592aSDelphine CC Chiu 
9157bb4592aSDelphine CC Chiu     uint8_t& bootMode = bootSeq.front();
9167bb4592aSDelphine CC Chiu 
9177bb4592aSDelphine CC Chiu     // One item is selected to set a new boot sequence.
9187bb4592aSDelphine CC Chiu     // The selected item become the first boot order.
9197bb4592aSDelphine CC Chiu     if (selectedItemIndex > 0 && selectedItemIndex < sizeBootOrder)
9207bb4592aSDelphine CC Chiu     {
9217bb4592aSDelphine CC Chiu         // Move the selected item to second element (the first one is boot mode)
9227bb4592aSDelphine CC Chiu         std::rotate(bootSeq.begin() + 1, bootSeq.begin() + selectedItemIndex,
9237bb4592aSDelphine CC Chiu                     bootSeq.begin() + selectedItemIndex + 1);
9247bb4592aSDelphine CC Chiu 
9257bb4592aSDelphine CC Chiu         bootMode |= bootValid;
9267bb4592aSDelphine CC Chiu         try
9277bb4592aSDelphine CC Chiu         {
9287bb4592aSDelphine CC Chiu             ipmi::boot::setBootOrder(bootObjPath, bootSeq, hostName);
9297bb4592aSDelphine CC Chiu         }
9307bb4592aSDelphine CC Chiu         catch (const std::exception& e)
9317bb4592aSDelphine CC Chiu         {
9327bb4592aSDelphine CC Chiu             lg2::error("Fail to set boot order : {ERROR}", "ERROR", e);
9337bb4592aSDelphine CC Chiu         }
934e7d23d0eSVijay Khemka 
935e7d23d0eSVijay Khemka         // refresh items
9367bb4592aSDelphine CC Chiu         return bootOrderPanel.select(0);
937e7d23d0eSVijay Khemka     }
938e7d23d0eSVijay Khemka 
939e7d23d0eSVijay Khemka     // '*': boot flags valid, BIOS has not yet read
940010dee04SPatrick Williams     bootOrderPanel.item_str[0] =
941010dee04SPatrick Williams         std::string("Boot Order") + ((bootMode & bootValid) ? "*" : "");
942e7d23d0eSVijay Khemka 
9437bb4592aSDelphine CC Chiu     static const std::unordered_map<uint8_t, const char*>
9447bb4592aSDelphine CC Chiu         bootOrderMappingTable = {
9457bb4592aSDelphine CC Chiu             {0x00, " USB device"}, {0x01, " Network v4"}, {0x02, " SATA HDD"},
9467bb4592aSDelphine CC Chiu             {0x03, " SATA-CDROM"}, {0x04, " Other"},      {0x09, " Network v6"},
9477bb4592aSDelphine CC Chiu         };
9487bb4592aSDelphine CC Chiu 
9497bb4592aSDelphine CC Chiu     size_t validItem = 0;
9507bb4592aSDelphine CC Chiu     for (size_t i = 1; i < sizeBootOrder; i++)
951e7d23d0eSVijay Khemka     {
9527bb4592aSDelphine CC Chiu         auto find = bootOrderMappingTable.find(bootSeq[i]);
9537bb4592aSDelphine CC Chiu         if (find == bootOrderMappingTable.end())
954e7d23d0eSVijay Khemka         {
9557bb4592aSDelphine CC Chiu             lg2::error("Unknown boot order : {BOOTORDER}", "BOOTORDER",
9567bb4592aSDelphine CC Chiu                        bootSeq[i]);
957e7d23d0eSVijay Khemka             break;
958e7d23d0eSVijay Khemka         }
959e7d23d0eSVijay Khemka 
9607bb4592aSDelphine CC Chiu         bootOrderPanel.item_str[i] = find->second;
961e7d23d0eSVijay Khemka 
9627bb4592aSDelphine CC Chiu         validItem++;
963e39f9393SWilly Tu     }
9647bb4592aSDelphine CC Chiu 
9657bb4592aSDelphine CC Chiu     bootOrderPanel.item_num = validItem;
966a758d0a4SPatrick Williams     return panel::BOOT_ORDER;
967e7d23d0eSVijay Khemka }
968e7d23d0eSVijay Khemka 
panel_power_policy(size_t)969a758d0a4SPatrick Williams static panel panel_power_policy(size_t)
970e7d23d0eSVijay Khemka {
971e39f9393SWilly Tu /* To be cleaned */
972e39f9393SWilly Tu #if 0
973e7d23d0eSVijay Khemka     uint8_t buff[32] = {0};
974e7d23d0eSVijay Khemka     uint8_t res_len;
97539836ffaSKarthikeyan Pasupathi     size_t pos = plat_get_fru_sel();
976e7d23d0eSVijay Khemka     uint8_t policy;
977e39f9393SWilly Tu     uint8_t pwr_policy_item_map[3] = {POWER_CFG_ON, POWER_CFG_LPS,
978e39f9393SWilly Tu                                       POWER_CFG_OFF};
979e7d23d0eSVijay Khemka 
980e39f9393SWilly Tu     if (pos != FRU_ALL)
981e39f9393SWilly Tu     {
982e39f9393SWilly Tu         if (item > 0 && item <= sizeof(pwr_policy_item_map))
983e39f9393SWilly Tu         {
984e7d23d0eSVijay Khemka             policy = pwr_policy_item_map[item - 1];
98513ce3793SPatrick Williams             pal_set_power_restore_policy(pos, &policy, nullptr);
986e7d23d0eSVijay Khemka         }
98713ce3793SPatrick Williams         pal_get_chassis_status(pos, nullptr, buff, &res_len);
988e7d23d0eSVijay Khemka         policy = (((uint8_t)buff[0]) >> 5) & 0x7;
989e39f9393SWilly Tu         snprintf(panels[PANEL_POWER_POLICY].item_str[1], 32, "%cPower On",
990e39f9393SWilly Tu                  policy == POWER_CFG_ON ? '*' : ' ');
991e39f9393SWilly Tu         snprintf(panels[PANEL_POWER_POLICY].item_str[2], 32, "%cLast State",
992e39f9393SWilly Tu                  policy == POWER_CFG_LPS ? '*' : ' ');
993e39f9393SWilly Tu         snprintf(panels[PANEL_POWER_POLICY].item_str[3], 32, "%cPower Off",
994e39f9393SWilly Tu                  policy == POWER_CFG_OFF ? '*' : ' ');
995e7d23d0eSVijay Khemka         panels[PANEL_POWER_POLICY].item_num = 3;
996e39f9393SWilly Tu     }
997e39f9393SWilly Tu     else
998e39f9393SWilly Tu     {
999e7d23d0eSVijay Khemka         panels[PANEL_POWER_POLICY].item_num = 0;
1000e7d23d0eSVijay Khemka     }
1001e39f9393SWilly Tu #endif
1002a758d0a4SPatrick Williams     return panel::POWER_POLICY;
1003e7d23d0eSVijay Khemka }
1004e7d23d0eSVijay Khemka 
plat_udbg_control_panel(uint8_t cur_panel,uint8_t operation,uint8_t item,uint8_t * count,uint8_t * buffer)1005a758d0a4SPatrick Williams ipmi_ret_t plat_udbg_control_panel(uint8_t cur_panel, uint8_t operation,
10065e589481SPatrick Williams                                    uint8_t item, uint8_t* count,
10075e589481SPatrick Williams                                    uint8_t* buffer)
1008e7d23d0eSVijay Khemka {
1009a758d0a4SPatrick Williams     if (cur_panel > panelNum || cur_panel < std::to_underlying(panel::MAIN))
1010e7d23d0eSVijay Khemka         return IPMI_CC_PARM_OUT_OF_RANGE;
1011e7d23d0eSVijay Khemka 
1012e7d23d0eSVijay Khemka     // No more item; End of item list
1013a758d0a4SPatrick Williams     if (item > panels[cur_panel].item_num)
1014e7d23d0eSVijay Khemka         return IPMI_CC_PARM_OUT_OF_RANGE;
1015e7d23d0eSVijay Khemka 
1016e7d23d0eSVijay Khemka     switch (operation)
1017e7d23d0eSVijay Khemka     {
1018e7d23d0eSVijay Khemka         case 0: // Get Description
1019e7d23d0eSVijay Khemka             break;
1020e7d23d0eSVijay Khemka         case 1: // Select item
1021a758d0a4SPatrick Williams             cur_panel = std::to_underlying(panels[cur_panel].select(item));
1022e7d23d0eSVijay Khemka             item = 0;
1023e7d23d0eSVijay Khemka             break;
1024e7d23d0eSVijay Khemka         case 2: // Back
1025a758d0a4SPatrick Williams             cur_panel = std::to_underlying(panels[cur_panel].parent);
1026e7d23d0eSVijay Khemka             item = 0;
1027e7d23d0eSVijay Khemka             break;
1028e7d23d0eSVijay Khemka         default:
1029e7d23d0eSVijay Khemka             return IPMI_CC_PARM_OUT_OF_RANGE;
1030e7d23d0eSVijay Khemka     }
1031e7d23d0eSVijay Khemka 
1032a758d0a4SPatrick Williams     buffer[0] = cur_panel;
1033e7d23d0eSVijay Khemka     buffer[1] = item;
1034a758d0a4SPatrick Williams     buffer[2] = std::size(panels[cur_panel].item_str[item]);
10357bb4592aSDelphine CC Chiu 
103613ce3793SPatrick Williams     if (buffer[2] > 0 && (buffer[2] + 3u) < FRAME_PAGE_BUF_SIZE)
1037e7d23d0eSVijay Khemka     {
1038a758d0a4SPatrick Williams         std::memcpy(&buffer[3], (panels[cur_panel].item_str[item]).c_str(),
10397bb4592aSDelphine CC Chiu                     buffer[2]);
1040e7d23d0eSVijay Khemka     }
1041e7d23d0eSVijay Khemka     *count = buffer[2] + 3;
1042e7d23d0eSVijay Khemka     return IPMI_CC_OK;
1043e7d23d0eSVijay Khemka }
1044e7d23d0eSVijay Khemka 
1045e7d23d0eSVijay Khemka } // end of namespace ipmi
1046