=== modified file 'ChangeLog' --- ChangeLog 2011-01-05 00:28:28 +0000 +++ ChangeLog 2011-01-05 05:42:55 +0000 @@ -1,3 +1,13 @@ +2011-01-04 Elliott Mitchell + + * include/grub/i386/tsc.h: Create shared macros for handling all the + tiny little blobs of assembly where we'd like to be able to clobber + %ebx. Replace the many uses of #ifdef(APPLE_CC)/#ifdef(__x64_64__) + with usage of these macros. Testing found %rbx *can* be clobbered in + amd64/64-bit mode. + * grub-core/loader/i386/xnu.c: Propogate usage of the macros created + above to this file. Removes sections of copy&paste code. + 2011-01-05 Vladimir Serbinenko * util/grub-install.in: Determine ofpathname, nvsetenv and efibootmgr === modified file 'grub-core/loader/i386/xnu.c' --- grub-core/loader/i386/xnu.c 2010-09-05 11:05:36 +0000 +++ grub-core/loader/i386/xnu.c 2011-01-05 01:47:27 +0000 @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009,2011 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 @@ -130,62 +130,35 @@ if (! grub_cpu_is_cpuid_supported ()) return sane_value; -#ifdef APPLE_CC asm volatile ("movl $0, %%eax\n" -#ifdef __x86_64__ - "push %%rbx\n" -#else - "push %%ebx\n" -#endif + SAVE_REG_B "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" +#ifdef REGISTER_B_PRECIOUS + "movl %ebx, %edi" #endif + RESTORE_REG_B : "=a" (max_cpuid), - "=d" (manufacturer[1]), "=c" (manufacturer[2])); - - /* Only Intel for now is done. */ - if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0) - return sane_value; - +#ifdef REGISTER_B_PRECIOUS + "=di" (manufacturer[0]), #else - asm volatile ("movl $0, %%eax\n" - "cpuid" - : "=a" (max_cpuid), "=b" (manufacturer[0]), - "=d" (manufacturer[1]), "=c" (manufacturer[2])); + "=b" (manufacturer[0]), +#endif + "=d" (manufacturer[1]), "=c" (manufacturer[2])); /* Only Intel for now is done. */ if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0) return sane_value; -#endif /* Check Speedstep. */ if (max_cpuid < 1) return sane_value; -#ifdef APPLE_CC - asm volatile ("movl $1, %%eax\n" -#ifdef __x86_64__ - "push %%rbx\n" -#else - "push %%ebx\n" -#endif - "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" -#endif - : "=c" (capabilities): - : "%rax", "%rdx"); -#else - asm volatile ("movl $1, %%eax\n" + asm volatile ("movl $1, %%eax\n" + SAVE_REG_B "cpuid" + RESTORE_REG_B : "=c" (capabilities): - : "%rax", "%rbx", "%rdx"); -#endif + : "%rax" CLOBBER_REG_B, "%rdx"); if (! (capabilities & (1 << 7))) return sane_value; === modified file 'include/grub/i386/tsc.h' --- include/grub/i386/tsc.h 2010-01-03 22:05:07 +0000 +++ include/grub/i386/tsc.h 2011-01-05 05:23:07 +0000 @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2008,2009,2011 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 @@ -21,6 +21,21 @@ #include +/* for use with assembly segments utilizing the B register, alas in PIC +* non-64-bit mode, GCC can't deal with it being clobbered. */ +#if (defined(APPLE_CC) || defined(__pic__)) && !defined(__x86_64__) +#define REGISTER_C_PRECIOUS 1 +#define SAVE_REG_B "push %ebx\n" +#define RESTORE_REG_B "pop %ebx\n" +#define CLOBBER_REG_B + +#else +#define SAVE_REG_B +#define RESTORE_REG_B +#define CLOBBER_REG_B "%rbx". +#endif + + /* Read the TSC value, which increments with each CPU clock cycle. */ static __inline grub_uint64_t grub_get_tsc (void) @@ -29,24 +44,11 @@ /* The CPUID instruction is a 'serializing' instruction, and avoids out-of-order execution of the RDTSC instruction. */ -#ifdef APPLE_CC __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" -#ifdef __x86_64__ - "push %%rbx\n" -#else - "push %%ebx\n" -#endif + SAVE_REG_B "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" -#endif - :::"%rax", "%rcx", "%rdx"); -#else - __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" - "cpuid":::"%rax", "%rbx", "%rcx", "%rdx"); -#endif + RESTORE_REG_B + :::"%rax", CLOBBER_REG_B "%rcx", "%rdx"); /* Read TSC value. We cannot use "=A", since this would use %rax on x86_64. */ __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); @@ -54,12 +56,17 @@ return (((grub_uint64_t) hi) << 32) | lo; } -#ifdef __x86_64__ static __inline int grub_cpu_is_cpuid_supported (void) { - grub_uint64_t id_supported; +#ifdef __x86_64__ + /* there really any processors in this class that *don't* support cpuid?! */ +#if 0 + return 1; +#endif + + grub_size_t id_supported; __asm__ ("pushfq\n\t" "popq %%rax /* Get EFLAGS into EAX */\n\t" @@ -75,14 +82,8 @@ : /* Clobbered: */ "%rcx"); return id_supported != 0; -} - #else - -static __inline int -grub_cpu_is_cpuid_supported (void) -{ - grub_uint32_t id_supported; + grub_size_t id_supported; __asm__ ("pushfl\n\t" "popl %%eax /* Get EFLAGS into EAX */\n\t" @@ -98,6 +99,7 @@ : /* Clobbered: */ "%rcx"); return id_supported != 0; +#endif } #endif @@ -109,29 +111,13 @@ return 0; grub_uint32_t features; -#ifdef APPLE_CC - __asm__ ("movl $1, %%eax\n\t" -#ifdef __x86_64__ - "push %%rbx\n" -#else - "push %%ebx\n" -#endif - "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" -#endif - : "=d" (features) - : /* No inputs. */ - : /* Clobbered: */ "%rax", "%rcx"); -#else - __asm__ ("movl $1, %%eax\n\t" - "cpuid\n" - : "=d" (features) - : /* No inputs. */ - : /* Clobbered: */ "%rax", "%rbx", "%rcx"); -#endif + __asm__ ("movl $1, %%eax\n\t" + SAVE_REG_B + "cpuid\n" + RESTORE_REG_B + : "=d" (features) + : /* No inputs. */ + : /* Clobbered: */ "%rax", CLOBBER_REG_B "%rcx"); return (features & (1 << 4)) != 0; }