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