125210b06SDavid du Colombier #include "u.h"
225210b06SDavid du Colombier #include "../port/lib.h"
325210b06SDavid du Colombier #include "mem.h"
425210b06SDavid du Colombier #include "dat.h"
525210b06SDavid du Colombier #include "fns.h"
625210b06SDavid du Colombier #include "io.h"
725210b06SDavid du Colombier #include "ureg.h"
825210b06SDavid du Colombier
9*bf3a53f8SDavid du Colombier enum {
10*bf3a53f8SDavid du Colombier Ax,
11*bf3a53f8SDavid du Colombier Bx,
12*bf3a53f8SDavid du Colombier Cx,
13*bf3a53f8SDavid du Colombier Dx,
14*bf3a53f8SDavid du Colombier
15*bf3a53f8SDavid du Colombier /*
16*bf3a53f8SDavid du Colombier * common to intel & amd
17*bf3a53f8SDavid du Colombier */
18*bf3a53f8SDavid du Colombier Extfunc = 0x80000000,
19*bf3a53f8SDavid du Colombier Procsig,
20*bf3a53f8SDavid du Colombier
21*bf3a53f8SDavid du Colombier /* Procsig bits */
22*bf3a53f8SDavid du Colombier Dxlongmode = 1<<29,
23*bf3a53f8SDavid du Colombier };
24*bf3a53f8SDavid du Colombier
2525210b06SDavid du Colombier typedef unsigned long long u64intptr;
2625210b06SDavid du Colombier
27*bf3a53f8SDavid du Colombier static int
havelongmode(void)28*bf3a53f8SDavid du Colombier havelongmode(void)
29*bf3a53f8SDavid du Colombier {
30*bf3a53f8SDavid du Colombier ulong regs[4];
31*bf3a53f8SDavid du Colombier
32*bf3a53f8SDavid du Colombier memset(regs, 0, sizeof regs);
33*bf3a53f8SDavid du Colombier cpuid(Extfunc, regs);
34*bf3a53f8SDavid du Colombier if(regs[Ax] < Extfunc)
35*bf3a53f8SDavid du Colombier return 0;
36*bf3a53f8SDavid du Colombier
37*bf3a53f8SDavid du Colombier memset(regs, 0, sizeof regs);
38*bf3a53f8SDavid du Colombier cpuid(Procsig, regs);
39*bf3a53f8SDavid du Colombier return (regs[Dx] & Dxlongmode) != 0;
40*bf3a53f8SDavid du Colombier }
41*bf3a53f8SDavid du Colombier
4225210b06SDavid du Colombier void
warp64(uvlong entry)4325210b06SDavid du Colombier warp64(uvlong entry)
4425210b06SDavid du Colombier {
4525210b06SDavid du Colombier u64intptr kzero64 = 0xfffffffff0000000ull;
4625210b06SDavid du Colombier extern void _warp64(ulong);
4725210b06SDavid du Colombier
4825210b06SDavid du Colombier print("warp64(%#llux) %#llux %d\n", entry, entry & ~kzero64, nmmap);
49*bf3a53f8SDavid du Colombier if(!havelongmode()) {
50*bf3a53f8SDavid du Colombier print("can't run 64-bit kernel on 32-bit cpu\n");
51*bf3a53f8SDavid du Colombier delay(5000);
52*bf3a53f8SDavid du Colombier exit(0);
53*bf3a53f8SDavid du Colombier }
5425210b06SDavid du Colombier if(v_flag)
5525210b06SDavid du Colombier print("mkmultiboot\n");
5625210b06SDavid du Colombier mkmultiboot();
5725210b06SDavid du Colombier if(v_flag)
5825210b06SDavid du Colombier print("impulse\n");
5925210b06SDavid du Colombier /*
6025210b06SDavid du Colombier * No output after impulse().
6125210b06SDavid du Colombier */
6225210b06SDavid du Colombier if(v_flag)
6325210b06SDavid du Colombier print("_warp64\n");
6425210b06SDavid du Colombier impulse();
6525210b06SDavid du Colombier _warp64(entry & ~kzero64);
6625210b06SDavid du Colombier }
67