/[hurd]/hurd-l4/wortel/wortel.c
ViewVC logotype

Diff of /hurd-l4/wortel/wortel.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by marcus, Tue Sep 16 00:42:17 2003 UTC revision 1.10 by marcus, Tue Sep 16 19:24:05 2003 UTC
# Line 25  Line 25 
25  #include <alloca.h>  #include <alloca.h>
26    
27  #include "wortel.h"  #include "wortel.h"
28    #include "sigma0.h"
29    
30    
31  /* The program name.  */  /* The program name.  */
# Line 35  l4_word_t wortel_start; Line 36  l4_word_t wortel_start;
36  l4_word_t wortel_end;  l4_word_t wortel_end;
37    
38    
39    /* Unused memory.  These fpages mark memory which we needed at some
40       time, but don't need anymore.  It can be granted to the physical
41       memory server at startup.  This includes architecture dependent
42       boot data as well as the physical memory server module.  */
43    #define MAX_UNUSED_FPAGES 32
44    l4_fpage_t wortel_unused_fpages[MAX_UNUSED_FPAGES];
45    unsigned int wortel_unused_fpages_count;
46    
47    
48  /* Room for the arguments.  1 KB is a cramped half-screen full, which  /* Room for the arguments.  1 KB is a cramped half-screen full, which
49     should be more than enough.  */     should be more than enough.  */
50  char mods_args[1024];  char mods_args[1024];
# Line 140  make_fpages (l4_word_t start, l4_word_t Line 150  make_fpages (l4_word_t start, l4_word_t
150  }  }
151    
152    
 /* Request the fpage FPAGE from sigma0.  */  
 static void  
 sigma0_get_fpage (l4_fpage_t fpage)  
 {  
   l4_msg_t msg;  
   l4_msg_tag_t msg_tag;  
   l4_map_item_t map_item;  
   
   l4_accept (l4_map_grant_items (l4_complete_address_space));  
   l4_msg_clear (&msg);  
   l4_set_msg_label (&msg, 0xffa0);  
   l4_msg_append_word (&msg, fpage.raw);  
   l4_msg_append_word (&msg, L4_DEFAULT_MEMORY);  
   l4_msg_load (&msg);  
   msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1));  
   if (l4_ipc_failed (msg_tag))  
     panic ("sigma0 request failed during %s: %u",  
            l4_error_code () & 1 ? "receive" : "send",  
            (l4_error_code () >> 1) & 0x7);  
   if (l4_untyped_words (msg_tag) != 0  
       || l4_typed_words (msg_tag) != 2)  
     panic ("Invalid format of sigma0 reply");  
   l4_msg_store (msg_tag, &msg);  
   l4_msg_get_map_item (&msg, 0, &map_item);  
   if (map_item.send_fpage.raw == l4_nilpage.raw)  
     panic ("sigma0 rejected mapping");  
 }  
   
 /* Request an fpage of the size 2^SIZE from sigma0.  */  
 static l4_fpage_t  
 sigma0_get_any (unsigned int size)  
 {  
   l4_msg_t msg;  
   l4_msg_tag_t msg_tag;  
   l4_map_item_t map_item;  
   l4_fpage_t fpage = l4_fpage_add_rights (l4_fpage_log2 (-1, size),  
                                           l4_fully_accessible);  
   
   l4_accept (l4_map_grant_items (l4_complete_address_space));  
   l4_msg_clear (&msg);  
   l4_set_msg_label (&msg, 0xffa0);  
   debug ("Request 0x%x\n", fpage.raw);  
   l4_msg_append_word (&msg, fpage.raw);  
   l4_msg_append_word (&msg, L4_DEFAULT_MEMORY);  
   l4_msg_load (&msg);  
   msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1));  
   if (l4_ipc_failed (msg_tag))  
     panic ("sigma0 request failed during %s: %u",  
            l4_error_code () & 1 ? "receive" : "send",  
            (l4_error_code () >> 1) & 0x7);  
   if (l4_untyped_words (msg_tag) != 0  
       || l4_typed_words (msg_tag) != 2)  
     panic ("Invalid format of sigma0 reply");  
   l4_msg_store (msg_tag, &msg);  
   l4_msg_get_map_item (&msg, 0, &map_item);  
   debug ("Got 0x%x\n", map_item.send_fpage.raw);  
   return map_item.send_fpage;  
 }  
   
