grub2/0015-Refactor-arm-uboot-code-to-make-it-genereic.patch
Javier Martinez Canillas afb0baacd6
Use BLS fragment filename as menu entry id and for sort criterion
The BLS config filenames are guaranteed to be unique, so they can be
used as GRUB2 entry id and can also be used to sort the menu entries.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
2018-07-02 17:33:09 +02:00

405 lines
11 KiB
Diff

From d08c9685149e7788001ac9a209baa1d84c3628e0 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Mon, 8 May 2017 17:47:57 +0200
Subject: [PATCH 015/250] Refactor arm-uboot code to make it genereic.
arm-coreboot startup code can be very similar to arm-uboot but current code has
U-Boot specific references. So split U-Boot part from generic part.
---
grub-core/Makefile.core.def | 4 +-
grub-core/kern/arm/uboot/init.c | 70 ++++++++++++++++++++++++++++++
grub-core/kern/uboot/init.c | 16 -------
grub-core/kern/uboot/uboot.c | 35 ---------------
include/grub/arm/startup.h | 16 +++++++
grub-core/kern/arm/{uboot => }/startup.S | 66 ++++-------------------------
grub-core/kern/arm/uboot/uboot.S | 73 ++++++++++++++++++++++++++++++++
7 files changed, 171 insertions(+), 109 deletions(-)
create mode 100644 grub-core/kern/arm/uboot/init.c
create mode 100644 include/grub/arm/startup.h
rename grub-core/kern/arm/{uboot => }/startup.S (77%)
create mode 100644 grub-core/kern/arm/uboot/uboot.S
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8dcd0e5a998..fb59a7b1d6a 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -105,7 +105,7 @@ kernel = {
mips_startup = kern/mips/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
- arm_uboot_startup = kern/arm/uboot/startup.S;
+ arm_uboot_startup = kern/arm/startup.S;
arm_efi_startup = kern/arm/efi/startup.S;
arm64_efi_startup = kern/arm64/efi/startup.S;
@@ -149,6 +149,8 @@ kernel = {
uboot = kern/uboot/init.c;
uboot = kern/uboot/hw.c;
uboot = term/uboot/console.c;
+ arm_uboot = kern/arm/uboot/init.c;
+ arm_uboot = kern/arm/uboot/uboot.S;
terminfoinkernel = term/terminfo.c;
terminfoinkernel = term/tparm.c;
diff --git a/grub-core/kern/arm/uboot/init.c b/grub-core/kern/arm/uboot/init.c
new file mode 100644
index 00000000000..2a6aa3fdd3d
--- /dev/null
+++ b/grub-core/kern/arm/uboot/init.c
@@ -0,0 +1,70 @@
+/* init.c - generic U-Boot initialization and finalization */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2016 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/uboot/uboot.h>
+#include <grub/arm/startup.h>
+#include <grub/uboot/api_public.h>
+
+extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
+
+grub_uint32_t
+grub_uboot_get_machine_type (void)
+{
+ return grub_arm_saved_registers.r[1];
+}
+
+grub_addr_t
+grub_uboot_get_boot_data (void)
+{
+ return grub_arm_saved_registers.r[2];
+}
+
+int
+grub_uboot_api_init (void)
+{
+ struct api_signature *start, *end;
+ struct api_signature *p;
+ grub_addr_t grub_uboot_search_hint = grub_arm_saved_registers.sp;
+ if (grub_uboot_search_hint)
+ {
+ /* Extended search range to work around Trim Slice U-Boot issue */
+ start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff)
+ - 0x00500000);
+ end =
+ (struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN -
+ API_SIG_MAGLEN + 0x00500000);
+ }
+ else
+ {
+ start = 0;
+ end = (struct api_signature *) (256 * 1024 * 1024);
+ }
+
+ /* Structure alignment is (at least) 8 bytes */
+ for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8))
+ {
+ if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0)
+ {
+ grub_uboot_syscall_ptr = p->syscall;
+ return p->version;
+ }
+ }
+
+ return 0;
+}
diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c
index 5dcc106ed9b..3e338645c57 100644
--- a/grub-core/kern/uboot/init.c
+++ b/grub-core/kern/uboot/init.c
@@ -36,30 +36,14 @@
extern char __bss_start[];
extern char _end[];
extern grub_size_t grub_total_module_size;
-extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
static unsigned long timer_start;
-extern grub_uint32_t grub_uboot_machine_type;
-extern grub_addr_t grub_uboot_boot_data;
-
void
grub_exit (void)
{
grub_uboot_return (0);
}
-grub_uint32_t
-grub_uboot_get_machine_type (void)
-{
- return grub_uboot_machine_type;
-}
-
-grub_addr_t
-grub_uboot_get_boot_data (void)
-{
- return grub_uboot_boot_data;
-}
-
static grub_uint64_t
uboot_timer_ms (void)
{
diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c
index 6800a4beb1c..cf0168e62dd 100644
--- a/grub-core/kern/uboot/uboot.c
+++ b/grub-core/kern/uboot/uboot.c
@@ -39,48 +39,13 @@
* returns: 0 if the call not found, 1 if serviced
*/
-extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
extern int grub_uboot_syscall (int, int *, ...);
-extern grub_addr_t grub_uboot_search_hint;
static struct sys_info uboot_sys_info;
static struct mem_region uboot_mem_info[5];
static struct device_info * devices;
static int num_devices;
-int
-grub_uboot_api_init (void)
-{
- struct api_signature *start, *end;
- struct api_signature *p;
-
- if (grub_uboot_search_hint)
- {
- /* Extended search range to work around Trim Slice U-Boot issue */
- start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff)
- - 0x00500000);
- end =
- (struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN -
- API_SIG_MAGLEN + 0x00500000);
- }
- else
- {
- start = 0;
- end = (struct api_signature *) (256 * 1024 * 1024);
- }
-
- /* Structure alignment is (at least) 8 bytes */
- for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8))
- {
- if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0)
- {
- grub_uboot_syscall_ptr = p->syscall;
- return p->version;
- }
- }
-
- return 0;
-}
/*
* All functions below are wrappers around the grub_uboot_syscall() function
diff --git a/include/grub/arm/startup.h b/include/grub/arm/startup.h
new file mode 100644
index 00000000000..9afb6c57c0b
--- /dev/null
+++ b/include/grub/arm/startup.h
@@ -0,0 +1,16 @@
+#ifndef GRUB_STARTUP_CPU_HEADER
+#define GRUB_STARTUP_CPU_HEADER
+
+struct grub_arm_startup_registers
+{
+ /* registers 0-11 */
+ /* for U-boot r[1] is machine type */
+ /* for U-boot r[2] is boot data */
+ grub_uint32_t r[12];
+ grub_uint32_t sp;
+ grub_uint32_t lr;
+};
+
+extern struct grub_arm_startup_registers grub_arm_saved_registers;
+
+#endif
diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/startup.S
similarity index 77%
rename from grub-core/kern/arm/uboot/startup.S
rename to grub-core/kern/arm/startup.S
index 5efaae16e83..640837cba51 100644
--- a/grub-core/kern/arm/uboot/startup.S
+++ b/grub-core/kern/arm/startup.S
@@ -86,7 +86,7 @@ FUNCTION(codestart)
@ Stack pointer used as start address for signature probing
mov r12, sp
adr sp, entry_state
- push {r1-r12,lr} @ store U-Boot context (sp in r12)
+ push {r0-r12,lr} @ store U-Boot context (sp in r12)
adr r1, _start
ldr r0, bss_start_ptr @ src
@@ -153,69 +153,21 @@ reloc_done:
b EXT_C(grub_main)
- /*
- * uboot_syscall():
- * This function is effectively a veneer, so it cannot
- * modify the stack or corrupt any registers other than
- * r12 (ip). Furthermore it needs to restore r8 for
- * U-Boot (Global Data Pointer) and preserve it for Grub.
- */
-FUNCTION(grub_uboot_syscall)
- str r8, transition_space
- str lr, transition_space + 4
- str r9, transition_space + 8
-
- ldr r8, gd_backup
- ldr r9, gd_backup + 4
-
- bl do_syscall
-
- ldr r8, transition_space
- ldr lr, transition_space + 4
- ldr r9, transition_space + 8
-
- bx lr
-do_syscall:
-
- ldr ip, grub_uboot_syscall_ptr
- bx ip
-
-FUNCTION(grub_uboot_return)
- adr sp, entry_state_end
- pop {r4-r12, lr}
- mov sp, r12
- bx lr
-
-
.align 3
-@ U-boot context stack space
-entry_state_end:
-VARIABLE(grub_uboot_machine_type)
+@ U-boot/coreboot context stack space
+VARIABLE(grub_arm_saved_registers)
+ .long 0 @ r0
.long 0 @ r1
-VARIABLE(grub_uboot_boot_data)
.long 0 @ r2
.long 0 @ r3
.long 0 @ r4
.long 0 @ r5
.long 0 @ r6
.long 0 @ r7
-gd_backup:
- .long 0 @ r8 - U-Boot global data pointer up to 2013-09-21
- .long 0 @ r9 - U-Boot global data pointer 2013-09-21 onwards
- .long 0 @ r10
- .long 0 @ r11
-VARIABLE(grub_uboot_search_hint)@ U-Boot stack pointer -
- .long 0 @ also API signature address hint.
- .long 0 @ lr
-entry_state: @ backup for U-Boot context
-
-@ GRUB context stack space
-transition_space:
.long 0 @ r8
- .long 0 @ lr
.long 0 @ r9
-
-VARIABLE(grub_uboot_syscall_ptr)
- .long 0 @
-
- END
+ .long 0 @ r10
+ .long 0 @ r11
+ .long 0 @ sp
+ .long 0 @ lr
+entry_state:
diff --git a/grub-core/kern/arm/uboot/uboot.S b/grub-core/kern/arm/uboot/uboot.S
new file mode 100644
index 00000000000..d128775f19e
--- /dev/null
+++ b/grub-core/kern/arm/uboot/uboot.S
@@ -0,0 +1,73 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 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/offsets.h>
+#include <grub/symbol.h>
+#include <grub/machine/kernel.h>
+
+ /*
+ * uboot_syscall():
+ * This function is effectively a veneer, so it cannot
+ * modify the stack or corrupt any registers other than
+ * r12 (ip). Furthermore it needs to restore r8 for
+ * U-Boot (Global Data Pointer) and preserve it for Grub.
+ */
+FUNCTION(grub_uboot_syscall)
+ str r8, transition_space
+ str lr, transition_space + 4
+ str r9, transition_space + 8
+
+ ldr ip, saved_registers_ptr
+ ldr r8, [ip, #4 * 8]
+ ldr r9, [ip, #4 * 9]
+
+ bl do_syscall
+
+ ldr r8, transition_space
+ ldr lr, transition_space + 4
+ ldr r9, transition_space + 8
+
+ bx lr
+do_syscall:
+
+ ldr ip, grub_uboot_syscall_ptr
+ bx ip
+
+FUNCTION(grub_uboot_return)
+ ldr ip, saved_registers_ptr
+ ldr sp, [ip, #4 * 4]
+ pop {r4-r12, lr}
+ mov sp, r12
+ bx lr
+
+
+ .align 3
+
+@ GRUB context stack space
+transition_space:
+ .long 0 @ r8
+ .long 0 @ lr
+ .long 0 @ r9
+
+saved_registers_ptr:
+ .long EXT_C(grub_arm_saved_registers)
+
+VARIABLE(grub_uboot_syscall_ptr)
+ .long 0 @
+
+ END
--
2.17.1