diff options
Diffstat (limited to 'contrib/syslinux-4.02/com32/modules/ifcpu.c')
-rw-r--r-- | contrib/syslinux-4.02/com32/modules/ifcpu.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/modules/ifcpu.c b/contrib/syslinux-4.02/com32/modules/ifcpu.c new file mode 100644 index 0000000..a28acc4 --- /dev/null +++ b/contrib/syslinux-4.02/com32/modules/ifcpu.c @@ -0,0 +1,169 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2009 Erwan Velu - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston MA 02110-1301, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * ifcpu.c + * + */ + +#include <alloca.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <cpuid.h> +#include <unistd.h> +#include <syslinux/boot.h> +#include <com32.h> +#include <consoles.h> + +static inline void error(const char *msg) +{ + fputs(msg, stderr); +} + +static void usage(void) +{ + error("Run one command if system match some CPU features, another if it doesn't. \n" + "Usage: \n" + " label ifcpu \n" + " com32 ifcpu.c32 \n" + " append <option> <cpu_features> -- boot_entry_1 -- boot_entry_2 \n" + " label boot_entry_1 \n" + " kernel vmlinuz_entry1 \n" + " append ... \n" + " label boot_entry_2 \n" + " kernel vmlinuz_entry2 \n" + " append ... \n" + "\n" + "options could be :\n" + " debug : display some debugging messages \n" + " dry-run : just do the detection, don't boot \n" + "\n" + "cpu_features could be:\n" + " 64 : Processor is x86_64 compatible (lm cpu flag)\n" + " hvm : Processor features hardware virtualization (hvm or svm cpu flag)\n" + " multicore : Processor must be multi-core \n" + " smp : System must be multi-processor \n" + " pae : Processor features Physical Address Extension (PAE)\n" + "\n" + "if you want to match many cpu features, just separate them with a single space.\n"); +} + +/* XXX: this really should be librarized */ +static void boot_args(char **args) +{ + int len = 0, a = 0; + char **pp; + const char *p; + char c, *q, *str; + + for (pp = args; *pp; pp++) + len += strlen(*pp) + 1; + + q = str = alloca(len); + for (pp = args; *pp; pp++) { + p = *pp; + while ((c = *p++)) + *q++ = c; + *q++ = ' '; + a = 1; + } + q -= a; + *q = '\0'; + + if (!str[0]) + syslinux_run_default(); + else + syslinux_run_command(str); +} + +#define show_bool(mybool) mybool ? "found":"not found" + +int main(int argc, char *argv[]) +{ + char **args[3]; + int i=0; + int n=0; + bool hardware_matches = true; + bool multicore = false; + bool dryrun = false; + bool debug = false; + + s_cpu cpu; + console_ansi_raw(); + detect_cpu(&cpu); + + /* If no argument got passed, let's show the usage */ + if (argc == 1) { + usage(); + return -1; + } + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--")) { + argv[i] = NULL; + args[n++] = &argv[i + 1]; + } else if (!strcmp(argv[i], "64")) { + if (debug) + printf(" 64bit : %s on this system\n", + show_bool(cpu.flags.lm)); + hardware_matches = cpu.flags.lm && hardware_matches; + } else if (!strcmp(argv[i], "pae")) { + if (debug) + printf(" pae : %s on this system\n", + show_bool(cpu.flags.pae)); + hardware_matches = cpu.flags.pae && hardware_matches; + } else if (!strcmp(argv[i], "hvm")) { + if (debug) + printf(" hvm : %s on this system\n", + show_bool((cpu.flags.vmx || cpu.flags.svm))); + hardware_matches = (cpu.flags.vmx || cpu.flags.svm) + && hardware_matches; + } else if (!strcmp(argv[i], "multicore")) { + if (debug) + printf(" multicore : %d cores on this system\n", cpu.num_cores); + if (cpu.num_cores > 1) + multicore = true; + hardware_matches = multicore && hardware_matches; + } else if (!strcmp(argv[i], "smp")) { + if (debug) + printf(" smp : %s on this system\n", show_bool(cpu.flags.smp)); + hardware_matches = cpu.flags.smp && hardware_matches; + } else if (!strcmp(argv[i], "dry-run")) { + dryrun = true; + } else if (!strcmp(argv[i], "debug")) { + debug = true; + } + if (n >= 2) + break; + } + while (n < 2) { + args[n] = args[n - 1]; + n++; + } + if (debug) { + printf("\nBooting labels are : '%s' or '%s'\n", *args[0], *args[1]); + printf("Hardware requirements%smatch this system, let's booting '%s'\n", + hardware_matches ? " " : " doesn't ", + hardware_matches ? *args[0] : *args[1]); + printf("Sleeping 5sec before booting\n"); + if (!dryrun) + sleep(5); + } + + if (!dryrun) + boot_args(hardware_matches ? args[0] : args[1]); + else + printf("Dry-run mode, let's exiting\n"); + + return -1; +} |