/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2009 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/* This is an emulation of EFI runtime services.
This allows a more uniform boot on i386 machines.
As it emulates only runtime serviceit isn't able
to chainload EFI bootloader on non-EFI system (TODO) */
#ifdef __i386__
#else
#endif
#ifdef APPLE_CC
#else
#endif
void **address)
void *data);
void *data);
void
void **address)
static grub_uint32_t
static void
init_crc32_table (void)
static grub_uint32_t
/*
The log. It's used when examining memory dump
*/
/* Interface with grub */
extern grub_uint8_t efiemu_ptv_relocated;
extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[];
extern grub_uint8_t efiemu_variables[];
extern grub_uint32_t efiemu_varsize;
extern grub_int16_t efiemu_time_zone;
extern grub_uint8_t efiemu_time_daylight;
extern grub_uint32_t efiemu_time_accuracy;
/* Some standard functions because we need to be standalone */
static void
{
int i;
for (i = 0; i < count; i++)
}
static int
{
}
static grub_size_t
{
return ptr1 - a;
}
static int
{
return ptr1 == a + n;
}
static void
{
*ptr1 = b;
}
static inline void
{
"mov %%cl, %%al\n"
}
static inline grub_uint8_t
{
return ret;
}
/* Needed by some gcc versions */
int __stack_chk_fail ()
{
return 0;
}
/* The function that implement runtime services as specified in
EFI specification */
static inline grub_uint8_t
{
}
{
LOG ('a');
{
}
else
{
}
time->nanosecond = 0;
capabilities->sets_to_zero = 0;
return GRUB_EFI_SUCCESS;
}
{
LOG ('b');
return GRUB_EFI_SUCCESS;
}
/* Following 2 functions are vendor specific. So announce it as unsupported */
{
LOG ('c');
return GRUB_EFI_UNSUPPORTED;
}
{
LOG ('d');
return GRUB_EFI_UNSUPPORTED;
}
static grub_uint32_t
{
int i;
for (i = 1; i <= len; i++)
{
if (ref & 1)
ref >>= 1;
}
return result;
}
static void
init_crc32_table (void)
{
int i, j;
for(i = 0; i < 256; i++)
{
for (j = 0; j < 8; j++)
}
}
static grub_uint32_t
{
int i;
if (! crc32_table[1])
init_crc32_table ();
crc^= 0xffffffff;
for (i = 0; i < size; i++)
{
data++;
}
return crc ^ 0xffffffff;
}
{
LOG ('e');
/* Ensure that we are called only once */
if (efiemu_ptv_relocated)
return GRUB_EFI_UNSUPPORTED;
efiemu_ptv_relocated = 1;
/* Correct addresses using information supplied by grub */
{
/* Compute correction */
for (descptr = virtual_map;
{
}
/* Apply correction */
switch (cur_relloc->size)
{
case 8:
break;
case 4:
break;
case 2:
break;
case 1:
break;
}
}
/* Recompute crc32 of system table and runtime services */
(0, &efiemu_system_table, sizeof (efiemu_system_table));
(0, &efiemu_runtime_services, sizeof (efiemu_runtime_services));
return GRUB_EFI_SUCCESS;
}
/* since efiemu_set_virtual_address_map corrects all the pointers
we don't need efiemu_convert_pointer */
void **address)
{
LOG ('f');
return GRUB_EFI_UNSUPPORTED;
}
/* Next comes variable services. Because we have no vendor-independent
way to store these variables we have no non-volatility */
/* Find variable by name and GUID. */
static struct efi_variable *
{
{
return 0;
return efivar;
}
return 0;
}
void *data)
{
LOG ('g');
if (!efivar)
return GRUB_EFI_NOT_FOUND;
{
return GRUB_EFI_BUFFER_TOO_SMALL;
}
return GRUB_EFI_SUCCESS;
}
{
LOG ('l');
return GRUB_EFI_INVALID_PARAMETER;
if (variable_name[0])
{
if (!efivar)
return GRUB_EFI_NOT_FOUND;
}
else
LOG ('m');
return GRUB_EFI_NOT_FOUND;
{
return GRUB_EFI_BUFFER_TOO_SMALL;
}
LOG('h');
return GRUB_EFI_SUCCESS;
}
void *data)
{
LOG('i');
if (!variable_name[0])
return GRUB_EFI_INVALID_PARAMETER;
/* Delete variable if any */
if (efivar)
{
}
if (!data_size)
return GRUB_EFI_SUCCESS;
{
break;
}
return GRUB_EFI_OUT_OF_RESOURCES;
return GRUB_EFI_SUCCESS;
}
{
LOG ('j');
if (!high_count)
return GRUB_EFI_INVALID_PARAMETER;
return GRUB_EFI_SUCCESS;
}
/* To implement it with APM we need to go to real mode. It's too much hassle
Besides EFI specification says that this function shouldn't be used
on systems supporting ACPI
*/
void
{
LOG ('k');
}
{
.hdr =
{
.revision = 0x0001000a,
.header_size = sizeof (struct grub_efi_runtime_services),
.crc32 = 0, /* filled later*/
.reserved = 0
},
};
{'G', 'R', 'U', 'B', ' ', 'E', 'F', 'I', ' ',
'R', 'U', 'N', 'T', 'I', 'M', 'E', 0};
{
.hdr =
{
.revision = 0x0001000a,
.header_size = sizeof (struct grub_efi_system_table),
.crc32 = 0, /* filled later*/
.reserved = 0
},
.firmware_revision = 0x0001000a,
.console_in_handle = 0,
.con_in = 0,
.console_out_handle = 0,
.con_out = 0,
.standard_error_handle = 0,
.std_err = 0,
.boot_services = 0,
.num_table_entries = 0,
.configuration_table = 0
};