xref: /plan9-contrib/sys/src/9k/k10/multiboot.c (revision 9ef1f84b659abcb917c5c090acbce0772e494f21)
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 
7 typedef struct Mbi Mbi;
8 struct Mbi {
9 	u32int	flags;
10 	u32int	memlower;
11 	u32int	memupper;
12 	u32int	bootdevice;
13 	u32int	cmdline;
14 	u32int	modscount;
15 	u32int	modsaddr;
16 	u32int	syms[4];
17 	u32int	mmaplength;
18 	u32int	mmapaddr;
19 	u32int	driveslength;
20 	u32int	drivesaddr;
21 	u32int	configtable;
22 	u32int	bootloadername;
23 	u32int	apmtable;
24 	u32int	vbe[6];
25 };
26 
27 enum {						/* flags */
28 	Fmem		= 0x00000001,		/* mem* valid */
29 	Fbootdevice	= 0x00000002,		/* bootdevice valid */
30 	Fcmdline	= 0x00000004,		/* cmdline valid */
31 	Fmods		= 0x00000008,		/* mod* valid */
32 	Fsyms		= 0x00000010,		/* syms[] has a.out info */
33 	Felf		= 0x00000020,		/* syms[] has ELF info */
34 	Fmmap		= 0x00000040,		/* mmap* valid */
35 	Fdrives		= 0x00000080,		/* drives* valid */
36 	Fconfigtable	= 0x00000100,		/* configtable* valid */
37 	Fbootloadername	= 0x00000200,		/* bootloadername* valid */
38 	Fapmtable	= 0x00000400,		/* apmtable* valid */
39 	Fvbe		= 0x00000800,		/* vbe[] valid */
40 };
41 
42 typedef struct Mod Mod;
43 struct Mod {
44 	u32int	modstart;
45 	u32int	modend;
46 	u32int	string;
47 	u32int	reserved;
48 };
49 
50 typedef struct MMap MMap;
51 struct MMap {
52 	u32int	size;
53 	u32int	base[2];
54 	u32int	length[2];
55 	u32int	type;
56 };
57 
58 int
multiboot(u32int magic,u32int pmbi,int vflag)59 multiboot(u32int magic, u32int pmbi, int vflag)
60 {
61 	char *p;
62 	int i, n;
63 	Mbi *mbi;
64 	Mod *mod;
65 	MMap *mmap;
66 	u64int addr, len;
67 
68 	if(vflag)
69 		print("magic %#ux pmbi %#ux\n", magic, pmbi);
70 	if(magic != 0x2badb002)
71 		return -1;
72 
73 	mbi = KADDR(pmbi);
74 	if(vflag)
75 		print("flags %#ux\n", mbi->flags);
76 	if(mbi->flags & Fcmdline){
77 		p = KADDR(mbi->cmdline);
78 		if(vflag)
79 			print("cmdline <%s>\n", p);
80 		else
81 			optionsinit(p);
82 	}
83 	if(mbi->flags & Fmods){
84 		for(i = 0; i < mbi->modscount; i++){
85 			mod = KADDR(mbi->modsaddr + i*16);
86 			if(mod->string != 0)
87 				p = KADDR(mod->string);
88 			else
89 				p = "";
90 			if(vflag)
91 				print("mod %#ux %#ux <%s>\n",
92 					mod->modstart, mod->modend, p);
93 			else
94 				asmmodinit(mod->modstart, mod->modend, p);
95 		}
96 	}
97 	if(mbi->flags & Fmmap){
98 		mmap = KADDR(mbi->mmapaddr);
99 		n = 0;
100 		while(n < mbi->mmaplength){
101 			addr = (((u64int)mmap->base[1])<<32)|mmap->base[0];
102 			len = (((u64int)mmap->length[1])<<32)|mmap->length[0];
103 			switch(mmap->type){
104 			default:
105 				if(vflag)
106 					print("type %ud", mmap->type);
107 				break;
108 			case 1:
109 				if(vflag)
110 					print("Memory");
111 				else
112 					asmmapinit(addr, len, mmap->type);
113 				break;
114 			case 2:
115 				if(vflag)
116 					print("reserved");
117 				else
118 					asmmapinit(addr, len, mmap->type);
119 				break;
120 			case 3:
121 				if(vflag)
122 					print("ACPI Reclaim Memory");
123 				else
124 					asmmapinit(addr, len, mmap->type);
125 				break;
126 			case 4:
127 				if(vflag)
128 					print("ACPI NVS Memory");
129 				else
130 					asmmapinit(addr, len, mmap->type);
131 				break;
132 			}
133 			if(vflag)
134 				print("\n\t%#16.16llux %#16.16llux (%llud)\n",
135 					addr, addr+len, len);
136 
137 			n += mmap->size+sizeof(mmap->size);
138 			mmap = KADDR(mbi->mmapaddr+n);
139 		}
140 	}
141 	if(vflag && (mbi->flags & Fbootloadername)){
142 		p = KADDR(mbi->bootloadername);
143 		print("bootloadername <%s>\n", p);
144 	}
145 
146 	return 0;
147 }
148