Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dadigang
Ventoy
Commits
b63ce2a3
Commit
b63ce2a3
authored
Mar 05, 2021
by
longpanda
Browse files
experimental support for loongson mips64el uefi
parent
bb7e10d9
Changes
294
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
6626 additions
and
4 deletions
+6626
-4
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c
+47
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c
+40
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c
+495
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S
...MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S
+61
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c
+169
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S
+56
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S
+69
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c
+1660
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S
+26
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c
+1023
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c
GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c
+463
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
+5
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
+10
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c
+27
-4
GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h
GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h
+56
-0
GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h
GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h
+309
-0
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h
+1761
-0
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h
+339
-0
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h
+10
-0
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h
+0
-0
No files found.
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009,2017 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/kernel.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/cpu/mips.h>
grub_uint32_t
grub_arch_cpuclock
;
/* FIXME: use interrupt to count high. */
grub_uint64_t
grub_get_rtc
(
void
)
{
static
grub_uint32_t
high
=
0
;
static
grub_uint32_t
last
=
0
;
grub_uint32_t
low
;
asm
volatile
(
"mfc0 %0, "
GRUB_CPU_MIPS_COP0_TIMER_COUNT
:
"=r"
(
low
));
if
(
low
<
last
)
high
++
;
last
=
low
;
return
(((
grub_uint64_t
)
high
)
<<
32
)
|
low
;
}
void
grub_timer_init
(
grub_uint32_t
cpuclock
)
{
grub_arch_cpuclock
=
cpuclock
;
grub_install_get_time_ms
(
grub_rtc_get_time_ms
);
}
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c
0 → 100644
View file @
b63ce2a3
/* efi.c - generic EFI support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/kernel.h>
#include <grub/acpi.h>
#include <grub/loader.h>
void
grub_halt
(
void
)
{
grub_machine_fini
(
GRUB_LOADER_FLAG_NORETURN
);
#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) &&\
!defined(__riscv)
grub_acpi_halt
();
#endif
efi_call_4
(
grub_efi_system_table
->
runtime_services
->
reset_system
,
GRUB_EFI_RESET_SHUTDOWN
,
GRUB_EFI_SUCCESS
,
0
,
NULL
);
while
(
1
);
}
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2017 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/mm.h>
#include <grub/cache.h>
#include <grub/efi/efi.h>
#include <grub/cpu/efi/memory.h>
#include <grub/cpu/memory.h>
#include <grub/machine/loongson.h>
#pragma GCC diagnostic ignored "-Wunused-function"
#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp)
#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8)
#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start)
extern
grub_uint8_t
grub_efi_loongson_reset_start
;
extern
grub_uint8_t
grub_efi_loongson_reset_end
;
static
struct
{
grub_efi_loongson_boot_params
boot_params
;
grub_efi_loongson_memory_map
memory_map
;
grub_efi_loongson_cpu_info
cpu_info
;
grub_efi_loongson_system_info
system_info
;
grub_efi_loongson_irq_src_routing_table
irq_src_routing_table
;
grub_efi_loongson_interface_info
interface_info
;
grub_efi_loongson_special_attribute
special_attribute
;
grub_efi_loongson_board_devices
board_devices
;
}
GRUB_PACKED
*
loongson_boot_params
;
static
void
grub_efi_loongson_init_reset_system
(
void
)
{
grub_efi_loongson_boot_params
*
boot_params
;
grub_uint8_t
*
reset_code_addr
=
(
grub_uint8_t
*
)
loongson_boot_params
+
loongson_boot_params_size
;
boot_params
=
&
loongson_boot_params
->
boot_params
;
grub_efi_loongson_reset_system_addr
=
(
grub_uint64_t
)
grub_efi_system_table
->
runtime_services
->
reset_system
;
grub_memcpy
(
reset_code_addr
,
&
grub_efi_loongson_reset_start
,
loongson_reset_code_size
);
grub_arch_sync_caches
(
reset_code_addr
,
loongson_reset_code_size
);
boot_params
->
reset_system
.
reset_cold
=
(
grub_uint64_t
)
reset_code_addr
+
((
grub_uint64_t
)
&
grub_efi_loongson_reset_cold
-
(
grub_uint64_t
)
&
grub_efi_loongson_reset_start
);
boot_params
->
reset_system
.
reset_warm
=
(
grub_uint64_t
)
reset_code_addr
+
((
grub_uint64_t
)
&
grub_efi_loongson_reset_warm
-
(
grub_uint64_t
)
&
grub_efi_loongson_reset_start
);
boot_params
->
reset_system
.
shutdown
=
(
grub_uint64_t
)
reset_code_addr
+
((
grub_uint64_t
)
&
grub_efi_loongson_reset_shutdown
-
(
grub_uint64_t
)
&
grub_efi_loongson_reset_start
);
boot_params
->
reset_system
.
do_suspend
=
(
grub_uint64_t
)
reset_code_addr
+
((
grub_uint64_t
)
&
grub_efi_loongson_reset_suspend
-
(
grub_uint64_t
)
&
grub_efi_loongson_reset_start
);
}
static
void
grub_efi_loongson_init_smbios
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_smbios_table
*
dst
=
&
loongson_boot_params
->
boot_params
.
efi
.
smbios
;
dst
->
vers
=
smbios_table
->
vers
;
dst
->
vga_bios
=
smbios_table
->
vga_bios
;
}
static
void
grub_efi_loongson_init_cpu_info
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_cpu_info
*
src
=
(
void
*
)
smbios_table
->
lp
.
cpu_offset
;
grub_efi_loongson_cpu_info
*
dst
=
&
loongson_boot_params
->
cpu_info
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_cpu_info
));
loongson_params
->
cpu_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
static
void
grub_efi_loongson_init_system_info
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_system_info
*
src
=
(
void
*
)
smbios_table
->
lp
.
system_offset
;
grub_efi_loongson_system_info
*
dst
=
&
loongson_boot_params
->
system_info
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_system_info
));
loongson_params
->
system_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
static
void
grub_efi_loongson_init_irq_src_routing_table
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_irq_src_routing_table
*
src
=
(
void
*
)
smbios_table
->
lp
.
irq_offset
;
grub_efi_loongson_irq_src_routing_table
*
dst
=
&
loongson_boot_params
->
irq_src_routing_table
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_irq_src_routing_table
));
loongson_params
->
irq_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
static
void
grub_efi_loongson_init_interface_info
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_interface_info
*
src
=
(
void
*
)
smbios_table
->
lp
.
interface_offset
;
grub_efi_loongson_interface_info
*
dst
=
&
loongson_boot_params
->
interface_info
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_interface_info
));
loongson_params
->
interface_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
static
void
grub_efi_loongson_init_special_attribute
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_special_attribute
*
src
=
(
void
*
)
smbios_table
->
lp
.
special_offset
;
grub_efi_loongson_special_attribute
*
dst
=
&
loongson_boot_params
->
special_attribute
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_special_attribute
));
loongson_params
->
special_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
static
void
grub_efi_loongson_init_board_devices
(
grub_efi_loongson_smbios_table
*
smbios_table
)
{
grub_efi_loongson_board_devices
*
src
=
(
void
*
)
smbios_table
->
lp
.
boarddev_table_offset
;
grub_efi_loongson_board_devices
*
dst
=
&
loongson_boot_params
->
board_devices
;
if
(
!
src
)
return
;
grub_memcpy
(
dst
,
src
,
sizeof
(
grub_efi_loongson_board_devices
));
loongson_params
->
boarddev_table_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
}
#define ADD_MEMORY_DESCRIPTOR(desc, size) \
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
static
void
grub_efi_loongson_init_memory_map
(
grub_efi_loongson_smbios_table
*
smbios_table
,
grub_efi_memory_descriptor_t
*
mmap_buf
,
grub_efi_uintn_t
mmap_size
,
grub_efi_uintn_t
desc_size
)
{
grub_efi_loongson_memory_map
*
src
=
(
void
*
)
smbios_table
->
lp
.
memory_offset
;
grub_efi_loongson_memory_map
*
dst
=
&
loongson_boot_params
->
memory_map
;
grub_efi_memory_descriptor_t
*
mmap_end
;
grub_efi_memory_descriptor_t
*
desc
;
grub_efi_memory_descriptor_t
*
desc_next
;
grub_efi_uint32_t
mem_types_reserved
[]
=
{
1
,
// GRUB_EFI_RESERVED_MEMORY_TYPE
0
,
// GRUB_EFI_LOADER_CODE
0
,
// GRUB_EFI_LOADER_DATA
0
,
// GRUB_EFI_BOOT_SERVICES_CODE
0
,
// GRUB_EFI_BOOT_SERVICES_DATA
1
,
// GRUB_EFI_RUNTIME_SERVICES_CODE
1
,
// GRUB_EFI_RUNTIME_SERVICES_DATA
0
,
// GRUB_EFI_CONVENTIONAL_MEMORY
1
,
// GRUB_EFI_UNUSABLE_MEMORY
0
,
// GRUB_EFI_ACPI_RECLAIM_MEMORY
0
,
// GRUB_EFI_ACPI_MEMORY_NVS
1
,
// GRUB_EFI_MEMORY_MAPPED_IO
1
,
// GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE
1
,
// GRUB_EFI_PAL_CODE
1
,
// GRUB_EFI_PERSISTENT_MEMORY
};
grub_uint32_t
need_sort
=
1
;
if
(
!
src
)
return
;
dst
->
vers
=
src
->
vers
;
dst
->
nr_map
=
0
;
dst
->
mem_freq
=
src
->
mem_freq
;
loongson_params
->
memory_offset
=
(
grub_uint64_t
)
dst
-
(
grub_uint64_t
)
loongson_params
;
if
(
!
mmap_buf
||
!
mmap_size
||
!
desc_size
)
return
;
mmap_end
=
ADD_MEMORY_DESCRIPTOR
(
mmap_buf
,
mmap_size
);
/* drop reserved */
for
(
desc
=
mmap_buf
,
desc_next
=
desc
;
desc
<
mmap_end
;
desc
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
))
{
desc
->
type
=
mem_types_reserved
[
desc
->
type
];
if
(
desc
->
type
)
continue
;
if
(
desc
!=
desc_next
)
*
desc_next
=
*
desc
;
desc_next
=
ADD_MEMORY_DESCRIPTOR
(
desc_next
,
desc_size
);
}
mmap_end
=
desc_next
;
/* sort: low->high */
while
(
need_sort
)
{
need_sort
=
0
;
for
(
desc
=
mmap_buf
,
desc_next
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
);
(
desc
<
mmap_end
)
&&
(
desc_next
<
mmap_end
);
desc
=
desc_next
,
desc_next
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
))
{
grub_efi_memory_descriptor_t
tmp
;
if
(
desc
->
physical_start
<=
desc_next
->
physical_start
)
continue
;
tmp
=
*
desc
;
*
desc
=
*
desc_next
;
*
desc_next
=
tmp
;
need_sort
=
1
;
}
}
/* combine continuous memory map */
for
(
desc
=
mmap_buf
,
desc_next
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
);
desc_next
<
mmap_end
;
desc_next
=
ADD_MEMORY_DESCRIPTOR
(
desc_next
,
desc_size
))
{
grub_efi_physical_address_t
prev_end
=
desc
->
physical_start
+
(
desc
->
num_pages
<<
12
);
if
(
prev_end
==
desc_next
->
physical_start
)
{
desc
->
num_pages
+=
desc_next
->
num_pages
;
continue
;
}
desc
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
);
grub_memcpy
(
desc
,
desc_next
,
desc_size
);
}
mmap_end
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
);
/* write to loongson memory map */
for
(
desc
=
mmap_buf
;
desc
<
mmap_end
;
desc
=
ADD_MEMORY_DESCRIPTOR
(
desc
,
desc_size
))
{
grub_efi_physical_address_t
physical_start
=
grub_vtop
((
void
*
)
desc
->
physical_start
);
grub_efi_physical_address_t
physical_end
=
physical_start
+
(
desc
->
num_pages
<<
12
);
physical_start
=
ALIGN_UP
(
physical_start
,
0x100000
);
physical_end
=
ALIGN_DOWN
(
physical_end
,
0x100000
);
if
(
physical_start
>=
physical_end
||
(
physical_end
-
physical_start
)
<
0x100000
)
continue
;
dst
->
map
[
dst
->
nr_map
].
node_id
=
(
desc
->
physical_start
>>
44
)
&
0xf
;
dst
->
map
[
dst
->
nr_map
].
mem_type
=
(
physical_end
<=
0x10000000
)
?
GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW
:
GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH
;
dst
->
map
[
dst
->
nr_map
].
mem_start
=
physical_start
;
dst
->
map
[
dst
->
nr_map
].
mem_size
=
(
physical_end
-
physical_start
)
>>
20
;
grub_dprintf
(
"loongson"
,
"memory map %03u: 0x%016lx 0x%016lx @ %u
\n
"
,
dst
->
nr_map
,
physical_start
,
physical_end
-
physical_start
,
dst
->
map
[
dst
->
nr_map
].
node_id
);
dst
->
nr_map
++
;
}
}
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
#define SUB_MEMORY_DESCRIPTOR(desc, size) \
((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size)))
void
grub_efi_loongson_alloc_boot_params
(
void
)
{
grub_efi_memory_descriptor_t
*
mmap_buf
;
grub_efi_memory_descriptor_t
*
mmap_end
;
grub_efi_memory_descriptor_t
*
desc
;
grub_efi_uintn_t
mmap_size
;
grub_efi_uintn_t
desc_size
;
grub_efi_physical_address_t
address
;
grub_efi_allocate_type_t
type
;
grub_efi_uintn_t
pages
;
grub_efi_status_t
status
;
grub_efi_boot_services_t
*
b
;
int
mm_status
;
type
=
GRUB_EFI_ALLOCATE_ADDRESS
;
pages
=
BYTES_TO_PAGES
(
loongson_boot_params_size
+
loongson_reset_code_size
);
mmap_size
=
(
1
<<
12
);
mmap_buf
=
grub_malloc
(
mmap_size
);
if
(
!
mmap_buf
)
grub_fatal
(
"out of memory!"
);
mm_status
=
grub_efi_get_memory_map
(
&
mmap_size
,
mmap_buf
,
0
,
&
desc_size
,
0
);
if
(
mm_status
==
0
)
{
grub_free
(
mmap_buf
);
mmap_size
+=
desc_size
*
32
;
mmap_buf
=
grub_malloc
(
mmap_size
);
if
(
!
mmap_buf
)
grub_fatal
(
"out of memory!"
);
mm_status
=
grub_efi_get_memory_map
(
&
mmap_size
,
mmap_buf
,
0
,
&
desc_size
,
0
);
}
if
(
mm_status
<
0
)
grub_fatal
(
"cannot get memory map!"
);
mmap_end
=
ADD_MEMORY_DESCRIPTOR
(
mmap_buf
,
mmap_size
);
for
(
desc
=
SUB_MEMORY_DESCRIPTOR
(
mmap_end
,
desc_size
);
desc
>=
mmap_buf
;
desc
=
SUB_MEMORY_DESCRIPTOR
(
desc
,
desc_size
))
{
if
(
desc
->
type
!=
GRUB_EFI_CONVENTIONAL_MEMORY
)
continue
;
if
(
desc
->
physical_start
>=
GRUB_EFI_MAX_USABLE_ADDRESS
)
continue
;
if
(
desc
->
num_pages
<
pages
)
continue
;
address
=
desc
->
physical_start
;
break
;
}
grub_free
(
mmap_buf
);
b
=
grub_efi_system_table
->
boot_services
;
status
=
efi_call_4
(
b
->
allocate_pages
,
type
,
GRUB_EFI_RUNTIME_SERVICES_DATA
,
pages
,
&
address
);
if
(
status
!=
GRUB_EFI_SUCCESS
)
grub_fatal
(
"cannot allocate Loongson boot parameters!"
);
loongson_boot_params
=
(
void
*
)
((
grub_addr_t
)
address
);
}
void
grub_efi_loongson_free_boot_params
(
void
)
{
grub_efi_free_pages
((
grub_addr_t
)
loongson_boot_params
,
BYTES_TO_PAGES
(
loongson_boot_params_size
+
loongson_reset_code_size
));
}
void
*
grub_efi_loongson_get_smbios_table
(
void
)
{
static
grub_efi_loongson_smbios_table
*
smbios_table
;
grub_efi_loongson_boot_params
*
old_boot_params
;
struct
bootparamsinterface
*
boot_params
;
void
*
tmp_boot_params
=
NULL
;
char
*
p
=
NULL
;
if
(
smbios_table
)
return
smbios_table
;
tmp_boot_params
=
grub_efi_loongson_get_boot_params
();
if
(
tmp_boot_params
==
NULL
)
{
grub_dprintf
(
"loongson"
,
"tmp_boot_params is NULL
\n
"
);
return
tmp_boot_params
;
}
boot_params
=
(
struct
bootparamsinterface
*
)
tmp_boot_params
;
p
=
(
char
*
)
&
(
boot_params
->
signature
);
if
(
grub_strncmp
(
p
,
"BPI"
,
3
)
==
0
)
{
grub_dprintf
(
"loongson"
,
"find new bpi
\n
"
);
return
boot_params
?
boot_params
:
0
;
}
else
{
old_boot_params
=
(
grub_efi_loongson_boot_params
*
)
tmp_boot_params
;
return
old_boot_params
?
&
old_boot_params
->
efi
.
smbios
:
0
;
}
}
int
grub_efi_is_loongson
(
void
)
{
return
grub_efi_loongson_get_smbios_table
()
?
1
:
0
;
}
void
*
grub_efi_loongson_get_boot_params
(
void
)
{
static
void
*
boot_params
=
NULL
;
grub_efi_configuration_table_t
*
tables
;
grub_efi_guid_t
smbios_guid
=
GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID
;
unsigned
int
i
;
if
(
boot_params
)
return
boot_params
;
/* Look for Loongson SMBIOS in UEFI config tables. */
tables
=
grub_efi_system_table
->
configuration_table
;
for
(
i
=
0
;
i
<
grub_efi_system_table
->
num_table_entries
;
i
++
)
if
(
grub_memcmp
(
&
tables
[
i
].
vendor_guid
,
&
smbios_guid
,
sizeof
(
smbios_guid
))
==
0
)
{
boot_params
=
tables
[
i
].
vendor_table
;
grub_dprintf
(
"loongson"
,
"found registered SMBIOS @ %p
\n
"
,
boot_params
);
break
;
}
return
boot_params
;
}
grub_uint8_t
grub_efi_loongson_calculatesum8
(
const
grub_uint8_t
*
buffer
,
grub_efi_uintn_t
length
)
{
grub_uint8_t
sum
;
grub_efi_uintn_t
count
;
for
(
sum
=
0
,
count
=
0
;
count
<
length
;
count
++
)
{
sum
=
(
grub_uint8_t
)
(
sum
+
*
(
buffer
+
count
));
}
return
sum
;
}
grub_uint8_t
grub_efi_loongson_grub_calculatechecksum8
(
const
grub_uint8_t
*
buffer
,
grub_efi_uintn_t
length
)
{
grub_uint8_t
checksum
;
checksum
=
grub_efi_loongson_calculatesum8
(
buffer
,
length
);
return
(
grub_uint8_t
)
(
0x100
-
checksum
);
}
grub_uint32_t
grub_efi_loongson_memmap_sort
(
struct
memmap
array
[],
grub_uint32_t
length
,
mem_map
*
bpmem
,
grub_uint32_t
index
,
grub_uint32_t
memtype
)
{
grub_uint64_t
tempmemsize
=
0
;
grub_uint32_t
j
=
0
;
grub_uint32_t
t
=
0
;
for
(
j
=
0
;
j
<
length
;)
{
tempmemsize
=
array
[
j
].
memsize
;
for
(
t
=
j
+
1
;
t
<
length
;
t
++
)
{
if
(
array
[
j
].
memstart
+
tempmemsize
==
array
[
t
].
memstart
)
{
tempmemsize
+=
array
[
t
].
memsize
;
}
else
{
break
;
}
}
bpmem
->
map
[
index
].
memtype
=
memtype
;
bpmem
->
map
[
index
].
memstart
=
array
[
j
].
memstart
;
bpmem
->
map
[
index
].
memsize
=
tempmemsize
;
grub_dprintf
(
"loongson"
,
"map[%d]:type %x, start 0x%llx, end 0x%llx
\n
"
,
index
,
bpmem
->
map
[
index
].
memtype
,
(
unsigned
long
long
)
bpmem
->
map
[
index
].
memstart
,
(
unsigned
long
long
)
bpmem
->
map
[
index
].
memstart
+
bpmem
->
map
[
index
].
memsize
);
j
=
t
;
index
++
;
}
return
index
;
}
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S
0 → 100644
View file @
b63ce2a3
/*
*
GRUB
--
GRand
Unified
Bootloader
*
Copyright
(
C
)
2017
Free
Software
Foundation
,
Inc
.
*
*
GRUB
is
free
software
:
you
can
redistribute
it
and
/
or
modify
*
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
/>
.
*/
#include <grub/symbol.h>
.
file
"loongson.S"
.
text
.
set
push
.
set
noreorder
.
align
4
VARIABLE
(
grub_efi_loongson_reset_start
)
VARIABLE
(
grub_efi_loongson_reset_system_addr
)
.
dword
0
reset_system
:
bal
1
f
move
$a1
,
$zero
1
:
ld
$t9
,
-
16
(
$ra
)
move
$a2
,
$zero
jalr
$t9
move
$a3
,
$zero
FUNCTION
(
grub_efi_loongson_reset_cold
)
b
reset_system
li
$a0
,
0
FUNCTION
(
grub_efi_loongson_reset_warm
)
b
reset_system
li
$a0
,
1
FUNCTION
(
grub_efi_loongson_reset_shutdown
)
b
reset_system
li
$a0
,
2
FUNCTION
(
grub_efi_loongson_reset_suspend
)
b
reset_system
li
$a0
,
3
VARIABLE
(
grub_efi_loongson_reset_end
)
.
set
pop
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2017 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/cache.h>
#include <grub/mips64/relocator.h>
#include <grub/relocator_private.h>
extern
grub_uint8_t
grub_relocator_forward_start
;
extern
grub_uint8_t
grub_relocator_forward_end
;
extern
grub_uint8_t
grub_relocator_backward_start
;
extern
grub_uint8_t
grub_relocator_backward_end
;
#define REGW_SIZEOF (6 * sizeof (grub_uint32_t))
#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \
- &grub_relocator_##x##_start)
#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
+ REGW_SIZEOF * 3)
grub_size_t
grub_relocator_align
=
sizeof
(
grub_uint64_t
);
grub_size_t
grub_relocator_forward_size
;
grub_size_t
grub_relocator_backward_size
;
grub_size_t
grub_relocator_jumper_size
=
JUMP_SIZEOF
+
REGW_SIZEOF
;
void
grub_cpu_relocator_init
(
void
)
{
grub_relocator_forward_size
=
RELOCATOR_SIZEOF
(
forward
);
grub_relocator_backward_size
=
RELOCATOR_SIZEOF
(
backward
);
}
static
void
write_reg
(
int
regn
,
grub_uint64_t
val
,
void
**
target
)
{
grub_uint32_t
lui
;
grub_uint32_t
ori
;
grub_uint32_t
dsll
;
/* lui $r, 0 */
lui
=
(
0x3c00
|
regn
)
<<
16
;
/* ori $r, $r, 0 */
ori
=
(
0x3400
|
(
regn
<<
5
)
|
regn
)
<<
16
;
/* dsll $r, $r, 16 */
dsll
=
(
regn
<<
16
)
|
(
regn
<<
11
)
|
(
16
<<
6
)
|
56
;
/* lui $r, val[63:48]. */
*
(
grub_uint32_t
*
)
*
target
=
lui
|
(
grub_uint16_t
)
(
val
>>
48
);
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* ori $r, val[47:32]. */
*
(
grub_uint32_t
*
)
*
target
=
ori
|
(
grub_uint16_t
)
(
val
>>
32
);
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* dsll $r, $r, 16 */
*
(
grub_uint32_t
*
)
*
target
=
dsll
;
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* ori $r, val[31:16]. */
*
(
grub_uint32_t
*
)
*
target
=
ori
|
(
grub_uint16_t
)
(
val
>>
16
);
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* dsll $r, $r, 16 */
*
(
grub_uint32_t
*
)
*
target
=
dsll
;
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* ori $r, val[15:0]. */
*
(
grub_uint32_t
*
)
*
target
=
ori
|
(
grub_uint16_t
)
val
;
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
}
static
void
write_jump
(
int
regn
,
void
**
target
)
{
/* j $r. */
*
(
grub_uint32_t
*
)
*
target
=
(
regn
<<
21
)
|
0x8
;
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
/* nop. */
*
(
grub_uint32_t
*
)
*
target
=
0
;
*
target
=
((
grub_uint32_t
*
)
*
target
)
+
1
;
}
void
grub_cpu_relocator_jumper
(
void
*
rels
,
grub_addr_t
addr
)
{
write_reg
(
1
,
addr
,
&
rels
);
write_jump
(
1
,
&
rels
);
}
void
grub_cpu_relocator_backward
(
void
*
ptr0
,
void
*
src
,
void
*
dest
,
grub_size_t
size
)
{
void
*
ptr
=
ptr0
;
write_reg
(
8
,
(
grub_uint64_t
)
src
,
&
ptr
);
write_reg
(
9
,
(
grub_uint64_t
)
dest
,
&
ptr
);
write_reg
(
10
,
(
grub_uint64_t
)
size
,
&
ptr
);
grub_memcpy
(
ptr
,
&
grub_relocator_backward_start
,
RELOCATOR_SRC_SIZEOF
(
backward
));
}
void
grub_cpu_relocator_forward
(
void
*
ptr0
,
void
*
src
,
void
*
dest
,
grub_size_t
size
)
{
void
*
ptr
=
ptr0
;
write_reg
(
8
,
(
grub_uint64_t
)
src
,
&
ptr
);
write_reg
(
9
,
(
grub_uint64_t
)
dest
,
&
ptr
);
write_reg
(
10
,
(
grub_uint64_t
)
size
,
&
ptr
);
grub_memcpy
(
ptr
,
&
grub_relocator_forward_start
,
RELOCATOR_SRC_SIZEOF
(
forward
));
}
grub_err_t
grub_relocator64_boot
(
struct
grub_relocator
*
rel
,
struct
grub_relocator64_state
state
)
{
grub_relocator_chunk_t
ch
;
void
*
ptr
;
grub_err_t
err
;
void
*
relst
;
grub_size_t
relsize
;
grub_size_t
stateset_size
=
31
*
REGW_SIZEOF
+
JUMP_SIZEOF
;
unsigned
i
;
grub_addr_t
vtarget
;
err
=
grub_relocator_alloc_chunk_align
(
rel
,
&
ch
,
0
,
(
0xffffffff
-
stateset_size
)
+
1
,
stateset_size
,
grub_relocator_align
,
GRUB_RELOCATOR_PREFERENCE_NONE
,
0
);
if
(
err
)
return
err
;
ptr
=
get_virtual_current_address
(
ch
);
for
(
i
=
1
;
i
<
32
;
i
++
)
write_reg
(
i
,
state
.
gpr
[
i
],
&
ptr
);
write_jump
(
state
.
jumpreg
,
&
ptr
);
vtarget
=
(
grub_addr_t
)
grub_map_memory
(
get_physical_target_address
(
ch
),
stateset_size
);
err
=
grub_relocator_prepare_relocs
(
rel
,
vtarget
,
&
relst
,
&
relsize
);
if
(
err
)
return
err
;
grub_arch_sync_caches
((
void
*
)
relst
,
relsize
);
((
void
(
*
)
(
void
))
relst
)
();
/* Not reached. */
return
GRUB_ERR_NONE
;
}
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S
0 → 100644
View file @
b63ce2a3
/*
*
GRUB
--
GRand
Unified
Bootloader
*
Copyright
(
C
)
2017
Free
Software
Foundation
,
Inc
.
*
*
GRUB
is
free
software
:
you
can
redistribute
it
and
/
or
modify
*
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
/>
.
*/
#include <grub/symbol.h>
.
p2align
4
/*
force
16
-
byte
alignment
*/
.
set
push
.
set
noreorder
.
set
nomacro
VARIABLE
(
grub_relocator_forward_start
)
copycont1
:
ld
$
11
,
0
(
$
8
)
sd
$
11
,
0
(
$
9
)
daddiu
$
8
,
$
8
,
8
daddiu
$
10
,
$
10
,
-
8
bne
$
10
,
$
0
,
copycont1
daddiu
$
9
,
$
9
,
8
VARIABLE
(
grub_relocator_forward_end
)
VARIABLE
(
grub_relocator_backward_start
)
daddu
$
9
,
$
9
,
$
10
daddu
$
8
,
$
8
,
$
10
/
*
Backward
movsl
is
implicitly
off
-
by
-
one
.
compensate
that
.
*/
daddiu
$
9
,
$
9
,
-
8
daddiu
$
8
,
$
8
,
-
8
copycont2
:
ld
$
11
,
0
(
$
8
)
sd
$
11
,
0
(
$
9
)
daddiu
$
8
,
$
8
,
-
8
daddiu
$
10
,
$
10
,
-
8
bne
$
10
,
$
0
,
copycont2
daddiu
$
9
,
$
9
,
-
8
VARIABLE
(
grub_relocator_backward_end
)
.
set
pop
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S
0 → 100644
View file @
b63ce2a3
/*
*
GRUB
--
GRand
Unified
Bootloader
*
Copyright
(
C
)
2003
,
2007
,
2009
Free
Software
Foundation
,
Inc
.
*
*
GRUB
is
free
software
:
you
can
redistribute
it
and
/
or
modify
*
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
/>
.
*/
#include <grub/symbol.h>
#include <grub/dl.h>
#include <grub/mips64/asm.h>
.
file
"setjmp.S"
GRUB_MOD_LICENSE
"
GPLv3
+"
.
text
/*
*
int
grub_setjmp
(
grub_jmp_buf
env
)
*/
FUNCTION
(
grub_setjmp
)
GRUB_ASM_REG_S
$s0
,
0
(
$a0
)
GRUB_ASM_REG_S
$s1
,
8
(
$a0
)
GRUB_ASM_REG_S
$s2
,
16
(
$a0
)
GRUB_ASM_REG_S
$s3
,
24
(
$a0
)
GRUB_ASM_REG_S
$s4
,
32
(
$a0
)
GRUB_ASM_REG_S
$s5
,
40
(
$a0
)
GRUB_ASM_REG_S
$s6
,
48
(
$a0
)
GRUB_ASM_REG_S
$s7
,
56
(
$a0
)
GRUB_ASM_REG_S
$s8
,
64
(
$a0
)
GRUB_ASM_REG_S
$gp
,
72
(
$a0
)
GRUB_ASM_REG_S
$sp
,
80
(
$a0
)
GRUB_ASM_REG_S
$ra
,
88
(
$a0
)
move
$v0
,
$zero
move
$v1
,
$zero
jr
$ra
nop
/*
*
int
grub_longjmp
(
grub_jmp_buf
env
,
int
val
)
*/
FUNCTION
(
grub_longjmp
)
GRUB_ASM_REG_L
$s0
,
0
(
$a0
)
GRUB_ASM_REG_L
$s1
,
8
(
$a0
)
GRUB_ASM_REG_L
$s2
,
16
(
$a0
)
GRUB_ASM_REG_L
$s3
,
24
(
$a0
)
GRUB_ASM_REG_L
$s4
,
32
(
$a0
)
GRUB_ASM_REG_L
$s5
,
40
(
$a0
)
GRUB_ASM_REG_L
$s6
,
48
(
$a0
)
GRUB_ASM_REG_L
$s7
,
56
(
$a0
)
GRUB_ASM_REG_L
$s8
,
64
(
$a0
)
GRUB_ASM_REG_L
$gp
,
72
(
$a0
)
GRUB_ASM_REG_L
$sp
,
80
(
$a0
)
GRUB_ASM_REG_L
$ra
,
88
(
$a0
)
addiu
$v0
,
$zero
,
1
movn
$v0
,
$a1
,
$a1
move
$v1
,
$zero
jr
$ra
nop
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009, 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/relocator.h>
#include <grub/relocator_private.h>
#include <grub/mm_private.h>
#include <grub/misc.h>
#include <grub/cache.h>
#include <grub/memory.h>
#include <grub/dl.h>
#include <grub/i18n.h>
GRUB_MOD_LICENSE
(
"GPLv3+"
);
struct
grub_relocator
{
struct
grub_relocator_chunk
*
chunks
;
grub_phys_addr_t
postchunks
;
grub_phys_addr_t
highestaddr
;
grub_phys_addr_t
highestnonpostaddr
;
grub_size_t
relocators_size
;
};
struct
grub_relocator_subchunk
{
enum
{
CHUNK_TYPE_IN_REGION
,
CHUNK_TYPE_REGION_START
,
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
CHUNK_TYPE_FIRMWARE
,
CHUNK_TYPE_LEFTOVER
#endif
}
type
;
grub_mm_region_t
reg
;
grub_phys_addr_t
start
;
grub_size_t
size
;
grub_size_t
pre_size
;
struct
grub_relocator_extra_block
*
extra
;
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
struct
grub_relocator_fw_leftover
*
pre
,
*
post
;
#endif
};
struct
grub_relocator_chunk
{
struct
grub_relocator_chunk
*
next
;
grub_phys_addr_t
src
;
void
*
srcv
;
grub_phys_addr_t
target
;
grub_size_t
size
;
struct
grub_relocator_subchunk
*
subchunks
;
unsigned
nsubchunks
;
};
struct
grub_relocator_extra_block
{
struct
grub_relocator_extra_block
*
next
;
struct
grub_relocator_extra_block
**
prev
;
grub_phys_addr_t
start
;
grub_phys_addr_t
end
;
};
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
struct
grub_relocator_fw_leftover
{
struct
grub_relocator_fw_leftover
*
next
;
struct
grub_relocator_fw_leftover
**
prev
;
grub_phys_addr_t
quantstart
;
grub_uint8_t
freebytes
[
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
/
8
];
};
static
struct
grub_relocator_fw_leftover
*
leftovers
;
#endif
static
struct
grub_relocator_extra_block
*
extra_blocks
;
void
*
get_virtual_current_address
(
grub_relocator_chunk_t
in
)
{
return
in
->
srcv
;
}
grub_phys_addr_t
get_physical_target_address
(
grub_relocator_chunk_t
in
)
{
return
in
->
target
;
}
struct
grub_relocator
*
grub_relocator_new
(
void
)
{
struct
grub_relocator
*
ret
;
grub_cpu_relocator_init
();
ret
=
grub_zalloc
(
sizeof
(
struct
grub_relocator
));
if
(
!
ret
)
return
NULL
;
ret
->
postchunks
=
~
(
grub_phys_addr_t
)
0
;
ret
->
relocators_size
=
grub_relocator_jumper_size
;
grub_dprintf
(
"relocator"
,
"relocators_size=%lu
\n
"
,
(
unsigned
long
)
ret
->
relocators_size
);
return
ret
;
}
#define DIGITSORT_BITS 8
#define DIGITSORT_MASK ((1 << DIGITSORT_BITS) - 1)
#define BITS_IN_BYTE 8
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
static
inline
int
is_start
(
int
type
)
{
return
!
(
type
&
1
)
&&
(
type
!=
COLLISION_START
);
}
static
void
allocate_regstart
(
grub_phys_addr_t
addr
,
grub_size_t
size
,
grub_mm_region_t
rb
,
grub_mm_region_t
*
regancestor
,
grub_mm_header_t
hancestor
)
{
grub_addr_t
newreg_start
,
newreg_raw_start
=
(
grub_addr_t
)
rb
+
(
addr
-
grub_vtop
(
rb
))
+
size
;
grub_addr_t
newreg_size
,
newreg_presize
;
grub_mm_header_t
new_header
;
grub_mm_header_t
hb
=
(
grub_mm_header_t
)
(
rb
+
1
);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"ra = %p, rb = %p
\n
"
,
regancestor
,
rb
);
#endif
newreg_start
=
ALIGN_UP
(
newreg_raw_start
,
GRUB_MM_ALIGN
);
newreg_presize
=
newreg_start
-
newreg_raw_start
;
newreg_size
=
rb
->
size
-
(
newreg_start
-
(
grub_addr_t
)
rb
);
if
((
hb
->
size
<<
GRUB_MM_ALIGN_LOG2
)
>=
newreg_start
-
(
grub_addr_t
)
rb
)
{
grub_mm_header_t
newhnext
=
hb
->
next
;
grub_size_t
newhsize
=
((
hb
->
size
<<
GRUB_MM_ALIGN_LOG2
)
-
(
newreg_start
-
(
grub_addr_t
)
rb
))
>>
GRUB_MM_ALIGN_LOG2
;
new_header
=
(
void
*
)
(
newreg_start
+
sizeof
(
*
rb
));
if
(
newhnext
==
hb
)
newhnext
=
new_header
;
new_header
->
next
=
newhnext
;
new_header
->
size
=
newhsize
;
new_header
->
magic
=
GRUB_MM_FREE_MAGIC
;
}
else
{
new_header
=
hb
->
next
;
if
(
new_header
==
hb
)
new_header
=
(
void
*
)
(
newreg_start
+
sizeof
(
*
rb
));
}
{
struct
grub_mm_header
*
newregfirst
=
rb
->
first
;
struct
grub_mm_region
*
newregnext
=
rb
->
next
;
struct
grub_mm_region
*
newreg
=
(
void
*
)
newreg_start
;
hancestor
->
next
=
new_header
;
if
(
newregfirst
==
hb
)
newregfirst
=
new_header
;
newreg
->
first
=
newregfirst
;
newreg
->
next
=
newregnext
;
newreg
->
pre_size
=
newreg_presize
;
newreg
->
size
=
newreg_size
;
*
regancestor
=
newreg
;
{
grub_mm_header_t
h
=
newreg
->
first
,
hp
=
NULL
;
do
{
if
((
void
*
)
h
<
(
void
*
)
(
newreg
+
1
))
grub_fatal
(
"Failed to adjust memory region: %p, %p, %p, %p, %p"
,
newreg
,
newreg
->
first
,
h
,
hp
,
hb
);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
if
((
void
*
)
h
==
(
void
*
)
(
newreg
+
1
))
grub_dprintf
(
"relocator"
,
"Free start memory region: %p, %p, %p, %p, %p"
,
newreg
,
newreg
->
first
,
h
,
hp
,
hb
);
#endif
hp
=
h
;
h
=
h
->
next
;
}
while
(
h
!=
newreg
->
first
);
}
}
}
static
void
allocate_inreg
(
grub_phys_addr_t
paddr
,
grub_size_t
size
,
grub_mm_header_t
hb
,
grub_mm_header_t
hbp
,
grub_mm_region_t
rb
)
{
struct
grub_mm_header
*
foll
=
NULL
;
grub_addr_t
vaddr
=
(
grub_addr_t
)
hb
+
(
paddr
-
grub_vtop
(
hb
));
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"inreg paddr = 0x%lx, size = %lu,"
" hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx
\n
"
,
(
unsigned
long
)
paddr
,
(
unsigned
long
)
size
,
hb
,
hbp
,
rb
,
(
unsigned
long
)
vaddr
);
#endif
if
(
ALIGN_UP
(
vaddr
+
size
,
GRUB_MM_ALIGN
)
+
GRUB_MM_ALIGN
<=
(
grub_addr_t
)
(
hb
+
hb
->
size
))
{
foll
=
(
void
*
)
ALIGN_UP
(
vaddr
+
size
,
GRUB_MM_ALIGN
);
foll
->
magic
=
GRUB_MM_FREE_MAGIC
;
foll
->
size
=
hb
+
hb
->
size
-
foll
;
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"foll = %p, foll->size = %lu
\n
"
,
foll
,
(
unsigned
long
)
foll
->
size
);
#endif
}
if
(
vaddr
-
(
grub_addr_t
)
hb
>=
sizeof
(
*
hb
))
{
hb
->
size
=
((
vaddr
-
(
grub_addr_t
)
hb
)
>>
GRUB_MM_ALIGN_LOG2
);
if
(
foll
)
{
foll
->
next
=
hb
;
hbp
->
next
=
foll
;
if
(
rb
->
first
==
hb
)
{
rb
->
first
=
foll
;
}
}
}
else
{
if
(
foll
)
{
foll
->
next
=
hb
->
next
;
}
else
foll
=
hb
->
next
;
hbp
->
next
=
foll
;
if
(
rb
->
first
==
hb
)
{
rb
->
first
=
foll
;
}
if
(
rb
->
first
==
hb
)
{
rb
->
first
=
(
void
*
)
(
rb
+
1
);
}
}
}
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
static
void
check_leftover
(
struct
grub_relocator_fw_leftover
*
lo
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
sizeof
(
lo
->
freebytes
);
i
++
)
if
(
lo
->
freebytes
[
i
]
!=
0xff
)
return
;
grub_relocator_firmware_free_region
(
lo
->
quantstart
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
*
lo
->
prev
=
lo
->
next
;
if
(
lo
->
next
)
lo
->
next
->
prev
=
lo
->
prev
;
}
#endif
static
void
free_subchunk
(
const
struct
grub_relocator_subchunk
*
subchu
)
{
switch
(
subchu
->
type
)
{
case
CHUNK_TYPE_REGION_START
:
{
grub_mm_region_t
r1
,
r2
,
*
rp
;
grub_mm_header_t
h
;
grub_size_t
pre_size
;
r1
=
subchu
->
reg
;
r2
=
(
grub_mm_region_t
)
ALIGN_UP
((
grub_addr_t
)
subchu
->
reg
+
(
grub_vtop
(
subchu
->
reg
)
-
subchu
->
start
)
+
subchu
->
size
,
GRUB_MM_ALIGN
);
for
(
rp
=
&
grub_mm_base
;
*
rp
&&
*
rp
!=
r2
;
rp
=
&
((
*
rp
)
->
next
));
pre_size
=
subchu
->
pre_size
;
if
(
*
rp
)
{
grub_mm_header_t
h2
,
*
hp
;
r1
->
first
=
r2
->
first
;
r1
->
next
=
r2
->
next
;
r1
->
pre_size
=
pre_size
;
r1
->
size
=
r2
->
size
+
(
r2
-
r1
)
*
sizeof
(
*
r2
);
*
rp
=
r1
;
h
=
(
grub_mm_header_t
)
(
r1
+
1
);
h
->
next
=
r2
->
first
;
h
->
magic
=
GRUB_MM_FREE_MAGIC
;
h
->
size
=
(
r2
-
r1
-
1
);
for
(
hp
=
&
r2
->
first
,
h2
=
*
hp
;
h2
->
next
!=
r2
->
first
;
hp
=
&
(
h2
->
next
),
h2
=
*
hp
)
if
(
h2
==
(
grub_mm_header_t
)
(
r2
+
1
))
break
;
if
(
h2
==
(
grub_mm_header_t
)
(
r2
+
1
))
{
h
->
size
=
h2
->
size
+
(
h2
-
h
);
h
->
next
=
h2
->
next
;
*
hp
=
h
;
if
(
hp
==
&
r2
->
first
)
{
for
(
h2
=
r2
->
first
;
h2
->
next
!=
r2
->
first
;
h2
=
h2
->
next
);
h2
->
next
=
h
;
}
}
else
{
h2
->
next
=
h
;
}
}
else
{
r1
->
pre_size
=
pre_size
;
r1
->
size
=
(
r2
-
r1
)
*
sizeof
(
*
r2
);
/* Find where to insert this region.
Put a smaller one before bigger ones,
to prevent fragmentation. */
for
(
rp
=
&
grub_mm_base
;
*
rp
;
rp
=
&
((
*
rp
)
->
next
))
if
((
*
rp
)
->
size
>
r1
->
size
)
break
;
r1
->
next
=
*
rp
;
*
rp
=
r1
->
next
;
h
=
(
grub_mm_header_t
)
(
r1
+
1
);
r1
->
first
=
h
;
h
->
next
=
h
;
h
->
magic
=
GRUB_MM_FREE_MAGIC
;
h
->
size
=
(
r2
-
r1
-
1
);
}
for
(
r2
=
grub_mm_base
;
r2
;
r2
=
r2
->
next
)
if
((
grub_addr_t
)
r2
+
r2
->
size
==
(
grub_addr_t
)
r1
)
break
;
if
(
r2
)
{
grub_mm_header_t
hl2
,
hl
,
g
;
g
=
(
grub_mm_header_t
)
((
grub_addr_t
)
r2
+
r2
->
size
);
g
->
size
=
(
grub_mm_header_t
)
r1
-
g
;
r2
->
size
+=
r1
->
size
;
for
(
hl
=
r2
->
first
;
hl
->
next
!=
r2
->
first
;
hl
=
hl
->
next
);
for
(
hl2
=
r1
->
first
;
hl2
->
next
!=
r1
->
first
;
hl2
=
hl2
->
next
);
hl2
->
next
=
r2
->
first
;
r2
->
first
=
r1
->
first
;
hl
->
next
=
r2
->
first
;
*
rp
=
(
*
rp
)
->
next
;
grub_free
(
g
+
1
);
}
break
;
}
case
CHUNK_TYPE_IN_REGION
:
{
grub_mm_header_t
h
=
(
grub_mm_header_t
)
ALIGN_DOWN
((
grub_addr_t
)
subchu
->
start
,
GRUB_MM_ALIGN
);
h
->
size
=
((
subchu
->
start
+
subchu
->
size
+
GRUB_MM_ALIGN
-
1
)
/
GRUB_MM_ALIGN
)
-
(
subchu
->
start
/
GRUB_MM_ALIGN
)
-
1
;
h
->
next
=
h
;
h
->
magic
=
GRUB_MM_ALLOC_MAGIC
;
grub_free
(
h
+
1
);
break
;
}
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
case
CHUNK_TYPE_FIRMWARE
:
case
CHUNK_TYPE_LEFTOVER
:
{
grub_addr_t
fstart
,
fend
;
fstart
=
ALIGN_UP
(
subchu
->
start
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
fend
=
ALIGN_DOWN
(
subchu
->
start
+
subchu
->
size
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
if
(
fstart
<
fend
)
grub_relocator_firmware_free_region
(
fstart
,
fend
-
fstart
);
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
if
(
subchu
->
pre
)
{
int
off
=
subchu
->
start
-
fstart
-
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
grub_memset
(
subchu
->
pre
->
freebytes
+
off
/
8
+
1
,
0xff
,
sizeof
(
subchu
->
pre
->
freebytes
)
-
off
/
8
-
1
);
subchu
->
pre
->
freebytes
[
off
/
8
]
|=
~
((
1
<<
(
off
%
8
))
-
1
);
check_leftover
(
subchu
->
pre
);
}
if
(
subchu
->
post
)
{
int
off
=
subchu
->
start
+
subchu
->
size
-
fend
;
grub_memset
(
subchu
->
pre
->
freebytes
,
0xff
,
sizeof
(
subchu
->
pre
->
freebytes
)
-
off
/
8
);
subchu
->
pre
->
freebytes
[
off
/
8
]
|=
((
1
<<
(
8
-
(
off
%
8
)))
-
1
);
check_leftover
(
subchu
->
post
);
}
#endif
*
subchu
->
extra
->
prev
=
subchu
->
extra
->
next
;
grub_free
(
subchu
->
extra
);
}
break
;
#endif
}
}
static
int
malloc_in_range
(
struct
grub_relocator
*
rel
,
grub_addr_t
start
,
grub_addr_t
end
,
grub_addr_t
align
,
grub_size_t
size
,
struct
grub_relocator_chunk
*
res
,
int
from_low_priv
,
int
collisioncheck
)
{
grub_mm_region_t
r
,
*
ra
,
base_saved
;
struct
grub_relocator_mmap_event
*
events
=
NULL
,
*
eventt
=
NULL
,
*
t
;
/* 128 is just in case of additional malloc (shouldn't happen). */
unsigned
maxevents
=
2
+
128
;
grub_mm_header_t
p
,
pa
;
unsigned
*
counter
;
int
nallocs
=
0
;
unsigned
j
,
N
=
0
;
grub_addr_t
target
=
0
;
grub_dprintf
(
"relocator"
,
"trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx
\n
"
,
(
unsigned
long
)
start
,
(
unsigned
long
)
end
,
(
unsigned
long
)
align
,
(
unsigned
long
)
size
);
start
=
ALIGN_UP
(
start
,
align
);
end
=
ALIGN_DOWN
(
end
-
size
,
align
)
+
size
;
if
(
end
<
start
+
size
)
return
0
;
/* We have to avoid any allocations when filling scanline events.
Hence 2-stages.
*/
for
(
r
=
grub_mm_base
;
r
;
r
=
r
->
next
)
{
p
=
r
->
first
;
do
{
if
((
grub_addr_t
)
p
<
(
grub_addr_t
)
(
r
+
1
)
||
(
grub_addr_t
)
p
>=
(
grub_addr_t
)
(
r
+
1
)
+
r
->
size
)
grub_fatal
(
"%d: out of range pointer: %p
\n
"
,
__LINE__
,
p
);
maxevents
+=
2
;
p
=
p
->
next
;
}
while
(
p
!=
r
->
first
);
maxevents
+=
4
;
}
if
(
collisioncheck
&&
rel
)
{
struct
grub_relocator_chunk
*
chunk
;
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
maxevents
+=
2
;
}
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
{
struct
grub_relocator_extra_block
*
cur
;
for
(
cur
=
extra_blocks
;
cur
;
cur
=
cur
->
next
)
maxevents
+=
2
;
}
for
(
r
=
grub_mm_base
;
r
;
r
=
r
->
next
)
maxevents
+=
2
;
maxevents
+=
grub_relocator_firmware_get_max_events
();
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
{
struct
grub_relocator_fw_leftover
*
cur
;
for
(
cur
=
leftovers
;
cur
;
cur
=
cur
->
next
)
{
int
l
=
0
;
unsigned
i
;
for
(
i
=
0
;
i
<
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
i
++
)
{
if
(
l
!=
((
cur
->
freebytes
[
i
/
8
]
>>
(
i
%
8
))
&
1
))
maxevents
++
;
l
=
((
cur
->
freebytes
[
i
/
8
]
>>
(
i
%
8
))
&
1
);
}
if
(
l
)
maxevents
++
;
}
}
#endif
eventt
=
grub_malloc
(
maxevents
*
sizeof
(
events
[
0
]));
counter
=
grub_malloc
((
DIGITSORT_MASK
+
2
)
*
sizeof
(
counter
[
0
]));
events
=
grub_malloc
(
maxevents
*
sizeof
(
events
[
0
]));
if
(
!
events
||
!
eventt
||
!
counter
)
{
grub_dprintf
(
"relocator"
,
"events or counter allocation failed %d
\n
"
,
maxevents
);
grub_free
(
events
);
grub_free
(
eventt
);
grub_free
(
counter
);
return
0
;
}
if
(
collisioncheck
&&
rel
)
{
struct
grub_relocator_chunk
*
chunk
;
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
{
events
[
N
].
type
=
COLLISION_START
;
events
[
N
].
pos
=
chunk
->
target
;
N
++
;
events
[
N
].
type
=
COLLISION_END
;
events
[
N
].
pos
=
chunk
->
target
+
chunk
->
size
;
N
++
;
}
}
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
for
(
r
=
grub_mm_base
;
r
;
r
=
r
->
next
)
{
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"Blocking at 0x%lx-0x%lx
\n
"
,
(
unsigned
long
)
r
-
r
->
pre_size
,
(
unsigned
long
)
(
r
+
1
)
+
r
->
size
);
#endif
events
[
N
].
type
=
FIRMWARE_BLOCK_START
;
events
[
N
].
pos
=
(
grub_addr_t
)
r
-
r
->
pre_size
;
N
++
;
events
[
N
].
type
=
FIRMWARE_BLOCK_END
;
events
[
N
].
pos
=
(
grub_addr_t
)
(
r
+
1
)
+
r
->
size
;
N
++
;
}
{
struct
grub_relocator_extra_block
*
cur
;
for
(
cur
=
extra_blocks
;
cur
;
cur
=
cur
->
next
)
{
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"Blocking at 0x%lx-0x%lx
\n
"
,
(
unsigned
long
)
cur
->
start
,
(
unsigned
long
)
cur
->
end
);
#endif
events
[
N
].
type
=
FIRMWARE_BLOCK_START
;
events
[
N
].
pos
=
cur
->
start
;
N
++
;
events
[
N
].
type
=
FIRMWARE_BLOCK_END
;
events
[
N
].
pos
=
cur
->
end
;
N
++
;
}
}
N
+=
grub_relocator_firmware_fill_events
(
events
+
N
);
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
{
struct
grub_relocator_fw_leftover
*
cur
;
for
(
cur
=
leftovers
;
cur
;
cur
=
cur
->
next
)
{
unsigned
i
;
int
l
=
0
;
for
(
i
=
0
;
i
<
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
i
++
)
{
if
(
l
!=
((
cur
->
freebytes
[
i
/
8
]
>>
(
i
%
8
))
&
1
))
{
events
[
N
].
type
=
l
?
REG_LEFTOVER_END
:
REG_LEFTOVER_START
;
events
[
N
].
pos
=
cur
->
quantstart
+
i
;
events
[
N
].
leftover
=
cur
;
N
++
;
}
l
=
((
cur
->
freebytes
[
i
/
8
]
>>
(
i
%
8
))
&
1
);
}
if
(
l
)
{
events
[
N
].
type
=
REG_LEFTOVER_END
;
events
[
N
].
pos
=
cur
->
quantstart
+
i
;
events
[
N
].
leftover
=
cur
;
N
++
;
}
}
}
#endif
#endif
/* No malloc from this point. */
base_saved
=
grub_mm_base
;
grub_mm_base
=
NULL
;
for
(
ra
=
&
base_saved
,
r
=
*
ra
;
r
;
ra
=
&
(
r
->
next
),
r
=
*
ra
)
{
pa
=
r
->
first
;
p
=
pa
->
next
;
if
(
p
->
magic
==
GRUB_MM_ALLOC_MAGIC
)
continue
;
do
{
if
(
p
->
magic
!=
GRUB_MM_FREE_MAGIC
)
grub_fatal
(
"%s:%d free magic broken at %p (0x%x)
\n
"
,
__FILE__
,
__LINE__
,
p
,
p
->
magic
);
if
(
p
==
(
grub_mm_header_t
)
(
r
+
1
))
{
events
[
N
].
type
=
REG_BEG_START
;
events
[
N
].
pos
=
grub_vtop
(
r
)
-
r
->
pre_size
;
events
[
N
].
reg
=
r
;
events
[
N
].
regancestor
=
ra
;
events
[
N
].
head
=
p
;
events
[
N
].
hancestor
=
pa
;
N
++
;
events
[
N
].
type
=
REG_BEG_END
;
events
[
N
].
pos
=
grub_vtop
(
p
+
p
->
size
)
-
sizeof
(
*
r
)
-
sizeof
(
struct
grub_mm_header
);
N
++
;
}
else
{
events
[
N
].
type
=
IN_REG_START
;
events
[
N
].
pos
=
grub_vtop
(
p
);
events
[
N
].
head
=
p
;
events
[
N
].
hancestor
=
pa
;
events
[
N
].
reg
=
r
;
N
++
;
events
[
N
].
type
=
IN_REG_END
;
events
[
N
].
pos
=
grub_vtop
(
p
+
p
->
size
);
N
++
;
}
pa
=
p
;
p
=
pa
->
next
;
}
while
(
pa
!=
r
->
first
);
}
/* Put ending events after starting events. */
{
int
st
=
0
,
e
=
N
/
2
;
for
(
j
=
0
;
j
<
N
;
j
++
)
if
(
is_start
(
events
[
j
].
type
)
||
events
[
j
].
type
==
COLLISION_START
)
eventt
[
st
++
]
=
events
[
j
];
else
eventt
[
e
++
]
=
events
[
j
];
t
=
eventt
;
eventt
=
events
;
events
=
t
;
}
{
unsigned
i
;
for
(
i
=
0
;
i
<
(
BITS_IN_BYTE
*
sizeof
(
grub_addr_t
)
/
DIGITSORT_BITS
);
i
++
)
{
grub_memset
(
counter
,
0
,
(
1
+
(
1
<<
DIGITSORT_BITS
))
*
sizeof
(
counter
[
0
]));
for
(
j
=
0
;
j
<
N
;
j
++
)
counter
[((
events
[
j
].
pos
>>
(
DIGITSORT_BITS
*
i
))
&
DIGITSORT_MASK
)
+
1
]
++
;
for
(
j
=
0
;
j
<=
DIGITSORT_MASK
;
j
++
)
counter
[
j
+
1
]
+=
counter
[
j
];
for
(
j
=
0
;
j
<
N
;
j
++
)
eventt
[
counter
[((
events
[
j
].
pos
>>
(
DIGITSORT_BITS
*
i
))
&
DIGITSORT_MASK
)]
++
]
=
events
[
j
];
t
=
eventt
;
eventt
=
events
;
events
=
t
;
}
}
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
retry:
#endif
/* Now events are nicely sorted. */
{
int
nstarted
=
0
,
ncollisions
=
0
,
nstartedfw
=
0
,
nblockfw
=
0
;
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
int
nlefto
=
0
;
#else
const
int
nlefto
=
0
;
#endif
grub_addr_t
starta
=
0
;
for
(
j
=
from_low_priv
?
0
:
N
-
1
;
from_low_priv
?
j
<
N
:
(
j
+
1
);
from_low_priv
?
j
++
:
j
--
)
{
int
isinsidebefore
,
isinsideafter
;
isinsidebefore
=
(
!
ncollisions
&&
(
nstarted
||
(((
nlefto
||
nstartedfw
)
&&
!
nblockfw
))));
switch
(
events
[
j
].
type
)
{
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
case
REG_FIRMWARE_START
:
nstartedfw
++
;
break
;
case
REG_FIRMWARE_END
:
nstartedfw
--
;
break
;
case
FIRMWARE_BLOCK_START
:
nblockfw
++
;
break
;
case
FIRMWARE_BLOCK_END
:
nblockfw
--
;
break
;
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case
REG_LEFTOVER_START
:
nlefto
++
;
break
;
case
REG_LEFTOVER_END
:
nlefto
--
;
break
;
#endif
case
COLLISION_START
:
ncollisions
++
;
break
;
case
COLLISION_END
:
ncollisions
--
;
break
;
case
IN_REG_START
:
case
REG_BEG_START
:
nstarted
++
;
break
;
case
IN_REG_END
:
case
REG_BEG_END
:
nstarted
--
;
break
;
}
isinsideafter
=
(
!
ncollisions
&&
(
nstarted
||
((
nlefto
||
nstartedfw
)
&&
!
nblockfw
)));
if
(
from_low_priv
)
{
if
(
!
isinsidebefore
&&
isinsideafter
)
starta
=
ALIGN_UP
(
events
[
j
].
pos
,
align
);
if
(
isinsidebefore
&&
!
isinsideafter
)
{
target
=
starta
;
if
(
target
<
start
)
target
=
start
;
if
(
target
+
size
<=
end
&&
target
+
size
<=
events
[
j
].
pos
)
/* Found an usable address. */
goto
found
;
}
}
else
{
if
(
!
isinsidebefore
&&
isinsideafter
)
{
if
(
events
[
j
].
pos
>=
size
)
starta
=
ALIGN_DOWN
(
events
[
j
].
pos
-
size
,
align
)
+
size
;
else
starta
=
0
;
}
if
(
isinsidebefore
&&
!
isinsideafter
&&
starta
>=
size
)
{
target
=
starta
-
size
;
if
(
target
>
end
-
size
)
target
=
end
-
size
;
if
(
target
>=
start
&&
target
>=
events
[
j
].
pos
)
goto
found
;
}
}
}
}
grub_mm_base
=
base_saved
;
grub_free
(
events
);
grub_free
(
eventt
);
grub_free
(
counter
);
return
0
;
found:
{
int
inreg
=
0
,
regbeg
=
0
,
ncol
=
0
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
int
fwin
=
0
,
fwb
=
0
,
fwlefto
=
0
;
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
int
last_lo
=
0
;
#endif
int
last_start
=
0
;
for
(
j
=
0
;
j
<
N
;
j
++
)
{
int
typepre
;
if
(
ncol
)
typepre
=
-
1
;
else
if
(
regbeg
)
typepre
=
CHUNK_TYPE_REGION_START
;
else
if
(
inreg
)
typepre
=
CHUNK_TYPE_IN_REGION
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
else
if
(
fwin
&&
!
fwb
)
typepre
=
CHUNK_TYPE_FIRMWARE
;
else
if
(
fwlefto
&&
!
fwb
)
typepre
=
CHUNK_TYPE_LEFTOVER
;
#endif
else
typepre
=
-
1
;
if
(
j
!=
0
&&
events
[
j
-
1
].
pos
!=
events
[
j
].
pos
)
{
grub_addr_t
alloc_start
,
alloc_end
;
alloc_start
=
max
(
events
[
j
-
1
].
pos
,
target
);
alloc_end
=
min
(
events
[
j
].
pos
,
target
+
size
);
if
(
alloc_end
>
alloc_start
)
{
switch
(
typepre
)
{
case
CHUNK_TYPE_REGION_START
:
allocate_regstart
(
alloc_start
,
alloc_end
-
alloc_start
,
events
[
last_start
].
reg
,
events
[
last_start
].
regancestor
,
events
[
last_start
].
hancestor
);
/* TODO: maintain a reverse lookup tree for hancestor. */
{
unsigned
k
;
for
(
k
=
0
;
k
<
N
;
k
++
)
if
(
events
[
k
].
hancestor
==
events
[
last_start
].
head
)
events
[
k
].
hancestor
=
events
[
last_start
].
hancestor
;
}
break
;
case
CHUNK_TYPE_IN_REGION
:
allocate_inreg
(
alloc_start
,
alloc_end
-
alloc_start
,
events
[
last_start
].
head
,
events
[
last_start
].
hancestor
,
events
[
last_start
].
reg
);
{
unsigned
k
;
for
(
k
=
0
;
k
<
N
;
k
++
)
if
(
events
[
k
].
hancestor
==
events
[
last_start
].
head
)
events
[
k
].
hancestor
=
events
[
last_start
].
hancestor
;
}
break
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
case
CHUNK_TYPE_FIRMWARE
:
{
grub_addr_t
fstart
,
fend
;
fstart
=
ALIGN_DOWN
(
alloc_start
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
fend
=
ALIGN_UP
(
alloc_end
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"requesting %lx-%lx
\n
"
,
(
unsigned
long
)
fstart
,
(
unsigned
long
)
fend
);
#endif
/* The failure here can be very expensive. */
if
(
!
grub_relocator_firmware_alloc_region
(
fstart
,
fend
-
fstart
))
{
if
(
from_low_priv
)
start
=
fend
;
else
end
=
fstart
;
goto
retry
;
}
break
;
}
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case
CHUNK_TYPE_LEFTOVER
:
{
unsigned
offstart
=
alloc_start
%
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
unsigned
offend
=
alloc_end
%
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
struct
grub_relocator_fw_leftover
*
lo
=
events
[
last_lo
].
leftover
;
if
(
offend
==
0
&&
alloc_end
!=
alloc_start
)
offend
=
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
lo
->
freebytes
[
offstart
/
8
]
&=
((
1
<<
(
8
-
(
start
%
8
)))
-
1
);
grub_memset
(
lo
->
freebytes
+
(
offstart
+
7
)
/
8
,
0
,
offend
/
8
-
(
offstart
+
7
)
/
8
);
lo
->
freebytes
[
offend
/
8
]
&=
~
((
1
<<
(
offend
%
8
))
-
1
);
}
break
;
#endif
}
nallocs
++
;
}
}
switch
(
events
[
j
].
type
)
{
case
REG_BEG_START
:
case
IN_REG_START
:
if
(
events
[
j
].
type
==
REG_BEG_START
&&
(
grub_addr_t
)
(
events
[
j
].
reg
+
1
)
>
target
)
regbeg
++
;
else
inreg
++
;
last_start
=
j
;
break
;
case
REG_BEG_END
:
case
IN_REG_END
:
if
(
regbeg
)
regbeg
--
;
else
inreg
--
;
break
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
case
REG_FIRMWARE_START
:
fwin
++
;
break
;
case
REG_FIRMWARE_END
:
fwin
--
;
break
;
case
FIRMWARE_BLOCK_START
:
fwb
++
;
break
;
case
FIRMWARE_BLOCK_END
:
fwb
--
;
break
;
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case
REG_LEFTOVER_START
:
fwlefto
++
;
last_lo
=
j
;
break
;
case
REG_LEFTOVER_END
:
fwlefto
--
;
break
;
#endif
case
COLLISION_START
:
ncol
++
;
break
;
case
COLLISION_END
:
ncol
--
;
break
;
}
}
}
/* Malloc is available again. */
grub_mm_base
=
base_saved
;
grub_free
(
eventt
);
grub_free
(
counter
);
{
int
last_start
=
0
;
int
inreg
=
0
,
regbeg
=
0
,
ncol
=
0
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
int
fwin
=
0
,
fwlefto
=
0
,
fwb
=
0
;
#endif
unsigned
cural
=
0
;
int
oom
=
0
;
res
->
subchunks
=
grub_malloc
(
sizeof
(
res
->
subchunks
[
0
])
*
nallocs
);
if
(
!
res
->
subchunks
)
oom
=
1
;
res
->
nsubchunks
=
nallocs
;
for
(
j
=
0
;
j
<
N
;
j
++
)
{
int
typepre
;
if
(
ncol
)
typepre
=
-
1
;
else
if
(
regbeg
)
typepre
=
CHUNK_TYPE_REGION_START
;
else
if
(
inreg
)
typepre
=
CHUNK_TYPE_IN_REGION
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
else
if
(
fwin
&&
!
fwb
)
typepre
=
CHUNK_TYPE_FIRMWARE
;
else
if
(
fwlefto
&&
!
fwb
)
typepre
=
CHUNK_TYPE_LEFTOVER
;
#endif
else
typepre
=
-
1
;
if
(
j
!=
0
&&
events
[
j
-
1
].
pos
!=
events
[
j
].
pos
)
{
grub_addr_t
alloc_start
,
alloc_end
;
struct
grub_relocator_subchunk
tofree
;
struct
grub_relocator_subchunk
*
curschu
=
&
tofree
;
if
(
!
oom
)
curschu
=
&
res
->
subchunks
[
cural
];
alloc_start
=
max
(
events
[
j
-
1
].
pos
,
target
);
alloc_end
=
min
(
events
[
j
].
pos
,
target
+
size
);
if
(
alloc_end
>
alloc_start
)
{
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
grub_dprintf
(
"relocator"
,
"subchunk 0x%lx-0x%lx, %d
\n
"
,
(
unsigned
long
)
alloc_start
,
(
unsigned
long
)
alloc_end
,
typepre
);
#endif
curschu
->
type
=
typepre
;
curschu
->
start
=
alloc_start
;
curschu
->
size
=
alloc_end
-
alloc_start
;
if
(
typepre
==
CHUNK_TYPE_REGION_START
||
typepre
==
CHUNK_TYPE_IN_REGION
)
{
curschu
->
reg
=
events
[
last_start
].
reg
;
curschu
->
pre_size
=
alloc_start
-
events
[
j
-
1
].
pos
;
}
if
(
!
oom
&&
(
typepre
==
CHUNK_TYPE_REGION_START
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
||
typepre
==
CHUNK_TYPE_FIRMWARE
#endif
))
{
struct
grub_relocator_extra_block
*
ne
;
ne
=
grub_malloc
(
sizeof
(
*
ne
));
if
(
!
ne
)
{
oom
=
1
;
grub_memcpy
(
&
tofree
,
curschu
,
sizeof
(
tofree
));
}
else
{
ne
->
start
=
alloc_start
;
ne
->
end
=
alloc_end
;
ne
->
next
=
extra_blocks
;
ne
->
prev
=
&
extra_blocks
;
if
(
extra_blocks
)
extra_blocks
->
prev
=
&
(
ne
->
next
);
extra_blocks
=
ne
;
curschu
->
extra
=
ne
;
}
}
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
if
(
!
oom
&&
typepre
==
CHUNK_TYPE_FIRMWARE
)
{
grub_addr_t
fstart
,
fend
;
fstart
=
ALIGN_DOWN
(
alloc_start
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
fend
=
ALIGN_UP
(
alloc_end
,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
);
{
struct
grub_relocator_fw_leftover
*
lo1
=
NULL
;
struct
grub_relocator_fw_leftover
*
lo2
=
NULL
;
if
(
fstart
!=
alloc_start
)
lo1
=
grub_malloc
(
sizeof
(
*
lo1
));
if
(
fend
!=
alloc_end
)
lo2
=
grub_malloc
(
sizeof
(
*
lo2
));
if
((
!
lo1
&&
fstart
!=
alloc_start
)
||
(
!
lo2
&&
fend
!=
alloc_end
))
{
struct
grub_relocator_extra_block
*
ne
;
grub_free
(
lo1
);
grub_free
(
lo2
);
lo1
=
NULL
;
lo2
=
NULL
;
oom
=
1
;
grub_memcpy
(
&
tofree
,
curschu
,
sizeof
(
tofree
));
ne
=
extra_blocks
;
extra_blocks
=
extra_blocks
->
next
;
grub_free
(
ne
);
}
if
(
lo1
)
{
lo1
->
quantstart
=
fstart
;
grub_memset
(
lo1
->
freebytes
,
0xff
,
(
alloc_start
-
fstart
)
/
8
);
lo1
->
freebytes
[(
alloc_start
-
fstart
)
/
8
]
=
(
1
<<
((
alloc_start
-
fstart
)
%
8
))
-
1
;
grub_memset
(
lo1
->
freebytes
+
((
alloc_start
-
fstart
)
/
8
)
+
1
,
0
,
sizeof
(
lo1
->
freebytes
)
-
(
alloc_start
-
fstart
)
/
8
-
1
);
lo1
->
next
=
leftovers
;
lo1
->
prev
=
&
leftovers
;
if
(
leftovers
)
leftovers
->
prev
=
&
lo1
->
next
;
leftovers
=
lo1
;
}
if
(
lo2
)
{
lo2
->
quantstart
=
fend
-
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT
;
grub_memset
(
lo2
->
freebytes
,
0
,
(
alloc_end
-
lo2
->
quantstart
)
/
8
);
lo2
->
freebytes
[(
alloc_end
-
lo2
->
quantstart
)
/
8
]
=
~
((
1
<<
((
alloc_end
-
lo2
->
quantstart
)
%
8
))
-
1
);
grub_memset
(
lo2
->
freebytes
+
((
alloc_end
-
lo2
->
quantstart
)
/
8
)
+
1
,
0
,
sizeof
(
lo2
->
freebytes
)
-
(
alloc_end
-
lo2
->
quantstart
)
/
8
-
1
);
lo2
->
prev
=
&
leftovers
;
if
(
leftovers
)
leftovers
->
prev
=
&
lo2
->
next
;
lo2
->
next
=
leftovers
;
leftovers
=
lo2
;
}
curschu
->
pre
=
lo1
;
curschu
->
post
=
lo2
;
}
}
if
(
typepre
==
CHUNK_TYPE_LEFTOVER
)
{
curschu
->
pre
=
events
[
last_start
].
leftover
;
curschu
->
post
=
events
[
last_start
].
leftover
;
}
#endif
if
(
!
oom
)
cural
++
;
else
free_subchunk
(
&
tofree
);
}
}
switch
(
events
[
j
].
type
)
{
case
REG_BEG_START
:
case
IN_REG_START
:
if
(
events
[
j
].
type
==
REG_BEG_START
&&
(
grub_addr_t
)
(
events
[
j
].
reg
+
1
)
>
target
)
regbeg
++
;
else
inreg
++
;
last_start
=
j
;
break
;
case
REG_BEG_END
:
case
IN_REG_END
:
inreg
=
regbeg
=
0
;
break
;
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
case
REG_FIRMWARE_START
:
fwin
++
;
break
;
case
REG_FIRMWARE_END
:
fwin
--
;
break
;
case
FIRMWARE_BLOCK_START
:
fwb
++
;
break
;
case
FIRMWARE_BLOCK_END
:
fwb
--
;
break
;
#endif
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case
REG_LEFTOVER_START
:
fwlefto
++
;
break
;
case
REG_LEFTOVER_END
:
fwlefto
--
;
break
;
#endif
case
COLLISION_START
:
ncol
++
;
break
;
case
COLLISION_END
:
ncol
--
;
break
;
}
}
if
(
oom
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
cural
;
i
++
)
free_subchunk
(
&
res
->
subchunks
[
i
]);
grub_free
(
res
->
subchunks
);
grub_dprintf
(
"relocator"
,
"allocation failed with out-of-memory
\n
"
);
grub_free
(
events
);
return
0
;
}
}
res
->
src
=
target
;
res
->
size
=
size
;
grub_free
(
events
);
grub_dprintf
(
"relocator"
,
"allocated: 0x%lx+0x%lx
\n
"
,
(
unsigned
long
)
target
,
(
unsigned
long
)
size
);
return
1
;
}
static
void
adjust_limits
(
struct
grub_relocator
*
rel
,
grub_phys_addr_t
*
min_addr
,
grub_phys_addr_t
*
max_addr
,
grub_phys_addr_t
in_min
,
grub_phys_addr_t
in_max
)
{
struct
grub_relocator_chunk
*
chunk
;
*
min_addr
=
0
;
*
max_addr
=
rel
->
postchunks
;
/* Keep chunks in memory in the same order as they'll be after relocation. */
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
{
if
(
chunk
->
target
>
in_max
&&
chunk
->
src
<
*
max_addr
&&
chunk
->
src
<
rel
->
postchunks
)
*
max_addr
=
chunk
->
src
;
if
(
chunk
->
target
+
chunk
->
size
<=
in_min
&&
chunk
->
src
+
chunk
->
size
>
*
min_addr
&&
chunk
->
src
<
rel
->
postchunks
)
*
min_addr
=
chunk
->
src
+
chunk
->
size
;
}
}
grub_err_t
grub_relocator_alloc_chunk_addr
(
struct
grub_relocator
*
rel
,
grub_relocator_chunk_t
*
out
,
grub_phys_addr_t
target
,
grub_size_t
size
)
{
struct
grub_relocator_chunk
*
chunk
;
grub_phys_addr_t
min_addr
=
0
,
max_addr
;
if
(
target
>
~
size
)
return
grub_error
(
GRUB_ERR_BUG
,
"address is out of range"
);
adjust_limits
(
rel
,
&
min_addr
,
&
max_addr
,
target
,
target
);
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
if
((
chunk
->
target
<=
target
&&
target
<
chunk
->
target
+
chunk
->
size
)
||
(
target
<=
chunk
->
target
&&
chunk
->
target
<
target
+
size
))
return
grub_error
(
GRUB_ERR_BUG
,
"overlap detected"
);
chunk
=
grub_malloc
(
sizeof
(
struct
grub_relocator_chunk
));
if
(
!
chunk
)
return
grub_errno
;
grub_dprintf
(
"relocator"
,
"min_addr = 0x%llx, max_addr = 0x%llx, target = 0x%llx
\n
"
,
(
unsigned
long
long
)
min_addr
,
(
unsigned
long
long
)
max_addr
,
(
unsigned
long
long
)
target
);
do
{
/* A trick to improve Linux allocation. */
#if defined (__i386__) || defined (__x86_64__)
if
(
target
<
0x100000
)
if
(
malloc_in_range
(
rel
,
rel
->
highestnonpostaddr
,
~
(
grub_addr_t
)
0
,
1
,
size
,
chunk
,
0
,
1
))
{
if
(
rel
->
postchunks
>
chunk
->
src
)
rel
->
postchunks
=
chunk
->
src
;
break
;
}
#elif defined(__mips__) && (_MIPS_SIM == _ABI64)
if
(
malloc_in_range
(
rel
,
target
,
max_addr
,
8
,
size
,
chunk
,
1
,
0
))
break
;
#endif
if
(
malloc_in_range
(
rel
,
target
,
max_addr
,
1
,
size
,
chunk
,
1
,
0
))
break
;
if
(
malloc_in_range
(
rel
,
min_addr
,
target
,
1
,
size
,
chunk
,
0
,
0
))
break
;
if
(
malloc_in_range
(
rel
,
rel
->
highestnonpostaddr
,
~
(
grub_addr_t
)
0
,
1
,
size
,
chunk
,
0
,
1
))
{
if
(
rel
->
postchunks
>
chunk
->
src
)
rel
->
postchunks
=
chunk
->
src
;
break
;
}
grub_dprintf
(
"relocator"
,
"not allocated
\n
"
);
grub_free
(
chunk
);
return
grub_error
(
GRUB_ERR_OUT_OF_MEMORY
,
N_
(
"out of memory"
));
}
while
(
0
);
grub_dprintf
(
"relocator"
,
"allocated 0x%llx/0x%llx
\n
"
,
(
unsigned
long
long
)
chunk
->
src
,
(
unsigned
long
long
)
target
);
if
(
rel
->
highestaddr
<
target
+
size
)
rel
->
highestaddr
=
target
+
size
;
if
(
rel
->
highestaddr
<
chunk
->
src
+
size
)
rel
->
highestaddr
=
chunk
->
src
+
size
;
if
(
chunk
->
src
<
rel
->
postchunks
)
{
if
(
rel
->
highestnonpostaddr
<
target
+
size
)
rel
->
highestnonpostaddr
=
target
+
size
;
if
(
rel
->
highestnonpostaddr
<
chunk
->
src
+
size
)
rel
->
highestnonpostaddr
=
chunk
->
src
+
size
;
}
grub_dprintf
(
"relocator"
,
"relocators_size=%ld
\n
"
,
(
unsigned
long
)
rel
->
relocators_size
);
if
(
chunk
->
src
<
target
)
rel
->
relocators_size
+=
grub_relocator_backward_size
;
if
(
chunk
->
src
>
target
)
rel
->
relocators_size
+=
grub_relocator_forward_size
;
grub_dprintf
(
"relocator"
,
"relocators_size=%ld
\n
"
,
(
unsigned
long
)
rel
->
relocators_size
);
chunk
->
target
=
target
;
chunk
->
size
=
size
;
chunk
->
next
=
rel
->
chunks
;
rel
->
chunks
=
chunk
;
grub_dprintf
(
"relocator"
,
"cur = %p, next = %p
\n
"
,
rel
->
chunks
,
rel
->
chunks
->
next
);
chunk
->
srcv
=
grub_map_memory
(
chunk
->
src
,
chunk
->
size
);
*
out
=
chunk
;
#ifdef DEBUG_RELOCATOR
grub_memset
(
chunk
->
srcv
,
0xfa
,
chunk
->
size
);
grub_mm_check
();
#endif
return
GRUB_ERR_NONE
;
}
/* Context for grub_relocator_alloc_chunk_align. */
struct
grub_relocator_alloc_chunk_align_ctx
{
grub_phys_addr_t
min_addr
,
max_addr
;
grub_size_t
size
,
align
;
int
preference
;
struct
grub_relocator_chunk
*
chunk
;
int
found
;
};
/* Helper for grub_relocator_alloc_chunk_align. */
static
int
grub_relocator_alloc_chunk_align_iter
(
grub_uint64_t
addr
,
grub_uint64_t
sz
,
grub_memory_type_t
type
,
void
*
data
)
{
struct
grub_relocator_alloc_chunk_align_ctx
*
ctx
=
data
;
grub_uint64_t
candidate
;
if
(
type
!=
GRUB_MEMORY_AVAILABLE
)
return
0
;
candidate
=
ALIGN_UP
(
addr
,
ctx
->
align
);
if
(
candidate
<
ctx
->
min_addr
)
candidate
=
ALIGN_UP
(
ctx
->
min_addr
,
ctx
->
align
);
if
(
candidate
+
ctx
->
size
>
addr
+
sz
||
candidate
>
ALIGN_DOWN
(
ctx
->
max_addr
,
ctx
->
align
))
return
0
;
if
(
ctx
->
preference
==
GRUB_RELOCATOR_PREFERENCE_HIGH
)
candidate
=
ALIGN_DOWN
(
min
(
addr
+
sz
-
ctx
->
size
,
ctx
->
max_addr
),
ctx
->
align
);
if
(
!
ctx
->
found
||
(
ctx
->
preference
==
GRUB_RELOCATOR_PREFERENCE_HIGH
&&
candidate
>
ctx
->
chunk
->
target
))
ctx
->
chunk
->
target
=
candidate
;
if
(
!
ctx
->
found
||
(
ctx
->
preference
==
GRUB_RELOCATOR_PREFERENCE_LOW
&&
candidate
<
ctx
->
chunk
->
target
))
ctx
->
chunk
->
target
=
candidate
;
ctx
->
found
=
1
;
return
0
;
}
grub_err_t
grub_relocator_alloc_chunk_align
(
struct
grub_relocator
*
rel
,
grub_relocator_chunk_t
*
out
,
grub_phys_addr_t
min_addr
,
grub_phys_addr_t
max_addr
,
grub_size_t
size
,
grub_size_t
align
,
int
preference
,
int
avoid_efi_boot_services
)
{
struct
grub_relocator_alloc_chunk_align_ctx
ctx
=
{
.
min_addr
=
min_addr
,
.
max_addr
=
max_addr
,
.
size
=
size
,
.
align
=
align
,
.
preference
=
preference
,
.
found
=
0
};
grub_addr_t
min_addr2
=
0
,
max_addr2
;
if
(
max_addr
>
~
size
)
max_addr
=
~
size
;
#ifdef GRUB_MACHINE_PCBIOS
if
(
min_addr
<
0x1000
)
min_addr
=
0x1000
;
#endif
grub_dprintf
(
"relocator"
,
"chunks = %p
\n
"
,
rel
->
chunks
);
ctx
.
chunk
=
grub_malloc
(
sizeof
(
struct
grub_relocator_chunk
));
if
(
!
ctx
.
chunk
)
return
grub_errno
;
if
(
malloc_in_range
(
rel
,
min_addr
,
max_addr
,
align
,
size
,
ctx
.
chunk
,
preference
!=
GRUB_RELOCATOR_PREFERENCE_HIGH
,
1
))
{
grub_dprintf
(
"relocator"
,
"allocated 0x%llx/0x%llx
\n
"
,
(
unsigned
long
long
)
ctx
.
chunk
->
src
,
(
unsigned
long
long
)
ctx
.
chunk
->
src
);
grub_dprintf
(
"relocator"
,
"chunks = %p
\n
"
,
rel
->
chunks
);
ctx
.
chunk
->
target
=
ctx
.
chunk
->
src
;
ctx
.
chunk
->
size
=
size
;
ctx
.
chunk
->
next
=
rel
->
chunks
;
rel
->
chunks
=
ctx
.
chunk
;
ctx
.
chunk
->
srcv
=
grub_map_memory
(
ctx
.
chunk
->
src
,
ctx
.
chunk
->
size
);
*
out
=
ctx
.
chunk
;
return
GRUB_ERR_NONE
;
}
adjust_limits
(
rel
,
&
min_addr2
,
&
max_addr2
,
min_addr
,
max_addr
);
grub_dprintf
(
"relocator"
,
"Adjusted limits from %lx-%lx to %lx-%lx
\n
"
,
(
unsigned
long
)
min_addr
,
(
unsigned
long
)
max_addr
,
(
unsigned
long
)
min_addr2
,
(
unsigned
long
)
max_addr2
);
do
{
if
(
malloc_in_range
(
rel
,
min_addr2
,
max_addr2
,
align
,
size
,
ctx
.
chunk
,
1
,
1
))
break
;
if
(
malloc_in_range
(
rel
,
rel
->
highestnonpostaddr
,
~
(
grub_addr_t
)
0
,
1
,
size
,
ctx
.
chunk
,
0
,
1
))
{
if
(
rel
->
postchunks
>
ctx
.
chunk
->
src
)
rel
->
postchunks
=
ctx
.
chunk
->
src
;
break
;
}
return
grub_error
(
GRUB_ERR_OUT_OF_MEMORY
,
N_
(
"out of memory"
));
}
while
(
0
);
{
#ifdef GRUB_MACHINE_EFI
grub_efi_mmap_iterate
(
grub_relocator_alloc_chunk_align_iter
,
&
ctx
,
avoid_efi_boot_services
);
#elif defined (__powerpc__) || defined (GRUB_MACHINE_XEN)
(
void
)
avoid_efi_boot_services
;
grub_machine_mmap_iterate
(
grub_relocator_alloc_chunk_align_iter
,
&
ctx
);
#else
(
void
)
avoid_efi_boot_services
;
grub_mmap_iterate
(
grub_relocator_alloc_chunk_align_iter
,
&
ctx
);
#endif
if
(
!
ctx
.
found
)
return
grub_error
(
GRUB_ERR_BAD_OS
,
"couldn't find suitable memory target"
);
}
while
(
1
)
{
struct
grub_relocator_chunk
*
chunk2
;
for
(
chunk2
=
rel
->
chunks
;
chunk2
;
chunk2
=
chunk2
->
next
)
if
((
chunk2
->
target
<=
ctx
.
chunk
->
target
&&
ctx
.
chunk
->
target
<
chunk2
->
target
+
chunk2
->
size
)
||
(
ctx
.
chunk
->
target
<=
chunk2
->
target
&&
chunk2
->
target
<
ctx
.
chunk
->
target
+
size
))
{
if
(
preference
==
GRUB_RELOCATOR_PREFERENCE_HIGH
)
ctx
.
chunk
->
target
=
ALIGN_DOWN
(
chunk2
->
target
,
align
);
else
ctx
.
chunk
->
target
=
ALIGN_UP
(
chunk2
->
target
+
chunk2
->
size
,
align
);
break
;
}
if
(
!
chunk2
)
break
;
}
grub_dprintf
(
"relocator"
,
"relocators_size=%ld
\n
"
,
(
unsigned
long
)
rel
->
relocators_size
);
if
(
ctx
.
chunk
->
src
<
ctx
.
chunk
->
target
)
rel
->
relocators_size
+=
grub_relocator_backward_size
;
if
(
ctx
.
chunk
->
src
>
ctx
.
chunk
->
target
)
rel
->
relocators_size
+=
grub_relocator_forward_size
;
grub_dprintf
(
"relocator"
,
"relocators_size=%ld
\n
"
,
(
unsigned
long
)
rel
->
relocators_size
);
ctx
.
chunk
->
size
=
size
;
ctx
.
chunk
->
next
=
rel
->
chunks
;
rel
->
chunks
=
ctx
.
chunk
;
grub_dprintf
(
"relocator"
,
"cur = %p, next = %p
\n
"
,
rel
->
chunks
,
rel
->
chunks
->
next
);
ctx
.
chunk
->
srcv
=
grub_map_memory
(
ctx
.
chunk
->
src
,
ctx
.
chunk
->
size
);
*
out
=
ctx
.
chunk
;
#ifdef DEBUG_RELOCATOR
grub_memset
(
ctx
.
chunk
->
srcv
,
0xfa
,
ctx
.
chunk
->
size
);
grub_mm_check
();
#endif
return
GRUB_ERR_NONE
;
}
void
grub_relocator_unload
(
struct
grub_relocator
*
rel
)
{
struct
grub_relocator_chunk
*
chunk
,
*
next
;
if
(
!
rel
)
return
;
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
next
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
chunk
->
nsubchunks
;
i
++
)
free_subchunk
(
&
chunk
->
subchunks
[
i
]);
grub_unmap_memory
(
chunk
->
srcv
,
chunk
->
size
);
next
=
chunk
->
next
;
grub_free
(
chunk
->
subchunks
);
grub_free
(
chunk
);
}
grub_free
(
rel
);
}
grub_err_t
grub_relocator_prepare_relocs
(
struct
grub_relocator
*
rel
,
grub_addr_t
addr
,
void
**
relstart
,
grub_size_t
*
relsize
)
{
grub_uint8_t
*
rels
;
grub_uint8_t
*
rels0
;
struct
grub_relocator_chunk
*
sorted
;
grub_size_t
nchunks
=
0
;
unsigned
j
;
struct
grub_relocator_chunk
movers_chunk
;
grub_dprintf
(
"relocator"
,
"Preparing relocs (size=%ld)
\n
"
,
(
unsigned
long
)
rel
->
relocators_size
);
if
(
!
malloc_in_range
(
rel
,
0
,
~
(
grub_addr_t
)
0
-
rel
->
relocators_size
+
1
,
grub_relocator_align
,
rel
->
relocators_size
,
&
movers_chunk
,
1
,
1
))
return
grub_error
(
GRUB_ERR_OUT_OF_MEMORY
,
N_
(
"out of memory"
));
movers_chunk
.
srcv
=
rels
=
rels0
=
grub_map_memory
(
movers_chunk
.
src
,
movers_chunk
.
size
);
if
(
relsize
)
*
relsize
=
rel
->
relocators_size
;
grub_dprintf
(
"relocator"
,
"Relocs allocated at %p
\n
"
,
movers_chunk
.
srcv
);
{
unsigned
i
;
grub_size_t
count
[
257
];
struct
grub_relocator_chunk
*
from
,
*
to
,
*
tmp
;
grub_memset
(
count
,
0
,
sizeof
(
count
));
{
struct
grub_relocator_chunk
*
chunk
;
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
{
grub_dprintf
(
"relocator"
,
"chunk %p->%p, 0x%lx
\n
"
,
(
void
*
)
chunk
->
src
,
(
void
*
)
chunk
->
target
,
(
unsigned
long
)
chunk
->
size
);
nchunks
++
;
count
[(
chunk
->
src
&
0xff
)
+
1
]
++
;
}
}
from
=
grub_malloc
(
nchunks
*
sizeof
(
sorted
[
0
]));
to
=
grub_malloc
(
nchunks
*
sizeof
(
sorted
[
0
]));
if
(
!
from
||
!
to
)
{
grub_free
(
from
);
grub_free
(
to
);
return
grub_errno
;
}
for
(
j
=
0
;
j
<
256
;
j
++
)
count
[
j
+
1
]
+=
count
[
j
];
{
struct
grub_relocator_chunk
*
chunk
;
for
(
chunk
=
rel
->
chunks
;
chunk
;
chunk
=
chunk
->
next
)
from
[
count
[
chunk
->
src
&
0xff
]
++
]
=
*
chunk
;
}
for
(
i
=
1
;
i
<
GRUB_CPU_SIZEOF_VOID_P
;
i
++
)
{
grub_memset
(
count
,
0
,
sizeof
(
count
));
for
(
j
=
0
;
j
<
nchunks
;
j
++
)
count
[((
from
[
j
].
src
>>
(
8
*
i
))
&
0xff
)
+
1
]
++
;
for
(
j
=
0
;
j
<
256
;
j
++
)
count
[
j
+
1
]
+=
count
[
j
];
for
(
j
=
0
;
j
<
nchunks
;
j
++
)
to
[
count
[(
from
[
j
].
src
>>
(
8
*
i
))
&
0xff
]
++
]
=
from
[
j
];
tmp
=
to
;
to
=
from
;
from
=
tmp
;
}
sorted
=
from
;
grub_free
(
to
);
}
for
(
j
=
0
;
j
<
nchunks
;
j
++
)
{
grub_dprintf
(
"relocator"
,
"sorted chunk %p->%p, 0x%lx
\n
"
,
(
void
*
)
sorted
[
j
].
src
,
(
void
*
)
sorted
[
j
].
target
,
(
unsigned
long
)
sorted
[
j
].
size
);
if
(
sorted
[
j
].
src
<
sorted
[
j
].
target
)
{
grub_cpu_relocator_backward
((
void
*
)
rels
,
sorted
[
j
].
srcv
,
grub_map_memory
(
sorted
[
j
].
target
,
sorted
[
j
].
size
),
sorted
[
j
].
size
);
rels
+=
grub_relocator_backward_size
;
}
if
(
sorted
[
j
].
src
>
sorted
[
j
].
target
)
{
grub_cpu_relocator_forward
((
void
*
)
rels
,
sorted
[
j
].
srcv
,
grub_map_memory
(
sorted
[
j
].
target
,
sorted
[
j
].
size
),
sorted
[
j
].
size
);
rels
+=
grub_relocator_forward_size
;
}
if
(
sorted
[
j
].
src
==
sorted
[
j
].
target
)
grub_arch_sync_caches
(
sorted
[
j
].
srcv
,
sorted
[
j
].
size
);
}
grub_cpu_relocator_jumper
((
void
*
)
rels
,
(
grub_addr_t
)
addr
);
*
relstart
=
rels0
;
grub_free
(
sorted
);
return
GRUB_ERR_NONE
;
}
void
grub_mm_check_real
(
const
char
*
file
,
int
line
)
{
grub_mm_region_t
r
;
grub_mm_header_t
p
,
pa
;
for
(
r
=
grub_mm_base
;
r
;
r
=
r
->
next
)
{
pa
=
r
->
first
;
p
=
pa
->
next
;
if
(
p
->
magic
==
GRUB_MM_ALLOC_MAGIC
)
continue
;
do
{
if
((
grub_addr_t
)
p
<
(
grub_addr_t
)
(
r
+
1
)
||
(
grub_addr_t
)
p
>=
(
grub_addr_t
)
(
r
+
1
)
+
r
->
size
)
grub_fatal
(
"%s:%d: out of range pointer: %p
\n
"
,
file
,
line
,
p
);
if
(
p
->
magic
!=
GRUB_MM_FREE_MAGIC
)
grub_fatal
(
"%s:%d free magic broken at %p (0x%x)
\n
"
,
file
,
line
,
p
,
p
->
magic
);
pa
=
p
;
p
=
pa
->
next
;
}
while
(
pa
!=
r
->
first
);
}
}
GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S
0 → 100644
View file @
b63ce2a3
#if defined(__i386__)
#include "./i386/setjmp.S"
#elif defined(__x86_64__)
#include "./x86_64/setjmp.S"
#elif defined(__sparc__)
#include "./sparc64/setjmp.S"
#elif defined(__mips__)
#if _MIPS_SIM == _ABI64
#include "./mips64/setjmp.S"
#else
#include "./mips/setjmp.S"
#endif
#elif defined(__powerpc__) || defined(__PPC__)
#include "./powerpc/setjmp.S"
#elif defined(__ia64__)
#include "./ia64/setjmp.S"
#include "./ia64/longjmp.S"
#elif defined(__arm__)
#include "./arm/setjmp.S"
#elif defined(__aarch64__)
#include "./arm64/setjmp.S"
#elif defined(__riscv)
#include "./riscv/setjmp.S"
#else
#error "Unknown target cpu type"
#endif
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c
0 → 100644
View file @
b63ce2a3
/* linux.c - boot Linux */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,2009,2010,2017 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/elf.h>
#include <grub/elfload.h>
#include <grub/loader.h>
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/cpu/relocator.h>
#include <grub/machine/loongson.h>
#include <grub/memory.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
#include <grub/term.h>
#include <grub/env.h>
GRUB_MOD_LICENSE
(
"GPLv3+"
);
#define _ull unsigned long long
#pragma GCC diagnostic ignored "-Wcast-align"
typedef
unsigned
long
size_t
;
static
grub_dl_t
my_mod
;
static
int
loaded
;
static
grub_uint32_t
tmp_index
=
0
;
static
grub_size_t
linux_size
;
static
struct
grub_relocator
*
relocator
;
static
grub_addr_t
target_addr
,
entry_addr
;
static
int
linux_argc
;
static
grub_uint8_t
*
linux_args_addr
;
static
grub_off_t
rd_addr_arg_off
,
rd_size_arg_off
;
static
int
initrd_loaded
=
0
;
static
grub_uint32_t
j
=
0
;
static
grub_uint32_t
t
=
0
;
grub_uint64_t
tempMemsize
=
0
;
grub_uint32_t
free_index
=
0
;
grub_uint32_t
reserve_index
=
0
;
grub_uint32_t
acpi_table_index
=
0
;
grub_uint32_t
acpi_nvs_index
=
0
;
#define LINUX_MAX_ARGC 1024
static
int
ventoy_debug
=
0
;
static
int
ventoy_initrd_called
=
0
;
static
int
ventoy_linux_argc
=
0
;
static
char
**
ventoy_linux_args
=
NULL
;
static
int
ventoy_extra_initrd_num
=
0
;
static
char
*
ventoy_extra_initrd_list
[
256
];
static
grub_err_t
grub_cmd_initrd
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[]);
static
inline
grub_size_t
page_align
(
grub_size_t
size
)
{
return
(
size
+
(
1
<<
12
)
-
1
)
&
(
~
((
1
<<
12
)
-
1
));
}
/* Find the optimal number of pages for the memory map. Is it better to
move this code to efi/mm.c? */
static
grub_efi_uintn_t
find_mmap_size
(
void
)
{
static
grub_efi_uintn_t
mmap_size
=
0
;
if
(
mmap_size
!=
0
)
return
mmap_size
;
mmap_size
=
(
1
<<
12
);
while
(
1
)
{
int
ret
;
grub_efi_memory_descriptor_t
*
mmap
;
grub_efi_uintn_t
desc_size
;
mmap
=
grub_malloc
(
mmap_size
);
if
(
!
mmap
)
return
0
;
ret
=
grub_efi_get_memory_map
(
&
mmap_size
,
mmap
,
0
,
&
desc_size
,
0
);
grub_free
(
mmap
);
if
(
ret
<
0
)
{
grub_error
(
GRUB_ERR_IO
,
"cannot get memory map"
);
return
0
;
}
else
if
(
ret
>
0
)
break
;
mmap_size
+=
(
1
<<
12
);
}
/* Increase the size a bit for safety, because GRUB allocates more on
later, and EFI itself may allocate more. */
mmap_size
+=
(
1
<<
12
);
return
page_align
(
mmap_size
);
}
static
void
ventoy_debug_pause
(
void
)
{
char
key
;
if
(
0
==
ventoy_debug
)
{
return
;
}
grub_printf
(
"press Enter to continue ......
\n
"
);
while
(
1
)
{
key
=
grub_getkey
();
if
(
key
==
'\n'
||
key
==
'\r'
)
{
break
;
}
}
}
static
int
ventoy_preboot
(
void
)
{
int
i
;
const
char
*
file
;
char
buf
[
128
];
if
(
ventoy_debug
)
{
grub_printf
(
"ventoy_preboot %d %d
\n
"
,
ventoy_linux_argc
,
ventoy_initrd_called
);
ventoy_debug_pause
();
}
if
(
ventoy_linux_argc
==
0
)
{
return
0
;
}
if
(
ventoy_initrd_called
)
{
ventoy_initrd_called
=
0
;
return
0
;
}
grub_snprintf
(
buf
,
sizeof
(
buf
),
"mem:%s:size:%s"
,
grub_env_get
(
"ventoy_cpio_addr"
),
grub_env_get
(
"ventoy_cpio_size"
));
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
buf
);
file
=
grub_env_get
(
"vtoy_img_part_file"
);
if
(
file
)
{
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
file
);
}
if
(
ventoy_debug
)
{
grub_printf
(
"========== initrd list ==========
\n
"
);
for
(
i
=
0
;
i
<
ventoy_extra_initrd_num
;
i
++
)
{
grub_printf
(
"%s
\n
"
,
ventoy_extra_initrd_list
[
i
]);
}
grub_printf
(
"=================================
\n
"
);
ventoy_debug_pause
();
}
grub_cmd_initrd
(
NULL
,
ventoy_extra_initrd_num
,
ventoy_extra_initrd_list
);
return
0
;
}
static
int
ventoy_boot_opt_filter
(
char
*
opt
)
{
if
(
grub_strcmp
(
opt
,
"noinitrd"
)
==
0
)
{
return
1
;
}
if
(
grub_strcmp
(
opt
,
"vga=current"
)
==
0
)
{
return
1
;
}
if
(
grub_strncmp
(
opt
,
"rdinit="
,
7
)
==
0
)
{
if
(
grub_strcmp
(
opt
,
"rdinit=/vtoy/vtoy"
)
!=
0
)
{
opt
[
0
]
=
'v'
;
opt
[
1
]
=
't'
;
}
return
0
;
}
if
(
grub_strncmp
(
opt
,
"init="
,
5
)
==
0
)
{
opt
[
0
]
=
'v'
;
opt
[
1
]
=
't'
;
return
0
;
}
if
(
ventoy_debug
)
{
if
(
grub_strcmp
(
opt
,
"quiet"
)
==
0
)
{
return
1
;
}
if
(
grub_strncmp
(
opt
,
"loglevel="
,
9
)
==
0
)
{
return
1
;
}
if
(
grub_strcmp
(
opt
,
"splash"
)
==
0
)
{
return
1
;
}
}
return
0
;
}
static
int
ventoy_bootopt_hook
(
int
argc
,
char
*
argv
[])
{
int
i
;
int
count
=
0
;
const
char
*
env
;
char
c
;
char
*
newenv
;
char
*
last
,
*
pos
;
//grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc);
if
(
ventoy_linux_argc
==
0
)
{
return
0
;
}
/* the 1st parameter is BOOT_IMAGE=xxxx */
if
(
argc
>
0
&&
0
==
ventoy_boot_opt_filter
(
argv
[
0
]))
{
ventoy_linux_args
[
count
++
]
=
grub_strdup
(
argv
[
0
]);
}
for
(
i
=
0
;
i
<
ventoy_linux_argc
;
i
++
)
{
ventoy_linux_args
[
count
]
=
ventoy_linux_args
[
i
+
(
LINUX_MAX_ARGC
/
2
)];
ventoy_linux_args
[
i
+
(
LINUX_MAX_ARGC
/
2
)]
=
NULL
;
if
(
ventoy_linux_args
[
count
][
0
]
==
'@'
)
{
env
=
grub_env_get
(
ventoy_linux_args
[
count
]
+
1
);
if
(
env
)
{
grub_free
(
ventoy_linux_args
[
count
]);
newenv
=
grub_strdup
(
env
);
last
=
newenv
;
while
(
*
last
)
{
while
(
*
last
)
{
if
(
*
last
!=
' '
&&
*
last
!=
'\t'
)
{
break
;
}
last
++
;
}
if
(
*
last
==
0
)
{
break
;
}
for
(
pos
=
last
;
*
pos
;
pos
++
)
{
if
(
*
pos
==
' '
||
*
pos
==
'\t'
)
{
c
=
*
pos
;
*
pos
=
0
;
if
(
0
==
ventoy_boot_opt_filter
(
last
))
{
ventoy_linux_args
[
count
++
]
=
grub_strdup
(
last
);
}
*
pos
=
c
;
break
;
}
}
if
(
*
pos
==
0
)
{
if
(
0
==
ventoy_boot_opt_filter
(
last
))
{
ventoy_linux_args
[
count
++
]
=
grub_strdup
(
last
);
}
break
;
}
last
=
pos
+
1
;
}
}
else
{
count
++
;
}
}
else
{
count
++
;
}
}
/* We have processed the 1st parameter before, so start from 1 */
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
ventoy_boot_opt_filter
(
argv
[
i
]))
{
continue
;
}
ventoy_linux_args
[
count
++
]
=
grub_strdup
(
argv
[
i
]);
}
if
(
ventoy_debug
)
{
ventoy_linux_args
[
count
++
]
=
grub_strdup
(
"loglevel=7"
);
}
ventoy_linux_argc
=
count
;
if
(
ventoy_debug
)
{
grub_printf
(
"========== bootoption ==========
\n
"
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
grub_printf
(
"%s "
,
ventoy_linux_args
[
i
]);
}
grub_printf
(
"
\n
================================
\n
"
);
}
return
0
;
}
static
grub_err_t
grub_cmd_set_boot_opt
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
int
i
;
const
char
*
vtdebug
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
ventoy_linux_args
[
ventoy_linux_argc
+
(
LINUX_MAX_ARGC
/
2
)
]
=
grub_strdup
(
argv
[
i
]);
ventoy_linux_argc
++
;
}
vtdebug
=
grub_env_get
(
"vtdebug_flag"
);
if
(
vtdebug
&&
vtdebug
[
0
])
{
ventoy_debug
=
1
;
}
if
(
ventoy_debug
)
grub_printf
(
"ventoy set boot opt %d
\n
"
,
ventoy_linux_argc
);
return
0
;
}
static
grub_err_t
grub_cmd_unset_boot_opt
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
int
i
;
(
void
)
argc
;
(
void
)
argv
;
for
(
i
=
0
;
i
<
LINUX_MAX_ARGC
;
i
++
)
{
if
(
ventoy_linux_args
[
i
])
{
grub_free
(
ventoy_linux_args
[
i
]);
}
}
ventoy_debug
=
0
;
ventoy_linux_argc
=
0
;
ventoy_initrd_called
=
0
;
grub_memset
(
ventoy_linux_args
,
0
,
sizeof
(
char
*
)
*
LINUX_MAX_ARGC
);
return
0
;
}
static
grub_err_t
grub_cmd_extra_initrd_append
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
int
newclen
=
0
;
char
*
pos
=
NULL
;
char
*
end
=
NULL
;
char
buf
[
256
]
=
{
0
};
if
(
argc
!=
1
)
{
return
1
;
}
for
(
pos
=
argv
[
0
];
*
pos
;
pos
++
)
{
if
(
*
pos
==
'/'
)
{
end
=
pos
;
}
}
if
(
end
)
{
/* grub2 newc bug workaround */
newclen
=
(
int
)
grub_strlen
(
end
+
1
);
if
((
110
+
newclen
)
%
4
==
0
)
{
grub_snprintf
(
buf
,
sizeof
(
buf
),
"newc:.%s:%s"
,
end
+
1
,
argv
[
0
]);
}
else
{
grub_snprintf
(
buf
,
sizeof
(
buf
),
"newc:%s:%s"
,
end
+
1
,
argv
[
0
]);
}
if
(
ventoy_extra_initrd_num
<
256
)
{
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
buf
);
}
}
return
0
;
}
static
grub_err_t
grub_cmd_extra_initrd_reset
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
int
i
;
(
void
)
argc
;
(
void
)
argv
;
for
(
i
=
0
;
i
<
ventoy_extra_initrd_num
;
i
++
)
{
if
(
ventoy_extra_initrd_list
[
i
])
{
grub_free
(
ventoy_extra_initrd_list
[
i
]);
}
}
grub_memset
(
ventoy_extra_initrd_list
,
0
,
sizeof
(
ventoy_extra_initrd_list
));
return
0
;
}
static
grub_err_t
grub_linux_boot
(
void
)
{
struct
grub_relocator64_state
state
;
grub_int8_t
checksum
=
0
;
grub_efi_memory_descriptor_t
*
lsdesc
=
NULL
;
ventoy_preboot
();
grub_memset
(
&
state
,
0
,
sizeof
(
state
));
/* Boot the kernel. */
state
.
gpr
[
1
]
=
entry_addr
;
grub_dprintf
(
"loongson"
,
"entry_addr is 0x%llx
\n
"
,
(
_ull
)
state
.
gpr
[
1
]);
state
.
gpr
[
4
]
=
linux_argc
;
grub_dprintf
(
"loongson"
,
"linux_argc is %lld
\n
"
,
(
_ull
)
state
.
gpr
[
4
]);
state
.
gpr
[
5
]
=
(
grub_addr_t
)
linux_args_addr
;
grub_dprintf
(
"loongson"
,
"args_addr is 0x%llx
\n
"
,
(
_ull
)
state
.
gpr
[
5
]);
if
(
grub_efi_is_loongson
())
{
grub_efi_uintn_t
mmap_size
;
grub_efi_uintn_t
desc_size
;
grub_efi_memory_descriptor_t
*
mmap_buf
;
grub_err_t
err
;
struct
bootparamsinterface
*
boot_params
;
void
*
tmp_boot_params
=
NULL
;
grub_efi_uint8_t
new_interface_flag
=
0
;
mem_map
*
new_interface_mem
=
NULL
;
char
*
p
=
NULL
;
struct
memmap
reserve_mem
[
GRUB_EFI_LOONGSON_MMAP_MAX
];
struct
memmap
free_mem
[
GRUB_EFI_LOONGSON_MMAP_MAX
];
struct
memmap
acpi_table_mem
[
GRUB_EFI_LOONGSON_MMAP_MAX
];
struct
memmap
acpi_nvs_mem
[
GRUB_EFI_LOONGSON_MMAP_MAX
];
grub_memset
(
reserve_mem
,
0
,
sizeof
(
struct
memmap
)
*
GRUB_EFI_LOONGSON_MMAP_MAX
);
grub_memset
(
free_mem
,
0
,
sizeof
(
struct
memmap
)
*
GRUB_EFI_LOONGSON_MMAP_MAX
);
grub_memset
(
acpi_table_mem
,
0
,
sizeof
(
struct
memmap
)
*
GRUB_EFI_LOONGSON_MMAP_MAX
);
grub_memset
(
acpi_nvs_mem
,
0
,
sizeof
(
struct
memmap
)
*
GRUB_EFI_LOONGSON_MMAP_MAX
);
tmp_boot_params
=
grub_efi_loongson_get_boot_params
();
if
(
tmp_boot_params
==
NULL
)
{
grub_printf
(
"not find param
\n
"
);
return
-
1
;
}
boot_params
=
(
struct
bootparamsinterface
*
)
tmp_boot_params
;
p
=
(
char
*
)
&
(
boot_params
->
signature
);
if
(
grub_strncmp
(
p
,
"BPI"
,
3
)
==
0
)
{
/* Check extlist headers */
ext_list
*
listpointer
=
NULL
;
listpointer
=
boot_params
->
extlist
;
for
(
;
listpointer
!=
NULL
;
listpointer
=
listpointer
->
next
)
{
char
*
pl
=
(
char
*
)
&
(
listpointer
->
signature
);
if
(
grub_strncmp
(
pl
,
"MEM"
,
3
)
==
0
)
{
new_interface_mem
=
(
mem_map
*
)
listpointer
;
}
}
new_interface_flag
=
1
;
grub_dprintf
(
"loongson"
,
"get new parameter interface
\n
"
);
}
else
{
new_interface_flag
=
0
;
grub_dprintf
(
"loongson"
,
"get old parameter interface
\n
"
);
}
state
.
gpr
[
6
]
=
(
grub_uint64_t
)
tmp_boot_params
;
grub_dprintf
(
"loongson"
,
"boot_params is 0x%llx
\n
"
,
(
_ull
)
state
.
gpr
[
6
]);
mmap_size
=
find_mmap_size
();
if
(
!
mmap_size
)
return
grub_errno
;
mmap_buf
=
grub_efi_allocate_any_pages
(
page_align
(
mmap_size
)
>>
12
);
if
(
!
mmap_buf
)
return
grub_error
(
GRUB_ERR_IO
,
"cannot allocate memory map"
);
err
=
grub_efi_finish_boot_services
(
&
mmap_size
,
mmap_buf
,
NULL
,
&
desc_size
,
NULL
);
//grub_printf("%s-%d\n", __func__, __LINE__);
if
(
err
)
return
err
;
if
(
new_interface_flag
)
{
if
(
!
mmap_buf
||
!
mmap_size
||
!
desc_size
)
return
-
1
;
tmp_index
=
new_interface_mem
->
mapcount
;
//grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index);
/*
According to UEFI SPEC,mmap_buf is the accurate Memory Map array \
now we can fill platform specific memory structure.
*/
for
(
lsdesc
=
mmap_buf
;
lsdesc
<
(
grub_efi_memory_descriptor_t
*
)((
char
*
)
mmap_buf
+
mmap_size
);
lsdesc
=
(
grub_efi_memory_descriptor_t
*
)((
char
*
)
lsdesc
+
desc_size
))
{
/* Recovery */
if
((
lsdesc
->
type
!=
GRUB_EFI_ACPI_RECLAIM_MEMORY
)
&&
\
(
lsdesc
->
type
!=
GRUB_EFI_ACPI_MEMORY_NVS
)
&&
\
(
lsdesc
->
type
!=
GRUB_EFI_RUNTIME_SERVICES_DATA
)
&&
\
(
lsdesc
->
type
!=
GRUB_EFI_RUNTIME_SERVICES_CODE
)
&&
\
(
lsdesc
->
type
!=
GRUB_EFI_RESERVED_MEMORY_TYPE
)
&&
\
(
lsdesc
->
type
!=
GRUB_EFI_PAL_CODE
))
{
free_mem
[
free_index
].
memtype
=
GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW
;
free_mem
[
free_index
].
memstart
=
(
lsdesc
->
physical_start
)
&
0xffffffffffff
;
free_mem
[
free_index
].
memsize
=
lsdesc
->
num_pages
*
4096
;
free_index
++
;
/*ACPI*/
}
else
if
((
lsdesc
->
type
==
GRUB_EFI_ACPI_RECLAIM_MEMORY
)){
acpi_table_mem
[
acpi_table_index
].
memtype
=
GRUB_EFI_LOONGSON_ACPI_TABLE
;
acpi_table_mem
[
acpi_table_index
].
memstart
=
(
lsdesc
->
physical_start
)
&
0xffffffffffff
;
acpi_table_mem
[
acpi_table_index
].
memsize
=
lsdesc
->
num_pages
*
4096
;
acpi_table_index
++
;
}
else
if
((
lsdesc
->
type
==
GRUB_EFI_ACPI_MEMORY_NVS
)){
acpi_nvs_mem
[
acpi_nvs_index
].
memtype
=
GRUB_EFI_LOONGSON_ACPI_NVS
;
acpi_nvs_mem
[
acpi_nvs_index
].
memstart
=
(
lsdesc
->
physical_start
)
&
0xffffffffffff
;
acpi_nvs_mem
[
acpi_nvs_index
].
memsize
=
lsdesc
->
num_pages
*
4096
;
acpi_nvs_index
++
;
/* Reserve */
}
else
{
reserve_mem
[
reserve_index
].
memtype
=
GRUB_EFI_LOONGSON_MEMORY_RESERVED
;
reserve_mem
[
reserve_index
].
memstart
=
(
lsdesc
->
physical_start
)
&
0xffffffffffff
;
reserve_mem
[
reserve_index
].
memsize
=
lsdesc
->
num_pages
*
4096
;
reserve_index
++
;
}
}
/* Recovery sort */
for
(
j
=
0
;
j
<
free_index
;)
{
tempMemsize
=
free_mem
[
j
].
memsize
;
for
(
t
=
j
+
1
;
t
<
free_index
;
t
++
)
{
if
((
free_mem
[
j
].
memstart
+
tempMemsize
==
free_mem
[
t
].
memstart
)
&&
(
free_mem
[
j
].
memtype
==
free_mem
[
t
].
memtype
))
{
tempMemsize
+=
free_mem
[
t
].
memsize
;
}
else
{
break
;
}
}
if
(
free_mem
[
j
].
memstart
>=
0x10000000
)
/*HIGH MEM*/
new_interface_mem
->
map
[
tmp_index
].
memtype
=
GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH
;
else
new_interface_mem
->
map
[
tmp_index
].
memtype
=
GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW
;
new_interface_mem
->
map
[
tmp_index
].
memstart
=
free_mem
[
j
].
memstart
;
new_interface_mem
->
map
[
tmp_index
].
memsize
=
tempMemsize
;
grub_dprintf
(
"loongson"
,
"map[%d]:type %x, start 0x%llx, end 0x%llx
\n
"
,
tmp_index
,
new_interface_mem
->
map
[
tmp_index
].
memtype
,
(
_ull
)
new_interface_mem
->
map
[
tmp_index
].
memstart
,
(
_ull
)
new_interface_mem
->
map
[
tmp_index
].
memstart
+
new_interface_mem
->
map
[
tmp_index
].
memsize
);
j
=
t
;
tmp_index
++
;
}
/*ACPI Sort*/
tmp_index
=
grub_efi_loongson_memmap_sort
(
acpi_table_mem
,
acpi_table_index
,
new_interface_mem
,
tmp_index
,
GRUB_EFI_LOONGSON_ACPI_TABLE
);
tmp_index
=
grub_efi_loongson_memmap_sort
(
acpi_nvs_mem
,
acpi_nvs_index
,
new_interface_mem
,
tmp_index
,
GRUB_EFI_LOONGSON_ACPI_NVS
);
/*Reserve Sort*/
tmp_index
=
grub_efi_loongson_memmap_sort
(
reserve_mem
,
reserve_index
,
new_interface_mem
,
tmp_index
,
GRUB_EFI_LOONGSON_MEMORY_RESERVED
);
new_interface_mem
->
mapcount
=
tmp_index
;
new_interface_mem
->
header
.
checksum
=
0
;
//grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index);
checksum
=
grub_efi_loongson_grub_calculatechecksum8
((
grub_uint8_t
*
)
new_interface_mem
,
new_interface_mem
->
header
.
length
);
new_interface_mem
->
header
.
checksum
=
checksum
;
}
}
state
.
jumpreg
=
1
;
grub_relocator64_boot
(
relocator
,
state
);
return
GRUB_ERR_NONE
;
}
static
grub_err_t
grub_linux_unload
(
void
)
{
grub_relocator_unload
(
relocator
);
grub_dl_unref
(
my_mod
);
loaded
=
0
;
return
GRUB_ERR_NONE
;
}
static
grub_err_t
grub_linux_load32
(
grub_elf_t
elf
,
const
char
*
filename
)
{
Elf32_Addr
base
;
grub_err_t
err
;
grub_uint8_t
*
playground
;
/* Linux's entry point incorrectly contains a virtual address. */
entry_addr
=
elf
->
ehdr
.
ehdr32
.
e_entry
;
linux_size
=
grub_elf32_size
(
elf
,
&
base
,
0
);
if
(
linux_size
==
0
)
return
grub_errno
;
target_addr
=
base
;
linux_size
=
ALIGN_UP
(
base
+
linux_size
-
base
,
8
);
relocator
=
grub_relocator_new
();
if
(
!
relocator
)
return
grub_errno
;
{
grub_relocator_chunk_t
ch
;
err
=
grub_relocator_alloc_chunk_addr
(
relocator
,
&
ch
,
grub_vtop
((
void
*
)
target_addr
),
linux_size
);
if
(
err
)
return
err
;
playground
=
get_virtual_current_address
(
ch
);
}
/* Now load the segments into the area we claimed. */
return
grub_elf32_load
(
elf
,
filename
,
playground
-
base
,
GRUB_ELF_LOAD_FLAGS_NONE
,
0
,
0
);
}
static
grub_err_t
grub_linux_load64
(
grub_elf_t
elf
,
const
char
*
filename
)
{
Elf64_Addr
base
;
grub_err_t
err
;
grub_uint8_t
*
playground
;
/* Linux's entry point incorrectly contains a virtual address. */
entry_addr
=
elf
->
ehdr
.
ehdr64
.
e_entry
;
grub_dprintf
(
"loongson"
,
"entry address = 0x%llx
\n
"
,
(
_ull
)
entry_addr
);
linux_size
=
grub_elf64_size
(
elf
,
&
base
,
0
);
grub_dprintf
(
"loongson"
,
"base = 0x%llx
\n
"
,
(
_ull
)
base
);
if
(
linux_size
==
0
)
return
grub_errno
;
target_addr
=
base
;
linux_size
=
ALIGN_UP
(
base
+
linux_size
-
base
,
8
);
relocator
=
grub_relocator_new
();
if
(
!
relocator
)
return
grub_errno
;
{
grub_relocator_chunk_t
ch
;
err
=
grub_relocator_alloc_chunk_addr
(
relocator
,
&
ch
,
grub_vtop
((
void
*
)
target_addr
),
linux_size
);
if
(
err
)
return
err
;
playground
=
get_virtual_current_address
(
ch
);
//playground = 0xffffffff81ee0000; //将内核直接load到elf头指定内存,而非grub分配的空间
//playground = 0xffffffff80200000;
}
grub_printf
(
"playground:0x%llx
\n
"
,
(
_ull
)
playground
);
/* Now load the segments into the area we claimed. */
return
grub_elf64_load
(
elf
,
filename
,
playground
-
base
,
GRUB_ELF_LOAD_FLAGS_NONE
,
0
,
0
);
}
static
grub_err_t
grub_cmd_linux
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
grub_elf_t
elf
=
0
;
int
size
;
int
i
;
grub_uint32_t
*
linux_argv
;
char
*
linux_args
;
grub_err_t
err
;
if
(
argc
==
0
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"filename expected"
));
if
(
ventoy_linux_argc
)
{
ventoy_bootopt_hook
(
argc
,
argv
);
argc
=
ventoy_linux_argc
;
argv
=
ventoy_linux_args
;
}
elf
=
grub_elf_open
(
argv
[
0
],
GRUB_FILE_TYPE_LINUX_KERNEL
);
if
(
!
elf
)
return
grub_errno
;
if
(
elf
->
ehdr
.
ehdr32
.
e_type
!=
ET_EXEC
)
{
grub_elf_close
(
elf
);
return
grub_error
(
GRUB_ERR_UNKNOWN_OS
,
N_
(
"this ELF file is not of the right type"
));
}
/* Release the previously used memory. */
grub_loader_unset
();
loaded
=
0
;
/* For arguments. */
linux_argc
=
argc
;
/* Main arguments. */
size
=
(
linux_argc
)
*
sizeof
(
grub_uint32_t
);
/* Initrd address and size. */
size
+=
2
*
sizeof
(
grub_uint32_t
);
/* NULL terminator. */
size
+=
sizeof
(
grub_uint32_t
);
/* First argument is always "a0". */
size
+=
ALIGN_UP
(
sizeof
(
"a0"
),
4
);
/* Normal arguments. */
for
(
i
=
1
;
i
<
argc
;
i
++
)
size
+=
ALIGN_UP
(
grub_strlen
(
argv
[
i
])
+
1
,
4
);
/* rd arguments. */
size
+=
ALIGN_UP
(
sizeof
(
"rd_start=0xXXXXXXXXXXXXXXXX"
),
4
);
size
+=
ALIGN_UP
(
sizeof
(
"rd_size=0xXXXXXXXXXXXXXXXX"
),
4
);
size
=
ALIGN_UP
(
size
,
8
);
if
(
grub_elf_is_elf32
(
elf
))
err
=
grub_linux_load32
(
elf
,
argv
[
0
]);
else
if
(
grub_elf_is_elf64
(
elf
))
err
=
grub_linux_load64
(
elf
,
argv
[
0
]);
else
err
=
grub_error
(
GRUB_ERR_BAD_OS
,
N_
(
"invalid arch-dependent ELF magic"
));
grub_elf_close
(
elf
);
if
(
err
)
return
err
;
{
grub_relocator_chunk_t
ch
;
err
=
grub_relocator_alloc_chunk_align
(
relocator
,
&
ch
,
0
,
(
0xffffffff
-
size
)
+
1
,
size
,
8
,
GRUB_RELOCATOR_PREFERENCE_HIGH
,
0
);
if
(
err
)
return
err
;
linux_args_addr
=
get_virtual_current_address
(
ch
);
}
linux_argv
=
(
grub_uint32_t
*
)
linux_args_addr
;
linux_args
=
(
char
*
)
(
linux_argv
+
(
linux_argc
+
1
+
2
));
grub_memcpy
(
linux_args
,
"a0"
,
sizeof
(
"a0"
));
*
linux_argv
=
(
grub_uint32_t
)
(
grub_addr_t
)
linux_args
;
linux_argv
++
;
linux_args
+=
ALIGN_UP
(
sizeof
(
"a0"
),
4
);
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
grub_memcpy
(
linux_args
,
argv
[
i
],
grub_strlen
(
argv
[
i
])
+
1
);
*
linux_argv
=
(
grub_uint32_t
)
(
grub_addr_t
)
linux_args
;
linux_argv
++
;
linux_args
+=
ALIGN_UP
(
grub_strlen
(
argv
[
i
])
+
1
,
4
);
}
/* Reserve space for rd arguments. */
rd_addr_arg_off
=
(
grub_uint8_t
*
)
linux_args
-
linux_args_addr
;
linux_args
+=
ALIGN_UP
(
sizeof
(
"rd_start=0xXXXXXXXXXXXXXXXX"
),
4
);
*
linux_argv
=
0
;
linux_argv
++
;
rd_size_arg_off
=
(
grub_uint8_t
*
)
linux_args
-
linux_args_addr
;
linux_args
+=
ALIGN_UP
(
sizeof
(
"rd_size=0xXXXXXXXXXXXXXXXX"
),
4
);
*
linux_argv
=
0
;
linux_argv
++
;
*
linux_argv
=
0
;
//wake up other cores
{
__asm__
(
"dli $8, 0x900000003ff01000
\n\t
"
"dli $11, 0
\n\t
"
"dsll $11, 8
\n\t
"
"or $8, $8,$11
\n\t
"
"li $9, 0x5a5a
\n\t
"
"sw $9, 32($8)
\n\t
"
"nop
\n\t
"
:
:
);
}
grub_loader_set
(
grub_linux_boot
,
grub_linux_unload
,
0
);
initrd_loaded
=
0
;
loaded
=
1
;
grub_dl_ref
(
my_mod
);
return
GRUB_ERR_NONE
;
}
static
grub_err_t
grub_cmd_initrd
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
grub_size_t
size
=
0
;
void
*
initrd_dest
;
grub_err_t
err
;
struct
grub_linux_initrd_context
initrd_ctx
=
{
0
,
0
,
0
};
if
(
argc
==
0
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"filename expected"
));
if
(
!
loaded
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"you need to load the kernel first"
));
if
(
initrd_loaded
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"only one initrd command can be issued."
);
if
(
grub_initrd_init
(
argc
,
argv
,
&
initrd_ctx
))
goto
fail
;
size
=
grub_get_initrd_size
(
&
initrd_ctx
);
{
grub_relocator_chunk_t
ch
;
err
=
grub_relocator_alloc_chunk_align
(
relocator
,
&
ch
,
0
,
(
0xffffffff
-
size
)
+
1
,
size
,
0x10000
,
GRUB_RELOCATOR_PREFERENCE_HIGH
,
0
);
if
(
err
)
goto
fail
;
initrd_dest
=
get_virtual_current_address
(
ch
);
}
if
(
grub_initrd_load
(
&
initrd_ctx
,
argv
,
initrd_dest
))
goto
fail
;
grub_snprintf
((
char
*
)
linux_args_addr
+
rd_addr_arg_off
,
sizeof
(
"rd_start=0xXXXXXXXXXXXXXXXX"
),
"rd_start=0x%lx"
,
(
grub_uint64_t
)
initrd_dest
);
((
grub_uint32_t
*
)
linux_args_addr
)[
linux_argc
]
=
(
grub_uint32_t
)
((
grub_addr_t
)
linux_args_addr
+
rd_addr_arg_off
);
linux_argc
++
;
grub_snprintf
((
char
*
)
linux_args_addr
+
rd_size_arg_off
,
sizeof
(
"rd_size=0xXXXXXXXXXXXXXXXXX"
),
"rd_size=0x%lx"
,
(
grub_uint64_t
)
size
);
((
grub_uint32_t
*
)
linux_args_addr
)[
linux_argc
]
=
(
grub_uint32_t
)
((
grub_addr_t
)
linux_args_addr
+
rd_size_arg_off
);
linux_argc
++
;
initrd_loaded
=
1
;
fail:
grub_initrd_close
(
&
initrd_ctx
);
return
grub_errno
;
}
static
grub_err_t
ventoy_cmd_initrd
(
grub_command_t
cmd
__attribute__
((
unused
)),
int
argc
,
char
*
argv
[])
{
int
i
;
const
char
*
file
;
char
buf
[
64
];
if
(
ventoy_debug
)
grub_printf
(
"ventoy_cmd_initrd %d
\n
"
,
ventoy_linux_argc
);
if
(
ventoy_linux_argc
==
0
)
{
return
grub_cmd_initrd
(
cmd
,
argc
,
argv
);
}
grub_snprintf
(
buf
,
sizeof
(
buf
),
"mem:%s:size:%s"
,
grub_env_get
(
"ventoy_cpio_addr"
),
grub_env_get
(
"ventoy_cpio_size"
));
if
(
ventoy_debug
)
grub_printf
(
"membuf=%s
\n
"
,
buf
);
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
buf
);
file
=
grub_env_get
(
"vtoy_img_part_file"
);
if
(
file
)
{
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
file
);
}
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
ventoy_extra_initrd_list
[
ventoy_extra_initrd_num
++
]
=
grub_strdup
(
argv
[
i
]);
}
ventoy_initrd_called
=
1
;
if
(
ventoy_debug
)
{
grub_printf
(
"========== initrd list ==========
\n
"
);
for
(
i
=
0
;
i
<
ventoy_extra_initrd_num
;
i
++
)
{
grub_printf
(
"%s
\n
"
,
ventoy_extra_initrd_list
[
i
]);
}
grub_printf
(
"=================================
\n
"
);
}
return
grub_cmd_initrd
(
cmd
,
ventoy_extra_initrd_num
,
ventoy_extra_initrd_list
);
}
static
grub_command_t
cmd_linux
,
cmd_initrd
;
static
grub_command_t
cmd_set_bootopt
,
cmd_unset_bootopt
,
cmd_extra_initrd_append
,
cmd_extra_initrd_reset
;
GRUB_MOD_INIT
(
linux
)
{
cmd_linux
=
grub_register_command
(
"linux"
,
grub_cmd_linux
,
0
,
N_
(
"Load Linux."
));
cmd_initrd
=
grub_register_command
(
"initrd"
,
ventoy_cmd_initrd
,
0
,
N_
(
"Load initrd."
));
cmd_set_bootopt
=
grub_register_command
(
"vt_set_boot_opt"
,
grub_cmd_set_boot_opt
,
0
,
N_
(
"set ext boot opt"
));
cmd_unset_bootopt
=
grub_register_command
(
"vt_unset_boot_opt"
,
grub_cmd_unset_boot_opt
,
0
,
N_
(
"unset ext boot opt"
));
cmd_extra_initrd_append
=
grub_register_command
(
"vt_img_extra_initrd_append"
,
grub_cmd_extra_initrd_append
,
0
,
N_
(
""
));
cmd_extra_initrd_reset
=
grub_register_command
(
"vt_img_extra_initrd_reset"
,
grub_cmd_extra_initrd_reset
,
0
,
N_
(
""
));
ventoy_linux_args
=
grub_zalloc
(
sizeof
(
char
*
)
*
LINUX_MAX_ARGC
);
my_mod
=
mod
;
}
GRUB_MOD_FINI
(
linux
)
{
grub_unregister_command
(
cmd_linux
);
grub_unregister_command
(
cmd_initrd
);
}
GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#include <grub/serial.h>
#include <grub/term.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/terminfo.h>
#if !defined (GRUB_MACHINE_EMU) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
#include <grub/cpu/io.h>
#endif
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/list.h>
#ifdef GRUB_MACHINE_MIPS_LOONGSON
#include <grub/machine/kernel.h>
#endif
#ifdef GRUB_MACHINE_IEEE1275
#include <grub/ieee1275/console.h>
#endif
GRUB_MOD_LICENSE
(
"GPLv3+"
);
#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports))
enum
{
OPTION_UNIT
,
OPTION_PORT
,
OPTION_SPEED
,
OPTION_WORD
,
OPTION_PARITY
,
OPTION_STOP
,
OPTION_BASE_CLOCK
,
OPTION_RTSCTS
};
/* Argument options. */
static
const
struct
grub_arg_option
options
[]
=
{
{
"unit"
,
'u'
,
0
,
N_
(
"Set the serial unit."
),
0
,
ARG_TYPE_INT
},
{
"port"
,
'p'
,
0
,
N_
(
"Set the serial port address."
),
0
,
ARG_TYPE_STRING
},
{
"speed"
,
's'
,
0
,
N_
(
"Set the serial port speed."
),
0
,
ARG_TYPE_INT
},
{
"word"
,
'w'
,
0
,
N_
(
"Set the serial port word length."
),
0
,
ARG_TYPE_INT
},
{
"parity"
,
'r'
,
0
,
N_
(
"Set the serial port parity."
),
0
,
ARG_TYPE_STRING
},
{
"stop"
,
't'
,
0
,
N_
(
"Set the serial port stop bits."
),
0
,
ARG_TYPE_INT
},
{
"base-clock"
,
'b'
,
0
,
N_
(
"Set the base frequency."
),
0
,
ARG_TYPE_STRING
},
{
"rtscts"
,
'f'
,
0
,
N_
(
"Enable/disable RTS/CTS."
),
"on|off"
,
ARG_TYPE_STRING
},
{
0
,
0
,
0
,
0
,
0
,
0
}
};
static
struct
grub_serial_port
*
grub_serial_ports
;
struct
grub_serial_output_state
{
struct
grub_terminfo_output_state
tinfo
;
struct
grub_serial_port
*
port
;
};
struct
grub_serial_input_state
{
struct
grub_terminfo_input_state
tinfo
;
struct
grub_serial_port
*
port
;
};
static
void
serial_put
(
grub_term_output_t
term
,
const
int
c
)
{
struct
grub_serial_output_state
*
data
=
term
->
data
;
data
->
port
->
driver
->
put
(
data
->
port
,
c
);
}
static
int
serial_fetch
(
grub_term_input_t
term
)
{
struct
grub_serial_input_state
*
data
=
term
->
data
;
return
data
->
port
->
driver
->
fetch
(
data
->
port
);
}
static
const
struct
grub_serial_input_state
grub_serial_terminfo_input_template
=
{
.
tinfo
=
{
.
readkey
=
serial_fetch
}
};
static
const
struct
grub_serial_output_state
grub_serial_terminfo_output_template
=
{
.
tinfo
=
{
.
put
=
serial_put
,
.
size
=
{
80
,
24
}
}
};
static
struct
grub_serial_input_state
grub_serial_terminfo_input
;
static
struct
grub_serial_output_state
grub_serial_terminfo_output
;
static
int
registered
=
0
;
static
struct
grub_term_input
grub_serial_term_input
=
{
.
name
=
"serial"
,
.
init
=
grub_terminfo_input_init
,
.
getkey
=
grub_terminfo_getkey
,
.
data
=
&
grub_serial_terminfo_input
};
static
struct
grub_term_output
grub_serial_term_output
=
{
.
name
=
"serial"
,
.
init
=
grub_terminfo_output_init
,
.
putchar
=
grub_terminfo_putchar
,
.
getwh
=
grub_terminfo_getwh
,
.
getxy
=
grub_terminfo_getxy
,
.
gotoxy
=
grub_terminfo_gotoxy
,
.
cls
=
grub_terminfo_cls
,
.
setcolorstate
=
grub_terminfo_setcolorstate
,
.
setcursor
=
grub_terminfo_setcursor
,
.
flags
=
GRUB_TERM_CODE_TYPE_ASCII
,
.
data
=
&
grub_serial_terminfo_output
,
.
progress_update_divisor
=
GRUB_PROGRESS_SLOW
};
struct
grub_serial_port
*
grub_serial_find
(
const
char
*
name
)
{
struct
grub_serial_port
*
port
;
FOR_SERIAL_PORTS
(
port
)
if
(
grub_strcmp
(
port
->
name
,
name
)
==
0
)
break
;
#if ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC)
if
(
!
port
&&
grub_memcmp
(
name
,
"port"
,
sizeof
(
"port"
)
-
1
)
==
0
&&
grub_isxdigit
(
name
[
sizeof
(
"port"
)
-
1
]))
{
name
=
grub_serial_ns8250_add_port
(
grub_strtoul
(
&
name
[
sizeof
(
"port"
)
-
1
],
0
,
16
));
if
(
!
name
)
return
NULL
;
FOR_SERIAL_PORTS
(
port
)
if
(
grub_strcmp
(
port
->
name
,
name
)
==
0
)
break
;
}
#endif
#ifdef GRUB_MACHINE_IEEE1275
if
(
!
port
&&
grub_memcmp
(
name
,
"ieee1275/"
,
sizeof
(
"ieee1275/"
)
-
1
)
==
0
)
{
name
=
grub_ofserial_add_port
(
&
name
[
sizeof
(
"ieee1275/"
)
-
1
]);
if
(
!
name
)
return
NULL
;
FOR_SERIAL_PORTS
(
port
)
if
(
grub_strcmp
(
port
->
name
,
name
)
==
0
)
break
;
}
#endif
return
port
;
}
static
grub_err_t
grub_cmd_serial
(
grub_extcmd_context_t
ctxt
,
int
argc
,
char
**
args
)
{
struct
grub_arg_list
*
state
=
ctxt
->
state
;
char
pname
[
40
];
const
char
*
name
=
NULL
;
struct
grub_serial_port
*
port
;
struct
grub_serial_config
config
;
grub_err_t
err
;
if
(
state
[
OPTION_UNIT
].
set
)
{
grub_snprintf
(
pname
,
sizeof
(
pname
),
"com%ld"
,
grub_strtoul
(
state
[
0
].
arg
,
0
,
0
));
name
=
pname
;
}
if
(
state
[
OPTION_PORT
].
set
)
{
grub_snprintf
(
pname
,
sizeof
(
pname
),
"port%lx"
,
grub_strtoul
(
state
[
1
].
arg
,
0
,
0
));
name
=
pname
;
}
if
(
argc
>=
1
)
name
=
args
[
0
];
if
(
!
name
)
name
=
"com0"
;
port
=
grub_serial_find
(
name
);
if
(
!
port
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"serial port `%s' isn't found"
),
name
);
config
=
port
->
config
;
if
(
state
[
OPTION_SPEED
].
set
)
{
config
.
speed
=
grub_strtoul
(
state
[
OPTION_SPEED
].
arg
,
0
,
0
);
if
(
config
.
speed
==
0
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"unsupported serial port parity"
));
}
if
(
state
[
OPTION_WORD
].
set
)
config
.
word_len
=
grub_strtoul
(
state
[
OPTION_WORD
].
arg
,
0
,
0
);
if
(
state
[
OPTION_PARITY
].
set
)
{
if
(
!
grub_strcmp
(
state
[
OPTION_PARITY
].
arg
,
"no"
))
config
.
parity
=
GRUB_SERIAL_PARITY_NONE
;
else
if
(
!
grub_strcmp
(
state
[
OPTION_PARITY
].
arg
,
"odd"
))
config
.
parity
=
GRUB_SERIAL_PARITY_ODD
;
else
if
(
!
grub_strcmp
(
state
[
OPTION_PARITY
].
arg
,
"even"
))
config
.
parity
=
GRUB_SERIAL_PARITY_EVEN
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"unsupported serial port parity"
));
}
if
(
state
[
OPTION_RTSCTS
].
set
)
{
if
(
grub_strcmp
(
state
[
OPTION_RTSCTS
].
arg
,
"on"
)
==
0
)
config
.
rtscts
=
1
;
else
if
(
grub_strcmp
(
state
[
OPTION_RTSCTS
].
arg
,
"off"
)
==
0
)
config
.
rtscts
=
0
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"unsupported serial port flow control"
));
}
if
(
state
[
OPTION_STOP
].
set
)
{
if
(
!
grub_strcmp
(
state
[
OPTION_STOP
].
arg
,
"1"
))
config
.
stop_bits
=
GRUB_SERIAL_STOP_BITS_1
;
else
if
(
!
grub_strcmp
(
state
[
OPTION_STOP
].
arg
,
"2"
))
config
.
stop_bits
=
GRUB_SERIAL_STOP_BITS_2
;
else
if
(
!
grub_strcmp
(
state
[
OPTION_STOP
].
arg
,
"1.5"
))
config
.
stop_bits
=
GRUB_SERIAL_STOP_BITS_1_5
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
N_
(
"unsupported serial port stop bits number"
));
}
if
(
state
[
OPTION_BASE_CLOCK
].
set
)
{
char
*
ptr
;
config
.
base_clock
=
grub_strtoull
(
state
[
OPTION_BASE_CLOCK
].
arg
,
&
ptr
,
0
);
if
(
grub_errno
)
return
grub_errno
;
if
(
ptr
&&
*
ptr
==
'M'
)
config
.
base_clock
*=
1000000
;
if
(
ptr
&&
(
*
ptr
==
'k'
||
*
ptr
==
'K'
))
config
.
base_clock
*=
1000
;
}
if
(
config
.
speed
==
0
)
config
.
speed
=
9600
;
/* Initialize with new settings. */
err
=
port
->
driver
->
configure
(
port
,
&
config
);
if
(
err
)
return
err
;
#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
/* Compatibility kludge. */
if
(
port
->
driver
==
&
grub_ns8250_driver
)
{
if
(
!
registered
)
{
grub_terminfo_output_register
(
&
grub_serial_term_output
,
"vt100"
);
grub_term_register_input
(
"serial"
,
&
grub_serial_term_input
);
grub_term_register_output
(
"serial"
,
&
grub_serial_term_output
);
}
grub_serial_terminfo_output
.
port
=
port
;
grub_serial_terminfo_input
.
port
=
port
;
registered
=
1
;
}
#endif
return
GRUB_ERR_NONE
;
}
#ifdef GRUB_MACHINE_MIPS_LOONGSON
const
char
loongson_defserial
[][
6
]
=
{
[
GRUB_ARCH_MACHINE_YEELOONG
]
=
"com0"
,
[
GRUB_ARCH_MACHINE_FULOONG2F
]
=
"com2"
,
[
GRUB_ARCH_MACHINE_FULOONG2E
]
=
"com1"
};
#endif
grub_err_t
grub_serial_register
(
struct
grub_serial_port
*
port
)
{
struct
grub_term_input
*
in
;
struct
grub_term_output
*
out
;
struct
grub_serial_input_state
*
indata
;
struct
grub_serial_output_state
*
outdata
;
in
=
grub_malloc
(
sizeof
(
*
in
));
if
(
!
in
)
return
grub_errno
;
indata
=
grub_malloc
(
sizeof
(
*
indata
));
if
(
!
indata
)
{
grub_free
(
in
);
return
grub_errno
;
}
grub_memcpy
(
in
,
&
grub_serial_term_input
,
sizeof
(
*
in
));
in
->
data
=
indata
;
in
->
name
=
grub_xasprintf
(
"serial_%s"
,
port
->
name
);
grub_memcpy
(
indata
,
&
grub_serial_terminfo_input
,
sizeof
(
*
indata
));
if
(
!
in
->
name
)
{
grub_free
(
in
);
grub_free
(
indata
);
return
grub_errno
;
}
out
=
grub_zalloc
(
sizeof
(
*
out
));
if
(
!
out
)
{
grub_free
(
indata
);
grub_free
((
char
*
)
in
->
name
);
grub_free
(
in
);
return
grub_errno
;
}
outdata
=
grub_malloc
(
sizeof
(
*
outdata
));
if
(
!
outdata
)
{
grub_free
(
indata
);
grub_free
((
char
*
)
in
->
name
);
grub_free
(
out
);
grub_free
(
in
);
return
grub_errno
;
}
grub_memcpy
(
out
,
&
grub_serial_term_output
,
sizeof
(
*
out
));
out
->
data
=
outdata
;
out
->
name
=
in
->
name
;
grub_memcpy
(
outdata
,
&
grub_serial_terminfo_output
,
sizeof
(
*
outdata
));
grub_list_push
(
GRUB_AS_LIST_P
(
&
grub_serial_ports
),
GRUB_AS_LIST
(
port
));
((
struct
grub_serial_input_state
*
)
in
->
data
)
->
port
=
port
;
((
struct
grub_serial_output_state
*
)
out
->
data
)
->
port
=
port
;
port
->
term_in
=
in
;
port
->
term_out
=
out
;
grub_terminfo_output_register
(
out
,
"vt100"
);
#ifdef GRUB_MACHINE_MIPS_LOONGSON
if
(
grub_strcmp
(
port
->
name
,
loongson_defserial
[
grub_arch_machine
])
==
0
)
{
grub_term_register_input_active
(
"serial_*"
,
in
);
grub_term_register_output_active
(
"serial_*"
,
out
);
}
else
{
grub_term_register_input_inactive
(
"serial_*"
,
in
);
grub_term_register_output_inactive
(
"serial_*"
,
out
);
}
#else
grub_term_register_input
(
"serial_*"
,
in
);
grub_term_register_output
(
"serial_*"
,
out
);
#endif
return
GRUB_ERR_NONE
;
}
void
grub_serial_unregister
(
struct
grub_serial_port
*
port
)
{
if
(
port
->
driver
->
fini
)
port
->
driver
->
fini
(
port
);
if
(
port
->
term_in
)
grub_term_unregister_input
(
port
->
term_in
);
if
(
port
->
term_out
)
grub_term_unregister_output
(
port
->
term_out
);
grub_list_remove
(
GRUB_AS_LIST
(
port
));
}
void
grub_serial_unregister_driver
(
struct
grub_serial_driver
*
driver
)
{
struct
grub_serial_port
*
port
,
*
next
;
for
(
port
=
grub_serial_ports
;
port
;
port
=
next
)
{
next
=
port
->
next
;
if
(
port
->
driver
==
driver
)
grub_serial_unregister
(
port
);
}
}
static
grub_extcmd_t
cmd
;
GRUB_MOD_INIT
(
serial
)
{
cmd
=
grub_register_extcmd
(
"serial"
,
grub_cmd_serial
,
0
,
N_
(
"[OPTIONS...]"
),
N_
(
"Configure serial port."
),
options
);
grub_memcpy
(
&
grub_serial_terminfo_output
,
&
grub_serial_terminfo_output_template
,
sizeof
(
grub_serial_terminfo_output
));
grub_memcpy
(
&
grub_serial_terminfo_input
,
&
grub_serial_terminfo_input_template
,
sizeof
(
grub_serial_terminfo_input
));
#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
grub_ns8250_init
();
#endif
#ifdef GRUB_MACHINE_IEEE1275
grub_ofserial_init
();
#endif
#ifdef GRUB_MACHINE_EFI
grub_efiserial_init
();
#endif
#ifdef GRUB_MACHINE_ARC
grub_arcserial_init
();
#endif
}
GRUB_MOD_FINI
(
serial
)
{
while
(
grub_serial_ports
)
grub_serial_unregister
(
grub_serial_ports
);
if
(
registered
)
{
grub_term_unregister_input
(
&
grub_serial_term_input
);
grub_term_unregister_output
(
&
grub_serial_term_output
);
}
grub_unregister_extcmd
(
cmd
);
}
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
View file @
b63ce2a3
...
...
@@ -1427,6 +1427,11 @@ static int ventoy_arch_mode_init(void)
g_ventoy_plat_data
=
VTOY_PLAT_ARM64_UEFI
;
grub_snprintf
(
g_arch_mode_suffix
,
sizeof
(
g_arch_mode_suffix
),
"%s"
,
"aa64"
);
}
else
if
(
grub_strcmp
(
GRUB_TARGET_CPU
,
"mips64el"
)
==
0
)
{
g_ventoy_plat_data
=
VTOY_PLAT_MIPS_UEFI
;
grub_snprintf
(
g_arch_mode_suffix
,
sizeof
(
g_arch_mode_suffix
),
"%s"
,
"mips"
);
}
else
{
g_ventoy_plat_data
=
VTOY_PLAT_X86_64_UEFI
;
...
...
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
View file @
b63ce2a3
...
...
@@ -56,6 +56,16 @@
#define VTOY_PLAT_ARM64_UEFI 0x41413634
#define VTOY_PLAT_X86_64_UEFI 0x55454649
#define VTOY_PLAT_X86_LEGACY 0x42494f53
#define VTOY_PLAT_MIPS_UEFI 0x4D495053
#define VTOY_COMM_CPIO "ventoy.cpio"
#if defined(__arm__) || defined(__aarch64__)
#define VTOY_ARCH_CPIO "ventoy_arm64.cpio"
#elif defined(__mips__)
#define VTOY_ARCH_CPIO "ventoy_mips64.cpio"
#else
#define VTOY_ARCH_CPIO "ventoy_x86.cpio"
#endif
#define VTOY_PWD_CORRUPTED(err) \
{\
...
...
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c
View file @
b63ce2a3
...
...
@@ -1124,6 +1124,7 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
grub_uint32_t
injection_size
=
0
;
grub_uint32_t
dud_size
=
0
;
grub_file_t
file
;
grub_file_t
archfile
;
grub_file_t
tmpfile
;
ventoy_img_chunk_list
chunk_list
;
...
...
@@ -1142,12 +1143,21 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
img_chunk_size
=
g_img_chunk_list
.
cur_chunk
*
sizeof
(
ventoy_img_chunk
);
file
=
ventoy_grub_file_open
(
VENTOY_FILE_TYPE
,
"%s"
,
args
[
0
]);
file
=
ventoy_grub_file_open
(
VENTOY_FILE_TYPE
,
"%s
/%s
"
,
args
[
0
]
,
VTOY_COMM_CPIO
);
if
(
!
file
)
{
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Can't open file %s
\n
"
,
args
[
0
]);
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Can't open file %s/%s
\n
"
,
args
[
0
],
VTOY_COMM_CPIO
);
}
archfile
=
ventoy_grub_file_open
(
VENTOY_FILE_TYPE
,
"%s/%s"
,
args
[
0
],
VTOY_ARCH_CPIO
);
if
(
!
archfile
)
{
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Can't open file %s/%s
\n
"
,
args
[
0
],
VTOY_ARCH_CPIO
);
grub_file_close
(
file
);
}
debug
(
"load %s %s success
\n
"
,
VTOY_COMM_CPIO
,
VTOY_ARCH_CPIO
);
if
(
g_ventoy_cpio_buf
)
{
grub_free
(
g_ventoy_cpio_buf
);
...
...
@@ -1234,22 +1244,29 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
debug
(
"dud not configed %s
\n
"
,
args
[
1
]);
}
g_ventoy_cpio_buf
=
grub_malloc
(
file
->
size
+
40960
+
template_size
+
g_ventoy_cpio_buf
=
grub_malloc
(
file
->
size
+
archfile
->
size
+
40960
+
template_size
+
persistent_size
+
injection_size
+
dud_size
+
img_chunk_size
);
if
(
NULL
==
g_ventoy_cpio_buf
)
{
grub_file_close
(
file
);
grub_file_close
(
archfile
);
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Can't alloc memory %llu
\n
"
,
file
->
size
);
}
grub_file_read
(
file
,
g_ventoy_cpio_buf
,
file
->
size
);
buf
=
(
grub_uint8_t
*
)(
g_ventoy_cpio_buf
+
file
->
size
-
4
);
while
(
*
((
grub_uint32_t
*
)
buf
)
!=
0x37303730
)
{
buf
-=
4
;
}
grub_file_read
(
archfile
,
buf
,
archfile
->
size
);
buf
+=
(
archfile
->
size
-
4
);
while
(
*
((
grub_uint32_t
*
)
buf
)
!=
0x37303730
)
{
buf
-=
4
;
}
/* get initrd head len */
initrd_head_len
=
ventoy_cpio_newc_fill_head
(
buf
,
0
,
NULL
,
"initrd000.xx"
);
...
...
@@ -1313,6 +1330,7 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
ventoy_cpio_newc_fill_head
(
g_ventoy_initrd_head
,
0
,
NULL
,
"initrd000.xx"
);
grub_file_close
(
file
);
grub_file_close
(
archfile
);
if
(
grub_strcmp
(
args
[
3
],
"busybox=64"
)
==
0
)
{
...
...
@@ -1324,6 +1342,11 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
debug
(
"cpio busybox proc %s
\n
"
,
args
[
3
]);
ventoy_cpio_busybox64
((
cpio_newc_header
*
)
g_ventoy_cpio_buf
,
"a64"
);
}
else
if
(
grub_strcmp
(
args
[
3
],
"busybox=m64"
)
==
0
)
{
debug
(
"cpio busybox proc %s
\n
"
,
args
[
3
]);
ventoy_cpio_busybox64
((
cpio_newc_header
*
)
g_ventoy_cpio_buf
,
"m64"
);
}
VENTOY_CMD_RETURN
(
GRUB_ERR_NONE
);
}
...
...
GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h
0 → 100644
View file @
b63ce2a3
/* cache.h - Flush the processor's cache. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#ifndef GRUB_CACHE_H
#define GRUB_CACHE_H 1
#include <grub/symbol.h>
#include <grub/types.h>
#if defined (__i386__) || defined (__x86_64__)
static
inline
void
grub_arch_sync_caches
(
void
*
address
__attribute__
((
unused
)),
grub_size_t
len
__attribute__
((
unused
)))
{
}
#else
void
EXPORT_FUNC
(
grub_arch_sync_caches
)
(
void
*
address
,
grub_size_t
len
);
#endif
#ifndef GRUB_MACHINE_EMU
#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \
defined (__sparc__)
#elif defined (__i386__) || defined (__x86_64__)
static
inline
void
grub_arch_sync_dma_caches
(
volatile
void
*
address
__attribute__
((
unused
)),
grub_size_t
len
__attribute__
((
unused
)))
{
}
#elif defined(__mips__) && (_MIPS_SIM != _ABI64)
void
EXPORT_FUNC
(
grub_arch_sync_dma_caches
)
(
volatile
void
*
address
,
grub_size_t
len
);
#endif
#endif
#ifdef __arm__
void
grub_arm_cache_enable
(
void
);
#endif
#endif
/* ! GRUB_CACHE_HEADER */
GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h
0 → 100644
View file @
b63ce2a3
/* dl.h - types and prototypes for loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#ifndef GRUB_DL_H
#define GRUB_DL_H 1
#include <grub/symbol.h>
#ifndef ASM_FILE
#include <grub/err.h>
#include <grub/types.h>
#include <grub/elf.h>
#include <grub/list.h>
#include <grub/misc.h>
#endif
/*
* Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules
* to collect module names, so we define them only when they are not
* defined already.
*/
#ifndef ASM_FILE
#ifndef GRUB_MOD_INIT
#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL)
#define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
static void \
grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
#define GRUB_MOD_FINI(name) \
static void grub_mod_fini (void) __attribute__ ((used)); \
static void \
grub_mod_fini (void)
#elif defined (GRUB_KERNEL)
#define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
void \
grub_##name##_init (void) { grub_mod_init (0); } \
static void \
grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
#define GRUB_MOD_FINI(name) \
static void grub_mod_fini (void) __attribute__ ((used)); \
void \
grub_##name##_fini (void) { grub_mod_fini (); } \
static void \
grub_mod_fini (void)
#else
#define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
void grub_##name##_init (void); \
void \
grub_##name##_init (void) { grub_mod_init (0); } \
static void \
grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
#define GRUB_MOD_FINI(name) \
static void grub_mod_fini (void) __attribute__ ((used)); \
void grub_##name##_fini (void); \
void \
grub_##name##_fini (void) { grub_mod_fini (); } \
static void \
grub_mod_fini (void)
#endif
#endif
#endif
#ifndef ASM_FILE
#ifdef __APPLE__
#define GRUB_MOD_SECTION(x) "_" #x ", _" #x ""
#else
#define GRUB_MOD_SECTION(x) "." #x
#endif
#else
#ifdef __APPLE__
#define GRUB_MOD_SECTION(x) _ ## x , _ ##x
#else
#define GRUB_MOD_SECTION(x) . ## x
#endif
#endif
/* Me, Vladimir Serbinenko, hereby I add this module check as per new
GNU module policy. Note that this license check is informative only.
Modules have to be licensed under GPLv3 or GPLv3+ (optionally
multi-licensed under other licences as well) independently of the
presence of this check and solely by linking (module loading in GRUB
constitutes linking) and GRUB core being licensed under GPLv3+.
Be sure to understand your license obligations.
*/
#ifndef ASM_FILE
#if GNUC_PREREQ (3,2)
#define ATTRIBUTE_USED __used__
#else
#define ATTRIBUTE_USED __unused__
#endif
#define GRUB_MOD_LICENSE(license) \
static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
#define GRUB_MOD_DEP(name) \
static const char grub_module_depend_##name[] \
__attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
#define GRUB_MOD_NAME(name) \
static const char grub_module_name_##name[] \
__attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name
#else
#ifdef __APPLE__
.
macro
GRUB_MOD_LICENSE
.
section
GRUB_MOD_SECTION
(
module_license
)
.
ascii
"LICENSE="
.
ascii
$
0
.
byte
0
.
endm
#else
.
macro
GRUB_MOD_LICENSE
license
.
section
GRUB_MOD_SECTION
(
module_license
),
"a"
.
ascii
"LICENSE="
.
ascii
"\license"
.
byte
0
.
endm
#endif
#endif
/* Under GPL license obligations you have to distribute your module
under GPLv3(+). However, you can also distribute the same code under
another license as long as GPLv3(+) version is provided.
*/
#define GRUB_MOD_DUAL_LICENSE(x)
#ifndef ASM_FILE
struct
grub_dl_segment
{
struct
grub_dl_segment
*
next
;
void
*
addr
;
grub_size_t
size
;
unsigned
section
;
};
typedef
struct
grub_dl_segment
*
grub_dl_segment_t
;
struct
grub_dl
;
struct
grub_dl_dep
{
struct
grub_dl_dep
*
next
;
struct
grub_dl
*
mod
;
};
typedef
struct
grub_dl_dep
*
grub_dl_dep_t
;
#ifndef GRUB_UTIL
struct
grub_dl
{
char
*
name
;
int
ref_count
;
int
persistent
;
grub_dl_dep_t
dep
;
grub_dl_segment_t
segment
;
Elf_Sym
*
symtab
;
grub_size_t
symsize
;
void
(
*
init
)
(
struct
grub_dl
*
mod
);
void
(
*
fini
)
(
void
);
#if !defined (__i386__) && !defined (__x86_64__)
void
*
got
;
void
*
gotptr
;
void
*
tramp
;
void
*
trampptr
;
#endif
#if defined(__mips__) && (_MIPS_SIM != _ABI64)
grub_uint32_t
*
reginfo
;
#endif
void
*
base
;
grub_size_t
sz
;
struct
grub_dl
*
next
;
};
#endif
typedef
struct
grub_dl
*
grub_dl_t
;
grub_dl_t
grub_dl_load_file
(
const
char
*
filename
);
grub_dl_t
EXPORT_FUNC
(
grub_dl_load
)
(
const
char
*
name
);
grub_dl_t
grub_dl_load_core
(
void
*
addr
,
grub_size_t
size
);
grub_dl_t
EXPORT_FUNC
(
grub_dl_load_core_noinit
)
(
void
*
addr
,
grub_size_t
size
);
int
EXPORT_FUNC
(
grub_dl_unload
)
(
grub_dl_t
mod
);
void
grub_dl_unload_unneeded
(
void
);
int
EXPORT_FUNC
(
grub_dl_ref
)
(
grub_dl_t
mod
);
int
EXPORT_FUNC
(
grub_dl_unref
)
(
grub_dl_t
mod
);
extern
grub_dl_t
EXPORT_VAR
(
grub_dl_head
);
#ifndef GRUB_UTIL
#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head))
#ifdef GRUB_MACHINE_EMU
void
*
grub_osdep_dl_memalign
(
grub_size_t
align
,
grub_size_t
size
);
void
grub_dl_osdep_dl_free
(
void
*
ptr
);
#endif
static
inline
void
grub_dl_init
(
grub_dl_t
mod
)
{
if
(
mod
->
init
)
(
mod
->
init
)
(
mod
);
mod
->
next
=
grub_dl_head
;
grub_dl_head
=
mod
;
}
static
inline
grub_dl_t
grub_dl_get
(
const
char
*
name
)
{
grub_dl_t
l
;
FOR_DL_MODULES
(
l
)
if
(
grub_strcmp
(
name
,
l
->
name
)
==
0
)
return
l
;
return
0
;
}
static
inline
void
grub_dl_set_persistent
(
grub_dl_t
mod
)
{
mod
->
persistent
=
1
;
}
static
inline
int
grub_dl_is_persistent
(
grub_dl_t
mod
)
{
return
mod
->
persistent
;
}
#endif
grub_err_t
grub_dl_register_symbol
(
const
char
*
name
,
void
*
addr
,
int
isfunc
,
grub_dl_t
mod
);
grub_err_t
grub_arch_dl_check_header
(
void
*
ehdr
);
#ifndef GRUB_UTIL
grub_err_t
grub_arch_dl_relocate_symbols
(
grub_dl_t
mod
,
void
*
ehdr
,
Elf_Shdr
*
s
,
grub_dl_segment_t
seg
);
#endif
#if defined (__mips__) && (_MIPS_SIM != _ABI64)
#define GRUB_LINKER_HAVE_INIT 1
void
grub_arch_dl_init_linker
(
void
);
#endif
#define GRUB_IA64_DL_TRAMP_ALIGN 16
#define GRUB_IA64_DL_GOT_ALIGN 16
grub_err_t
grub_ia64_dl_get_tramp_got_size
(
const
void
*
ehdr
,
grub_size_t
*
tramp
,
grub_size_t
*
got
);
grub_err_t
grub_arm64_dl_get_tramp_got_size
(
const
void
*
ehdr
,
grub_size_t
*
tramp
,
grub_size_t
*
got
);
#if defined (__ia64__)
#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN
#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN
#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size
#elif defined (__aarch64__)
#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size
#else
grub_err_t
grub_arch_dl_get_tramp_got_size
(
const
void
*
ehdr
,
grub_size_t
*
tramp
,
grub_size_t
*
got
);
#endif
#if defined (__powerpc__) || (defined (__mips__) && (_MIPS_SIM != _ABI64)) || defined (__arm__) || \
(defined(__riscv) && (__riscv_xlen == 32))
#define GRUB_ARCH_DL_TRAMP_ALIGN 4
#define GRUB_ARCH_DL_GOT_ALIGN 4
#endif
#if defined (__aarch64__) || defined (__sparc__) || (defined (__mips__) && (_MIPS_SIM == _ABI64)) || \
(defined(__riscv) && (__riscv_xlen == 64))
#define GRUB_ARCH_DL_TRAMP_ALIGN 8
#define GRUB_ARCH_DL_GOT_ALIGN 8
#endif
#endif
#endif
/* ! GRUB_DL_H */
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h
0 → 100644
View file @
b63ce2a3
/* efi.h - declare EFI types and functions */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#ifndef GRUB_EFI_API_HEADER
#define GRUB_EFI_API_HEADER 1
#include <grub/types.h>
#include <grub/symbol.h>
/* For consistency and safety, we name the EFI-defined types differently.
All names are transformed into lower case, _t appended, and
grub_efi_ prepended. */
/* Constants. */
#define GRUB_EFI_EVT_TIMER 0x80000000
#define GRUB_EFI_EVT_RUNTIME 0x40000000
#define GRUB_EFI_EVT_RUNTIME_CONTEXT 0x20000000
#define GRUB_EFI_EVT_NOTIFY_WAIT 0x00000100
#define GRUB_EFI_EVT_NOTIFY_SIGNAL 0x00000200
#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
#define GRUB_EFI_TPL_APPLICATION 4
#define GRUB_EFI_TPL_CALLBACK 8
#define GRUB_EFI_TPL_NOTIFY 16
#define GRUB_EFI_TPL_HIGH_LEVEL 31
#define GRUB_EFI_MEMORY_UC 0x0000000000000001LL
#define GRUB_EFI_MEMORY_WC 0x0000000000000002LL
#define GRUB_EFI_MEMORY_WT 0x0000000000000004LL
#define GRUB_EFI_MEMORY_WB 0x0000000000000008LL
#define GRUB_EFI_MEMORY_UCE 0x0000000000000010LL
#define GRUB_EFI_MEMORY_WP 0x0000000000001000LL
#define GRUB_EFI_MEMORY_RP 0x0000000000002000LL
#define GRUB_EFI_MEMORY_XP 0x0000000000004000LL
#define GRUB_EFI_MEMORY_NV 0x0000000000008000LL
#define GRUB_EFI_MEMORY_MORE_RELIABLE 0x0000000000010000LL
#define GRUB_EFI_MEMORY_RO 0x0000000000020000LL
#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL
#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020
#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
#define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
#define GRUB_EFI_TIME_ADJUST_DAYLIGHT 0x01
#define GRUB_EFI_TIME_IN_DAYLIGHT 0x02
#define GRUB_EFI_UNSPECIFIED_TIMEZONE 0x07FF
#define GRUB_EFI_OPTIONAL_PTR 0x00000001
#define GRUB_EFI_LOADED_IMAGE_GUID \
{ 0x5b1b31a1, 0x9562, 0x11d2, \
{ 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_DISK_IO_GUID \
{ 0xce345171, 0xba0b, 0x11d2, \
{ 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_BLOCK_IO_GUID \
{ 0x964e5b21, 0x6459, 0x11d2, \
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_SERIAL_IO_GUID \
{ 0xbb25cf6f, 0xf1d4, 0x11d2, \
{ 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \
}
#define GRUB_EFI_SIMPLE_NETWORK_GUID \
{ 0xa19832b9, 0xac25, 0x11d3, \
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_PXE_GUID \
{ 0x03c4e603, 0xac28, 0x11d3, \
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_DEVICE_PATH_GUID \
{ 0x09576e91, 0x6d3f, 0x11d2, \
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
{ 0x387477c1, 0x69c7, 0x11d2, \
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
{ 0xdd9e7534, 0x7762, 0x4698, \
{ 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \
}
#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
{ 0x387477c2, 0x69c7, 0x11d2, \
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \
{ 0x31878c87, 0xb75, 0x11d5, \
{ 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \
{ 0x8D59D32B, 0xC655, 0x4AE9, \
{ 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \
}
#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \
{ 0x18A031AB, 0xB443, 0x4D1A, \
{ 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \
}
#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \
{ 0x5B1B31A1, 0x9562, 0x11d2, \
{ 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
}
#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \
{ 0x56EC3091, 0x954C, 0x11d2, \
{ 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
}
#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
{ 0x0964e5b22, 0x6459, 0x11d2, \
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \
{ 0x1e93e633, 0xd65a, 0x459e, \
{ 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \
}
#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \
{ 0x1d85cd7f, 0xf43d, 0x11d2, \
{ 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \
{ 0x932f47e6, 0x2362, 0x4002, \
{ 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \
}
#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \
{ 0x3e745226, 0x9818, 0x45b6, \
{ 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \
}
#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \
{ 0x2755590C, 0x6F3C, 0x42FA, \
{ 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \
}
#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \
{ 0xEBA4E8D2, 0x3858, 0x41EC, \
{ 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
}
#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \
{ 0xd8117cfe, 0x94a6, 0x11d4, \
{ 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
{ 0x8b843e20, 0x8132, 0x4852, \
{ 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \
}
#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \
{ 0x379be4e, 0xd706, 0x437d, \
{ 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
}
#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
{ 0x5c99a21, 0xc70f, 0x4ad2, \
{ 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \
}
#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \
{ 0xffe06bdd, 0x6107, 0x46a6, \
{ 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \
}
#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
{ 0x587e72d7, 0xcc50, 0x4f79, \
{ 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \
}
#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \
{ 0xef9fc172, 0xa1b2, 0x4693, \
{ 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \
}
#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \
{ 0xfd96974, 0x23aa, 0x4cdc, \
{ 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \
}
#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \
{ 0x31a6406a, 0x6bdf, 0x4e46, \
{ 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \
}
#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \
{ 0xe9ca4775, 0x8657, 0x47fc, \
{ 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \
}
#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \
{ 0x330d4706, 0xf2a0, 0x4e4f, \
{ 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \
}
#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \
{ 0x6a7a5cff, 0xe8d9, 0x4f70, \
{ 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \
}
#define GRUB_EFI_USB_IO_PROTOCOL_GUID \
{ 0x2B2F68D6, 0x0CD2, 0x44cf, \
{ 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \
}
#define GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID \
{ 0xa31280ad, 0x481e, 0x41b6, \
{ 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } \
}
#define GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID \
{ 0xfc1bcdb0, 0x7d31, 0x49aa, \
{ 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } \
}
#define GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID \
{ 0xee4e5898, 0x3914, 0x4259, \
{ 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } \
}
#define GRUB_EFI_TSC_FREQUENCY_GUID \
{ 0xdba6a7e3, 0xbb57, 0x4be7, \
{ 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } \
}
#define GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID \
{ 0xb122a263, 0x3661, 0x4f68, \
{ 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } \
}
#define GRUB_EFI_DXE_SERVICES_TABLE_GUID \
{ 0x05ad34ba, 0x6f02, 0x4214, \
{ 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \
}
#define GRUB_EFI_HOB_LIST_GUID \
{ 0x7739f24c, 0x93d7, 0x11d4, \
{ 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID \
{ 0x4c19049f, 0x4137, 0x4dd3, \
{ 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } \
}
#define GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID \
{ 0x49152e77, 0x1ada, 0x4764, \
{ 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \
}
#define GRUB_EFI_MPS_TABLE_GUID \
{ 0xeb9d2d2f, 0x2d88, 0x11d3, \
{ 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_ACPI_TABLE_GUID \
{ 0xeb9d2d30, 0x2d88, 0x11d3, \
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_ACPI_20_TABLE_GUID \
{ 0x8868e871, 0xe4f1, 0x11d3, \
{ 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
}
#define GRUB_EFI_SMBIOS_TABLE_GUID \
{ 0xeb9d2d31, 0x2d88, 0x11d3, \
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_SAL_TABLE_GUID \
{ 0xeb9d2d32, 0x2d88, 0x11d3, \
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define GRUB_EFI_HCDP_TABLE_GUID \
{ 0xf951938d, 0x620b, 0x42ef, \
{ 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
}
#define GRUB_EFI_DEVICE_TREE_GUID \
{ 0xb1b621d5, 0xf19c, 0x41a5, \
{ 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
}
#define GRUB_EFI_VENDOR_APPLE_GUID \
{ 0x2B0585EB, 0xD8B8, 0x49A9, \
{ 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
}
struct
grub_efi_sal_system_table
{
grub_uint32_t
signature
;
grub_uint32_t
total_table_len
;
grub_uint16_t
sal_rev
;
grub_uint16_t
entry_count
;
grub_uint8_t
checksum
;
grub_uint8_t
reserved1
[
7
];
grub_uint16_t
sal_a_version
;
grub_uint16_t
sal_b_version
;
grub_uint8_t
oem_id
[
32
];
grub_uint8_t
product_id
[
32
];
grub_uint8_t
reserved2
[
8
];
grub_uint8_t
entries
[
0
];
};
enum
{
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR
=
0
,
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR
=
1
,
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES
=
2
,
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR
=
3
,
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE
=
4
,
GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP
=
5
};
struct
grub_efi_sal_system_table_entrypoint_descriptor
{
grub_uint8_t
type
;
grub_uint8_t
pad
[
7
];
grub_uint64_t
pal_proc_addr
;
grub_uint64_t
sal_proc_addr
;
grub_uint64_t
global_data_ptr
;
grub_uint64_t
reserved
[
2
];
};
struct
grub_efi_sal_system_table_memory_descriptor
{
grub_uint8_t
type
;
grub_uint8_t
sal_used
;
grub_uint8_t
attr
;
grub_uint8_t
ar
;
grub_uint8_t
attr_mask
;
grub_uint8_t
mem_type
;
grub_uint8_t
usage
;
grub_uint8_t
unknown
;
grub_uint64_t
addr
;
grub_uint64_t
len
;
grub_uint64_t
unknown2
;
};
struct
grub_efi_sal_system_table_platform_features
{
grub_uint8_t
type
;
grub_uint8_t
flags
;
grub_uint8_t
reserved
[
14
];
};
struct
grub_efi_sal_system_table_translation_register_descriptor
{
grub_uint8_t
type
;
grub_uint8_t
register_type
;
grub_uint8_t
register_number
;
grub_uint8_t
reserved
[
5
];
grub_uint64_t
addr
;
grub_uint64_t
page_size
;
grub_uint64_t
reserver
;
};
struct
grub_efi_sal_system_table_purge_translation_coherence
{
grub_uint8_t
type
;
grub_uint8_t
reserved
[
3
];
grub_uint32_t
ndomains
;
grub_uint64_t
coherence
;
};
struct
grub_efi_sal_system_table_ap_wakeup
{
grub_uint8_t
type
;
grub_uint8_t
mechanism
;
grub_uint8_t
reserved
[
6
];
grub_uint64_t
vector
;
};
enum
{
GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK
=
1
,
GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT
=
2
,
GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT
=
4
,
GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT
=
8
,
};
typedef
enum
grub_efi_parity_type
{
GRUB_EFI_SERIAL_DEFAULT_PARITY
,
GRUB_EFI_SERIAL_NO_PARITY
,
GRUB_EFI_SERIAL_EVEN_PARITY
,
GRUB_EFI_SERIAL_ODD_PARITY
}
grub_efi_parity_type_t
;
typedef
enum
grub_efi_stop_bits
{
GRUB_EFI_SERIAL_DEFAULT_STOP_BITS
,
GRUB_EFI_SERIAL_1_STOP_BIT
,
GRUB_EFI_SERIAL_1_5_STOP_BITS
,
GRUB_EFI_SERIAL_2_STOP_BITS
}
grub_efi_stop_bits_t
;
/* Enumerations. */
enum
grub_efi_timer_delay
{
GRUB_EFI_TIMER_CANCEL
,
GRUB_EFI_TIMER_PERIODIC
,
GRUB_EFI_TIMER_RELATIVE
};
typedef
enum
grub_efi_timer_delay
grub_efi_timer_delay_t
;
enum
grub_efi_allocate_type
{
GRUB_EFI_ALLOCATE_ANY_PAGES
,
GRUB_EFI_ALLOCATE_MAX_ADDRESS
,
GRUB_EFI_ALLOCATE_ADDRESS
,
GRUB_EFI_MAX_ALLOCATION_TYPE
};
typedef
enum
grub_efi_allocate_type
grub_efi_allocate_type_t
;
enum
grub_efi_memory_type
{
GRUB_EFI_RESERVED_MEMORY_TYPE
,
GRUB_EFI_LOADER_CODE
,
GRUB_EFI_LOADER_DATA
,
GRUB_EFI_BOOT_SERVICES_CODE
,
GRUB_EFI_BOOT_SERVICES_DATA
,
GRUB_EFI_RUNTIME_SERVICES_CODE
,
GRUB_EFI_RUNTIME_SERVICES_DATA
,
GRUB_EFI_CONVENTIONAL_MEMORY
,
GRUB_EFI_UNUSABLE_MEMORY
,
GRUB_EFI_ACPI_RECLAIM_MEMORY
,
GRUB_EFI_ACPI_MEMORY_NVS
,
GRUB_EFI_MEMORY_MAPPED_IO
,
GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE
,
GRUB_EFI_PAL_CODE
,
GRUB_EFI_PERSISTENT_MEMORY
,
GRUB_EFI_MAX_MEMORY_TYPE
};
typedef
enum
grub_efi_memory_type
grub_efi_memory_type_t
;
enum
grub_efi_interface_type
{
GRUB_EFI_NATIVE_INTERFACE
};
typedef
enum
grub_efi_interface_type
grub_efi_interface_type_t
;
enum
grub_efi_locate_search_type
{
GRUB_EFI_ALL_HANDLES
,
GRUB_EFI_BY_REGISTER_NOTIFY
,
GRUB_EFI_BY_PROTOCOL
};
typedef
enum
grub_efi_locate_search_type
grub_efi_locate_search_type_t
;
enum
grub_efi_reset_type
{
GRUB_EFI_RESET_COLD
,
GRUB_EFI_RESET_WARM
,
GRUB_EFI_RESET_SHUTDOWN
};
typedef
enum
grub_efi_reset_type
grub_efi_reset_type_t
;
/* Types. */
typedef
char
grub_efi_boolean_t
;
#if GRUB_CPU_SIZEOF_VOID_P == 8
typedef
grub_int64_t
grub_efi_intn_t
;
typedef
grub_uint64_t
grub_efi_uintn_t
;
#else
typedef
grub_int32_t
grub_efi_intn_t
;
typedef
grub_uint32_t
grub_efi_uintn_t
;
#endif
typedef
grub_int8_t
grub_efi_int8_t
;
typedef
grub_uint8_t
grub_efi_uint8_t
;
typedef
grub_int16_t
grub_efi_int16_t
;
typedef
grub_uint16_t
grub_efi_uint16_t
;
typedef
grub_int32_t
grub_efi_int32_t
;
typedef
grub_uint32_t
grub_efi_uint32_t
;
typedef
grub_int64_t
grub_efi_int64_t
;
typedef
grub_uint64_t
grub_efi_uint64_t
;
typedef
grub_uint8_t
grub_efi_char8_t
;
typedef
grub_uint16_t
grub_efi_char16_t
;
typedef
grub_efi_intn_t
grub_efi_status_t
;
#define GRUB_EFI_ERROR_CODE(value) \
((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value))
#define GRUB_EFI_WARNING_CODE(value) (value)
#define GRUB_EFI_SUCCESS 0
#define GRUB_EFI_LOAD_ERROR GRUB_EFI_ERROR_CODE (1)
#define GRUB_EFI_INVALID_PARAMETER GRUB_EFI_ERROR_CODE (2)
#define GRUB_EFI_UNSUPPORTED GRUB_EFI_ERROR_CODE (3)
#define GRUB_EFI_BAD_BUFFER_SIZE GRUB_EFI_ERROR_CODE (4)
#define GRUB_EFI_BUFFER_TOO_SMALL GRUB_EFI_ERROR_CODE (5)
#define GRUB_EFI_NOT_READY GRUB_EFI_ERROR_CODE (6)
#define GRUB_EFI_DEVICE_ERROR GRUB_EFI_ERROR_CODE (7)
#define GRUB_EFI_WRITE_PROTECTED GRUB_EFI_ERROR_CODE (8)
#define GRUB_EFI_OUT_OF_RESOURCES GRUB_EFI_ERROR_CODE (9)
#define GRUB_EFI_VOLUME_CORRUPTED GRUB_EFI_ERROR_CODE (10)
#define GRUB_EFI_VOLUME_FULL GRUB_EFI_ERROR_CODE (11)
#define GRUB_EFI_NO_MEDIA GRUB_EFI_ERROR_CODE (12)
#define GRUB_EFI_MEDIA_CHANGED GRUB_EFI_ERROR_CODE (13)
#define GRUB_EFI_NOT_FOUND GRUB_EFI_ERROR_CODE (14)
#define GRUB_EFI_ACCESS_DENIED GRUB_EFI_ERROR_CODE (15)
#define GRUB_EFI_NO_RESPONSE GRUB_EFI_ERROR_CODE (16)
#define GRUB_EFI_NO_MAPPING GRUB_EFI_ERROR_CODE (17)
#define GRUB_EFI_TIMEOUT GRUB_EFI_ERROR_CODE (18)
#define GRUB_EFI_NOT_STARTED GRUB_EFI_ERROR_CODE (19)
#define GRUB_EFI_ALREADY_STARTED GRUB_EFI_ERROR_CODE (20)
#define GRUB_EFI_ABORTED GRUB_EFI_ERROR_CODE (21)
#define GRUB_EFI_ICMP_ERROR GRUB_EFI_ERROR_CODE (22)
#define GRUB_EFI_TFTP_ERROR GRUB_EFI_ERROR_CODE (23)
#define GRUB_EFI_PROTOCOL_ERROR GRUB_EFI_ERROR_CODE (24)
#define GRUB_EFI_INCOMPATIBLE_VERSION GRUB_EFI_ERROR_CODE (25)
#define GRUB_EFI_SECURITY_VIOLATION GRUB_EFI_ERROR_CODE (26)
#define GRUB_EFI_CRC_ERROR GRUB_EFI_ERROR_CODE (27)
#define GRUB_EFI_WARN_UNKNOWN_GLYPH GRUB_EFI_WARNING_CODE (1)
#define GRUB_EFI_WARN_DELETE_FAILURE GRUB_EFI_WARNING_CODE (2)
#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3)
#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4)
typedef
void
*
grub_efi_handle_t
;
typedef
void
*
grub_efi_event_t
;
typedef
grub_efi_uint64_t
grub_efi_lba_t
;
typedef
grub_efi_uintn_t
grub_efi_tpl_t
;
typedef
grub_uint8_t
grub_efi_mac_address_t
[
32
];
typedef
grub_uint8_t
grub_efi_ipv4_address_t
[
4
];
typedef
grub_uint16_t
grub_efi_ipv6_address_t
[
8
];
typedef
grub_uint8_t
grub_efi_ip_address_t
[
8
]
__attribute__
((
aligned
(
4
)));
typedef
grub_efi_uint64_t
grub_efi_physical_address_t
;
typedef
grub_efi_uint64_t
grub_efi_virtual_address_t
;
struct
grub_efi_guid
{
grub_uint32_t
data1
;
grub_uint16_t
data2
;
grub_uint16_t
data3
;
grub_uint8_t
data4
[
8
];
}
__attribute__
((
aligned
(
8
)));
typedef
struct
grub_efi_guid
grub_efi_guid_t
;
struct
grub_efi_packed_guid
{
grub_uint32_t
data1
;
grub_uint16_t
data2
;
grub_uint16_t
data3
;
grub_uint8_t
data4
[
8
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_packed_guid
grub_efi_packed_guid_t
;
/* XXX although the spec does not specify the padding, this actually
must have the padding! */
struct
grub_efi_memory_descriptor
{
grub_efi_uint32_t
type
;
grub_efi_uint32_t
padding
;
grub_efi_physical_address_t
physical_start
;
grub_efi_virtual_address_t
virtual_start
;
grub_efi_uint64_t
num_pages
;
grub_efi_uint64_t
attribute
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_memory_descriptor
grub_efi_memory_descriptor_t
;
/* Device Path definitions. */
struct
grub_efi_device_path
{
grub_efi_uint8_t
type
;
grub_efi_uint8_t
subtype
;
grub_efi_uint16_t
length
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_device_path
grub_efi_device_path_t
;
/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it.
It seems to be identical to EFI_DEVICE_PATH. */
typedef
struct
grub_efi_device_path
grub_efi_device_path_protocol_t
;
#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
/* The End of Device Path nodes. */
#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
(GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
== GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
((grub_efi_device_path_t *) ((char *) (dp) \
+ GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
/* Hardware Device Path. */
#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1
struct
grub_efi_pci_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint8_t
function
;
grub_efi_uint8_t
device
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_pci_device_path
grub_efi_pci_device_path_t
;
#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2
struct
grub_efi_pccard_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint8_t
function
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_pccard_device_path
grub_efi_pccard_device_path_t
;
#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3
struct
grub_efi_memory_mapped_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
memory_type
;
grub_efi_physical_address_t
start_address
;
grub_efi_physical_address_t
end_address
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_memory_mapped_device_path
grub_efi_memory_mapped_device_path_t
;
#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4
struct
grub_efi_vendor_device_path
{
grub_efi_device_path_t
header
;
grub_efi_packed_guid_t
vendor_guid
;
grub_efi_uint8_t
vendor_defined_data
[
0
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_vendor_device_path
grub_efi_vendor_device_path_t
;
#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5
struct
grub_efi_controller_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
controller_number
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_controller_device_path
grub_efi_controller_device_path_t
;
/* ACPI Device Path. */
#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2
#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1
struct
grub_efi_acpi_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
hid
;
grub_efi_uint32_t
uid
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_acpi_device_path
grub_efi_acpi_device_path_t
;
#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2
struct
grub_efi_expanded_acpi_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
hid
;
grub_efi_uint32_t
uid
;
grub_efi_uint32_t
cid
;
char
hidstr
[
0
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_expanded_acpi_device_path
grub_efi_expanded_acpi_device_path_t
;
#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
(((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
(GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+ grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \
(GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+ grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
/* Messaging Device Path. */
#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3
#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1
struct
grub_efi_atapi_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint8_t
primary_secondary
;
grub_efi_uint8_t
slave_master
;
grub_efi_uint16_t
lun
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_atapi_device_path
grub_efi_atapi_device_path_t
;
#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2
struct
grub_efi_scsi_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint16_t
pun
;
grub_efi_uint16_t
lun
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_scsi_device_path
grub_efi_scsi_device_path_t
;
#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3
struct
grub_efi_fibre_channel_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
reserved
;
grub_efi_uint64_t
wwn
;
grub_efi_uint64_t
lun
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_fibre_channel_device_path
grub_efi_fibre_channel_device_path_t
;
#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4
struct
grub_efi_1394_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
reserved
;
grub_efi_uint64_t
guid
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_1394_device_path
grub_efi_1394_device_path_t
;
#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5
struct
grub_efi_usb_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint8_t
parent_port_number
;
grub_efi_uint8_t
usb_interface
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_usb_device_path
grub_efi_usb_device_path_t
;
#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15
struct
grub_efi_usb_class_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint16_t
vendor_id
;
grub_efi_uint16_t
product_id
;
grub_efi_uint8_t
device_class
;
grub_efi_uint8_t
device_subclass
;
grub_efi_uint8_t
device_protocol
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_usb_class_device_path
grub_efi_usb_class_device_path_t
;
#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6
struct
grub_efi_i2o_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
tid
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_i2o_device_path
grub_efi_i2o_device_path_t
;
#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11
struct
grub_efi_mac_address_device_path
{
grub_efi_device_path_t
header
;
grub_efi_mac_address_t
mac_address
;
grub_efi_uint8_t
if_type
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_mac_address_device_path
grub_efi_mac_address_device_path_t
;
#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12
struct
grub_efi_ipv4_device_path
{
grub_efi_device_path_t
header
;
grub_efi_ipv4_address_t
local_ip_address
;
grub_efi_ipv4_address_t
remote_ip_address
;
grub_efi_uint16_t
local_port
;
grub_efi_uint16_t
remote_port
;
grub_efi_uint16_t
protocol
;
grub_efi_uint8_t
static_ip_address
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_ipv4_device_path
grub_efi_ipv4_device_path_t
;
#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13
struct
grub_efi_ipv6_device_path
{
grub_efi_device_path_t
header
;
grub_efi_ipv6_address_t
local_ip_address
;
grub_efi_ipv6_address_t
remote_ip_address
;
grub_efi_uint16_t
local_port
;
grub_efi_uint16_t
remote_port
;
grub_efi_uint16_t
protocol
;
grub_efi_uint8_t
static_ip_address
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_ipv6_device_path
grub_efi_ipv6_device_path_t
;
#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9
struct
grub_efi_infiniband_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
resource_flags
;
grub_efi_uint8_t
port_gid
[
16
];
grub_efi_uint64_t
remote_id
;
grub_efi_uint64_t
target_port_id
;
grub_efi_uint64_t
device_id
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_infiniband_device_path
grub_efi_infiniband_device_path_t
;
#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14
struct
grub_efi_uart_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
reserved
;
grub_efi_uint64_t
baud_rate
;
grub_efi_uint8_t
data_bits
;
grub_efi_uint8_t
parity
;
grub_efi_uint8_t
stop_bits
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_uart_device_path
grub_efi_uart_device_path_t
;
#define GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE 18
struct
grub_efi_sata_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint16_t
hba_port
;
grub_efi_uint16_t
multiplier_port
;
grub_efi_uint16_t
lun
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_sata_device_path
grub_efi_sata_device_path_t
;
#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
/* Media Device Path. */
#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4
#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1
struct
grub_efi_hard_drive_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
partition_number
;
grub_efi_lba_t
partition_start
;
grub_efi_lba_t
partition_size
;
grub_efi_uint8_t
partition_signature
[
16
];
grub_efi_uint8_t
partmap_type
;
grub_efi_uint8_t
signature_type
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_hard_drive_device_path
grub_efi_hard_drive_device_path_t
;
#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2
struct
grub_efi_cdrom_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint32_t
boot_entry
;
grub_efi_lba_t
partition_start
;
grub_efi_lba_t
partition_size
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_cdrom_device_path
grub_efi_cdrom_device_path_t
;
#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3
struct
grub_efi_vendor_media_device_path
{
grub_efi_device_path_t
header
;
grub_efi_packed_guid_t
vendor_guid
;
grub_efi_uint8_t
vendor_defined_data
[
0
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_vendor_media_device_path
grub_efi_vendor_media_device_path_t
;
#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4
struct
grub_efi_file_path_device_path
{
grub_efi_device_path_t
header
;
grub_efi_char16_t
path_name
[
0
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_file_path_device_path
grub_efi_file_path_device_path_t
;
#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5
struct
grub_efi_protocol_device_path
{
grub_efi_device_path_t
header
;
grub_efi_packed_guid_t
guid
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_protocol_device_path
grub_efi_protocol_device_path_t
;
#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE 6
struct
grub_efi_piwg_device_path
{
grub_efi_device_path_t
header
;
grub_efi_packed_guid_t
guid
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_piwg_device_path
grub_efi_piwg_device_path_t
;
/* BIOS Boot Specification Device Path. */
#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5
#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1
struct
grub_efi_bios_device_path
{
grub_efi_device_path_t
header
;
grub_efi_uint16_t
device_type
;
grub_efi_uint16_t
status_flags
;
char
description
[
0
];
}
GRUB_PACKED
;
typedef
struct
grub_efi_bios_device_path
grub_efi_bios_device_path_t
;
struct
grub_efi_open_protocol_information_entry
{
grub_efi_handle_t
agent_handle
;
grub_efi_handle_t
controller_handle
;
grub_efi_uint32_t
attributes
;
grub_efi_uint32_t
open_count
;
};
typedef
struct
grub_efi_open_protocol_information_entry
grub_efi_open_protocol_information_entry_t
;
struct
grub_efi_time
{
grub_efi_uint16_t
year
;
grub_efi_uint8_t
month
;
grub_efi_uint8_t
day
;
grub_efi_uint8_t
hour
;
grub_efi_uint8_t
minute
;
grub_efi_uint8_t
second
;
grub_efi_uint8_t
pad1
;
grub_efi_uint32_t
nanosecond
;
grub_efi_int16_t
time_zone
;
grub_efi_uint8_t
daylight
;
grub_efi_uint8_t
pad2
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_time
grub_efi_time_t
;
struct
grub_efi_time_capabilities
{
grub_efi_uint32_t
resolution
;
grub_efi_uint32_t
accuracy
;
grub_efi_boolean_t
sets_to_zero
;
};
typedef
struct
grub_efi_time_capabilities
grub_efi_time_capabilities_t
;
struct
grub_efi_input_key
{
grub_efi_uint16_t
scan_code
;
grub_efi_char16_t
unicode_char
;
};
typedef
struct
grub_efi_input_key
grub_efi_input_key_t
;
typedef
grub_efi_uint8_t
grub_efi_key_toggle_state_t
;
struct
grub_efi_key_state
{
grub_efi_uint32_t
key_shift_state
;
grub_efi_key_toggle_state_t
key_toggle_state
;
};
typedef
struct
grub_efi_key_state
grub_efi_key_state_t
;
#define GRUB_EFI_SHIFT_STATE_VALID 0x80000000
#define GRUB_EFI_RIGHT_SHIFT_PRESSED 0x00000001
#define GRUB_EFI_LEFT_SHIFT_PRESSED 0x00000002
#define GRUB_EFI_RIGHT_CONTROL_PRESSED 0x00000004
#define GRUB_EFI_LEFT_CONTROL_PRESSED 0x00000008
#define GRUB_EFI_RIGHT_ALT_PRESSED 0x00000010
#define GRUB_EFI_LEFT_ALT_PRESSED 0x00000020
#define GRUB_EFI_RIGHT_LOGO_PRESSED 0x00000040
#define GRUB_EFI_LEFT_LOGO_PRESSED 0x00000080
#define GRUB_EFI_MENU_KEY_PRESSED 0x00000100
#define GRUB_EFI_SYS_REQ_PRESSED 0x00000200
#define GRUB_EFI_TOGGLE_STATE_VALID 0x80
#define GRUB_EFI_KEY_STATE_EXPOSED 0x40
#define GRUB_EFI_SCROLL_LOCK_ACTIVE 0x01
#define GRUB_EFI_NUM_LOCK_ACTIVE 0x02
#define GRUB_EFI_CAPS_LOCK_ACTIVE 0x04
struct
grub_efi_simple_text_output_mode
{
grub_efi_int32_t
max_mode
;
grub_efi_int32_t
mode
;
grub_efi_int32_t
attribute
;
grub_efi_int32_t
cursor_column
;
grub_efi_int32_t
cursor_row
;
grub_efi_boolean_t
cursor_visible
;
};
typedef
struct
grub_efi_simple_text_output_mode
grub_efi_simple_text_output_mode_t
;
/* Tables. */
struct
grub_efi_table_header
{
grub_efi_uint64_t
signature
;
grub_efi_uint32_t
revision
;
grub_efi_uint32_t
header_size
;
grub_efi_uint32_t
crc32
;
grub_efi_uint32_t
reserved
;
};
typedef
struct
grub_efi_table_header
grub_efi_table_header_t
;
struct
grub_efi_boot_services
{
grub_efi_table_header_t
hdr
;
grub_efi_tpl_t
(
*
raise_tpl
)
(
grub_efi_tpl_t
new_tpl
);
void
(
*
restore_tpl
)
(
grub_efi_tpl_t
old_tpl
);
grub_efi_status_t
(
*
allocate_pages
)
(
grub_efi_allocate_type_t
type
,
grub_efi_memory_type_t
memory_type
,
grub_efi_uintn_t
pages
,
grub_efi_physical_address_t
*
memory
);
grub_efi_status_t
(
*
free_pages
)
(
grub_efi_physical_address_t
memory
,
grub_efi_uintn_t
pages
);
grub_efi_status_t
(
*
get_memory_map
)
(
grub_efi_uintn_t
*
memory_map_size
,
grub_efi_memory_descriptor_t
*
memory_map
,
grub_efi_uintn_t
*
map_key
,
grub_efi_uintn_t
*
descriptor_size
,
grub_efi_uint32_t
*
descriptor_version
);
grub_efi_status_t
(
*
allocate_pool
)
(
grub_efi_memory_type_t
pool_type
,
grub_efi_uintn_t
size
,
void
**
buffer
);
grub_efi_status_t
(
*
free_pool
)
(
void
*
buffer
);
grub_efi_status_t
(
*
create_event
)
(
grub_efi_uint32_t
type
,
grub_efi_tpl_t
notify_tpl
,
void
(
*
notify_function
)
(
grub_efi_event_t
event
,
void
*
context
),
void
*
notify_context
,
grub_efi_event_t
*
event
);
grub_efi_status_t
(
*
set_timer
)
(
grub_efi_event_t
event
,
grub_efi_timer_delay_t
type
,
grub_efi_uint64_t
trigger_time
);
grub_efi_status_t
(
*
wait_for_event
)
(
grub_efi_uintn_t
num_events
,
grub_efi_event_t
*
event
,
grub_efi_uintn_t
*
index
);
grub_efi_status_t
(
*
signal_event
)
(
grub_efi_event_t
event
);
grub_efi_status_t
(
*
close_event
)
(
grub_efi_event_t
event
);
grub_efi_status_t
(
*
check_event
)
(
grub_efi_event_t
event
);
grub_efi_status_t
(
*
install_protocol_interface
)
(
grub_efi_handle_t
*
handle
,
grub_efi_guid_t
*
protocol
,
grub_efi_interface_type_t
protocol_interface_type
,
void
*
protocol_interface
);
grub_efi_status_t
(
*
reinstall_protocol_interface
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
void
*
old_interface
,
void
*
new_interface
);
grub_efi_status_t
(
*
uninstall_protocol_interface
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
void
*
protocol_interface
);
grub_efi_status_t
(
*
handle_protocol
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
void
**
protocol_interface
);
void
*
reserved
;
grub_efi_status_t
(
*
register_protocol_notify
)
(
grub_efi_guid_t
*
protocol
,
grub_efi_event_t
event
,
void
**
registration
);
grub_efi_status_t
(
*
locate_handle
)
(
grub_efi_locate_search_type_t
search_type
,
grub_efi_guid_t
*
protocol
,
void
*
search_key
,
grub_efi_uintn_t
*
buffer_size
,
grub_efi_handle_t
*
buffer
);
grub_efi_status_t
(
*
locate_device_path
)
(
grub_efi_guid_t
*
protocol
,
grub_efi_device_path_t
**
device_path
,
grub_efi_handle_t
*
device
);
grub_efi_status_t
(
*
install_configuration_table
)
(
grub_efi_guid_t
*
guid
,
void
*
table
);
grub_efi_status_t
(
*
load_image
)
(
grub_efi_boolean_t
boot_policy
,
grub_efi_handle_t
parent_image_handle
,
grub_efi_device_path_t
*
file_path
,
void
*
source_buffer
,
grub_efi_uintn_t
source_size
,
grub_efi_handle_t
*
image_handle
);
grub_efi_status_t
(
*
start_image
)
(
grub_efi_handle_t
image_handle
,
grub_efi_uintn_t
*
exit_data_size
,
grub_efi_char16_t
**
exit_data
);
grub_efi_status_t
(
*
exit
)
(
grub_efi_handle_t
image_handle
,
grub_efi_status_t
exit_status
,
grub_efi_uintn_t
exit_data_size
,
grub_efi_char16_t
*
exit_data
)
__attribute__
((
noreturn
));
grub_efi_status_t
(
*
unload_image
)
(
grub_efi_handle_t
image_handle
);
grub_efi_status_t
(
*
exit_boot_services
)
(
grub_efi_handle_t
image_handle
,
grub_efi_uintn_t
map_key
);
grub_efi_status_t
(
*
get_next_monotonic_count
)
(
grub_efi_uint64_t
*
count
);
grub_efi_status_t
(
*
stall
)
(
grub_efi_uintn_t
microseconds
);
grub_efi_status_t
(
*
set_watchdog_timer
)
(
grub_efi_uintn_t
timeout
,
grub_efi_uint64_t
watchdog_code
,
grub_efi_uintn_t
data_size
,
grub_efi_char16_t
*
watchdog_data
);
grub_efi_status_t
(
*
connect_controller
)
(
grub_efi_handle_t
controller_handle
,
grub_efi_handle_t
*
driver_image_handle
,
grub_efi_device_path_protocol_t
*
remaining_device_path
,
grub_efi_boolean_t
recursive
);
grub_efi_status_t
(
*
disconnect_controller
)
(
grub_efi_handle_t
controller_handle
,
grub_efi_handle_t
driver_image_handle
,
grub_efi_handle_t
child_handle
);
grub_efi_status_t
(
*
open_protocol
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
void
**
protocol_interface
,
grub_efi_handle_t
agent_handle
,
grub_efi_handle_t
controller_handle
,
grub_efi_uint32_t
attributes
);
grub_efi_status_t
(
*
close_protocol
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
grub_efi_handle_t
agent_handle
,
grub_efi_handle_t
controller_handle
);
grub_efi_status_t
(
*
open_protocol_information
)
(
grub_efi_handle_t
handle
,
grub_efi_guid_t
*
protocol
,
grub_efi_open_protocol_information_entry_t
**
entry_buffer
,
grub_efi_uintn_t
*
entry_count
);
grub_efi_status_t
(
*
protocols_per_handle
)
(
grub_efi_handle_t
handle
,
grub_efi_packed_guid_t
***
protocol_buffer
,
grub_efi_uintn_t
*
protocol_buffer_count
);
grub_efi_status_t
(
*
locate_handle_buffer
)
(
grub_efi_locate_search_type_t
search_type
,
grub_efi_guid_t
*
protocol
,
void
*
search_key
,
grub_efi_uintn_t
*
no_handles
,
grub_efi_handle_t
**
buffer
);
grub_efi_status_t
(
*
locate_protocol
)
(
grub_efi_guid_t
*
protocol
,
void
*
registration
,
void
**
protocol_interface
);
grub_efi_status_t
(
*
install_multiple_protocol_interfaces
)
(
grub_efi_handle_t
*
handle
,
...);
grub_efi_status_t
(
*
uninstall_multiple_protocol_interfaces
)
(
grub_efi_handle_t
handle
,
...);
grub_efi_status_t
(
*
calculate_crc32
)
(
void
*
data
,
grub_efi_uintn_t
data_size
,
grub_efi_uint32_t
*
crc32
);
void
(
*
copy_mem
)
(
void
*
destination
,
void
*
source
,
grub_efi_uintn_t
length
);
void
(
*
set_mem
)
(
void
*
buffer
,
grub_efi_uintn_t
size
,
grub_efi_uint8_t
value
);
};
typedef
struct
grub_efi_boot_services
grub_efi_boot_services_t
;
struct
grub_efi_runtime_services
{
grub_efi_table_header_t
hdr
;
grub_efi_status_t
(
*
get_time
)
(
grub_efi_time_t
*
time
,
grub_efi_time_capabilities_t
*
capabilities
);
grub_efi_status_t
(
*
set_time
)
(
grub_efi_time_t
*
time
);
grub_efi_status_t
(
*
get_wakeup_time
)
(
grub_efi_boolean_t
*
enabled
,
grub_efi_boolean_t
*
pending
,
grub_efi_time_t
*
time
);
grub_efi_status_t
(
*
set_wakeup_time
)
(
grub_efi_boolean_t
enabled
,
grub_efi_time_t
*
time
);
grub_efi_status_t
(
*
set_virtual_address_map
)
(
grub_efi_uintn_t
memory_map_size
,
grub_efi_uintn_t
descriptor_size
,
grub_efi_uint32_t
descriptor_version
,
grub_efi_memory_descriptor_t
*
virtual_map
);
grub_efi_status_t
(
*
convert_pointer
)
(
grub_efi_uintn_t
debug_disposition
,
void
**
address
);
#define GRUB_EFI_GLOBAL_VARIABLE_GUID \
{ 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B,0x8C }}
grub_efi_status_t
(
*
get_variable
)
(
grub_efi_char16_t
*
variable_name
,
const
grub_efi_guid_t
*
vendor_guid
,
grub_efi_uint32_t
*
attributes
,
grub_efi_uintn_t
*
data_size
,
void
*
data
);
grub_efi_status_t
(
*
get_next_variable_name
)
(
grub_efi_uintn_t
*
variable_name_size
,
grub_efi_char16_t
*
variable_name
,
grub_efi_guid_t
*
vendor_guid
);
grub_efi_status_t
(
*
set_variable
)
(
grub_efi_char16_t
*
variable_name
,
const
grub_efi_guid_t
*
vendor_guid
,
grub_efi_uint32_t
attributes
,
grub_efi_uintn_t
data_size
,
void
*
data
);
grub_efi_status_t
(
*
get_next_high_monotonic_count
)
(
grub_efi_uint32_t
*
high_count
);
void
(
*
reset_system
)
(
grub_efi_reset_type_t
reset_type
,
grub_efi_status_t
reset_status
,
grub_efi_uintn_t
data_size
,
grub_efi_char16_t
*
reset_data
);
};
typedef
struct
grub_efi_runtime_services
grub_efi_runtime_services_t
;
struct
grub_efi_configuration_table
{
grub_efi_packed_guid_t
vendor_guid
;
void
*
vendor_table
;
}
GRUB_PACKED
;
typedef
struct
grub_efi_configuration_table
grub_efi_configuration_table_t
;
#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
struct
grub_efi_serial_io_interface
{
grub_efi_uint32_t
revision
;
void
(
*
reset
)
(
void
);
grub_efi_status_t
(
*
set_attributes
)
(
struct
grub_efi_serial_io_interface
*
this
,
grub_efi_uint64_t
speed
,
grub_efi_uint32_t
fifo_depth
,
grub_efi_uint32_t
timeout
,
grub_efi_parity_type_t
parity
,
grub_uint8_t
word_len
,
grub_efi_stop_bits_t
stop_bits
);
grub_efi_status_t
(
*
set_control_bits
)
(
struct
grub_efi_serial_io_interface
*
this
,
grub_efi_uint32_t
flags
);
void
(
*
get_control_bits
)
(
void
);
grub_efi_status_t
(
*
write
)
(
struct
grub_efi_serial_io_interface
*
this
,
grub_efi_uintn_t
*
buf_size
,
void
*
buffer
);
grub_efi_status_t
(
*
read
)
(
struct
grub_efi_serial_io_interface
*
this
,
grub_efi_uintn_t
*
buf_size
,
void
*
buffer
);
};
struct
grub_efi_simple_input_interface
{
grub_efi_status_t
(
*
reset
)
(
struct
grub_efi_simple_input_interface
*
this
,
grub_efi_boolean_t
extended_verification
);
grub_efi_status_t
(
*
read_key_stroke
)
(
struct
grub_efi_simple_input_interface
*
this
,
grub_efi_input_key_t
*
key
);
grub_efi_event_t
wait_for_key
;
};
typedef
struct
grub_efi_simple_input_interface
grub_efi_simple_input_interface_t
;
struct
grub_efi_key_data
{
grub_efi_input_key_t
key
;
grub_efi_key_state_t
key_state
;
};
typedef
struct
grub_efi_key_data
grub_efi_key_data_t
;
typedef
grub_efi_status_t
(
*
grub_efi_key_notify_function_t
)
(
grub_efi_key_data_t
*
key_data
);
struct
grub_efi_simple_text_input_ex_interface
{
grub_efi_status_t
(
*
reset
)
(
struct
grub_efi_simple_text_input_ex_interface
*
this
,
grub_efi_boolean_t
extended_verification
);
grub_efi_status_t
(
*
read_key_stroke
)
(
struct
grub_efi_simple_text_input_ex_interface
*
this
,
grub_efi_key_data_t
*
key_data
);
grub_efi_event_t
wait_for_key
;
grub_efi_status_t
(
*
set_state
)
(
struct
grub_efi_simple_text_input_ex_interface
*
this
,
grub_efi_key_toggle_state_t
*
key_toggle_state
);
grub_efi_status_t
(
*
register_key_notify
)
(
struct
grub_efi_simple_text_input_ex_interface
*
this
,
grub_efi_key_data_t
*
key_data
,
grub_efi_key_notify_function_t
key_notification_function
);
grub_efi_status_t
(
*
unregister_key_notify
)
(
struct
grub_efi_simple_text_input_ex_interface
*
this
,
void
*
notification_handle
);
};
typedef
struct
grub_efi_simple_text_input_ex_interface
grub_efi_simple_text_input_ex_interface_t
;
struct
grub_efi_simple_text_output_interface
{
grub_efi_status_t
(
*
reset
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_boolean_t
extended_verification
);
grub_efi_status_t
(
*
output_string
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_char16_t
*
string
);
grub_efi_status_t
(
*
test_string
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_char16_t
*
string
);
grub_efi_status_t
(
*
query_mode
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_uintn_t
mode_number
,
grub_efi_uintn_t
*
columns
,
grub_efi_uintn_t
*
rows
);
grub_efi_status_t
(
*
set_mode
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_uintn_t
mode_number
);
grub_efi_status_t
(
*
set_attributes
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_uintn_t
attribute
);
grub_efi_status_t
(
*
clear_screen
)
(
struct
grub_efi_simple_text_output_interface
*
this
);
grub_efi_status_t
(
*
set_cursor_position
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_uintn_t
column
,
grub_efi_uintn_t
row
);
grub_efi_status_t
(
*
enable_cursor
)
(
struct
grub_efi_simple_text_output_interface
*
this
,
grub_efi_boolean_t
visible
);
grub_efi_simple_text_output_mode_t
*
mode
;
};
typedef
struct
grub_efi_simple_text_output_interface
grub_efi_simple_text_output_interface_t
;
typedef
grub_uint8_t
grub_efi_pxe_packet_t
[
1472
];
typedef
struct
grub_efi_pxe_mode
{
grub_uint8_t
unused
[
52
];
grub_efi_pxe_packet_t
dhcp_discover
;
grub_efi_pxe_packet_t
dhcp_ack
;
grub_efi_pxe_packet_t
proxy_offer
;
grub_efi_pxe_packet_t
pxe_discover
;
grub_efi_pxe_packet_t
pxe_reply
;
}
grub_efi_pxe_mode_t
;
typedef
struct
grub_efi_pxe
{
grub_uint64_t
rev
;
void
(
*
start
)
(
void
);
void
(
*
stop
)
(
void
);
void
(
*
dhcp
)
(
void
);
void
(
*
discover
)
(
void
);
void
(
*
mftp
)
(
void
);
void
(
*
udpwrite
)
(
void
);
void
(
*
udpread
)
(
void
);
void
(
*
setipfilter
)
(
void
);
void
(
*
arp
)
(
void
);
void
(
*
setparams
)
(
void
);
void
(
*
setstationip
)
(
void
);
void
(
*
setpackets
)
(
void
);
struct
grub_efi_pxe_mode
*
mode
;
}
grub_efi_pxe_t
;
#define GRUB_EFI_BLACK 0x00
#define GRUB_EFI_BLUE 0x01
#define GRUB_EFI_GREEN 0x02
#define GRUB_EFI_CYAN 0x03
#define GRUB_EFI_RED 0x04
#define GRUB_EFI_MAGENTA 0x05
#define GRUB_EFI_BROWN 0x06
#define GRUB_EFI_LIGHTGRAY 0x07
#define GRUB_EFI_BRIGHT 0x08
#define GRUB_EFI_DARKGRAY 0x08
#define GRUB_EFI_LIGHTBLUE 0x09
#define GRUB_EFI_LIGHTGREEN 0x0A
#define GRUB_EFI_LIGHTCYAN 0x0B
#define GRUB_EFI_LIGHTRED 0x0C
#define GRUB_EFI_LIGHTMAGENTA 0x0D
#define GRUB_EFI_YELLOW 0x0E
#define GRUB_EFI_WHITE 0x0F
#define GRUB_EFI_BACKGROUND_BLACK 0x00
#define GRUB_EFI_BACKGROUND_BLUE 0x10
#define GRUB_EFI_BACKGROUND_GREEN 0x20
#define GRUB_EFI_BACKGROUND_CYAN 0x30
#define GRUB_EFI_BACKGROUND_RED 0x40
#define GRUB_EFI_BACKGROUND_MAGENTA 0x50
#define GRUB_EFI_BACKGROUND_BROWN 0x60
#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70
#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg)))
struct
grub_efi_system_table
{
grub_efi_table_header_t
hdr
;
grub_efi_char16_t
*
firmware_vendor
;
grub_efi_uint32_t
firmware_revision
;
grub_efi_handle_t
console_in_handler
;
grub_efi_simple_input_interface_t
*
con_in
;
grub_efi_handle_t
console_out_handler
;
grub_efi_simple_text_output_interface_t
*
con_out
;
grub_efi_handle_t
standard_error_handle
;
grub_efi_simple_text_output_interface_t
*
std_err
;
grub_efi_runtime_services_t
*
runtime_services
;
grub_efi_boot_services_t
*
boot_services
;
grub_efi_uintn_t
num_table_entries
;
grub_efi_configuration_table_t
*
configuration_table
;
};
typedef
struct
grub_efi_system_table
grub_efi_system_table_t
;
struct
grub_efi_loaded_image
{
grub_efi_uint32_t
revision
;
grub_efi_handle_t
parent_handle
;
grub_efi_system_table_t
*
system_table
;
grub_efi_handle_t
device_handle
;
grub_efi_device_path_t
*
file_path
;
void
*
reserved
;
grub_efi_uint32_t
load_options_size
;
void
*
load_options
;
void
*
image_base
;
grub_efi_uint64_t
image_size
;
grub_efi_memory_type_t
image_code_type
;
grub_efi_memory_type_t
image_data_type
;
grub_efi_status_t
(
*
unload
)
(
grub_efi_handle_t
image_handle
);
};
typedef
struct
grub_efi_loaded_image
grub_efi_loaded_image_t
;
struct
grub_efi_disk_io
{
grub_efi_uint64_t
revision
;
grub_efi_status_t
(
*
read
)
(
struct
grub_efi_disk_io
*
this
,
grub_efi_uint32_t
media_id
,
grub_efi_uint64_t
offset
,
grub_efi_uintn_t
buffer_size
,
void
*
buffer
);
grub_efi_status_t
(
*
write
)
(
struct
grub_efi_disk_io
*
this
,
grub_efi_uint32_t
media_id
,
grub_efi_uint64_t
offset
,
grub_efi_uintn_t
buffer_size
,
void
*
buffer
);
};
typedef
struct
grub_efi_disk_io
grub_efi_disk_io_t
;
struct
grub_efi_block_io_media
{
grub_efi_uint32_t
media_id
;
grub_efi_boolean_t
removable_media
;
grub_efi_boolean_t
media_present
;
grub_efi_boolean_t
logical_partition
;
grub_efi_boolean_t
read_only
;
grub_efi_boolean_t
write_caching
;
grub_efi_uint8_t
pad
[
3
];
grub_efi_uint32_t
block_size
;
grub_efi_uint32_t
io_align
;
grub_efi_uint8_t
pad2
[
4
];
grub_efi_lba_t
last_block
;
};
typedef
struct
grub_efi_block_io_media
grub_efi_block_io_media_t
;
typedef
grub_uint8_t
grub_efi_mac_t
[
32
];
struct
grub_efi_simple_network_mode
{
grub_uint32_t
state
;
grub_uint32_t
hwaddr_size
;
grub_uint32_t
media_header_size
;
grub_uint32_t
max_packet_size
;
grub_uint32_t
nvram_size
;
grub_uint32_t
nvram_access_size
;
grub_uint32_t
receive_filter_mask
;
grub_uint32_t
receive_filter_setting
;
grub_uint32_t
max_mcast_filter_count
;
grub_uint32_t
mcast_filter_count
;
grub_efi_mac_t
mcast_filter
[
16
];
grub_efi_mac_t
current_address
;
grub_efi_mac_t
broadcast_address
;
grub_efi_mac_t
permanent_address
;
grub_uint8_t
if_type
;
grub_uint8_t
mac_changeable
;
grub_uint8_t
multitx_supported
;
grub_uint8_t
media_present_supported
;
grub_uint8_t
media_present
;
};
enum
{
GRUB_EFI_NETWORK_STOPPED
,
GRUB_EFI_NETWORK_STARTED
,
GRUB_EFI_NETWORK_INITIALIZED
,
};
enum
{
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
=
0x01
,
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
=
0x02
,
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
=
0x04
,
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
=
0x08
,
GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
=
0x10
,
};
struct
grub_efi_simple_network
{
grub_uint64_t
revision
;
grub_efi_status_t
(
*
start
)
(
struct
grub_efi_simple_network
*
this
);
grub_efi_status_t
(
*
stop
)
(
struct
grub_efi_simple_network
*
this
);
grub_efi_status_t
(
*
initialize
)
(
struct
grub_efi_simple_network
*
this
,
grub_efi_uintn_t
extra_rx
,
grub_efi_uintn_t
extra_tx
);
void
(
*
reset
)
(
void
);
grub_efi_status_t
(
*
shutdown
)
(
struct
grub_efi_simple_network
*
this
);
grub_efi_status_t
(
*
receive_filters
)
(
struct
grub_efi_simple_network
*
this
,
grub_uint32_t
enable
,
grub_uint32_t
disable
,
grub_efi_boolean_t
reset_mcast_filter
,
grub_efi_uintn_t
mcast_filter_count
,
grub_efi_mac_address_t
*
mcast_filter
);
void
(
*
station_address
)
(
void
);
void
(
*
statistics
)
(
void
);
void
(
*
mcastiptomac
)
(
void
);
void
(
*
nvdata
)
(
void
);
grub_efi_status_t
(
*
get_status
)
(
struct
grub_efi_simple_network
*
this
,
grub_uint32_t
*
int_status
,
void
**
txbuf
);
grub_efi_status_t
(
*
transmit
)
(
struct
grub_efi_simple_network
*
this
,
grub_efi_uintn_t
header_size
,
grub_efi_uintn_t
buffer_size
,
void
*
buffer
,
grub_efi_mac_t
*
src_addr
,
grub_efi_mac_t
*
dest_addr
,
grub_efi_uint16_t
*
protocol
);
grub_efi_status_t
(
*
receive
)
(
struct
grub_efi_simple_network
*
this
,
grub_efi_uintn_t
*
header_size
,
grub_efi_uintn_t
*
buffer_size
,
void
*
buffer
,
grub_efi_mac_t
*
src_addr
,
grub_efi_mac_t
*
dest_addr
,
grub_uint16_t
*
protocol
);
void
(
*
waitforpacket
)
(
void
);
struct
grub_efi_simple_network_mode
*
mode
;
};
typedef
struct
grub_efi_simple_network
grub_efi_simple_network_t
;
struct
grub_efi_block_io
{
grub_efi_uint64_t
revision
;
grub_efi_block_io_media_t
*
media
;
grub_efi_status_t
(
*
reset
)
(
struct
grub_efi_block_io
*
this
,
grub_efi_boolean_t
extended_verification
);
grub_efi_status_t
(
*
read_blocks
)
(
struct
grub_efi_block_io
*
this
,
grub_efi_uint32_t
media_id
,
grub_efi_lba_t
lba
,
grub_efi_uintn_t
buffer_size
,
void
*
buffer
);
grub_efi_status_t
(
*
write_blocks
)
(
struct
grub_efi_block_io
*
this
,
grub_efi_uint32_t
media_id
,
grub_efi_lba_t
lba
,
grub_efi_uintn_t
buffer_size
,
void
*
buffer
);
grub_efi_status_t
(
*
flush_blocks
)
(
struct
grub_efi_block_io
*
this
);
};
typedef
struct
grub_efi_block_io
grub_efi_block_io_t
;
#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
|| defined (__aarch64__) || defined(__mips__) || defined (__MINGW64__) || defined (__CYGWIN__) \
|| defined(__riscv)
#define efi_call_0(func) func()
#define efi_call_1(func, a) func(a)
#define efi_call_2(func, a, b) func(a, b)
#define efi_call_3(func, a, b, c) func(a, b, c)
#define efi_call_4(func, a, b, c, d) func(a, b, c, d)
#define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e)
#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g)
#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) func(a, b, c, d, e, f, g, h, i, j)
#else
#define efi_call_0(func) \
efi_wrap_0(func)
#define efi_call_1(func, a) \
efi_wrap_1(func, (grub_uint64_t) (a))
#define efi_call_2(func, a, b) \
efi_wrap_2(func, (grub_uint64_t) (a), (grub_uint64_t) (b))
#define efi_call_3(func, a, b, c) \
efi_wrap_3(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c))
#define efi_call_4(func, a, b, c, d) \
efi_wrap_4(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c), (grub_uint64_t) (d))
#define efi_call_5(func, a, b, c, d, e) \
efi_wrap_5(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e))
#define efi_call_6(func, a, b, c, d, e, f) \
efi_wrap_6(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
(grub_uint64_t) (f))
#define efi_call_7(func, a, b, c, d, e, f, g) \
efi_wrap_7(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
(grub_uint64_t) (f), (grub_uint64_t) (g))
#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \
efi_wrap_10(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
(grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
(grub_uint64_t) (f), (grub_uint64_t) (g), (grub_uint64_t) (h), \
(grub_uint64_t) (i), (grub_uint64_t) (j))
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_0
)
(
void
*
func
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_1
)
(
void
*
func
,
grub_uint64_t
arg1
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_2
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_3
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_4
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
,
grub_uint64_t
arg4
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_5
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
,
grub_uint64_t
arg4
,
grub_uint64_t
arg5
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_6
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
,
grub_uint64_t
arg4
,
grub_uint64_t
arg5
,
grub_uint64_t
arg6
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_7
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
,
grub_uint64_t
arg4
,
grub_uint64_t
arg5
,
grub_uint64_t
arg6
,
grub_uint64_t
arg7
);
grub_uint64_t
EXPORT_FUNC
(
efi_wrap_10
)
(
void
*
func
,
grub_uint64_t
arg1
,
grub_uint64_t
arg2
,
grub_uint64_t
arg3
,
grub_uint64_t
arg4
,
grub_uint64_t
arg5
,
grub_uint64_t
arg6
,
grub_uint64_t
arg7
,
grub_uint64_t
arg8
,
grub_uint64_t
arg9
,
grub_uint64_t
arg10
);
#endif
#endif
/* ! GRUB_EFI_API_HEADER */
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h
0 → 100644
View file @
b63ce2a3
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* 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/>.
*/
#ifndef GRUB_EFI_PE32_HEADER
#define GRUB_EFI_PE32_HEADER 1
#include <grub/types.h>
#include <grub/efi/memory.h>
/* The MSDOS compatibility stub. This was copied from the output of
objcopy, and it is not necessary to care about what this means. */
#define GRUB_PE32_MSDOS_STUB \
{ \
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
}
#define GRUB_PE32_MSDOS_STUB_SIZE 0x80
#define GRUB_PE32_MAGIC 0x5a4d
/* According to the spec, the minimal alignment is 512 bytes...
But some examples (such as EFI drivers in the Intel
Sample Implementation) use 32 bytes (0x20) instead, and it seems
to be working.
However, there is firmware showing up in the field now with
page alignment constraints to guarantee that page protection
bits take effect. Because currently existing GRUB code can not
properly distinguish between in-memory and in-file layout, let's
bump all alignment to GRUB_EFI_PAGE_SIZE. */
#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE
#define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT
struct
grub_pe32_coff_header
{
grub_uint16_t
machine
;
grub_uint16_t
num_sections
;
grub_uint32_t
time
;
grub_uint32_t
symtab_offset
;
grub_uint32_t
num_symbols
;
grub_uint16_t
optional_header_size
;
grub_uint16_t
characteristics
;
};
#define GRUB_PE32_MACHINE_I386 0x14c
#define GRUB_PE32_MACHINE_MIPS 0x166
#define GRUB_PE32_MACHINE_IA64 0x200
#define GRUB_PE32_MACHINE_X86_64 0x8664
#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
#define GRUB_PE32_MACHINE_ARM64 0xAA64
#define GRUB_PE32_MACHINE_RISCV32 0x5032
#define GRUB_PE32_MACHINE_RISCV64 0x5064
#define GRUB_PE32_RELOCS_STRIPPED 0x0001
#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002
#define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004
#define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008
#define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010
#define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020
#define GRUB_PE32_16BIT_MACHINE 0x0040
#define GRUB_PE32_BYTES_REVERSED_LO 0x0080
#define GRUB_PE32_32BIT_MACHINE 0x0100
#define GRUB_PE32_DEBUG_STRIPPED 0x0200
#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
#define GRUB_PE32_SYSTEM 0x1000
#define GRUB_PE32_DLL 0x2000
#define GRUB_PE32_UP_SYSTEM_ONLY 0x4000
#define GRUB_PE32_BYTES_REVERSED_HI 0x8000
struct
grub_pe32_data_directory
{
grub_uint32_t
rva
;
grub_uint32_t
size
;
};
struct
grub_pe32_optional_header
{
grub_uint16_t
magic
;
grub_uint8_t
major_linker_version
;
grub_uint8_t
minor_linker_version
;
grub_uint32_t
code_size
;
grub_uint32_t
data_size
;
grub_uint32_t
bss_size
;
grub_uint32_t
entry_addr
;
grub_uint32_t
code_base
;
grub_uint32_t
data_base
;
grub_uint32_t
image_base
;
grub_uint32_t
section_alignment
;
grub_uint32_t
file_alignment
;
grub_uint16_t
major_os_version
;
grub_uint16_t
minor_os_version
;
grub_uint16_t
major_image_version
;
grub_uint16_t
minor_image_version
;
grub_uint16_t
major_subsystem_version
;
grub_uint16_t
minor_subsystem_version
;
grub_uint32_t
reserved
;
grub_uint32_t
image_size
;
grub_uint32_t
header_size
;
grub_uint32_t
checksum
;
grub_uint16_t
subsystem
;
grub_uint16_t
dll_characteristics
;
grub_uint32_t
stack_reserve_size
;
grub_uint32_t
stack_commit_size
;
grub_uint32_t
heap_reserve_size
;
grub_uint32_t
heap_commit_size
;
grub_uint32_t
loader_flags
;
grub_uint32_t
num_data_directories
;
/* Data directories. */
struct
grub_pe32_data_directory
export_table
;
struct
grub_pe32_data_directory
import_table
;
struct
grub_pe32_data_directory
resource_table
;
struct
grub_pe32_data_directory
exception_table
;
struct
grub_pe32_data_directory
certificate_table
;
struct
grub_pe32_data_directory
base_relocation_table
;
struct
grub_pe32_data_directory
debug
;
struct
grub_pe32_data_directory
architecture
;
struct
grub_pe32_data_directory
global_ptr
;
struct
grub_pe32_data_directory
tls_table
;
struct
grub_pe32_data_directory
load_config_table
;
struct
grub_pe32_data_directory
bound_import
;
struct
grub_pe32_data_directory
iat
;
struct
grub_pe32_data_directory
delay_import_descriptor
;
struct
grub_pe32_data_directory
com_runtime_header
;
struct
grub_pe32_data_directory
reserved_entry
;
};
struct
grub_pe64_optional_header
{
grub_uint16_t
magic
;
grub_uint8_t
major_linker_version
;
grub_uint8_t
minor_linker_version
;
grub_uint32_t
code_size
;
grub_uint32_t
data_size
;
grub_uint32_t
bss_size
;
grub_uint32_t
entry_addr
;
grub_uint32_t
code_base
;
grub_uint64_t
image_base
;
grub_uint32_t
section_alignment
;
grub_uint32_t
file_alignment
;
grub_uint16_t
major_os_version
;
grub_uint16_t
minor_os_version
;
grub_uint16_t
major_image_version
;
grub_uint16_t
minor_image_version
;
grub_uint16_t
major_subsystem_version
;
grub_uint16_t
minor_subsystem_version
;
grub_uint32_t
reserved
;
grub_uint32_t
image_size
;
grub_uint32_t
header_size
;
grub_uint32_t
checksum
;
grub_uint16_t
subsystem
;
grub_uint16_t
dll_characteristics
;
grub_uint64_t
stack_reserve_size
;
grub_uint64_t
stack_commit_size
;
grub_uint64_t
heap_reserve_size
;
grub_uint64_t
heap_commit_size
;
grub_uint32_t
loader_flags
;
grub_uint32_t
num_data_directories
;
/* Data directories. */
struct
grub_pe32_data_directory
export_table
;
struct
grub_pe32_data_directory
import_table
;
struct
grub_pe32_data_directory
resource_table
;
struct
grub_pe32_data_directory
exception_table
;
struct
grub_pe32_data_directory
certificate_table
;
struct
grub_pe32_data_directory
base_relocation_table
;
struct
grub_pe32_data_directory
debug
;
struct
grub_pe32_data_directory
architecture
;
struct
grub_pe32_data_directory
global_ptr
;
struct
grub_pe32_data_directory
tls_table
;
struct
grub_pe32_data_directory
load_config_table
;
struct
grub_pe32_data_directory
bound_import
;
struct
grub_pe32_data_directory
iat
;
struct
grub_pe32_data_directory
delay_import_descriptor
;
struct
grub_pe32_data_directory
com_runtime_header
;
struct
grub_pe32_data_directory
reserved_entry
;
};
#define GRUB_PE32_PE32_MAGIC 0x10b
#define GRUB_PE32_PE64_MAGIC 0x20b
#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
struct
grub_pe32_section_table
{
char
name
[
8
];
grub_uint32_t
virtual_size
;
grub_uint32_t
virtual_address
;
grub_uint32_t
raw_data_size
;
grub_uint32_t
raw_data_offset
;
grub_uint32_t
relocations_offset
;
grub_uint32_t
line_numbers_offset
;
grub_uint16_t
num_relocations
;
grub_uint16_t
num_line_numbers
;
grub_uint32_t
characteristics
;
};
#define GRUB_PE32_SCN_CNT_CODE 0x00000020
#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
#define GRUB_PE32_SCN_MEM_READ 0x40000000
#define GRUB_PE32_SCN_MEM_WRITE 0x80000000
#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
#define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000
#define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000
#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
#define GRUB_PE32_SCN_ALIGN_SHIFT 20
#define GRUB_PE32_SCN_ALIGN_MASK 7
#define GRUB_PE32_SIGNATURE_SIZE 4
struct
grub_pe32_header
{
/* This should be filled in with GRUB_PE32_MSDOS_STUB. */
grub_uint8_t
msdos_stub
[
GRUB_PE32_MSDOS_STUB_SIZE
];
/* This is always PE\0\0. */
char
signature
[
GRUB_PE32_SIGNATURE_SIZE
];
/* The COFF file header. */
struct
grub_pe32_coff_header
coff_header
;
#if GRUB_TARGET_SIZEOF_VOID_P == 8
/* The Optional header. */
struct
grub_pe64_optional_header
optional_header
;
#else
/* The Optional header. */
struct
grub_pe32_optional_header
optional_header
;
#endif
};
struct
grub_pe32_fixup_block
{
grub_uint32_t
page_rva
;
grub_uint32_t
block_size
;
grub_uint16_t
entries
[
0
];
};
#define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
#define GRUB_PE32_REL_BASED_ABSOLUTE 0
#define GRUB_PE32_REL_BASED_HIGH 1
#define GRUB_PE32_REL_BASED_LOW 2
#define GRUB_PE32_REL_BASED_HIGHLOW 3
#define GRUB_PE32_REL_BASED_HIGHADJ 4
#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
#define GRUB_PE32_REL_BASED_MIPS_LOW 6
#define GRUB_PE32_REL_BASED_MIPS_HIGH 4
#define GRUB_PE32_REL_BASED_MIPS_HIGHER 7
#define GRUB_PE32_REL_BASED_MIPS_HIGHEST 8
#define GRUB_PE32_REL_BASED_ARM_MOV32A 5
#define GRUB_PE32_REL_BASED_RISCV_HI20 5
#define GRUB_PE32_REL_BASED_SECTION 6
#define GRUB_PE32_REL_BASED_REL 7
#define GRUB_PE32_REL_BASED_ARM_MOV32T 7
#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7
#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8
#define GRUB_PE32_REL_BASED_IA64_IMM64 9
#define GRUB_PE32_REL_BASED_DIR64 10
#define GRUB_PE32_REL_BASED_HIGH3ADJ 11
struct
grub_pe32_symbol
{
union
{
char
short_name
[
8
];
grub_uint32_t
long_name
[
2
];
};
grub_uint32_t
value
;
grub_uint16_t
section
;
grub_uint16_t
type
;
grub_uint8_t
storage_class
;
grub_uint8_t
num_aux
;
}
GRUB_PACKED
;
#define GRUB_PE32_SYM_CLASS_EXTERNAL 2
#define GRUB_PE32_SYM_CLASS_STATIC 3
#define GRUB_PE32_SYM_CLASS_FILE 0x67
#define GRUB_PE32_DT_FUNCTION 0x20
struct
grub_pe32_reloc
{
grub_uint32_t
offset
;
grub_uint32_t
symtab_index
;
grub_uint16_t
type
;
}
GRUB_PACKED
;
#define GRUB_PE32_REL_I386_DIR32 0x6
#define GRUB_PE32_REL_I386_REL32 0x14
#endif
/* ! GRUB_EFI_PE32_HEADER */
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h
0 → 100644
View file @
b63ce2a3
#ifndef GRUB_MIPS64_ASM_HEADER
#define GRUB_MIPS64_ASM_HEADER 1
#define GRUB_ASM_T4 $a4
#define GRUB_ASM_T5 $a5
#define GRUB_ASM_SZREG 8
#define GRUB_ASM_REG_S sd
#define GRUB_ASM_REG_L ld
#endif
GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h
0 → 100644
View file @
b63ce2a3
Prev
1
2
3
4
5
6
…
15
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment