Import of openhackware-0.4.1
[openhackware.git] / src / bootinfos.c
blob60f85a6bc931320f46a18a56588fa710d3d542ad
1 /*
2 * <bootinfos.c>
4 * Generate boot informations (bootinfos for Linux and residual data).
5 *
6 * Copyright (c) 2004-2005 Jocelyn Mayer
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include "bios.h"
25 #define BI_FIRST 0x1010 /* first record - marker */
26 #define BI_LAST 0x1011 /* last record - marker */
27 #define BI_CMD_LINE 0x1012
28 #define BI_BOOTLOADER_ID 0x1013
29 #define BI_INITRD 0x1014
30 #define BI_SYSMAP 0x1015
31 #define BI_MACHTYPE 0x1016
32 #define BI_MEMSIZE 0x1017
33 #define BI_BOARD_INFO 0x1018
35 static inline void put_long (void *addr, uint32_t l)
37 char *pos = addr;
38 pos[0] = (l >> 24) & 0xFF;
39 pos[1] = (l >> 16) & 0xFF;
40 pos[2] = (l >> 8) & 0xFF;
41 pos[3] = l & 0xFF;
44 static void *set_bootinfo_tag (void *addr, uint32_t tag, uint32_t size,
45 void *data)
47 char *pos = addr;
49 put_long(pos, tag);
50 pos += 4;
51 put_long(pos, size + 8);
52 pos += 4;
53 memcpy(pos, data, size);
54 pos += size;
56 return pos;
59 void prepare_bootinfos (void *p, uint32_t memsize,
60 void *cmdline, void *initrd, uint32_t initrd_size)
62 uint32_t tmpi[2];
64 /* BI_FIRST */
65 p = set_bootinfo_tag(p, BI_FIRST, 0, NULL);
66 /* BI_CMD_LINE */
67 if (cmdline != 0) {
68 p = set_bootinfo_tag(p, BI_CMD_LINE, strlen(cmdline), cmdline);
69 } else {
70 p = set_bootinfo_tag(p, BI_CMD_LINE, 0, NULL);
72 /* BI_MEM_SIZE */
73 p = set_bootinfo_tag(p, BI_MEMSIZE, 4, &memsize);
74 /* BI_INITRD */
75 tmpi[0] = (uint32_t)initrd;
76 tmpi[1] = initrd_size;
77 p = set_bootinfo_tag(p, BI_INITRD, 8, tmpi);
78 /* BI_LAST */
79 p = set_bootinfo_tag(p, BI_LAST, 0, 0);
82 /* Residual data */
83 #define MAX_CPUS 16
84 #define MAX_SEGS 64
85 #define MAX_MEMS 64
86 #define MAX_DEVS 256
88 typedef struct vital_t {
89 /* Motherboard dependents */
90 uint8_t model[32];
91 uint8_t serial[64];
92 uint16_t version;
93 uint16_t revision;
94 uint32_t firmware;
95 uint32_t NVRAM_size;
96 uint32_t nSIMMslots;
97 uint32_t nISAslots;
98 uint32_t nPCIslots;
99 uint32_t nPCMCIAslots;
100 uint32_t nMCAslots;
101 uint32_t nEISAslots;
102 uint32_t CPUHz;
103 uint32_t busHz;
104 uint32_t PCIHz;
105 uint32_t TBdiv;
106 /* CPU infos */
107 uint32_t wwidth;
108 uint32_t page_size;
109 uint32_t ChBlocSize;
110 uint32_t GrSize;
111 /* Cache and TLBs */
112 uint32_t cache_size;
113 uint32_t cache_type;
114 uint32_t cache_assoc;
115 uint32_t cache_lnsize;
116 uint32_t Icache_size;
117 uint32_t Icache_assoc;
118 uint32_t Icache_lnsize;
119 uint32_t Dcache_size;
120 uint32_t Dcache_assoc;
121 uint32_t Dcache_lnsize;
122 uint32_t TLB_size;
123 uint32_t TLB_type;
124 uint32_t TLB_assoc;
125 uint32_t ITLB_size;
126 uint32_t ITLB_assoc;
127 uint32_t DTLB_size;
128 uint32_t DTLB_assoc;
129 void *ext_vital;
130 } vital_t;
132 typedef struct PPC_CPU_t {
133 uint32_t pvr;
134 uint32_t serial;
135 uint32_t L2_size;
136 uint32_t L2_assoc;
137 } PPC_CPU_t;
139 typedef struct map_t {
140 uint32_t usage;
141 uint32_t base;
142 uint32_t count;
143 } map_t;
145 typedef struct PPC_mem_t {
146 uint32_t size;
147 } PPC_mem_t;
149 typedef struct PPC_device_t {
150 uint32_t busID;
151 uint32_t devID;
152 uint32_t serial;
153 uint32_t flags;
154 uint32_t type;
155 uint32_t subtype;
156 uint32_t interface;
157 uint32_t spare;
158 } PPC_device_t;
160 typedef struct residual_t {
161 uint32_t length;
162 uint16_t version;
163 uint16_t revision;
164 vital_t vital;
165 uint32_t nCPUs;
166 PPC_CPU_t CPUs[MAX_CPUS];
167 uint32_t max_mem;
168 uint32_t good_mem;
169 uint32_t nmaps;
170 map_t maps[MAX_SEGS];
171 uint32_t nmems;
172 PPC_mem_t memories[MAX_MEMS];
173 uint32_t ndevices;
174 PPC_device_t devices[MAX_DEVS];
175 /* TOFIX: No PNP devices */
176 } residual_t;
178 void residual_build (void *p, uint32_t memsize,
179 uint32_t load_base, uint32_t load_size,
180 uint32_t last_alloc)
182 const unsigned char model[] = "Qemu\0PPC\0";
183 residual_t *res = p;
184 int i;
186 if (res == NULL)
187 return;
188 res->length = sizeof(residual_t);
189 res->version = 1;
190 res->revision = 0;
191 memcpy(res->vital.model, model, sizeof(model));
192 res->vital.version = 1;
193 res->vital.revision = 0;
194 res->vital.firmware = 0x1D1;
195 res->vital.NVRAM_size = 0x2000;
196 res->vital.nSIMMslots = 1;
197 res->vital.nISAslots = 0;
198 res->vital.nPCIslots = 0;
199 res->vital.nPCMCIAslots = 0;
200 res->vital.nMCAslots = 0;
201 res->vital.nEISAslots = 0;
202 res->vital.CPUHz = 200 * 1000 * 1000;
203 res->vital.busHz = 100 * 1000 * 1000;
204 res->vital.PCIHz = 33 * 1000 * 1000;
205 res->vital.TBdiv = 1000;
206 res->vital.wwidth = 32;
207 res->vital.page_size = 4096;
208 res->vital.ChBlocSize = 32;
209 res->vital.GrSize = 32;
210 res->vital.cache_size = 0;
211 res->vital.cache_type = 0; /* No cache */
212 res->vital.cache_assoc = 8; /* Same as 601 */
213 res->vital.cache_lnsize = 32;
214 res->vital.Icache_size = 0;
215 res->vital.Icache_assoc = 8;
216 res->vital.Icache_lnsize = 32;
217 res->vital.Dcache_size = 0;
218 res->vital.Dcache_assoc = 8;
219 res->vital.Dcache_lnsize = 32;
220 res->vital.TLB_size = 0;
221 res->vital.TLB_type = 0; /* None */
222 res->vital.TLB_assoc = 2;
223 res->vital.ITLB_size = 0;
224 res->vital.ITLB_assoc = 2;
225 res->vital.DTLB_size = 0;
226 res->vital.DTLB_assoc = 2;
227 res->vital.ext_vital = NULL;
228 res->nCPUs = 1;
229 res->CPUs[0].pvr = mfpvr();
230 res->CPUs[0].serial = 0;
231 res->CPUs[0].L2_size = 0;
232 res->CPUs[0].L2_assoc = 8;
233 /* Memory infos */
234 res->max_mem = memsize;
235 res->good_mem = memsize;
236 /* Memory mappings */
237 /* First segment: firmware */
238 last_alloc = (last_alloc + 4095) & ~4095;
239 res->maps[0].usage = 0x0007;
240 res->maps[0].base = 0x00000000;
241 res->maps[0].count = last_alloc >> 12;
242 i = 1;
243 if (last_alloc != load_base) {
244 /* Free memory between firmware and boot image */
245 res->maps[1].usage = 0x0010;
246 res->maps[1].base = last_alloc >> 12;
247 res->maps[1].count = (load_base - last_alloc) >> 12;
248 i++;
250 /* Boot image */
251 load_size = (load_size + 4095) & ~4095;
252 res->maps[i].usage = 0x0008;
253 res->maps[i].base = load_base >> 12;
254 res->maps[i].count = load_size >> 12;
255 i++;
256 /* Free memory */
257 res->maps[i].usage = 0x0010;
258 res->maps[i].base = (load_base + load_size) >> 12;
259 res->maps[i].count = (memsize >> 12) - res->maps[i].base;
260 i++;
261 /* ISA IO region : 8MB */
262 res->maps[i].usage = 0x0040;
263 res->maps[i].base = 0x80000000 >> 12;
264 res->maps[i].count = 0x00800000 >> 12;
265 i++;
266 /* System registers : 8MB */
267 res->maps[i].usage = 0x0200;
268 res->maps[i].base = 0xBF800000 >> 12;
269 res->maps[i].count = 0x00800000 >> 12;
270 i++;
271 /* System ROM : 64 kB */
272 res->maps[i].usage = 0x2000;
273 res->maps[i].base = 0xFFFF0000 >> 12;
274 res->maps[i].count = 0x00010000 >> 12;
275 i++;
276 res->nmaps = i;
277 /* Memory SIMMs */
278 res->nmems = 1;
279 res->memories[0].size = memsize;
280 /* Describe no devices */
281 res->ndevices = 0;