]> git.proxmox.com Git - grub2.git/commitdiff
Workaround buggy timer in raspberry pie by using our own timer
authorVladimir Serbinenko <phcoder@gmail.com>
Sun, 22 Dec 2013 01:48:42 +0000 (02:48 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sun, 22 Dec 2013 01:48:42 +0000 (02:48 +0100)
implementation.

ChangeLog
grub-core/kern/uboot/init.c
include/grub/arm/linux.h
include/grub/arm/system.h

index b033eef3347a4e35eaaeb0599edf15a75f6da4b4..89d04eee66a555632dfc7d3a79512128e35a804c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Workaround buggy timer in raspberry pie by using our own timer
+       implementation.
+
 2013-12-22  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * include/grub/arm/uboot/kernel.h (GRUB_KERNEL_MACHINE_HEAP_SIZE):
index 71bc21b8f0188cab45f946ee92dd0a136794bc54..c7ad73dafe37d932ebf0abd44525f6d3c80972ce 100644 (file)
@@ -30,6 +30,7 @@
 #include <grub/uboot/disk.h>
 #include <grub/uboot/uboot.h>
 #include <grub/uboot/api_public.h>
+#include <grub/cpu/system.h>
 
 extern char __bss_start[];
 extern char _end[];
@@ -69,6 +70,19 @@ uboot_timer_ms (void)
   return (((grub_uint64_t) high) << 32) | cur;
 }
 
+#ifdef __arm__
+static grub_uint64_t
+rpi_timer_ms (void)
+{
+  static grub_uint32_t last = 0, high = 0;
+  grub_uint32_t cur = *(volatile grub_uint32_t *) 0x20003004;
+  if (cur < last)
+    high++;
+  last = cur;
+  return grub_divmod64 ((((grub_uint64_t) high) << 32) | cur, 1000, 0);
+}
+#endif
+
 void
 grub_machine_init (void)
 {
@@ -106,8 +120,17 @@ grub_machine_init (void)
   grub_uboot_probe_hardware ();
 
   /* Initialise timer */
-  timer_start = grub_uboot_get_timer (0);
-  grub_install_get_time_ms (uboot_timer_ms);
+#ifdef __arm__
+  if (grub_uboot_get_machine_type () == GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI)
+    {
+      grub_install_get_time_ms (rpi_timer_ms);
+    }
+  else
+#endif
+    {
+      timer_start = grub_uboot_get_timer (0);
+      grub_install_get_time_ms (uboot_timer_ms);
+    }
 
   /* Initialize  */
   grub_ubootdisk_init ();
index 29ab966602a3d73134138463b427fc7d5d41141d..059dbba4292a85fdd271e03913c59991b19380d9 100644 (file)
 #define LINUX_ZIMAGE_OFFSET 0x24
 #define LINUX_ZIMAGE_MAGIC  0x016f2818
 
-enum
-  {
-    GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI = 3138,
-    GRUB_ARM_MACHINE_TYPE_FDT = 0xFFFFFFFF
-  };
+#include "system.h"
 
 #if defined GRUB_MACHINE_UBOOT
 # include <grub/uboot/uboot.h>
index e2206000332bb1afbe6fbeb898e61f9c9d77f581..aa43ed63f5ba773227efb21a2d60423d166ec8cd 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef GRUB_SYSTEM_CPU_HEADER
 #define GRUB_SYSTEM_CPU_HEADER
 
+enum
+  {
+    GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI = 3138,
+    GRUB_ARM_MACHINE_TYPE_FDT = 0xFFFFFFFF
+  };
+
 void grub_arm_disable_caches_mmu (void);
 
 #endif /* ! GRUB_SYSTEM_CPU_HEADER */