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