/[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.4 by marcus, Tue Sep 9 21:43:12 2003 UTC revision 1.5 by marcus, Tue Sep 9 23:43:48 2003 UTC
# Line 21  Line 21 
21  #include <config.h>  #include <config.h>
22  #endif  #endif
23    
24    #include <alloca.h>
25    
26  #include "wortel.h"  #include "wortel.h"
27    
28    
# Line 63  load_components (void) Line 65  load_components (void)
65  static void  static void
66  start_components (void)  start_components (void)
67  {  {
68      l4_word_t min_page_size = getpagesize ();
69    l4_word_t ret;    l4_word_t ret;
70    l4_word_t control;    l4_word_t control;
71    l4_msg_t msg;    l4_msg_t msg;
72    l4_msg_tag_t msg_tag;    l4_msg_tag_t msg_tag;
73    unsigned int io_map = 0;    
74      if (physmem.low & (min_page_size - 1))
75        panic ("physmem is not page aligned on this architecture");
76      if (physmem.low > physmem.high)
77        panic ("physmem has invalid memory range");
78      if (physmem.ip < physmem.low || physmem.ip > physmem.high)
79        panic ("physmem has invalid IP");
80    
81    /* Thread nr is next available after rootserver thread nr,    /* Thread nr is next available after rootserver thread nr,
82       version part is 2 (rootserver is 1).  */       version part is 2 (rootserver is 1).  */
# Line 105  start_components (void) Line 114  start_components (void)
114    l4_msg_load (&msg);    l4_msg_load (&msg);
115    msg_tag = l4_send (physmem_server);    msg_tag = l4_send (physmem_server);
116    if (l4_ipc_failed (msg_tag))    if (l4_ipc_failed (msg_tag))
117      panic ("Sending startup message to physmemserver thread failed: %u",      panic ("Sending startup message to physmem thread failed: %u",
118             l4_error_code ());             l4_error_code ());
119    
120      {
121        l4_fpage_t *fpages;
122        unsigned int nr_fpages = 0;
123        l4_word_t start = physmem.low;
124        l4_word_t end = (physmem.high + min_page_size) & ~(min_page_size - 1);
125        l4_word_t region;
126    
127        /* We want to grant all the memory for the physmem binary image
128           with the first page fault, but we might have to send several
129           fpages.  So we first create a list of all fpages we need, then
130           we serve one after another, providing the one containing the
131           fault address last.  */
132    
133        /* A page-aligned region of size up to 2^k * min_page_size can be
134           covered by k fpages at most (proof by induction).  At this
135           point, END is at least one MIN_PAGE_SIZE larger than START.  */
136        region = (end - start) / min_page_size;
137        while (region > 0)
138          {
139            nr_fpages++;
140            region >>= 1;
141          }
142        fpages = alloca (sizeof (l4_fpage_t) * nr_fpages);
143    
144        nr_fpages = 0;
145        while (start < end)
146          {
147            fpages[nr_fpages] = l4_fpage (start, end - start);
148            start += l4_size (fpages[nr_fpages]);
149            nr_fpages++;
150          }
151    
152        /* Now serve page requests.  */
153        while (nr_fpages)
154          {
155            l4_grant_item_t grant_item;
156            l4_fpage_t fpage;
157            l4_word_t addr;
158            unsigned int i;
159    
160            msg_tag = l4_receive (physmem_server);
161            if (l4_ipc_failed (msg_tag))
162              panic ("Receiving messages from physmem thread failed: %u",
163                     (l4_error_code () >> 1) & 0x7);
164            if ((l4_label (msg_tag) >> 4) != 0xffe)
165              panic ("Message from physmem thread is not a page fault");
166            l4_msg_store (msg_tag, &msg);
167            if (l4_untyped_words (msg_tag) != 2 || l4_typed_words (msg_tag) != 0)
168              panic ("Invalid format of page fault message");
169            addr = l4_msg_word (&msg, 0);
170            if (addr != physmem.ip)
171              panic ("Page fault at unexpected address 0x%x (expected 0x%x)",
172                     addr, physmem.ip);
173    
174            if (nr_fpages == 1)
175              i = 0;
176            else
177              for (i = 0; i < nr_fpages; i++)
178                if (addr < l4_address (fpages[i])
179                    || addr >= l4_address (fpages[i]) + l4_size (fpages[i]))
180                  break;
181            if (i == nr_fpages)
182              panic ("Could not find suitable fpage");
183    
184            fpage = l4_fpage_add_rights (fpages[i], l4_fully_accessible);
185            debug ("Granting Fpage: 0x%x - 0x%x\n", l4_address (fpage),
186                   l4_address (fpage) + l4_size (fpage));
187    
188            if (i != 0)
189              fpages[i] = fpages[nr_fpages - 1];
190            nr_fpages--;
191    
192            /* First we have to request the fpage from sigma0.  */
193            l4_accept (l4_map_grant_items (l4_complete_address_space));
194            l4_msg_clear (&msg);
195            l4_set_msg_label (&msg, 0xffa0);
196            l4_msg_append_word (&msg, fpage.raw);
197            l4_msg_append_word (&msg, L4_DEFAULT_MEMORY);
198            l4_msg_load (&msg);
199            msg_tag = l4_call (l4_global_id (l4_thread_user_base (), 1));
200            if (l4_ipc_failed (msg_tag))
201              panic ("sigma0 request failed during %s: %u",
202                     l4_error_code () & 1 ? "receive" : "send",
203                     (l4_error_code () >> 1) & 0x7);
204            if (l4_untyped_words (msg_tag) != 0
205                || l4_typed_words (msg_tag) != 2)
206              panic ("Invalid format of sigma0 reply");
207            l4_msg_store (msg_tag, &msg);
208            if (l4_msg_word (&msg, 1) == l4_nilpage.raw)
209              panic ("sigma0 rejected mapping");
210    
211            /* Now we can grant the mapping to the physmem server.
212               FIXME: Should use the fpage returned by sigma0.  */
213            l4_msg_clear (&msg);
214            l4_set_msg_label (&msg, 0);
215            /* FIXME: Keep track of mappings already provided.  Possibly
216               map text section rx and data rw.  */
217            grant_item = l4_grant_item (fpage, l4_address (fpage));
218            l4_msg_append_grant_item (&msg, grant_item);
219            l4_msg_load (&msg);
220            l4_reply (physmem_server);
221          }
222      }
223    
224    do    do
225      {      {
226        l4_word_t label;        l4_word_t label;
# Line 117  start_components (void) Line 230  start_components (void)
230          panic ("Receiving messages from physmemserver thread failed: %u",          panic ("Receiving messages from physmemserver thread failed: %u",
231                 (l4_error_code () >> 1) & 0x7);                 (l4_error_code () >> 1) & 0x7);
232    
       /* FIXME: Check sender, etc.  */  
   
233        label = l4_label (msg_tag);        label = l4_label (msg_tag);
234        l4_msg_store (msg_tag, &msg);        l4_msg_store (msg_tag, &msg);
       if ((label >> 4) == 0xffe)  
         {  
           l4_grant_item_t grant_item;  
           l4_fpage_t fpage;  
           l4_word_t addr;  
235    
           /* This is a page fault.  */  
           if (l4_untyped_words (msg_tag) != 2  
               || l4_typed_words (msg_tag) != 0)  
             panic ("Invalid format of page fault msg");  
   
           if (!io_map)  
             {  
               l4_map_item_t map_item;  
   
               /* FIXME: This is a hack.  The first time we map the I/O  
                  ports into the task.  The kernel will repeat the page  
                  fault.  */  
               io_map = 1;  
   
               /* Now we can grant the mapping to the physmem server.  
                  FIXME: Should use the fpage returned by sigma0.  */  
               l4_msg_clear (&msg);  
               l4_set_msg_label (&msg, 0);  
               /* FIXME: Try to use largest fpage possible for the image.  
                  Keep track of mappings already provided.  Possibly map  
                  text section rx and data rw.  */  
               map_item = l4_map_item (l4_fpage_add_rights  
                                           (l4_io_fpage (0, 10),  
                                            l4_fully_accessible), 0);  
               l4_msg_append_map_item (&msg, map_item);  
               l4_msg_load (&msg);  
               l4_reply (physmem_server);  
               continue;  
             }  
   
           addr = l4_msg_word (&msg, 0) & ~((1 << 12) - 1);  
           fpage = l4_fpage_add_rights (l4_fpage_log2 (addr, 12),  
                                        l4_fully_accessible);  
           debug ("Serving Page Fault: %c%c%c at 0x%x (IP: 0x%x)\n",  
                  label & 4 ? 'x' : '-', label & 2 ? 'w' : '-',  
                  label & 1 ? 'r' : '-', addr,  
                  l4_msg_word (&msg, 1));  
   
           /* First we have to request the fpage from sigma0.  */  
           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);  
           if (l4_msg_word (&msg, 1) == l4_nilpage.raw)  
             panic ("sigma0 rejected mapping");  
   
           /* Now we can grant the mapping to the physmem server.  
              FIXME: Should use the fpage returned by sigma0.  */  
           l4_msg_clear (&msg);  
           l4_set_msg_label (&msg, 0);  
           /* FIXME: Try to use largest fpage possible for the image.  
              Keep track of mappings already provided.  Possibly map  
              text section rx and data rw.  */  
           grant_item = l4_grant_item (fpage, addr);  
           l4_msg_append_grant_item (&msg, grant_item);  
           l4_msg_load (&msg);  
         }  
236  #define WORTEL_MSG_PUTCHAR 1  #define WORTEL_MSG_PUTCHAR 1
237        else if (label == WORTEL_MSG_PUTCHAR)        if (label == WORTEL_MSG_PUTCHAR)
238          {          {
239            int chr;            int chr;
240    
# Line 212  start_components (void) Line 250  start_components (void)
250          }          }
251        else        else
252          panic ("Invalid message with tag 0x%x", msg_tag);          panic ("Invalid message with tag 0x%x", msg_tag);
   
       l4_reply (physmem_server);  
253      }      }
254    while (1);    while (1);
255  }  }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

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