=== modified file 'ChangeLog' --- ChangeLog 2011-01-05 11:23:06 +0000 +++ ChangeLog 2011-01-06 01:29:08 +0000 @@ -1,3 +1,13 @@ +2011-01-05 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 Run terminfo_cls on initing terminfo output to clear the screen and === 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-06 01:22:33 +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,27 @@ 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 + ASM_SAVE_REG_B "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" -#endif - : "=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; - -#else - asm volatile ("movl $0, %%eax\n" - "cpuid" - : "=a" (max_cpuid), "=b" (manufacturer[0]), + ASM_REST_REG_B_XCHG + : "=a" (max_cpuid), ASM_REG_B_OUT (manufacturer[0]), "=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 + ASM_SAVE_REG_B "cpuid\n" -#ifdef __x86_64__ - "pop %%rbx\n" -#else - "pop %%ebx\n" -#endif - : "=c" (capabilities): - : "%rax", "%rdx"); -#else - asm volatile ("movl $1, %%eax\n" - "cpuid" - : "=c" (capabilities): - : "%rax", "%rbx", "%rdx"); -#endif + ASM_REST_REG_B + : "=c" (capabilities): + : "%rax", ASM_CLOB_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-06 01:27:48 +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,24 @@ #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 ASM_SAVE_REG_B "movel %%ebx, %%edi\n" +#define ASM_REST_REG_B "movel %%edi, %%edx\n" +#define ASM_REST_REG_B_XCHG "xchg %%edi, %%edi\n" +#define ASM_CLOB_REG_B "%edi" +#define ASM_REG_B_OUT "=di" + +#else +#define ASM_SAVE_REG_B +#define ASM_REST_REG_B +#define ASM_REST_REG_B_XCHG +#define ASM_CLOB_REG_B "%rbx" +#define ASM_REG_B_OUT "=b" +#endif + + /* Read the TSC value, which increments with each CPU clock cycle. */ static __inline grub_uint64_t grub_get_tsc (void) @@ -29,24 +47,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 + __asm__ __volatile__ ("movl $0, %%eax\n\t" + ASM_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 + ASM_REST_REG_B + :::"%rax", ASM_CLOB_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 +59,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 +85,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,10 +102,9 @@ : /* Clobbered: */ "%rcx"); return id_supported != 0; +#endif } -#endif - static __inline int grub_cpu_is_tsc_supported (void) { @@ -109,29 +112,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" + ASM_SAVE_REG_B + "cpuid\n" + ASM_REST_REG_B + : "=d" (features) + : /* No inputs. */ + : /* Clobbered: */ "%rax", ASM_CLOB_REG_B, "%rcx"); return (features & (1 << 4)) != 0; }