blob: 2905479e658412735e6cbdfea44ac71b9378639b [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassfac4ced2016-11-07 08:47:08 -07002/*
3 * EFI hello world
4 *
5 * Copyright (c) 2016 Google, Inc
6 * Written by Simon Glass <sjg@chromium.org>
7 *
Heinrich Schuchardt08645802017-11-26 14:05:20 +01008 * This program demonstrates calling a boottime service.
9 * It writes a greeting and the load options to the console.
Simon Glassfac4ced2016-11-07 08:47:08 -070010 */
11
12#include <common.h>
Simon Glassfac4ced2016-11-07 08:47:08 -070013#include <efi_api.h>
14
Alexander Grafc28a9472017-12-11 09:40:47 +010015static const efi_guid_t loaded_image_guid = LOADED_IMAGE_GUID;
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010016static const efi_guid_t fdt_guid = EFI_FDT_GUID;
Bin Meng8e943292018-06-27 20:38:04 -070017static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010018static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
19
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020020/**
21 * hw_memcmp() - compare memory areas
22 *
23 * @buf1: pointer to first area
24 * @buf2: pointer to second area
25 * @length: number of bytes to compare
26 * Return: 0 if both memory areas are the same, otherwise the sign of the
27 * result value is the same as the sign of ghe difference between
28 * the first differing pair of bytes taken as u8.
29 */
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010030static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
31{
32 const u8 *pos1 = buf1;
33 const u8 *pos2 = buf2;
34
35 for (; length; --length) {
36 if (*pos1 != *pos2)
37 return *pos1 - *pos2;
38 ++pos1;
39 ++pos2;
40 }
41 return 0;
42}
Alexander Grafc28a9472017-12-11 09:40:47 +010043
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020044/**
45 * efi_main() - entry point of the EFI application.
Heinrich Schuchardt08645802017-11-26 14:05:20 +010046 *
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020047 * @handle: handle of the loaded image
48 * @systable: system table
49 * @return: status code
Heinrich Schuchardt08645802017-11-26 14:05:20 +010050 */
Simon Glassfac4ced2016-11-07 08:47:08 -070051efi_status_t EFIAPI efi_main(efi_handle_t handle,
52 struct efi_system_table *systable)
53{
54 struct efi_simple_text_output_protocol *con_out = systable->con_out;
55 struct efi_boot_services *boottime = systable->boottime;
Heinrich Schuchardt08645802017-11-26 14:05:20 +010056 struct efi_loaded_image *loaded_image;
Heinrich Schuchardt08645802017-11-26 14:05:20 +010057 efi_status_t ret;
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010058 efi_uintn_t i;
Heinrich Schuchardta0a61dd2018-02-05 18:24:26 +010059 u16 rev[] = L"0.0.0";
Simon Glassfac4ced2016-11-07 08:47:08 -070060
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020061 /* UEFI requires CR LF */
62 con_out->output_string(con_out, L"Hello, world!\r\n");
Heinrich Schuchardt08645802017-11-26 14:05:20 +010063
Heinrich Schuchardta0a61dd2018-02-05 18:24:26 +010064 /* Print the revision number */
65 rev[0] = (systable->hdr.revision >> 16) + '0';
66 rev[4] = systable->hdr.revision & 0xffff;
67 for (; rev[4] >= 10;) {
68 rev[4] -= 10;
69 ++rev[2];
70 }
71 /* Third digit is only to be shown if non-zero */
72 if (rev[4])
73 rev[4] += '0';
74 else
75 rev[3] = 0;
76
77 con_out->output_string(con_out, L"Running on UEFI ");
78 con_out->output_string(con_out, rev);
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020079 con_out->output_string(con_out, L"\r\n");
Heinrich Schuchardta0a61dd2018-02-05 18:24:26 +010080
Heinrich Schuchardt08645802017-11-26 14:05:20 +010081 /* Get the loaded image protocol */
82 ret = boottime->handle_protocol(handle, &loaded_image_guid,
83 (void **)&loaded_image);
84 if (ret != EFI_SUCCESS) {
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020085 con_out->output_string
86 (con_out, L"Cannot open loaded image protocol\r\n");
Heinrich Schuchardt08645802017-11-26 14:05:20 +010087 goto out;
88 }
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010089 /* Find configuration tables */
90 for (i = 0; i < systable->nr_tables; ++i) {
91 if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid,
92 sizeof(efi_guid_t)))
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020093 con_out->output_string
94 (con_out, L"Have device tree\r\n");
Bin Meng8e943292018-06-27 20:38:04 -070095 if (!hw_memcmp(&systable->tables[i].guid, &acpi_guid,
96 sizeof(efi_guid_t)))
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +020097 con_out->output_string
98 (con_out, L"Have ACPI 2.0 table\r\n");
Heinrich Schuchardt5a771522018-01-19 20:24:42 +010099 if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid,
100 sizeof(efi_guid_t)))
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +0200101 con_out->output_string
102 (con_out, L"Have SMBIOS table\r\n");
Heinrich Schuchardt5a771522018-01-19 20:24:42 +0100103 }
Heinrich Schuchardt08645802017-11-26 14:05:20 +0100104 /* Output the load options */
105 con_out->output_string(con_out, L"Load options: ");
106 if (loaded_image->load_options_size && loaded_image->load_options)
107 con_out->output_string(con_out,
108 (u16 *)loaded_image->load_options);
109 else
110 con_out->output_string(con_out, L"<none>");
Heinrich Schuchardt5b669d82018-09-24 23:53:51 +0200111 con_out->output_string(con_out, L"\r\n");
Heinrich Schuchardt08645802017-11-26 14:05:20 +0100112
113out:
114 boottime->exit(handle, ret, 0, NULL);
Simon Glassfac4ced2016-11-07 08:47:08 -0700115
Heinrich Schuchardt08645802017-11-26 14:05:20 +0100116 /* We should never arrive here */
117 return ret;
Simon Glassfac4ced2016-11-07 08:47:08 -0700118}