]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/kip_init-ia32.cpp
update
[l4.git] / kernel / fiasco / src / kern / ia32 / kip_init-ia32.cpp
1 INTERFACE [ia32,ux,amd64]:
2
3 #include "initcalls.h"
4 #include "types.h"
5
6 class Cpu;
7
8 class Kip_init
9 {
10 public:
11   /**
12    * Insert memory descriptor for the Kmem region and finish the memory
13    * info field.
14    * @post no more memory descriptors may be added
15    */
16   static void setup_kmem_region (Address kmem_base, Address kmem_size);
17 };
18
19 IMPLEMENTATION [ia32,ux,amd64]:
20
21 #include <cstring>
22 #include "boot_info.h"
23 #include "config.h"
24 #include "cpu.h"
25 #include "div32.h"
26 #include "kip.h"
27 #include "kmem.h"
28 #include "panic.h"
29
30
31 /** KIP initialization. */
32 PUBLIC static FIASCO_INIT
33 void
34 Kip_init::init_freq(Cpu const &cpu)
35 {
36   Kip::k()->frequency_cpu       = div32(cpu.frequency(), 1000);
37 }
38
39
40 namespace KIP_namespace
41 {
42   enum
43   {
44     Num_mem_descs = 50,
45     Max_len_version = 512,
46
47     Size_mem_descs = sizeof(Mword) * 2 * Num_mem_descs,
48   };
49
50   struct KIP
51   {
52     Kip kip;
53     char mem_descs[Size_mem_descs];
54   };
55
56   KIP my_kernel_info_page asm("my_kernel_info_page") __attribute__((section(".kernel_info_page"))) =
57     {
58       {
59         /* 00/00  */ L4_KERNEL_INFO_MAGIC,
60                      Config::kernel_version_id,
61                      (Size_mem_descs + sizeof(Kip)) >> 4,
62                      {}, 0, {},
63         /* 10/20  */ 0, 0, 0, 0,
64         /* 20/40  */ 0, 0, {},
65         /* 30/60  */ 0, 0, {},
66         /* 40/80  */ 0, 0, {},
67         /* 50/A0  */ 0, (sizeof(Kip) << (sizeof(Mword)*4)) | Num_mem_descs, 0, 0,
68         /* 60/C0  */ 0, 0, {},
69         /* A0/140 */ 0, 0,
70         /* B0/160 */ 0, 0, 0,
71         /* C0/180 */ {},
72         /* D0/1A0 */ {},
73         /* E0/1C0 */ 0, 0, {},
74         /* F0/1D0 */ { },
75       },
76       {}
77     };
78 };
79
80 PUBLIC static FIASCO_INIT
81 //IMPLEMENT
82 void Kip_init::init()
83 {
84   Kip *kinfo = reinterpret_cast<Kip*>(&KIP_namespace::my_kernel_info_page);
85   Kip::init_global_kip(kinfo);
86
87   Kip::k()->clock = 0;
88   Kip::k()->sched_granularity = Config::scheduler_granularity;
89
90   setup_user_virtual();
91
92   reserve_amd64_hole();
93
94
95   Mem_desc *md = kinfo->mem_descs();
96   Mem_desc *end = md + kinfo->num_mem_descs();
97
98   extern char _boot_sys_start[];
99   extern char _boot_sys_end[];
100
101   for (;md != end; ++md)
102     {
103       if (md->type() != Mem_desc::Reserved || md->is_virtual())
104         continue;
105
106       if (md->start() == (Address)_boot_sys_start
107           && md->end() == (Address)_boot_sys_end - 1)
108         md->type(Mem_desc::Undefined);
109
110       if (md->contains(Kmem::kernel_image_start())
111           && md->contains(Kmem::kcode_end()-1))
112         {
113           *md = Mem_desc(Kmem::kernel_image_start(), Kmem::kcode_end() -1,
114               Mem_desc::Reserved);
115         }
116     }
117 }
118
119
120 IMPLEMENTATION [amd64]:
121
122 PRIVATE static inline NOEXPORT NEEDS["kip.h"]
123 void
124 Kip_init::reserve_amd64_hole()
125 {
126   enum { Trigger = 0x0000800000000000UL };
127   Kip::k()->add_mem_region(Mem_desc(Trigger, ~Trigger, 
128                            Mem_desc::Reserved, true));
129 }
130
131 IMPLEMENTATION [!amd64]:
132
133 PRIVATE static inline NOEXPORT
134 void
135 Kip_init::reserve_amd64_hole()
136 {}
137
138 IMPLEMENTATION [!ux]:
139
140 PUBLIC static FIASCO_INIT
141 void
142 Kip_init::setup_user_virtual()
143 {
144   Kip *kinfo = reinterpret_cast<Kip*>(&KIP_namespace::my_kernel_info_page);
145   kinfo->add_mem_region(Mem_desc(0, Mem_layout::User_max - 1,
146                         Mem_desc::Conventional, true));
147 }
148
149 IMPLEMENTATION [ux]:
150
151 #include "boot_info.h"
152 #include "multiboot.h"
153 #include <cstring>
154
155 PUBLIC static FIASCO_INIT
156 void
157 Kip_init::setup_user_virtual()
158 {
159   Kip *kinfo = reinterpret_cast<Kip*>(&KIP_namespace::my_kernel_info_page);
160   // start at 64k because on some distributions (like Ubuntu 8.04) it's
161   // not allowed to map below a certain treshold
162   kinfo->add_mem_region(Mem_desc(Boot_info::min_mappable_address(),
163                                  Mem_layout::User_max - 1,
164                                  Mem_desc::Conventional, true));
165 }
166
167 PUBLIC static  FIASCO_INIT
168 void
169 Kip_init::setup_ux()
170 {
171   Kip::init_global_kip((Kip*)&KIP_namespace::my_kernel_info_page);
172
173   Multiboot_module *mbm = reinterpret_cast <Multiboot_module*>
174     (Kmem::phys_to_virt (Boot_info::mbi_virt()->mods_addr));
175   Kip::k()->user_ptr = (unsigned long)(Boot_info::mbi_phys());
176   Mem_desc *m = Kip::k()->mem_descs();
177
178   // start at 64k because on some distributions (like Ubuntu 8.04) it's
179   // not allowed to map below a certain treshold
180   *(m++) = Mem_desc(Boot_info::min_mappable_address(),
181                     ((Boot_info::mbi_virt()->mem_upper + 1024) << 10) - 1,
182                     Mem_desc::Conventional);
183   *(m++) = Mem_desc(Kmem::kernel_image_start(), Kmem::kcode_end() - 1, 
184       Mem_desc::Reserved);
185
186   mbm++;
187   Kip::k()->sigma0_ip           = mbm->reserved;
188   if ((Boot_info::sigma0_start() & Config::PAGE_MASK)
189       != ((Boot_info::sigma0_end() + (Config::PAGE_SIZE-1))
190            & Config::PAGE_MASK))
191     *(m++) = Mem_desc(Boot_info::sigma0_start() & Config::PAGE_MASK,
192                       ((Boot_info::sigma0_end() + (Config::PAGE_SIZE-1))
193                        & Config::PAGE_MASK) - 1,
194                       Mem_desc::Reserved);
195
196   mbm++;
197   Kip::k()->root_ip             = mbm->reserved;
198   if ((Boot_info::root_start() & Config::PAGE_MASK)
199       != ((Boot_info::root_end() + (Config::PAGE_SIZE-1)) & Config::PAGE_MASK))
200     *(m++) = Mem_desc(Boot_info::root_start() & Config::PAGE_MASK,
201                       ((Boot_info::root_end() + (Config::PAGE_SIZE-1))
202                        & Config::PAGE_MASK) - 1,
203                       Mem_desc::Bootloader);
204
205   unsigned long version_size = 0;
206   for (char const *v = Kip::k()->version_string(); *v; )
207     {
208       unsigned l = strlen(v) + 1;
209       v += l;
210       version_size += l;
211     }
212
213   version_size += 2;
214
215   Kip::k()->vhw_offset = (Kip::k()->offset_version_strings << 4) + version_size;
216
217   Kip::k()->vhw()->init();
218
219   unsigned long mod_start = ~0UL;
220   unsigned long mod_end = 0;
221
222   mbm++;
223
224   if (Boot_info::mbi_virt()->mods_count <= 3)
225     return;
226
227   for (unsigned i = 0; i < Boot_info::mbi_virt()->mods_count - 3; ++i)
228     {
229       if (mbm[i].mod_start < mod_start)
230         mod_start = mbm[i].mod_start;
231
232       if (mbm[i].mod_end > mod_end)
233         mod_end = mbm[i].mod_end;
234     }
235
236   mod_start &= ~(Config::PAGE_SIZE - 1);
237   mod_end = (mod_end + Config::PAGE_SIZE -1) & ~(Config::PAGE_SIZE - 1);
238
239   if (mod_end > mod_start)
240     *(m++) = Mem_desc(mod_start, mod_end - 1, Mem_desc::Bootloader);
241
242   *(m++) = Mem_desc(Boot_info::mbi_phys(),
243       ((Boot_info::mbi_phys() + Boot_info::mbi_size()
244        + Config::PAGE_SIZE-1) & Config::PAGE_MASK) -1,
245       Mem_desc::Bootloader);
246 }