153    
154  static void  static void
155  load_components (void)  load_components (void)
# Line 207  load_components (void) Line 158  load_components (void)
158    unsigned int nr_fpages;    unsigned int nr_fpages;
159    l4_word_t min_page_size = getpagesize ();    l4_word_t min_page_size = getpagesize ();
160    unsigned int i;    unsigned int i;
161      l4_word_t addr;
162      l4_word_t end_addr;
163    
164    /* One issue we have to solve is to make sure that when the physical    /* One issue we have to solve is to make sure that when the physical
165       memory server requests all the available physical pages, we know       memory server requests all the available physical fpages, we know
166       which pages we can give to it, and which we can't.  This can be       which fpages we can give to it, and which we can't.  This can be
167       left to sigma0, as long as we request all pages from sigma0 we       left to sigma0, as long as we request all fpages from sigma0 we
168       can't give to the physical memory server up-front.       can't give to the physical memory server up-front.
169    
170       We do this in several steps: First, we copy all of the startup       We do this in several steps: First, we copy all of the startup
171       information to memory that is part of the wortel binary image       information to memory that is part of the wortel binary image
172       itself.  This is done by the architecture dependant       itself.  This is done by the architecture dependent
173       find_components function.  Then we request all of our own memory,       find_components function.  Then we request all of our own memory,
174       and all the memory needed for the physical memory server image       all the memory for our modules, and finally all the memory needed
175       (at its destination address), and all the memory for each module       for the physical memory server image (at its destination
176       (at their corresponding load addresses).  */       address).  */
177    
178    if (wortel_start & (min_page_size - 1))    if (wortel_start & (min_page_size - 1))
179      panic ("%s does not start on a page boundary", program_name);      panic ("%s does not start on a page boundary", program_name);
180    loader_add_region (program_name, wortel_start, wortel_end);    loader_add_region (program_name, wortel_start, wortel_end);
181    nr_fpages = make_fpages (wortel_start, wortel_end, fpages);  
182    while (nr_fpages--)    /* We must request our own memory using the smallest fpages
183      sigma0_get_fpage (fpages[nr_fpages]);       possible, because we already have some memory mapped due to page
184         faults, and fpages are specified as inseparable objects.  */
185      for (addr = wortel_start; addr < wortel_end; addr += min_page_size)
186        sigma0_get_fpage (l4_fpage (addr, min_page_size));
187    
188    /* First protect all pages covered by the modules.  This will also    /* First protect all pages covered by the modules.  This will also
189       show if each module starts (and ends) on its own page.  */       show if each module starts (and ends) on its own page.  Request
190         all memory for all modules.  Although we can release the memory
191         for the physmem module later on, we have to touch it anyway to
192         load it to its destination address, and requesting the fpages now
193         allows us to choose how we want to split up the module in
194         (inseparable) fpages.  */
195    for (i = 0; i < mods_count; i++)    for (i = 0; i < mods_count; i++)
196      {      {
197        if (mods[i].start & (min_page_size - 1))        if (mods[i].start & (min_page_size - 1))
198          panic ("Module %s does not start on a page boundary", mods[i].name);          panic ("Module %s does not start on a page boundary", mods[i].name);
199        loader_add_region (mods[i].name, mods[i].start, mods[i].end);        loader_add_region (mods[i].name, mods[i].start, mods[i].end);
200    
201          nr_fpages = make_fpages (mods[i].start, mods[i].end, fpages);
202          if (i == MOD_PHYSMEM)
203            {
204              /* The physical memory server module memory can be recycled
205                 later.  */
206              if (nr_fpages + wortel_unused_fpages_count > MAX_UNUSED_FPAGES)
207                panic ("not enough room in unused fpages list for physmem-mod");
208              memcpy (&wortel_unused_fpages[wortel_unused_fpages_count],
209                      fpages, sizeof (l4_fpage_t) * nr_fpages);
210              wortel_unused_fpages_count += nr_fpages;
211            }
212    
213          while (nr_fpages--)
214            sigma0_get_fpage (fpages[nr_fpages]);
215      }      }
216    
217      /* Because loading the physical memory server to its destination
218         address will touch the destination memory, which we later want to
219         grant to the physical memory server using (inseparable) fpages,
220         we request the desired fpages up-front.  */
221      loader_elf_dest ("physmem-server", mods[MOD_PHYSMEM].start,
222                       mods[MOD_PHYSMEM].end, &addr, &end_addr);
223      nr_fpages = make_fpages (addr, end_addr, fpages);
224      while (nr_fpages--)
225        sigma0_get_fpage (fpages[nr_fpages]);
226    
227    /* Now load the physical memory server to its destination    /* Now load the physical memory server to its destination
228       address.  */       address.  */
229    if (!mods[MOD_PHYSMEM].start)    addr = mods[MOD_PHYSMEM].start;
230      end_addr = mods[MOD_PHYSMEM].end;
231      if (!addr)
232      panic ("No physical memory server found");      panic ("No physical memory server found");
233    loader_elf_load ("physmem-server", mods[MOD_PHYSMEM].start,    loader_elf_load ("physmem-server", addr, end_addr,
                    mods[MOD_PHYSMEM].end,  
234                     &mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end,                     &mods[MOD_PHYSMEM].start, &mods[MOD_PHYSMEM].end,
235                     &mods[MOD_PHYSMEM].ip);                     &mods[MOD_PHYSMEM].ip);
236    loader_remove_region ("physmem-mod");    loader_remove_region ("physmem-mod");
   
   /* Finally we can request all the memory for the physical memory  
      server and all other modules from sigma0.  This will register the  
      memory as taken by us, and the memory will not be returned by any  
      future request.  */  
   for (i = 0; i < mods_count; i++)  
     {  
       nr_fpages = make_fpages (mods[i].start, mods[i].end, fpages);  
       while (nr_fpages--)  
         sigma0_get_fpage (fpages[nr_fpages]);  
     }  
