diff --git a/ChangeLog b/ChangeLog index b033eef33..89d04eee6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-22 Vladimir Serbinenko + + Workaround buggy timer in raspberry pie by using our own timer + implementation. + 2013-12-22 Vladimir Serbinenko * include/grub/arm/uboot/kernel.h (GRUB_KERNEL_MACHINE_HEAP_SIZE): diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c index 71bc21b8f..c7ad73daf 100644 --- a/grub-core/kern/uboot/init.c +++ b/grub-core/kern/uboot/init.c @@ -30,6 +30,7 @@ #include #include #include +#include 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 (); diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h index 29ab96660..059dbba42 100644 --- a/include/grub/arm/linux.h +++ b/include/grub/arm/linux.h @@ -23,11 +23,7 @@ #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 diff --git a/include/grub/arm/system.h b/include/grub/arm/system.h index e22060003..aa43ed63f 100644 --- a/include/grub/arm/system.h +++ b/include/grub/arm/system.h @@ -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 */