xref: /plan9/sys/src/9/pcboot/warp64.c (revision bf3a53f86959e0d59761d324f198ede9838801c7)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"io.h"
7 #include	"ureg.h"
8 
9 enum {
10 	Ax,
11 	Bx,
12 	Cx,
13 	Dx,
14 
15 	/*
16 	 * common to intel & amd
17 	 */
18 	Extfunc	= 0x80000000,
19 	Procsig,
20 
21 	/* Procsig bits */
22 	Dxlongmode	= 1<<29,
23 };
24 
25 typedef unsigned long long u64intptr;
26 
27 static int
havelongmode(void)28 havelongmode(void)
29 {
30 	ulong regs[4];
31 
32 	memset(regs, 0, sizeof regs);
33 	cpuid(Extfunc, regs);
34 	if(regs[Ax] < Extfunc)
35 		return 0;
36 
37 	memset(regs, 0, sizeof regs);
38 	cpuid(Procsig, regs);
39 	return (regs[Dx] & Dxlongmode) != 0;
40 }
41 
42 void
warp64(uvlong entry)43 warp64(uvlong entry)
44 {
45 	u64intptr kzero64 = 0xfffffffff0000000ull;
46 	extern void _warp64(ulong);
47 
48 	print("warp64(%#llux) %#llux %d\n", entry, entry & ~kzero64, nmmap);
49 	if(!havelongmode()) {
50 		print("can't run 64-bit kernel on 32-bit cpu\n");
51 		delay(5000);
52 		exit(0);
53 	}
54 	if(v_flag)
55 		print("mkmultiboot\n");
56 	mkmultiboot();
57 	if(v_flag)
58 		print("impulse\n");
59 	/*
60 	 * No output after impulse().
61 	 */
62 	if(v_flag)
63 		print("_warp64\n");
64 	impulse();
65 	_warp64(entry & ~kzero64);
66 }
67