237  }  }
238    
239    
# Line 276  start_components (void) Line 252  start_components (void)
252        || mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end)        || mods[MOD_PHYSMEM].ip > mods[MOD_PHYSMEM].end)
253      panic ("physmem has invalid IP");      panic ("physmem has invalid IP");
254    
   
255    cap_id = wortel_add_user (2);    cap_id = wortel_add_user (2);
256    /* FIXME: Pass cap_id to physmem.  */    /* FIXME: Pass cap_id to physmem.  */
257    /* Thread nr is next available after rootserver thread nr,    /* Thread nr is next available after rootserver thread nr,
# Line 393  serve_bootstrap_requests (void) Line 368  serve_bootstrap_requests (void)
368    /* The size of the region that we are currently trying to allocate    /* The size of the region that we are currently trying to allocate
369       for GET_MEM requests.  If this is smaller than 2^10, no more       for GET_MEM requests.  If this is smaller than 2^10, no more
370       memory is available.  */       memory is available.  */
371    unsigned int get_mem_size = 12;    unsigned int get_mem_size = sizeof (l4_word_t) * 8 - 1;
372    
373      while (get_mem_size >= 10
374             && ! ((1 << get_mem_size) & l4_page_size_mask ()))
375        get_mem_size--;
376      
377    do    do
378      {      {
379        l4_thread_id_t from;        l4_thread_id_t from;
# Line 438  serve_bootstrap_requests (void) Line 417  serve_bootstrap_requests (void)
417            if (get_mem_size < 10)            if (get_mem_size < 10)
418              panic ("physmem server does not stop requesting memory");              panic ("physmem server does not stop requesting memory");
419    
420            do            /* Give out the memory.  First our unused fpages, then the
421              {               fpages we can get from sigma0.  */
422                fpage = sigma0_get_any (get_mem_size);            if (wortel_unused_fpages_count)
423                if (fpage.raw == l4_nilpage.raw)              fpage = wortel_unused_fpages[--wortel_unused_fpages_count];
424                  get_mem_size--;            else
425              }              do
426            while (fpage.raw == l4_nilpage.raw && get_mem_size >= 10);                {
427                    fpage = sigma0_get_any (get_mem_size);
428                    if (fpage.raw == l4_nilpage.raw)
429                      {
430                        get_mem_size--;
431                        while (get_mem_size >= 10
432                               && ! ((1 << get_mem_size) & l4_page_size_mask ()))
433                          get_mem_size--;
434                      }
435                  }
436                while (fpage.raw == l4_nilpage.raw && get_mem_size >= 10);
437    
438            grant_item = l4_grant_item (fpage, l4_address (fpage));            grant_item = l4_grant_item (fpage, l4_address (fpage));
439            l4_msg_clear (&msg);            l4_msg_clear (&msg);

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26