source: bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/* ----------------------------------------------------------------------- *
2 *
3 *   Copyright 2008 H. Peter Anvin - All Rights Reserved
4 *
5 *   This program is free software; you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
8 *   Boston MA 02110-1301, USA; either version 2 of the License, or
9 *   (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13/*
14 * ifcpu64.c
15 *
16 * Run one command if the CPU has 64-bit support, and another if it doesn't.
17 * Eventually this and other features should get folded into some kind
18 * of scripting engine.
19 *
20 * Usage:
21 *
22 *    label boot_kernel
23 *        com32 ifcpu64.c32
24 *        append boot_kernel_64 [-- boot_kernel_32pae] -- boot_kernel_32
25 *    label boot_kernel_32
26 *        kernel vmlinuz_32
27 *        append ...
28 *    label boot_kernel_64
29 *        kernel vmlinuz_64
30 *        append ...
31 */
32
33#include <alloca.h>
34#include <stdlib.h>
35#include <string.h>
36#include <cpuid.h>
37#include <syslinux/boot.h>
38
39static bool __constfunc cpu_has_cpuid(void)
40{
41    return cpu_has_eflag(X86_EFLAGS_ID);
42}
43
44static bool __constfunc cpu_has_level(uint32_t level)
45{
46    uint32_t group;
47    uint32_t limit;
48
49    if (!cpu_has_cpuid())
50        return false;
51
52    group = level & 0xffff0000;
53    limit = cpuid_eax(group);
54
55    if ((limit & 0xffff0000) != group)
56        return false;
57
58    if (level > limit)
59        return false;
60
61    return true;
62}
63
64/* This only supports feature groups 0 and 1, corresponding to the
65   Intel and AMD EDX bit vectors.  We can add more later if need be. */
66static bool __constfunc cpu_has_feature(int x)
67{
68    uint32_t level = ((x & 1) << 31) | 1;
69
70    return cpu_has_level(level) && ((cpuid_edx(level) >> (x & 31) & 1));
71}
72
73/* XXX: this really should be librarized */
74static void boot_args(char **args)
75{
76    int len = 0, a = 0;
77    char **pp;
78    const char *p;
79    char c, *q, *str;
80
81    for (pp = args; *pp; pp++)
82        len += strlen(*pp) + 1;
83
84    q = str = alloca(len);
85    for (pp = args; *pp; pp++) {
86        p = *pp;
87        while ((c = *p++))
88            *q++ = c;
89        *q++ = ' ';
90        a = 1;
91    }
92    q -= a;
93    *q = '\0';
94
95    if (!str[0])
96        syslinux_run_default();
97    else
98        syslinux_run_command(str);
99}
100
101int main(int argc, char *argv[])
102{
103    char **args[3];
104    int i;
105    int n;
106
107    args[0] = &argv[1];
108    n = 1;
109    for (i = 1; i < argc; i++) {
110        if (!strcmp(argv[i], "--")) {
111            argv[i] = NULL;
112            args[n++] = &argv[i + 1];
113        }
114        if (n >= 3)
115            break;
116    }
117    while (n < 3) {
118        args[n] = args[n - 1];
119        n++;
120    }
121
122    boot_args(cpu_has_feature(X86_FEATURE_LM) ? args[0] :
123              cpu_has_feature(X86_FEATURE_PAE) ? args[1] : args[2]);
124    return -1;
125}
Note: See TracBrowser for help on using the repository browser.