Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / src / post.c
1 // 32bit code to Power On Self Test (POST) a machine.
2 //
3 // Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002  MandrakeSoft S.A.
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "ioport.h" // PORT_*
9 #include "config.h" // CONFIG_*
10 #include "cmos.h" // CMOS_*
11 #include "util.h" // memset
12 #include "biosvar.h" // struct bios_data_area_s
13 #include "disk.h" // floppy_drive_setup
14 #include "ata.h" // ata_setup
15 #include "ahci.h" // ahci_setup
16 #include "memmap.h" // add_e820
17 #include "pic.h" // pic_setup
18 #include "pci.h" // create_pirtable
19 #include "acpi.h" // acpi_bios_init
20 #include "bregs.h" // struct bregs
21 #include "mptable.h" // mptable_init
22 #include "boot.h" // IPL
23 #include "usb.h" // usb_setup
24 #include "smbios.h" // smbios_init
25 #include "paravirt.h" // qemu_cfg_port_probe
26 #include "xen.h" // xen_probe_hvm_info
27 #include "ps2port.h" // ps2port_setup
28 #include "virtio-blk.h" // virtio_blk_setup
29
30
31 /****************************************************************
32  * BIOS init
33  ****************************************************************/
34
35 static void
36 init_ivt(void)
37 {
38     dprintf(3, "init ivt\n");
39
40     // Initialize all vectors to the default handler.
41     int i;
42     for (i=0; i<256; i++)
43         SET_IVT(i, FUNC16(entry_iret_official));
44
45     // Initialize all hw vectors to a default hw handler.
46     for (i=0x08; i<=0x0f; i++)
47         SET_IVT(i, FUNC16(entry_hwpic1));
48     for (i=0x70; i<=0x77; i++)
49         SET_IVT(i, FUNC16(entry_hwpic2));
50
51     // Initialize software handlers.
52     SET_IVT(0x02, FUNC16(entry_02));
53     SET_IVT(0x10, FUNC16(entry_10));
54     SET_IVT(0x11, FUNC16(entry_11));
55     SET_IVT(0x12, FUNC16(entry_12));
56     SET_IVT(0x13, FUNC16(entry_13_official));
57     SET_IVT(0x14, FUNC16(entry_14));
58     SET_IVT(0x15, FUNC16(entry_15));
59     SET_IVT(0x16, FUNC16(entry_16));
60     SET_IVT(0x17, FUNC16(entry_17));
61     SET_IVT(0x18, FUNC16(entry_18));
62     SET_IVT(0x19, FUNC16(entry_19_official));
63     SET_IVT(0x1a, FUNC16(entry_1a));
64     SET_IVT(0x40, FUNC16(entry_40));
65
66     // INT 60h-66h reserved for user interrupt
67     for (i=0x60; i<=0x66; i++)
68         SET_IVT(i, SEGOFF(0, 0));
69
70     // set vector 0x79 to zero
71     // this is used by 'gardian angel' protection system
72     SET_IVT(0x79, SEGOFF(0, 0));
73
74     SET_IVT(0x1E, SEGOFF(SEG_BIOS, (u32)&diskette_param_table2 - BUILD_BIOS_ADDR));
75 }
76
77 static void
78 init_bda(void)
79 {
80     dprintf(3, "init bda\n");
81
82     struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0);
83     memset(bda, 0, sizeof(*bda));
84
85     int esize = EBDA_SIZE_START;
86     SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize);
87     u16 ebda_seg = EBDA_SEGMENT_START;
88     SET_BDA(ebda_seg, ebda_seg);
89
90     // Init ebda
91     struct extended_bios_data_area_s *ebda = get_ebda_ptr();
92     memset(ebda, 0, sizeof(*ebda));
93     ebda->size = esize;
94
95     add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA2(ebda_seg, size) * 1024
96              , E820_RESERVED);
97 }
98
99 static void
100 ram_probe(void)
101 {
102     dprintf(3, "Find memory size\n");
103     if (CONFIG_COREBOOT) {
104         coreboot_setup();
105     } else if (usingXen()) {
106         xen_setup();
107     } else {
108         // On emulators, get memory size from nvram.
109         u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
110                   | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24));
111         if (rs)
112             rs += 16 * 1024 * 1024;
113         else
114             rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10)
115                    | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18))
116                   + 1 * 1024 * 1024);
117         RamSize = rs;
118         add_e820(0, rs, E820_RAM);
119
120         // Check for memory over 4Gig
121         u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16)
122                     | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24)
123                     | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32));
124         RamSizeOver4G = high;
125         add_e820(0x100000000ull, high, E820_RAM);
126
127         /* reserve 256KB BIOS area at the end of 4 GB */
128         add_e820(0xfffc0000, 256*1024, E820_RESERVED);
129     }
130
131     // Don't declare any memory between 0xa0000 and 0x100000
132     add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE);
133
134     // Mark known areas as reserved.
135     add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED);
136
137     u32 count = qemu_cfg_e820_entries();
138     if (count) {
139         struct e820_reservation entry;
140         int i;
141
142         for (i = 0; i < count; i++) {
143             qemu_cfg_e820_load_next(&entry);
144             add_e820(entry.address, entry.length, entry.type);
145         }
146     } else if (kvm_para_available()) {
147         // Backwards compatibility - provide hard coded range.
148         // 4 pages before the bios, 3 pages for vmx tss pages, the
149         // other page for EPT real mode pagetable
150         add_e820(0xfffbc000, 4*4096, E820_RESERVED);
151     }
152
153     dprintf(1, "Ram Size=0x%08x (0x%08x%08x high)\n"
154             , RamSize, (u32)(RamSizeOver4G >> 32), (u32)RamSizeOver4G);
155 }
156
157 static void
158 init_bios_tables(void)
159 {
160     if (CONFIG_COREBOOT) {
161         coreboot_copy_biostable();
162         return;
163     }
164     if (usingXen()) {
165         xen_copy_biostables();
166         return;
167     }
168
169     create_pirtable();
170
171     mptable_init();
172
173     smbios_init();
174
175     acpi_bios_init();
176 }
177
178 // Initialize hardware devices
179 static void
180 init_hw(void)
181 {
182     usb_setup();
183     ps2port_setup();
184     lpt_setup();
185     serial_setup();
186
187     floppy_setup();
188     ata_setup();
189     ahci_setup();
190     cbfs_payload_setup();
191     ramdisk_setup();
192     virtio_blk_setup();
193 }
194
195 // Begin the boot process by invoking an int0x19 in 16bit mode.
196 void VISIBLE32FLAT
197 startBoot(void)
198 {
199     // Clear low-memory allocations (required by PMM spec).
200     memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR);
201
202     dprintf(3, "Jump to int19\n");
203     struct bregs br;
204     memset(&br, 0, sizeof(br));
205     br.flags = F_IF;
206     call16_int(0x19, &br);
207 }
208
209 // Main setup code.
210 static void
211 maininit(void)
212 {
213     // Running at new code address - do code relocation fixups
214     malloc_fixupreloc();
215
216     // Setup ivt/bda/ebda
217     init_ivt();
218     init_bda();
219
220     // Init base pc hardware.
221     pic_setup();
222     timer_setup();
223     mathcp_setup();
224
225     // Initialize mtrr
226     mtrr_setup();
227
228     // Initialize pci
229     pci_setup();
230     smm_init();
231
232     // Setup Xen hypercalls
233     xen_init_hypercalls();
234
235     // Initialize internal tables
236     boot_setup();
237
238     // Start hardware initialization (if optionrom threading)
239     if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS)
240         init_hw();
241
242     // Find and initialize other cpus
243     smp_probe();
244
245     // Setup interfaces that option roms may need
246     bios32_setup();
247     pmm_setup();
248     pnp_setup();
249     kbd_setup();
250     mouse_setup();
251     init_bios_tables();
252
253     // Run vga option rom
254     vga_setup();
255
256     // Do hardware initialization (if running synchronously)
257     if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) {
258         init_hw();
259         wait_threads();
260     }
261
262     // Run option roms
263     optionrom_setup();
264
265     // Run BCVs and show optional boot menu
266     boot_prep();
267
268     // Finalize data structures before boot
269     cdemu_setup();
270     pmm_finalize();
271     malloc_finalize();
272     memmap_finalize();
273
274     // Setup bios checksum.
275     BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE);
276
277     // Write protect bios memory.
278     make_bios_readonly();
279
280     // Invoke int 19 to start boot process.
281     startBoot();
282 }
283
284
285 /****************************************************************
286  * POST entry and code relocation
287  ****************************************************************/
288
289 // Update given relocs for the code at 'dest' with a given 'delta'
290 static void
291 updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta)
292 {
293     u32 *reloc;
294     for (reloc = rstart; reloc < rend; reloc++)
295         *((u32*)(dest + *reloc)) += delta;
296 }
297
298 // Relocate init code and then call maininit() at new address.
299 static void
300 reloc_init(void)
301 {
302     if (!CONFIG_RELOCATE_INIT) {
303         maininit();
304         return;
305     }
306     // Symbols populated by the build.
307     extern u8 code32flat_start[];
308     extern u8 _reloc_min_align[];
309     extern u32 _reloc_abs_start[], _reloc_abs_end[];
310     extern u32 _reloc_rel_start[], _reloc_rel_end[];
311     extern u32 _reloc_init_start[], _reloc_init_end[];
312     extern u8 code32init_start[], code32init_end[];
313
314     // Allocate space for init code.
315     u32 initsize = code32init_end - code32init_start;
316     u32 align = (u32)&_reloc_min_align;
317     void *dest = memalign_tmp(align, initsize);
318     if (!dest)
319         panic("No space for init relocation.\n");
320
321     // Copy code and update relocs (init absolute, init relative, and runtime)
322     dprintf(1, "Relocating init from %p to %p (size %d)\n"
323             , code32init_start, dest, initsize);
324     s32 delta = dest - (void*)code32init_start;
325     memcpy(dest, code32init_start, initsize);
326     updateRelocs(dest, _reloc_abs_start, _reloc_abs_end, delta);
327     updateRelocs(dest, _reloc_rel_start, _reloc_rel_end, -delta);
328     updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
329
330     // Call maininit() in relocated code.
331     void (*func)(void) = (void*)maininit + delta;
332     barrier();
333     func();
334 }
335
336 // Setup for code relocation and then call reloc_init
337 void VISIBLE32INIT
338 dopost(void)
339 {
340     HaveRunPost = 1;
341
342     // Detect ram and setup internal malloc.
343     qemu_cfg_port_probe();
344     ram_probe();
345     malloc_setup();
346
347     // Relocate initialization code and call maininit().
348     reloc_init();
349 }
350
351 // Entry point for Power On Self Test (POST) - the BIOS initilization
352 // phase.  This function makes the memory at 0xc0000-0xfffff
353 // read/writable and then calls dopost().
354 void VISIBLE32FLAT
355 handle_post(void)
356 {
357     debug_serial_setup();
358     dprintf(1, "Start bios (version %s)\n", VERSION);
359
360     // Enable CPU caching
361     setcr0(getcr0() & ~(CR0_CD|CR0_NW));
362
363     // Clear CMOS reboot flag.
364     outb_cmos(0, CMOS_RESET_CODE);
365
366     // Make sure legacy DMA isn't running.
367     init_dma();
368
369     // Check if we are running under Xen.
370     xen_probe();
371
372     // Allow writes to modify bios area (0xf0000)
373     make_bios_writable();
374
375     // Now that memory is read/writable - start post process.
376     dopost();
377 }