Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / libopenbios / bootcode_load.c
1 /* 
2  * Raw bootcode loader (CHRP/Apple %BOOT)
3  * Written by Mark Cave-Ayland 2013
4  */
5
6 #include "config.h"
7 #include "kernel/kernel.h"
8 #include "libopenbios/bindings.h"
9 #include "libopenbios/bootcode_load.h"
10 #include "libc/diskio.h"
11 #include "drivers/drivers.h"
12 #define printf printk
13 #define debug printk
14
15
16 int 
17 bootcode_load(ihandle_t dev)
18 {
19     int retval = -1, count = 0, fd;
20     unsigned long bootcode, loadbase, entry, size, offset;
21     ihandle_t bootcode_info;
22
23     /* Mark the saved-program-state as invalid */
24     feval("0 state-valid !");
25
26     fd = open_ih(dev);
27     if (fd == -1) {
28         goto out;
29     }
30
31     /* If we don't have the get-bootcode-info word then we don't support
32        loading bootcode via %BOOT */
33     bootcode_info = find_ih_method("get-bootcode-info", dev);
34     if (!bootcode_info) {
35         goto out;
36     }
37     
38     /* Default to loading at load-base */
39     fword("load-base");
40     loadbase = POP();
41     entry = loadbase;
42     size = 0;
43     
44 #ifdef CONFIG_PPC
45     /*
46      * Apple OF does not honor load-base and instead uses pmBootLoad
47      * value from the boot partition descriptor.
48      *
49      * Tested with:
50      *   a debian image with QUIK installed
51      *   a debian image with iQUIK installed (https://github.com/andreiw/quik)
52      *   an IQUIK boot floppy
53      *   a NetBSD boot floppy (boots stage 2)
54      */
55     if (is_apple()) {
56         PUSH(bootcode_info);
57         fword("execute");
58
59         loadbase = POP();
60         entry = POP();
61         size = POP();
62     }
63 #endif
64     
65     bootcode = loadbase;
66     offset = 0;
67     
68     while(1) {
69         if (seek_io(fd, offset) == -1)
70             break;
71         count = read_io(fd, (void *)bootcode, 512);
72         offset += count;
73         bootcode += count;
74     }
75
76     /* If we didn't read anything then exit */
77     if (!count) {
78         goto out;
79     }
80
81     /* Use proper file size if we got it from bootcode info */
82     if (size == 0) {
83         size = offset;
84     }
85     
86     /* Initialise saved-program-state */
87     PUSH(entry);
88     feval("saved-program-state >sps.entry !");
89     PUSH(size);
90     feval("saved-program-state >sps.file-size !");
91     feval("bootcode saved-program-state >sps.file-type !");
92
93     feval("-1 state-valid !");
94
95 out:
96     close_io(fd);
97     return retval;
98 }
99