Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / bootinfos.c
1 /*
2  * <bootinfos.c>
3  *
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
11  *
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.
16  *
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
20  */
21
22 #include <stdlib.h>
23 #include "bios.h"
24
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
34
35 static inline void put_long (void *addr, uint32_t l)
36 {
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;
42 }
43
44 static void *set_bootinfo_tag (void *addr, uint32_t tag, uint32_t size,
45                                void *data)
46 {
47     char *pos = addr;
48
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;
55
56     return pos;
57 }
58
59 void prepare_bootinfos (void *p, uint32_t memsize,
60                         void *cmdline, void *initrd, uint32_t initrd_size)
61 {
62     uint32_t tmpi[2];
63
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);
71     }
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);
80 }
81
82 /* Residual data */
83 #define MAX_CPUS 16
84 #define MAX_SEGS 64
85 #define MAX_MEMS 64
86 #define MAX_DEVS 256
87
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;
131
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;
138
139 typedef struct map_t {
140     uint32_t usage;
141     uint32_t base;
142     uint32_t count;
143 } map_t;
144
145 typedef struct PPC_mem_t {
146     uint32_t size;
147 } PPC_mem_t;
148
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;
159
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;
177
178 void residual_build (void *p, uint32_t memsize,
179                      uint32_t load_base, uint32_t load_size,
180                      uint32_t last_alloc)
181 {
182     const unsigned char model[] = "Qemu\0PPC\0";
183     residual_t *res = p;
184     int i;
185
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++;
249     }
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;
282 }