1 // SPDX-License-Identifier: GPL-2.0+
3 * Building an expo from an FDT description
5 * Copyright 2022 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
9 #define LOG_CATEGORY LOGC_EXPO
18 #include <asm/cb_sysinfo.h>
21 * struct build_info - Information to use when building
24 const struct cb_cmos_option_table
*tab
;
25 struct cedit_priv
*priv
;
29 * convert_to_title() - Convert text to 'title' format and allocate a string
31 * Converts "this_is_a_test" to "This is a test" so it looks better
33 * @text: Text to convert
34 * Return: Allocated string, or NULL if out of memory
36 static char *convert_to_title(const char *text
)
38 int len
= strlen(text
);
41 buf
= malloc(len
+ 1);
45 for (s
= buf
; *text
; s
++, text
++) {
48 else if (*text
== '_')
59 * menu_build() - Build a menu and add it to a scene
61 * See doc/developer/expo.rst for a description of the format
63 * @info: Build information
64 * @entry: CMOS entry to build a menu for
65 * @scn: Scene to add the menu to
66 * @objp: Returns the object pointer
67 * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
68 * error, -ENOENT if there is a references to a non-existent string
70 static int menu_build(struct build_info
*info
,
71 const struct cb_cmos_entries
*entry
, struct scene
*scn
,
72 struct scene_obj
**objp
)
74 struct scene_obj_menu
*menu
;
75 const void *ptr
, *end
;
80 ret
= scene_menu(scn
, entry
->name
, 0, &menu
);
82 return log_msg_ret("men", ret
);
85 title
= convert_to_title(entry
->name
);
87 return log_msg_ret("con", -ENOMEM
);
90 ret
= scene_txt_str(scn
, "title", 0, 0, title
, NULL
);
92 return log_msg_ret("tit", ret
);
95 end
= (void *)info
->tab
+ info
->tab
->size
;
96 for (ptr
= (void *)info
->tab
+ info
->tab
->header_length
, i
= 0;
98 const struct cb_cmos_enums
*enums
= ptr
;
99 struct scene_menitem
*item
;
103 if (enums
->tag
!= CB_TAG_OPTION_ENUM
||
104 enums
->config_id
!= entry
->config_id
)
107 ret
= scene_txt_str(scn
, enums
->text
, 0, 0, enums
->text
, NULL
);
109 return log_msg_ret("tit", ret
);
112 ret
= scene_menuitem(scn
, menu_id
, simple_xtoa(i
), 0, 0, label
,
115 return log_msg_ret("mi", ret
);
116 item
->value
= enums
->value
;
124 * scene_build() - Build a scene and all its objects
126 * See doc/developer/expo.rst for a description of the format
128 * @info: Build information
129 * @scn: Scene to add the object to
130 * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
131 * error, -ENOENT if there is a references to a non-existent string
133 static int scene_build(struct build_info
*info
, struct expo
*exp
)
135 struct scene_obj_menu
*menu
;
136 const void *ptr
, *end
;
137 struct scene_obj
*obj
;
142 ret
= scene_new(exp
, "cmos", 0, &scn
);
144 return log_msg_ret("scn", ret
);
146 ret
= scene_txt_str(scn
, "title", 0, 0, "CMOS RAM settings", NULL
);
148 return log_msg_ret("add", ret
);
151 ret
= scene_txt_str(scn
, "prompt", 0, 0,
152 "UP and DOWN to choose, ENTER to select", NULL
);
154 return log_msg_ret("add", ret
);
156 end
= (void *)info
->tab
+ info
->tab
->size
;
157 for (ptr
= (void *)info
->tab
+ info
->tab
->header_length
; ptr
< end
;) {
158 const struct cb_cmos_entries
*entry
;
159 const struct cb_record
*rec
= ptr
;
163 if (rec
->tag
!= CB_TAG_OPTION
)
165 switch (entry
->config
) {
167 ret
= menu_build(info
, entry
, scn
, &obj
);
173 return log_msg_ret("add", ret
);
175 obj
->start_bit
= entry
->bit
;
176 obj
->bit_length
= entry
->length
;
179 ret
= scene_menu(scn
, "save", EXPOID_SAVE
, &menu
);
181 return log_msg_ret("men", ret
);
184 ret
= scene_txt_str(scn
, "save", 0, 0, "Save and exit", NULL
);
186 return log_msg_ret("sav", ret
);
188 ret
= scene_menuitem(scn
, menu_id
, "save", 0, 0, label
,
191 return log_msg_ret("mi", ret
);
193 ret
= scene_menu(scn
, "nosave", EXPOID_DISCARD
, &menu
);
195 return log_msg_ret("men", ret
);
198 ret
= scene_txt_str(scn
, "nosave", 0, 0, "Exit without saving", NULL
);
200 return log_msg_ret("nos", ret
);
202 ret
= scene_menuitem(scn
, menu_id
, "exit", 0, 0, label
,
205 return log_msg_ret("mi", ret
);
210 static int build_it(struct build_info
*info
, struct expo
**expp
)
215 ret
= expo_new("coreboot", NULL
, &exp
);
217 return log_msg_ret("exp", ret
);
218 expo_set_dynamic_start(exp
, EXPOID_BASE_ID
);
220 ret
= scene_build(info
, exp
);
222 return log_msg_ret("scn", ret
);
229 int cb_expo_build(struct expo
**expp
)
231 struct build_info info
;
235 info
.tab
= lib_sysinfo
.option_table
;
237 return log_msg_ret("tab", -ENOENT
);
239 ret
= build_it(&info
, &exp
);
241 return log_msg_ret("bui", ret
);