# HG changeset patch # User Pascal Bellard # Date 1408607817 -7200 # Node ID 5e47b1bdb6f4388b63bcc01c938482e130fafea8 # Parent 6dd4a6865e2ecd32c74bc1eca5cde39ce885dbb1 syslinux/c32box: x86_64 auto select diff -r 6dd4a6865e2e -r 5e47b1bdb6f4 syslinux/stuff/extra/md5sum.c --- a/syslinux/stuff/extra/md5sum.c Thu Aug 21 03:51:54 2014 +0200 +++ b/syslinux/stuff/extra/md5sum.c Thu Aug 21 09:56:57 2014 +0200 @@ -680,6 +680,7 @@ #include #include #include +#include #include #include #include @@ -757,6 +758,72 @@ return cmdline; } +static bool __constfunc cpu_has_cpuid(void) +{ + return cpu_has_eflag(X86_EFLAGS_ID); +} + +static bool __constfunc cpu_has_level(uint32_t level) +{ + uint32_t group; + uint32_t limit; + + if (!cpu_has_cpuid()) + return false; + + group = level & 0xffff0000; + limit = cpuid_eax(group); + + if ((limit & 0xffff0000) != group) + return false; + + if (level > limit) + return false; + + return true; +} + +/* This only supports feature groups 0 and 1, corresponding to the + Intel and AMD EDX bit vectors. We can add more later if need be. */ +static bool __constfunc cpu_has_feature(int x) +{ + uint32_t level = ((x & 1) << 31) | 1; + + return cpu_has_level(level) && ((cpuid_edx(level) >> (x & 31) & 1)); +} + +static char *extfilename(char *filename, char *ext, int feature) +{ +#define NEWFILENAMESZ 80 + static char newfilename[NEWFILENAMESZ+1]; + char *found = filename; + FILE *fp; + + if (strlen(filename) + strlen(ext) <= NEWFILENAMESZ) { + strcpy(newfilename, filename, NEWFILENAMESZ); + if (cpu_has_feature(feature)) { + strcat(newfilename, ext); + fp = fopen(newfilename, "r"); + if (fp) + found = newfilename; + fclose(fp); + } + } + return found; +} + +static char *bestextfilename(char *filename) +{ + char *found; + + //found = extfilename(filename, "fpu", X86_FEATURE_FPU); + //found = extfilename(filename, "686", X86_FEATURE_CMOV); + //found = extfilename(filename, "pae", X86_FEATURE_PAE); + found = extfilename(filename, "64", X86_FEATURE_LM); + //found = extfilename(filename, "guest", X86_FEATURE_HYPERVISOR); + return found; +} + static int setup_data_file(struct setup_data *setup_data, uint32_t type, const char *filename, bool opt_quiet) @@ -780,6 +847,7 @@ static int main_linux(int argc, char *argv[]) { const char *kernel_name; + const char *initrd_name; struct initramfs *initramfs; struct setup_data *setup_data; char *cmdline; @@ -812,7 +880,7 @@ return 1; } - kernel_name = arg; + kernel_name = bestextfilename(arg); errno = 0; boot_image = malloc(strlen(kernel_name) + 12); @@ -863,12 +931,13 @@ if (p) *p = '\0'; + initrd_name = bestextfilename(arg); if (!opt_quiet) - printf("Loading %s... ", arg); + printf("Loading %s... ", initrd_name); errno = 0; - if (initramfs_load_archive(initramfs, arg)) { + if (initramfs_load_archive(initramfs, initrd_name)) { if (opt_quiet) - printf("Loading %s ", kernel_name); + printf("Loading %s ", initrd_name); printf("failed: "); goto bail; }