]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/boot_info-ia32.cpp
c994c926be530553d851c1b5145be2cb93065060
[l4.git] / kernel / fiasco / src / kern / ia32 / boot_info-ia32.cpp
1 /* IA32/AMD64 Specific Boot info */
2 INTERFACE[ia32,ux,amd64]:
3
4 #include "multiboot.h"
5 #include "types.h"
6
7
8 EXTENSION class Boot_info
9 {
10 public:
11
12   static Address mbi_phys();
13
14   static Multiboot_info *mbi_virt();
15 };
16
17
18 //-------------------------------------------------------------------------
19 INTERFACE[ia32,amd64]:
20
21 EXTENSION class Boot_info 
22 {
23 private:
24   static Address  _mbi_pa;
25   static unsigned _flag;
26   static unsigned _checksum_ro;
27   static unsigned _checksum_rw;
28   static Multiboot_info _kmbi;
29 };
30
31
32 //-------------------------------------------------------------------------
33 IMPLEMENTATION[ia32,ux,amd64]:
34
35 #include "config.h"
36 #include "mem_layout.h"
37
38 PUBLIC static inline NEEDS ["config.h","mem_layout.h"]
39 Address
40 Boot_info::kmem_start(Address mem_max)
41 {
42   Address end_addr = (mbi_virt()->mem_upper + 1024) << 10;
43   Address size, base;
44
45   if (end_addr > mem_max)
46     end_addr = mem_max;
47
48   size = kmemsize();
49   if (!size)
50     {
51       size = end_addr / 100 * Config::kernel_mem_per_cent;
52       if (size > Config::kernel_mem_max)
53         size = Config::kernel_mem_max;
54     }
55
56   base = end_addr - size & Config::PAGE_MASK;
57   if (Mem_layout::phys_to_pmem(base) < Mem_layout::Physmem)
58     base = Mem_layout::pmem_to_phys(Mem_layout::Physmem);
59
60   return base;
61 }
62
63
64 //-----------------------------------------------------------------------------
65 IMPLEMENTATION[ia32,amd64]:
66
67 #include <cassert>
68 #include <cstring>
69 #include <cstdlib>
70 #include "checksum.h"
71 #include "cmdline.h"
72 #include "mem_layout.h"
73
74 // these members needs to be initialized with some
75 // data to go into the data section and not into bss
76 Address  Boot_info::_mbi_pa        = 125;
77 unsigned Boot_info::_flag          = 3;
78 unsigned Boot_info::_checksum_ro   = 15;
79 unsigned Boot_info::_checksum_rw   = 16;
80
81 // initialized after startup cleaned out the bss
82
83 Multiboot_info Boot_info::_kmbi;
84
85
86 /// \defgroup pre init setup
87 /**
88  * The Boot_info object must be set up with these functions
89  * before Boot_info::init() is called!
90  * This can be done either in __main, if booted on hardware
91  * or in an initializer with a higher priority than BOOT_INFO_INIT_PRIO
92  * (e.g UX_STARTUP1_INIT_PRIO) if the kernel runs on software (FIASCO-UX)
93  */
94 //@{
95
96 PUBLIC inline static 
97 void Boot_info::set_flags(unsigned aflags)
98 {  _flag = aflags; }
99
100 PUBLIC inline static 
101 void Boot_info::set_checksum_ro(unsigned ro_cs)
102 {  _checksum_ro = ro_cs; }
103
104 PUBLIC inline static 
105 void Boot_info::set_checksum_rw(unsigned rw_cs)
106 {  _checksum_rw = rw_cs; }
107 //@}
108
109
110 IMPLEMENT
111 void
112 Boot_info::init()
113 {
114   // we assume that we run in 1:1 mapped mode
115   _kmbi = *(Multiboot_info *)mbi_phys();
116   Cmdline::init(_kmbi.flags & Multiboot_info::Cmdline 
117       ? reinterpret_cast<char*>(_kmbi.cmdline)
118       : "");
119 }
120
121 PUBLIC inline static 
122 unsigned
123 Boot_info::get_flags(void)
124 {
125   return _flag;
126 }
127
128 PUBLIC inline static 
129 unsigned
130 Boot_info::get_checksum_ro(void)
131 {
132   return _checksum_ro;
133 }
134
135 PUBLIC inline static 
136 unsigned
137 Boot_info::get_checksum_rw(void)
138 {
139   return _checksum_rw;
140 }
141
142 PUBLIC static
143 void
144 Boot_info::reset_checksum_ro(void)
145 {
146   set_checksum_ro(Checksum::get_checksum_ro());
147 }
148
149 PUBLIC inline static
150 void
151 Boot_info::set_mbi_phys(Address phys)
152 {
153   _mbi_pa = phys;
154 }
155
156 IMPLEMENT inline
157 Address
158 Boot_info::mbi_phys(void)
159 {
160   return _mbi_pa;
161 }
162
163 IMPLEMENT inline
164 Multiboot_info *
165 Boot_info::mbi_virt()
166 {
167   return &_kmbi;
168 }
169
170 PUBLIC static
171 unsigned long
172 Boot_info::kmemsize()
173 {
174   const char *c;
175
176   return (  (c = strstr(Cmdline::cmdline(), " -kmemsize="))
177           ||(c = strstr(Cmdline::cmdline(), " -kmemsize ")))
178     ? strtol(c+11, 0, 0) << 20
179     : 0;
180 }