const efi_guid_t efi_guid_hii_string_protocol = EFI_HII_STRING_PROTOCOL_GUID;
static LIST_HEAD(efi_package_lists);
+static LIST_HEAD(efi_keyboard_layout_list);
struct efi_hii_packagelist {
struct list_head link;
efi_handle_t driver_handle;
u32 max_string_id;
struct list_head string_tables; /* list of efi_string_table */
+ struct list_head guid_list;
+ struct list_head keyboard_packages;
/* we could also track fonts, images, etc */
};
struct efi_string_info *strings;
};
+struct efi_guid_data {
+ struct list_head link;
+ struct efi_hii_guid_package package;
+};
+
+struct efi_keyboard_layout_data {
+ struct list_head link; /* in package */
+ struct list_head link_sys; /* in global list */
+ struct efi_hii_keyboard_layout keyboard_layout;
+};
+
+struct efi_keyboard_package_data {
+ struct list_head link; /* in package_list */
+ struct list_head keyboard_layout_list;
+};
+
static void free_strings_table(struct efi_string_table *stbl)
{
int i;
struct efi_string_table *stbl = NULL;
efi_status_t ret;
- debug("header_size: %08x\n",
- get_unaligned_le32(&strings_package->header_size));
- debug("string_info_offset: %08x\n",
- get_unaligned_le32(&strings_package->string_info_offset));
- debug("language_name: %u\n",
- get_unaligned_le16(&strings_package->language_name));
- debug("language: %s\n", strings_package->language);
+ EFI_PRINT("header_size: %08x\n",
+ get_unaligned_le32(&strings_package->header_size));
+ EFI_PRINT("string_info_offset: %08x\n",
+ get_unaligned_le32(&strings_package->string_info_offset));
+ EFI_PRINT("language_name: %u\n",
+ get_unaligned_le16(&strings_package->language_name));
+ EFI_PRINT("language: %s\n", strings_package->language);
/* count # of string entries: */
end = ((void *)strings_package)
block = end;
break;
default:
- debug("unknown HII string block type: %02x\n",
- block->block_type);
+ EFI_PRINT("unknown HII string block type: %02x\n",
+ block->block_type);
return EFI_INVALID_PARAMETER;
}
}
struct efi_hii_sibt_string_ucs2_block *ucs2;
ucs2 = (void *)block;
- debug("%4u: \"%ls\"\n", idx + 1, ucs2->string_text);
+ EFI_PRINT("%4u: \"%ls\"\n", idx + 1, ucs2->string_text);
stbl->strings[idx].string =
u16_strdup(ucs2->string_text);
if (!stbl->strings[idx].string) {
case EFI_HII_SIBT_END:
goto out;
default:
- debug("unknown HII string block type: %02x\n",
- block->block_type);
+ EFI_PRINT("unknown HII string block type: %02x\n",
+ block->block_type);
ret = EFI_INVALID_PARAMETER;
goto error;
}
error:
if (stbl) {
free(stbl->language);
- if (idx > 0)
- while (--idx >= 0)
- free(stbl->strings[idx].string);
+ while (idx > 0)
+ free(stbl->strings[--idx].string);
free(stbl->strings);
}
free(stbl);
return ret;
}
+static void remove_guid_package(struct efi_hii_packagelist *hii)
+{
+ struct efi_guid_data *data;
+
+ while (!list_empty(&hii->guid_list)) {
+ data = list_first_entry(&hii->guid_list,
+ struct efi_guid_data, link);
+ list_del(&data->link);
+ free(data);
+ }
+}
+
+static efi_status_t
+add_guid_package(struct efi_hii_packagelist *hii,
+ struct efi_hii_guid_package *package)
+{
+ struct efi_guid_data *data;
+
+ data = calloc(sizeof(*data), 1);
+ if (!data)
+ return EFI_OUT_OF_RESOURCES;
+
+ /* TODO: we don't know any about data field */
+ memcpy(&data->package, package, sizeof(*package));
+ list_add_tail(&data->link, &hii->guid_list);
+
+ return EFI_SUCCESS;
+}
+
+static void free_keyboard_layouts(struct efi_keyboard_package_data *package)
+{
+ struct efi_keyboard_layout_data *layout_data;
+
+ while (!list_empty(&package->keyboard_layout_list)) {
+ layout_data = list_first_entry(&package->keyboard_layout_list,
+ struct efi_keyboard_layout_data,
+ link);
+ list_del(&layout_data->link);
+ list_del(&layout_data->link_sys);
+ free(layout_data);
+ }
+}
+
+static void remove_keyboard_package(struct efi_hii_packagelist *hii)
+{
+ struct efi_keyboard_package_data *package;
+
+ while (!list_empty(&hii->keyboard_packages)) {
+ package = list_first_entry(&hii->keyboard_packages,
+ struct efi_keyboard_package_data,
+ link);
+ free_keyboard_layouts(package);
+ list_del(&package->link);
+ free(package);
+ }
+}
+
+static efi_status_t
+add_keyboard_package(struct efi_hii_packagelist *hii,
+ struct efi_hii_keyboard_package *keyboard_package)
+{
+ struct efi_keyboard_package_data *package_data;
+ struct efi_hii_keyboard_layout *layout;
+ struct efi_keyboard_layout_data *layout_data;
+ u16 layout_count, layout_length;
+ int i;
+
+ package_data = malloc(sizeof(*package_data));
+ if (!package_data)
+ return EFI_OUT_OF_RESOURCES;
+ INIT_LIST_HEAD(&package_data->link);
+ INIT_LIST_HEAD(&package_data->keyboard_layout_list);
+
+ layout = &keyboard_package->layout[0];
+ layout_count = get_unaligned_le16(&keyboard_package->layout_count);
+ for (i = 0; i < layout_count; i++) {
+ layout_length = get_unaligned_le16(&layout->layout_length);
+ layout_data = malloc(sizeof(*layout_data) + layout_length);
+ if (!layout_data)
+ goto out;
+
+ memcpy(&layout_data->keyboard_layout, layout, layout_length);
+ list_add_tail(&layout_data->link,
+ &package_data->keyboard_layout_list);
+ list_add_tail(&layout_data->link_sys,
+ &efi_keyboard_layout_list);
+
+ layout += layout_length;
+ }
+
+ list_add_tail(&package_data->link, &hii->keyboard_packages);
+
+ return EFI_SUCCESS;
+
+out:
+ free_keyboard_layouts(package_data);
+ free(package_data);
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
static struct efi_hii_packagelist *new_packagelist(void)
{
struct efi_hii_packagelist *hii;
hii = malloc(sizeof(*hii));
+ list_add_tail(&hii->link, &efi_package_lists);
hii->max_string_id = 0;
INIT_LIST_HEAD(&hii->string_tables);
+ INIT_LIST_HEAD(&hii->guid_list);
+ INIT_LIST_HEAD(&hii->keyboard_packages);
return hii;
}
static void free_packagelist(struct efi_hii_packagelist *hii)
{
remove_strings_package(hii);
+ remove_guid_package(hii);
+ remove_keyboard_package(hii);
list_del(&hii->link);
free(hii);
end = ((void *)package_list)
+ get_unaligned_le32(&package_list->package_length);
- debug("package_list: %pUl (%u)\n", &package_list->package_list_guid,
- get_unaligned_le32(&package_list->package_length));
+ EFI_PRINT("package_list: %pUl (%u)\n", &package_list->package_list_guid,
+ get_unaligned_le32(&package_list->package_length));
package = ((void *)package_list) + sizeof(*package_list);
while ((void *)package < end) {
- debug("package=%p, package type=%x, length=%u\n", package,
- efi_hii_package_type(package),
- efi_hii_package_len(package));
+ EFI_PRINT("package=%p, package type=%x, length=%u\n", package,
+ efi_hii_package_type(package),
+ efi_hii_package_len(package));
switch (efi_hii_package_type(package)) {
case EFI_HII_PACKAGE_TYPE_GUID:
- printf("\tGuid package not supported\n");
- ret = EFI_INVALID_PARAMETER;
+ ret = add_guid_package(hii,
+ (struct efi_hii_guid_package *)package);
break;
case EFI_HII_PACKAGE_FORMS:
- printf("\tForm package not supported\n");
+ EFI_PRINT("Form package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_STRINGS:
(struct efi_hii_strings_package *)package);
break;
case EFI_HII_PACKAGE_FONTS:
- printf("\tFont package not supported\n");
+ EFI_PRINT("Font package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_IMAGES:
- printf("\tImage package not supported\n");
+ EFI_PRINT("Image package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_SIMPLE_FONTS:
- printf("\tSimple font package not supported\n");
+ EFI_PRINT("Simple font package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_DEVICE_PATH:
- printf("\tDevice path package not supported\n");
+ EFI_PRINT("Device path package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
- printf("\tKeyboard layout package not supported\n");
- ret = EFI_INVALID_PARAMETER;
+ ret = add_keyboard_package(hii,
+ (struct efi_hii_keyboard_package *)package);
break;
case EFI_HII_PACKAGE_ANIMATIONS:
- printf("\tAnimation package not supported\n");
+ EFI_PRINT("Animation package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_END:
}
hii->driver_handle = driver_handle;
- list_add_tail(&hii->link, &efi_package_lists);
*handle = hii;
return EFI_EXIT(EFI_SUCCESS);
if (!package_list)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- debug("package_list: %pUl (%u)\n", &package_list->package_list_guid,
- get_unaligned_le32(&package_list->package_length));
+ EFI_PRINT("package_list: %pUl (%u)\n", &package_list->package_list_guid,
+ get_unaligned_le32(&package_list->package_length));
package = ((void *)package_list) + sizeof(*package_list);
end = ((void *)package_list)
+ get_unaligned_le32(&package_list->package_length);
while ((void *)package < end) {
- debug("package=%p, package type=%x, length=%u\n", package,
- efi_hii_package_type(package),
- efi_hii_package_len(package));
+ EFI_PRINT("package=%p, package type=%x, length=%u\n", package,
+ efi_hii_package_type(package),
+ efi_hii_package_len(package));
switch (efi_hii_package_type(package)) {
case EFI_HII_PACKAGE_TYPE_GUID:
- printf("\tGuid package not supported\n");
- ret = EFI_INVALID_PARAMETER;
+ remove_guid_package(hii);
break;
case EFI_HII_PACKAGE_FORMS:
- printf("\tForm package not supported\n");
+ EFI_PRINT("Form package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_STRINGS:
remove_strings_package(hii);
break;
case EFI_HII_PACKAGE_FONTS:
- printf("\tFont package not supported\n");
+ EFI_PRINT("Font package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_IMAGES:
- printf("\tImage package not supported\n");
+ EFI_PRINT("Image package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_SIMPLE_FONTS:
- printf("\tSimple font package not supported\n");
+ EFI_PRINT("Simple font package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_DEVICE_PATH:
- printf("\tDevice path package not supported\n");
+ EFI_PRINT("Device path package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
- printf("\tKeyboard layout package not supported\n");
+ remove_keyboard_package(hii);
break;
case EFI_HII_PACKAGE_ANIMATIONS:
- printf("\tAnimation package not supported\n");
+ EFI_PRINT("Animation package not supported\n");
ret = EFI_INVALID_PARAMETER;
break;
case EFI_HII_PACKAGE_END:
struct efi_hii_packagelist *hii =
(struct efi_hii_packagelist *)handle;
int package_cnt, package_max;
- efi_status_t ret = EFI_SUCCESS;
+ efi_status_t ret = EFI_NOT_FOUND;
EFI_ENTRY("%p, %u, %pUl, %p, %p", this, package_type, package_guid,
handle_buffer_length, handle);
if (!handle_buffer_length ||
- (*handle_buffer_length && !handle))
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ (*handle_buffer_length && !handle)) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
if ((package_type != EFI_HII_PACKAGE_TYPE_GUID && package_guid) ||
- (package_type == EFI_HII_PACKAGE_TYPE_GUID && !package_guid))
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ (package_type == EFI_HII_PACKAGE_TYPE_GUID && !package_guid)) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
- debug("package type=%x, guid=%pUl, length=%lu\n", (int)package_type,
- package_guid, *handle_buffer_length);
+ EFI_PRINT("package type=%x, guid=%pUl, length=%zu\n", (int)package_type,
+ package_guid, *handle_buffer_length);
package_cnt = 0;
package_max = *handle_buffer_length / sizeof(*handle);
case EFI_HII_PACKAGE_TYPE_ALL:
break;
case EFI_HII_PACKAGE_TYPE_GUID:
- printf("\tGuid package not supported\n");
- ret = EFI_INVALID_PARAMETER;
- continue;
- case EFI_HII_PACKAGE_FORMS:
- printf("\tForm package not supported\n");
- ret = EFI_INVALID_PARAMETER;
+ if (!list_empty(&hii->guid_list))
+ break;
continue;
case EFI_HII_PACKAGE_STRINGS:
if (!list_empty(&hii->string_tables))
break;
continue;
- case EFI_HII_PACKAGE_FONTS:
- printf("\tFont package not supported\n");
- ret = EFI_INVALID_PARAMETER;
- continue;
- case EFI_HII_PACKAGE_IMAGES:
- printf("\tImage package not supported\n");
- ret = EFI_INVALID_PARAMETER;
- continue;
- case EFI_HII_PACKAGE_SIMPLE_FONTS:
- printf("\tSimple font package not supported\n");
- ret = EFI_INVALID_PARAMETER;
- continue;
- case EFI_HII_PACKAGE_DEVICE_PATH:
- printf("\tDevice path package not supported\n");
- ret = EFI_INVALID_PARAMETER;
- continue;
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
- printf("\tKeyboard layout package not supported\n");
- continue;
- case EFI_HII_PACKAGE_ANIMATIONS:
- printf("\tAnimation package not supported\n");
- ret = EFI_INVALID_PARAMETER;
+ if (!list_empty(&hii->keyboard_packages))
+ break;
continue;
- case EFI_HII_PACKAGE_END:
- case EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN:
- case EFI_HII_PACKAGE_TYPE_SYSTEM_END:
default:
continue;
}
package_cnt++;
- if (package_cnt <= package_max)
+ if (package_cnt <= package_max) {
*handle++ = hii;
- else
+ ret = EFI_SUCCESS;
+ } else {
ret = EFI_BUFFER_TOO_SMALL;
+ }
}
*handle_buffer_length = package_cnt * sizeof(*handle);
-
+out:
return EFI_EXIT(ret);
}
u16 *key_guid_buffer_length,
efi_guid_t *key_guid_buffer)
{
+ struct efi_keyboard_layout_data *layout_data;
+ int package_cnt, package_max;
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %p, %p", this, key_guid_buffer_length, key_guid_buffer);
- return EFI_EXIT(EFI_NOT_FOUND);
+ if (!key_guid_buffer_length ||
+ (*key_guid_buffer_length && !key_guid_buffer))
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ package_cnt = 0;
+ package_max = *key_guid_buffer_length / sizeof(*key_guid_buffer);
+ list_for_each_entry(layout_data, &efi_keyboard_layout_list, link_sys) {
+ package_cnt++;
+ if (package_cnt <= package_max)
+ memcpy(key_guid_buffer++,
+ &layout_data->keyboard_layout.guid,
+ sizeof(*key_guid_buffer));
+ else
+ ret = EFI_BUFFER_TOO_SMALL;
+ }
+ *key_guid_buffer_length = package_cnt * sizeof(*key_guid_buffer);
+
+ return EFI_EXIT(ret);
}
static efi_status_t EFIAPI
u16 *keyboard_layout_length,
struct efi_hii_keyboard_layout *keyboard_layout)
{
+ struct efi_keyboard_layout_data *layout_data;
+ u16 layout_length;
+
EFI_ENTRY("%p, %pUl, %p, %p", this, key_guid, keyboard_layout_length,
keyboard_layout);
+ if (!keyboard_layout_length ||
+ (*keyboard_layout_length && !keyboard_layout))
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ /* TODO: no notion of current keyboard layout */
+ if (!key_guid)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ list_for_each_entry(layout_data, &efi_keyboard_layout_list, link_sys) {
+ if (!guidcmp(&layout_data->keyboard_layout.guid, key_guid))
+ goto found;
+ }
+
return EFI_EXIT(EFI_NOT_FOUND);
+
+found:
+ layout_length =
+ get_unaligned_le16(&layout_data->keyboard_layout.layout_length);
+ if (*keyboard_layout_length < layout_length) {
+ *keyboard_layout_length = layout_length;
+ return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
+ }
+
+ memcpy(keyboard_layout, &layout_data->keyboard_layout, layout_length);
+
+ return EFI_EXIT(EFI_SUCCESS);
}
static efi_status_t EFIAPI
}
*p = '\0';
- debug("languages: %s\n", languages);
+ EFI_PRINT("languages: %s\n", languages);
return EFI_EXIT(EFI_SUCCESS);
}