blob: bb2052e4d137044c2ddc131a1151d45bc16b5d3e [file] [log] [blame]
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001/*
2 * Copyright (c) 2018-present Facebook. All Rights Reserved.
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
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +053017#include <commandutils.hpp>
Patrick Williams2405ae92023-05-10 07:50:09 -050018#include <usb-dbg.hpp>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080019
20namespace ipmi
21{
22
Vijay Khemka63c99be2020-05-27 19:14:35 -070023ipmi_ret_t getNetworkData(uint8_t lan_param, char* data);
24int8_t getFruData(std::string& serial, std::string& name);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +053025int8_t sysConfig(std::vector<std::string>& data, size_t pos);
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +053026int8_t procInfo(std::string& result, size_t pos);
Vijay Khemkae7d23d02019-03-08 13:13:40 -080027
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053028bool isMultiHostPlatform();
29
30/* Declare Host Selector interface and path */
31namespace selector
32{
33const std::string path = "/xyz/openbmc_project/Chassis/Buttons/HostSelector";
34const std::string interface =
Potin Laicff150e2022-09-19 09:34:57 +080035 "xyz.openbmc_project.Chassis.Buttons.HostSelector";
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053036} // namespace selector
37
Vijay Khemka427b2762019-12-12 12:49:25 -080038/* Declare storage functions used here */
39namespace storage
40{
Vijay Khemka63c99be2020-05-27 19:14:35 -070041int getSensorValue(std::string&, double&);
42int getSensorUnit(std::string&, std::string&);
Delphine CC Chiu2ca4aa02023-02-01 16:30:18 +080043int getSensorThreshold(std::string&, std::string&);
Vijay Khemka58bd5d82019-12-13 11:05:56 -080044} // namespace storage
Vijay Khemka427b2762019-12-12 12:49:25 -080045
Delphine CC Chiu7bb45922023-04-10 13:34:04 +080046namespace boot
47{
48std::tuple<std::string, std::string> objPath(size_t id);
49void setBootOrder(std::string bootObjPath, const std::vector<uint8_t>& bootSeq,
50 std::string hostName);
51void getBootOrder(std::string bootObjPath, std::vector<uint8_t>& bootSeq,
52 std::string hostName);
53} // namespace boot
54
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053055void getMaxHostPosition(size_t& maxPosition)
Potin Laif24c78e2022-10-27 17:13:14 +080056{
57 try
58 {
59 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
Patrick Williams010dee02024-08-16 15:19:44 -040060 std::string service =
61 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
62 Value variant =
63 getDbusProperty(*dbus, service, ipmi::selector::path,
64 ipmi::selector::interface, "MaxPosition");
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053065 maxPosition = std::get<size_t>(variant);
Potin Laif24c78e2022-10-27 17:13:14 +080066 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053067 catch (const std::exception& e)
Potin Laif24c78e2022-10-27 17:13:14 +080068 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053069 lg2::error("Unable to get max host position - {MAXPOSITION}",
70 "MAXPOSITION", maxPosition);
71 throw e;
Potin Laif24c78e2022-10-27 17:13:14 +080072 }
Potin Laif24c78e2022-10-27 17:13:14 +080073}
74
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053075void getSelectorPosition(size_t& hostPosition)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053076{
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053077 try
78 {
79 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
Patrick Williams010dee02024-08-16 15:19:44 -040080 std::string service =
81 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053082 Value variant = getDbusProperty(*dbus, service, ipmi::selector::path,
83 ipmi::selector::interface, "Position");
84 hostPosition = std::get<size_t>(variant);
85 }
86 catch (const std::exception& e)
87 {
88 lg2::error("Unable to get host position - {POSITION}", "POSITION",
89 hostPosition);
90 throw e;
91 }
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053092}
93
Vijay Khemkae7d23d02019-03-08 13:13:40 -080094static int panelNum = (sizeof(panels) / sizeof(struct ctrl_panel)) - 1;
95
96/* Returns the FRU the hand-switch is switched to. If it is switched to BMC
97 * it returns FRU_ALL. Note, if in err, it returns FRU_ALL */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053098static size_t plat_get_fru_sel()
Vijay Khemkae7d23d02019-03-08 13:13:40 -080099{
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530100 size_t position;
101 bool platform = isMultiHostPlatform();
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530102 if (platform == true)
103 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530104 getSelectorPosition(position);
105 if (position == BMC_POSITION)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530106 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530107 return FRU_ALL;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530108 }
109 }
110 else
111 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530112 /* For Tiogapass it just return 1,
113 * can modify to support more platform */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530114 position = 1;
115 }
116 return position;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800117}
118
119// return 0 on seccuess
Patrick Williams13ce3792024-08-27 13:03:46 -0400120void frame::init(size_t size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800121{
122 // Reset status
123 idx_head = idx_tail = 0;
124 lines = 0;
125 esc_sts = 0;
126 pages = 1;
127
Patrick Williams13ce3792024-08-27 13:03:46 -0400128 if (buf != nullptr && max_size == size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800129 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400130 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800131 }
132
Patrick Williams13ce3792024-08-27 13:03:46 -0400133 if (buf != nullptr && max_size != size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800134 {
135 delete[] buf;
136 }
137 // Initialize Configuration
138 title[0] = '\0';
139 buf = new char[size];
140 max_size = size;
141 max_page = size;
142 line_per_page = 7;
143 line_width = 16;
Patrick Williams13ce3792024-08-27 13:03:46 -0400144 overwrite = false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800145
Patrick Williams13ce3792024-08-27 13:03:46 -0400146 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800147}
148
149// return 0 on seccuess
Patrick Williams13ce3792024-08-27 13:03:46 -0400150void frame::append(const std::string& str, size_t indent)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800151{
Patrick Williams13ce3792024-08-27 13:03:46 -0400152 for (auto ch : parse(str, indent))
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800153 {
154 if (isFull())
155 {
156 if (overwrite)
157 {
158 if (buf[idx_head] == LINE_DELIMITER)
159 lines--;
160 idx_head = (idx_head + 1) % max_size;
161 }
162 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400163 {
164 throw std::overflow_error("No room in buffer");
165 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800166 }
167
Patrick Williams13ce3792024-08-27 13:03:46 -0400168 buf[idx_tail] = ch;
169 if (ch == LINE_DELIMITER)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800170 lines++;
171
172 idx_tail = (idx_tail + 1) % max_size;
173 }
174
175 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
176
177 if (pages > max_page)
178 pages = max_page;
179
Patrick Williams13ce3792024-08-27 13:03:46 -0400180 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800181}
182
183// return page size
Patrick Williams13ce3792024-08-27 13:03:46 -0400184int frame::getPage(size_t page, char* page_buf, size_t page_buf_size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800185{
186 int ret;
187 uint16_t line = 0;
188 uint16_t idx, len;
189
Patrick Williams13ce3792024-08-27 13:03:46 -0400190 if (buf == nullptr)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800191 return -1;
192
193 // 1-based page
194 if (page > pages || page < 1)
195 return -1;
196
Patrick Williams13ce3792024-08-27 13:03:46 -0400197 if (page_buf == nullptr || page_buf_size == 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800198 return -1;
199
Patrick Williams13ce3792024-08-27 13:03:46 -0400200 ret = snprintf(page_buf, 17, "%-10s %02zd/%02zd", title, page, pages);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800201 len = strlen(page_buf);
202 if (ret < 0)
203 return -1;
204
205 line = 0;
206 idx = idx_head;
207 while (line < ((page - 1) * line_per_page) && idx != idx_tail)
208 {
209 if (buf[idx] == LINE_DELIMITER)
210 line++;
211 idx = (idx + 1) % max_size;
212 }
213
214 while (line < ((page)*line_per_page) && idx != idx_tail)
215 {
216 if (buf[idx] == LINE_DELIMITER)
217 {
218 line++;
219 }
220 else
221 {
222 page_buf[len++] = buf[idx];
223 if (len == (page_buf_size - 1))
224 {
225 break;
226 }
227 }
228 idx = (idx + 1) % max_size;
229 }
230
231 return len;
232}
233
Patrick Williams13ce3792024-08-27 13:03:46 -0400234bool frame::isFull() const
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800235{
Patrick Williams13ce3792024-08-27 13:03:46 -0400236 if (buf == nullptr)
237 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800238
239 if ((idx_tail + 1) % max_size == idx_head)
Patrick Williams13ce3792024-08-27 13:03:46 -0400240 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800241 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400242 return false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800243}
244
245// return 1 for Escape Sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400246bool frame::isEscSeq(char chr)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800247{
248 uint8_t curr_sts = esc_sts;
249
250 if (esc_sts == 0 && (chr == 0x1b))
251 esc_sts = 1; // Escape Sequence
252 else if (esc_sts == 1 && (chr == 0x5b))
253 esc_sts = 2; // Control Sequence Introducer(CSI)
254 else if (esc_sts == 1 && (chr != 0x5b))
255 esc_sts = 0;
256 else if (esc_sts == 2 && (chr >= 0x40 && chr <= 0x7e))
257 esc_sts = 0;
258
259 if (curr_sts || esc_sts)
Patrick Williams13ce3792024-08-27 13:03:46 -0400260 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800261 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400262 return false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800263}
264
265// return 0 on success
Patrick Williams13ce3792024-08-27 13:03:46 -0400266auto frame::parse(const std::string& input, size_t indent) -> std::string
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800267{
Patrick Williams13ce3792024-08-27 13:03:46 -0400268 if (indent > line_width)
269 return {};
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800270
Patrick Williams13ce3792024-08-27 13:03:46 -0400271 std::string result;
272 size_t linepos = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800273
Patrick Williams13ce3792024-08-27 13:03:46 -0400274 for (auto ch : input)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800275 {
Cosmo Chou6c02bfb2024-08-29 15:49:42 +0800276 if (linepos == 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800277 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400278 result.append(indent, ' ');
279 linepos = indent;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800280 }
281
Patrick Williams13ce3792024-08-27 13:03:46 -0400282 // Insert character.
283 result.push_back(ch);
Cosmo Chou6c02bfb2024-08-29 15:49:42 +0800284
285 if (!isEscSeq(ch))
286 {
287 // Check if new line is needed.
288 if (++linepos == line_width)
289 {
290 result.push_back(LINE_DELIMITER);
291 linepos = 0;
292 }
293 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800294 }
295
Patrick Williams13ce3792024-08-27 13:03:46 -0400296 // Fill out remaining line.
297 result.append(line_width - linepos, ' ');
298 result.push_back(LINE_DELIMITER);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800299
Patrick Williams13ce3792024-08-27 13:03:46 -0400300 return result;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800301}
302
Vijay Khemka63c99be2020-05-27 19:14:35 -0700303static int chk_cri_sel_update(uint8_t* cri_sel_up)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800304{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700305 FILE* fp;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800306 struct stat file_stat;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530307 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800308 static uint8_t pre_pos = 0xff;
309
310 fp = fopen("/mnt/data/cri_sel", "r");
311 if (fp)
312 {
313 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
314 (file_stat.st_mtime != frame_sel.mtime || pre_pos != pos))
315 {
316 *cri_sel_up = 1;
317 }
318 else
319 {
320 *cri_sel_up = 0;
321 }
322 fclose(fp);
323 }
324 else
325 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400326 if (frame_sel.buf == nullptr || frame_sel.lines != 0 || pre_pos != pos)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800327 {
328 *cri_sel_up = 1;
329 }
330 else
331 {
332 *cri_sel_up = 0;
333 }
334 }
335 pre_pos = pos;
336 return 0;
337}
338
Vijay Khemka63c99be2020-05-27 19:14:35 -0700339int plat_udbg_get_frame_info(uint8_t* num)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800340{
341 *num = 3;
342 return 0;
343}
344
Vijay Khemka63c99be2020-05-27 19:14:35 -0700345int plat_udbg_get_updated_frames(uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800346{
347 uint8_t cri_sel_up = 0;
348 uint8_t info_page_up = 1;
349
350 *count = 0;
351
352 // info page update
353 if (info_page_up == 1)
354 {
355 buffer[*count] = 1;
356 *count += 1;
357 }
358
359 // cri sel update
360 chk_cri_sel_update(&cri_sel_up);
361 if (cri_sel_up == 1)
362 {
363 buffer[*count] = 2;
364 *count += 1;
365 }
366
367 // cri sensor update
368 buffer[*count] = 3;
369 *count += 1;
370
371 return 0;
372}
373
Vijay Khemka63c99be2020-05-27 19:14:35 -0700374int plat_udbg_get_post_desc(uint8_t index, uint8_t* next, uint8_t phase,
375 uint8_t* end, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800376{
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700377 nlohmann::json postObj;
378 std::string postCode;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800379
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700380 /* Get post description data stored in json file */
381 std::ifstream file(JSON_POST_DATA_FILE);
382 if (file)
383 {
384 file >> postObj;
385 file.close();
386 }
387 else
388 {
389 phosphor::logging::log<phosphor::logging::level::ERR>(
390 "Post code description file not found",
391 phosphor::logging::entry("POST_CODE_FILE=%s", JSON_POST_DATA_FILE));
392 return -1;
393 }
394
395 std::string phaseStr = "PhaseAny";
396 if (postObj.find(phaseStr) == postObj.end())
397 {
398 phaseStr = "Phase" + std::to_string(phase);
399 }
400
401 if (postObj.find(phaseStr) == postObj.end())
402 {
403 phosphor::logging::log<phosphor::logging::level::ERR>(
404 "Post code phase not available",
405 phosphor::logging::entry("PHASE=%d", phase));
406 return -1;
407 }
408
409 auto phaseObj = postObj[phaseStr];
410 int phaseSize = phaseObj.size();
411
412 for (int i = 0; i < phaseSize; i++)
413 {
414 postCode = phaseObj[i][0];
415 if (index == stoul(postCode, nullptr, 16))
416 {
417 std::string postDesc = phaseObj[i][1];
418 *length = postDesc.size();
419 memcpy(buffer, postDesc.data(), *length);
420 buffer[*length] = '\0';
421
422 if (phaseSize != i + 1)
423 {
424 postCode = phaseObj[i + 1][0];
425 *next = stoul(postCode, nullptr, 16);
426 *end = 0;
427 }
428 else
429 {
430 if (postObj.size() != phase)
431 {
Patrick Williams010dee02024-08-16 15:19:44 -0400432 std::string nextPhaseStr =
433 "Phase" + std::to_string(phase + 1);
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700434 postCode = postObj[nextPhaseStr][0][0];
435 *next = stoul(postCode, nullptr, 16);
436 *end = 0;
437 }
438 else
439 {
440 *next = 0xff;
441 *end = 1;
442 }
443 }
444
445 return 0;
446 }
447 }
448
449 phosphor::logging::log<phosphor::logging::level::ERR>(
450 "Post code description data not available",
451 phosphor::logging::entry("PHASE_CODE=%d_0x%x", phase, index));
452 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800453}
454
Vijay Khemka63c99be2020-05-27 19:14:35 -0700455int plat_udbg_get_gpio_desc(uint8_t index, uint8_t* next, uint8_t* level,
456 uint8_t* def, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800457{
Vijay Khemka38183d62019-08-28 16:19:33 -0700458 nlohmann::json gpioObj;
459 std::string gpioPin;
460
461 /* Get gpio data stored in json file */
462 std::ifstream file(JSON_GPIO_DATA_FILE);
463 if (file)
464 {
465 file >> gpioObj;
466 file.close();
467 }
468 else
469 {
470 phosphor::logging::log<phosphor::logging::level::ERR>(
471 "GPIO pin description file not found",
472 phosphor::logging::entry("GPIO_PIN_DETAILS_FILE=%s",
473 JSON_GPIO_DATA_FILE));
474 return -1;
475 }
476
477 if (gpioObj.find(DEBUG_GPIO_KEY) == gpioObj.end())
478 {
479 phosphor::logging::log<phosphor::logging::level::ERR>(
480 "GPIO pin details not available",
481 phosphor::logging::entry("GPIO_JSON_KEY=%d", DEBUG_GPIO_KEY));
482 return -1;
483 }
484
485 auto obj = gpioObj[DEBUG_GPIO_KEY];
486 int objSize = obj.size();
487
488 for (int i = 0; i < objSize; i++)
489 {
490 if (obj[i].size() != GPIO_ARRAY_SIZE)
491 {
492 phosphor::logging::log<phosphor::logging::level::ERR>(
493 "Size of gpio array is incorrect",
494 phosphor::logging::entry("EXPECTED_SIZE=%d", GPIO_ARRAY_SIZE));
495 return -1;
496 }
497
498 gpioPin = obj[i][GPIO_PIN_INDEX];
499 if (index == stoul(gpioPin, nullptr, 16))
500 {
501 if (objSize != i + 1)
502 {
503 gpioPin = obj[i + 1][GPIO_PIN_INDEX];
504 *next = stoul(gpioPin, nullptr, 16);
505 }
506 else
507 {
508 *next = 0xff;
509 }
510
511 *level = obj[i][GPIO_LEVEL_INDEX];
512 *def = obj[i][GPIO_DEF_INDEX];
513 std::string gpioDesc = obj[i][GPIO_DESC_INDEX];
514 *length = gpioDesc.size();
515 memcpy(buffer, gpioDesc.data(), *length);
516 buffer[*length] = '\0';
517
518 return 0;
519 }
520 }
521
522 phosphor::logging::log<phosphor::logging::level::ERR>(
523 "GPIO pin description data not available",
524 phosphor::logging::entry("GPIO_PIN=0x%x", index));
525 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800526}
527
Bonnie Loe9baaff2022-11-08 16:36:21 +0800528static int getBiosVer(std::string& ver, size_t hostPosition)
Vijay Khemka88884b82019-08-27 15:23:07 -0700529{
530 nlohmann::json appObj;
531
532 std::ifstream file(JSON_APP_DATA_FILE);
533 if (file)
534 {
535 file >> appObj;
536 file.close();
Bonnie Loe9baaff2022-11-08 16:36:21 +0800537 std::string version_key = KEY_SYSFW_VER + std::to_string(hostPosition);
538
539 if (appObj.find(version_key) != appObj.end())
Vijay Khemka88884b82019-08-27 15:23:07 -0700540 {
Bonnie Loe9baaff2022-11-08 16:36:21 +0800541 ver = appObj[version_key].get<std::string>();
Vijay Khemka88884b82019-08-27 15:23:07 -0700542 return 0;
543 }
544 }
545
546 return -1;
547}
548
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530549int sendBicCmd(uint8_t netFn, uint8_t cmd, uint8_t bicAddr,
550 std::vector<uint8_t>& cmdData, std::vector<uint8_t>& respData)
551{
552 static constexpr uint8_t lun = 0;
553
554 auto bus = getSdBus();
555
556 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
557 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
558 "org.openbmc.Ipmb", "sendRequest");
559 method.append(bicAddr, netFn, lun, cmd, cmdData);
560
561 auto reply = bus->call(method);
562 if (reply.is_method_error())
563 {
564 phosphor::logging::log<phosphor::logging::level::ERR>(
565 "Error reading from BIC");
566 return -1;
567 }
568
569 IpmbMethodType resp;
570 reply.read(resp);
571
572 respData =
573 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
574
575 return 0;
576}
577
Vijay Khemka63c99be2020-05-27 19:14:35 -0700578int sendMeCmd(uint8_t netFn, uint8_t cmd, std::vector<uint8_t>& cmdData,
579 std::vector<uint8_t>& respData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -0700580{
581 auto bus = getSdBus();
582
583 if (DEBUG)
584 {
585 std::cout << "ME NetFn:cmd " << (int)netFn << ":" << (int)cmd << "\n";
586 std::cout << "ME req data: ";
587 for (auto d : cmdData)
588 {
589 std::cout << d << " ";
590 }
591 std::cout << "\n";
592 }
593
594 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
595 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
596 "org.openbmc.Ipmb", "sendRequest");
597 method.append(meAddress, netFn, lun, cmd, cmdData);
598
599 auto reply = bus->call(method);
600 if (reply.is_method_error())
601 {
602 phosphor::logging::log<phosphor::logging::level::ERR>(
603 "Error reading from ME");
604 return -1;
605 }
606
607 IpmbMethodType resp;
608 reply.read(resp);
609
610 respData =
611 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
612
613 if (DEBUG)
614 {
615 std::cout << "ME resp data: ";
616 for (auto d : respData)
617 {
618 std::cout << d << " ";
619 }
620 std::cout << "\n";
621 }
622
623 return 0;
624}
625
Willy Tue39f9392022-06-15 13:24:20 -0700626static int udbg_get_info_page(uint8_t, uint8_t page, uint8_t* next,
Vijay Khemka63c99be2020-05-27 19:14:35 -0700627 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800628{
Willy Tue39f9392022-06-15 13:24:20 -0700629 char line_buff[1000];
630 [[maybe_unused]] char* pres_dev = line_buff;
631 [[maybe_unused]] size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800632 int ret;
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530633 std::string serialName = "SerialNumber";
634 std::string partName = "PartNumber";
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800635 std::string verDel = "VERSION=";
636 std::string verPath = "/etc/os-release";
BonnieLo-wiwynn21a79232023-03-09 16:42:48 +0800637 size_t hostPosition = 0;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530638 size_t maxPosition;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800639
640 if (page == 1)
641 {
642 // Only update frame data while getting page 1
643
644 // initialize and clear frame
Patrick Williams13ce3792024-08-27 13:03:46 -0400645 frame_info.init();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800646 snprintf(frame_info.title, 32, "SYS_Info");
647
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530648 bool platform = isMultiHostPlatform();
649 if (platform == true)
650 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530651 hostPosition = plat_get_fru_sel();
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530652 }
653
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530654 getMaxHostPosition(maxPosition);
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +0530655 if (hostPosition == BMC_POSITION || hostInstances == "0")
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530656 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400657 frame_info.append("FRU:spb");
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530658 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530659 else if (hostPosition != BMC_POSITION && hostPosition <= maxPosition)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530660 {
661 std::string data = "FRU:slot" + std::to_string(hostPosition);
Patrick Williams13ce3792024-08-27 13:03:46 -0400662 frame_info.append(data);
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530663 }
664
665 // FRU
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800666 std::string data;
Patrick Williams13ce3792024-08-27 13:03:46 -0400667 frame_info.append("SN:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800668 if (getFruData(data, serialName) != 0)
669 {
670 data = "Not Found";
671 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400672 frame_info.append(data, 1);
673 frame_info.append("PN:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800674 if (getFruData(data, partName) != 0)
675 {
676 data = "Not Found";
677 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400678 frame_info.append(data, 1);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800679
680 // LAN
681 getNetworkData(3, line_buff);
Patrick Williams13ce3792024-08-27 13:03:46 -0400682 frame_info.append("BMC_IP:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800683 frame_info.append(line_buff, 1);
684 getNetworkData(59, line_buff);
Patrick Williams13ce3792024-08-27 13:03:46 -0400685 frame_info.append("BMC_IPv6:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800686 frame_info.append(line_buff, 1);
687
688 // BMC ver
689 std::ifstream file(verPath);
690 if (file)
691 {
692 std::string line;
693 while (std::getline(file, line))
694 {
695 if (line.find(verDel) != std::string::npos)
696 {
697 std::string bmcVer = line.substr(verDel.size());
Patrick Williams13ce3792024-08-27 13:03:46 -0400698 frame_info.append("BMC_FW_ver:");
699 frame_info.append(bmcVer, 1);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800700 break;
701 }
702 }
703 }
704
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530705 if (hostPosition != BMC_POSITION)
Vijay Khemka88884b82019-08-27 15:23:07 -0700706 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530707 // BIOS ver
708 std::string biosVer;
Bonnie Loe9baaff2022-11-08 16:36:21 +0800709 if (getBiosVer(biosVer, hostPosition) == 0)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530710 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400711 frame_info.append("BIOS_FW_ver:");
712 frame_info.append(biosVer, 1);
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530713 }
Vijay Khemka88884b82019-08-27 15:23:07 -0700714 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800715
Vijay Khemka317999d2020-01-02 13:43:42 -0800716 /* TBD: Board ID needs implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800717 // Board ID
718
719 // Battery - Use Escape sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400720 frame_info.append("Battery:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800721 frame_info.append(ESC_BAT " ", 1);
722 // frame_info.append(&frame_info, esc_bat, 1);
723
724 // MCU Version - Use Escape sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400725 frame_info.append("MCUbl_ver:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800726 frame_info.append(ESC_MCU_BL_VER, 1);
Patrick Williams13ce3792024-08-27 13:03:46 -0400727 frame_info.append("MCU_ver:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800728 frame_info.append(ESC_MCU_RUN_VER, 1);
729
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800730 // Sys config present device
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530731 if (hostPosition != BMC_POSITION)
732 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400733 frame_info.append("Sys Conf. info:");
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530734
735 // Dimm info
736 std::vector<std::string> data;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530737 if (sysConfig(data, pos) == 0)
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530738 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530739 for (auto& info : data)
740 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400741 frame_info.append(info, 1);
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530742 }
743 }
744 else
745 {
746 frame_info.append("Not Found", 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530747 }
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +0530748
749 // Processor info
750 std::string result;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530751 if (procInfo(result, pos) != 0)
752 {
753 result = "Not Found";
754 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400755 frame_info.append(result, 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530756 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800757
758 } // End of update frame
759
760 if (page > frame_info.pages)
761 {
762 return -1;
763 }
764
Vijay Khemka63c99be2020-05-27 19:14:35 -0700765 ret = frame_info.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800766 if (ret < 0)
767 {
768 *count = 0;
769 return -1;
770 }
771 *count = (uint8_t)ret;
772
773 if (page < frame_info.pages)
774 *next = page + 1;
775 else
776 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
777 // last page
778
779 return 0;
780}
781
Peter Yinb340aa22024-07-08 16:07:55 +0800782static int udbg_get_postcode(uint8_t, uint8_t page, uint8_t* next,
783 uint8_t* count, uint8_t* buffer)
784{
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800785 // up to 70 codes can be displayed on 10 pages
786 static constexpr size_t maxPostcodes = 70;
787
788 static constexpr const char* formatStr =
789 (postCodeSize == 4) ? "{:08X}"
790 : (postCodeSize == 8) ? "{:016X}"
791 : "{:02X}";
792
Peter Yinb340aa22024-07-08 16:07:55 +0800793 if (page == 1)
794 {
795 // Initialize and clear frame (example initialization)
Patrick Williams13ce3792024-08-27 13:03:46 -0400796 frame_postcode.init();
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800797 snprintf(frame_postcode.title, 32, "POST CODE");
798 frame_postcode.max_page = 10;
Peter Yinb340aa22024-07-08 16:07:55 +0800799
800 // Synchronously get D-Bus connection
801 auto bus = sdbusplus::bus::new_default();
802
803 // Build D-Bus method call
804 auto method = bus.new_method_call(
805 "xyz.openbmc_project.State.Boot.PostCode0", // Target service name
806 "/xyz/openbmc_project/State/Boot/PostCode0", // Object path
807 "xyz.openbmc_project.State.Boot.PostCode", // Interface name
808 "GetPostCodes"); // Method name
809
810 method.append(uint16_t(1)); // Add method parameter, assuming it's page
811
812 try
813 {
814 auto reply = bus.call(method); // Send synchronous method call
815
816 // Read postcode value
817 std::vector<std::tuple<uint64_t, std::vector<uint8_t>>> postcodes;
818 reply.read(postcodes);
819
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800820 // retrieve the latest postcodes
821 size_t numEntries = std::min(maxPostcodes, postcodes.size());
822 for (auto it = postcodes.rbegin();
823 it != postcodes.rbegin() + numEntries; ++it)
Peter Yinb340aa22024-07-08 16:07:55 +0800824 {
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800825 const auto& [code, extra] = *it;
826 std::string result = std::format(formatStr, code);
Potin Lai3c9f5b62024-08-28 13:40:37 +0800827 for (const auto& byte : extra)
828 {
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800829 result += std::format("{:02X}", byte);
Potin Lai3c9f5b62024-08-28 13:40:37 +0800830 }
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800831
Patrick Williams13ce3792024-08-27 13:03:46 -0400832 frame_postcode.append(result);
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800833 if (frame_postcode.lines >= maxPostcodes)
834 {
835 break;
836 }
Peter Yinb340aa22024-07-08 16:07:55 +0800837 }
838 }
839 catch (const std::exception& e)
840 {
841 // Handle exceptions
842 std::cerr << "Error retrieving postcodes: " << e.what()
843 << std::endl;
844 return -1;
845 }
846 }
847
848 if (page > frame_postcode.pages)
849 {
850 return -1;
851 }
852
853 int ret = frame_postcode.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
854 if (ret < 0)
855 {
856 *count = 0;
857 return -1;
858 }
859 *count = (uint8_t)ret;
860
861 if (page < frame_postcode.pages)
862 *next = page + 1;
863 else
864 *next = 0xFF; // Set next to 0xFF to indicate last page
865 return 0;
866}
867
Vijay Khemka63c99be2020-05-27 19:14:35 -0700868int plat_udbg_get_frame_data(uint8_t frame, uint8_t page, uint8_t* next,
869 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800870{
871 switch (frame)
872 {
873 case 1: // info_page
874 return udbg_get_info_page(frame, page, next, count, buffer);
Peter Yinb340aa22024-07-08 16:07:55 +0800875 case 2: // Extra Post Code
876 return udbg_get_postcode(frame, page, next, count, buffer);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800877 default:
878 return -1;
879 }
880}
881
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400882static panel panel_main(size_t item)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800883{
884 // Update item list when select item 0
885 switch (item)
886 {
887 case 1:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400888 return panels[std::to_underlying(panel::BOOT_ORDER)].select(0);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800889 case 2:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400890 return panels[std::to_underlying(panel::POWER_POLICY)].select(0);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800891 default:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400892 return panel::MAIN;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800893 }
894}
895
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400896static panel panel_boot_order(size_t selectedItemIndex)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800897{
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800898 static constexpr size_t sizeBootOrder = 6;
899 static constexpr size_t bootValid = 0x80;
900
901 std::vector<uint8_t> bootSeq;
902
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400903 ctrl_panel& bootOrderPanel = panels[std::to_underlying(panel::BOOT_ORDER)];
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800904
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530905 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800906
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800907 if (pos == FRU_ALL)
908 {
909 bootOrderPanel.item_num = 0;
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400910 return panel::BOOT_ORDER;
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800911 }
912
913 auto [bootObjPath, hostName] = ipmi::boot::objPath(pos);
914 ipmi::boot::getBootOrder(bootObjPath, bootSeq, hostName);
915
916 uint8_t& bootMode = bootSeq.front();
917
918 // One item is selected to set a new boot sequence.
919 // The selected item become the first boot order.
920 if (selectedItemIndex > 0 && selectedItemIndex < sizeBootOrder)
921 {
922 // Move the selected item to second element (the first one is boot mode)
923 std::rotate(bootSeq.begin() + 1, bootSeq.begin() + selectedItemIndex,
924 bootSeq.begin() + selectedItemIndex + 1);
925
926 bootMode |= bootValid;
927 try
928 {
929 ipmi::boot::setBootOrder(bootObjPath, bootSeq, hostName);
930 }
931 catch (const std::exception& e)
932 {
933 lg2::error("Fail to set boot order : {ERROR}", "ERROR", e);
Willy Tue39f9392022-06-15 13:24:20 -0700934 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800935
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800936 // refresh items
937 return bootOrderPanel.select(0);
938 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800939
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800940 // '*': boot flags valid, BIOS has not yet read
Patrick Williams010dee02024-08-16 15:19:44 -0400941 bootOrderPanel.item_str[0] =
942 std::string("Boot Order") + ((bootMode & bootValid) ? "*" : "");
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800943
944 static const std::unordered_map<uint8_t, const char*>
945 bootOrderMappingTable = {
946 {0x00, " USB device"}, {0x01, " Network v4"}, {0x02, " SATA HDD"},
947 {0x03, " SATA-CDROM"}, {0x04, " Other"}, {0x09, " Network v6"},
948 };
949
950 size_t validItem = 0;
951 for (size_t i = 1; i < sizeBootOrder; i++)
952 {
953 auto find = bootOrderMappingTable.find(bootSeq[i]);
954 if (find == bootOrderMappingTable.end())
Willy Tue39f9392022-06-15 13:24:20 -0700955 {
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800956 lg2::error("Unknown boot order : {BOOTORDER}", "BOOTORDER",
957 bootSeq[i]);
958 break;
Willy Tue39f9392022-06-15 13:24:20 -0700959 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800960
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800961 bootOrderPanel.item_str[i] = find->second;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800962
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800963 validItem++;
Willy Tue39f9392022-06-15 13:24:20 -0700964 }
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800965
966 bootOrderPanel.item_num = validItem;
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400967 return panel::BOOT_ORDER;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800968}
969
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400970static panel panel_power_policy(size_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800971{
Willy Tue39f9392022-06-15 13:24:20 -0700972/* To be cleaned */
973#if 0
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800974 uint8_t buff[32] = {0};
975 uint8_t res_len;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530976 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800977 uint8_t policy;
Willy Tue39f9392022-06-15 13:24:20 -0700978 uint8_t pwr_policy_item_map[3] = {POWER_CFG_ON, POWER_CFG_LPS,
979 POWER_CFG_OFF};
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800980
Willy Tue39f9392022-06-15 13:24:20 -0700981 if (pos != FRU_ALL)
982 {
983 if (item > 0 && item <= sizeof(pwr_policy_item_map))
984 {
985 policy = pwr_policy_item_map[item - 1];
Patrick Williams13ce3792024-08-27 13:03:46 -0400986 pal_set_power_restore_policy(pos, &policy, nullptr);
Willy Tue39f9392022-06-15 13:24:20 -0700987 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400988 pal_get_chassis_status(pos, nullptr, buff, &res_len);
Willy Tue39f9392022-06-15 13:24:20 -0700989 policy = (((uint8_t)buff[0]) >> 5) & 0x7;
990 snprintf(panels[PANEL_POWER_POLICY].item_str[1], 32, "%cPower On",
991 policy == POWER_CFG_ON ? '*' : ' ');
992 snprintf(panels[PANEL_POWER_POLICY].item_str[2], 32, "%cLast State",
993 policy == POWER_CFG_LPS ? '*' : ' ');
994 snprintf(panels[PANEL_POWER_POLICY].item_str[3], 32, "%cPower Off",
995 policy == POWER_CFG_OFF ? '*' : ' ');
996 panels[PANEL_POWER_POLICY].item_num = 3;
997 }
998 else
999 {
1000 panels[PANEL_POWER_POLICY].item_num = 0;
1001 }
1002#endif
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001003 return panel::POWER_POLICY;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001004}
1005
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001006ipmi_ret_t plat_udbg_control_panel(uint8_t cur_panel, uint8_t operation,
Patrick Williams5e589482024-07-13 16:18:13 -05001007 uint8_t item, uint8_t* count,
1008 uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001009{
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001010 if (cur_panel > panelNum || cur_panel < std::to_underlying(panel::MAIN))
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001011 return IPMI_CC_PARM_OUT_OF_RANGE;
1012
1013 // No more item; End of item list
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001014 if (item > panels[cur_panel].item_num)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001015 return IPMI_CC_PARM_OUT_OF_RANGE;
1016
1017 switch (operation)
1018 {
1019 case 0: // Get Description
1020 break;
1021 case 1: // Select item
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001022 cur_panel = std::to_underlying(panels[cur_panel].select(item));
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001023 item = 0;
1024 break;
1025 case 2: // Back
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001026 cur_panel = std::to_underlying(panels[cur_panel].parent);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001027 item = 0;
1028 break;
1029 default:
1030 return IPMI_CC_PARM_OUT_OF_RANGE;
1031 }
1032
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001033 buffer[0] = cur_panel;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001034 buffer[1] = item;
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001035 buffer[2] = std::size(panels[cur_panel].item_str[item]);
Delphine CC Chiu7bb45922023-04-10 13:34:04 +08001036
Patrick Williams13ce3792024-08-27 13:03:46 -04001037 if (buffer[2] > 0 && (buffer[2] + 3u) < FRAME_PAGE_BUF_SIZE)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001038 {
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001039 std::memcpy(&buffer[3], (panels[cur_panel].item_str[item]).c_str(),
Delphine CC Chiu7bb45922023-04-10 13:34:04 +08001040 buffer[2]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001041 }
1042 *count = buffer[2] + 3;
1043 return IPMI_CC_OK;
1044}
1045
1046} // end of namespace ipmi