1 // SPDX-License-Identifier: GPL-2.0+
3 * Building an expo from an FDT description
5 * Copyright 2022 Google LLC
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);