示例#1
0
/**
 * Map RAM.
 *
 * \param pager  pager implementing Sigma0 protocol
 * \return   #0  on success
 *          -#L4SIGMA0_NOTALIGNED phys, virt, or size not aligned
 *          -#L4SIGMA0_IPCERROR   IPC error
 *          -#L4SIGMA0_NOFPAGE    no fpage received
 */
L4_CV int
l4sigma0_map_mem(l4_cap_idx_t pager,
                 l4_addr_t phys, l4_addr_t virt, l4_addr_t size)
{
    l4_addr_t    d = L4_SUPERPAGESIZE;
    unsigned     l = L4_LOG2_SUPERPAGESIZE;
    l4_msgtag_t  tag;
    int error;
    l4_utcb_t *utcb = l4_utcb();

    if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1)))
    {
        l = L4_LOG2_PAGESIZE;
        d = L4_PAGESIZE;
    }

    if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1)))
        return -L4SIGMA0_NOTALIGNED;

    for (; size>0; phys+=d, size-=d, virt+=d)
    {
        do
        {
            l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
            l4_buf_regs_t *b = l4_utcb_br_u(utcb);
            tag = l4_msgtag(L4_PROTO_SIGMA0, 2, 0, 0);
            m->mr[0] = SIGMA0_REQ_FPAGE_RAM;
            m->mr[1] = l4_fpage(phys, l, L4_FPAGE_RWX).raw;

            b->bdr   = 0;
            b->br[0] = L4_ITEM_MAP;
            b->br[1] = l4_fpage(virt, l, L4_FPAGE_RWX).raw;
            tag = l4_ipc_call(pager, utcb, tag, L4_IPC_NEVER);
            if (l4_msgtag_has_error(tag))
                error = l4_utcb_tcr_u(utcb)->error;
            else
                error = 0;
        }
        while (error == L4_IPC_SECANCELED || error == L4_IPC_SEABORTED);

        if (error)
            return -L4SIGMA0_IPCERROR;

        if (l4_msgtag_items(tag) < 1)
            return -L4SIGMA0_NOFPAGE;
    }

    return 0;
}
示例#2
0
文件: libide.c 项目: B-Rich/hazelnut
/*
 * Function ide_write (drive, sec, buf, length)
 *
 *    Invokes an IPC to the IDE driver.  The buffer is mapped read-
 *    only to the driver, and the driver unmaps the buffer prior to
 *    sending the reply IPC.
 *
 */
int ide_write(dword_t drive, dword_t sec, void *buf, dword_t length)
{
    l4_msgdope_t result;
    dword_t dw0, dw1, dw2;
    l4_fpage_t fp;
    l4_idearg_t arg;
    int r;

    length = (length + L4_IDE_SECTOR_SIZE-1) & ~(L4_IDE_SECTOR_SIZE-1);

    arg.args.pos = sec;
    arg.args.length = length / L4_IDE_SECTOR_SIZE;
    arg.args.drive = drive;
    arg.args.write = 1;

    /* Create fpage that contains the buffer. */
    dw0 = (dword_t) buf & PAGE_MASK;
    dw1 = ((dword_t) buf + length + PAGE_SIZE-1) & PAGE_MASK;
    for ( r = PAGE_BITS-1, dw2 = (dw1-dw0) >> PAGE_BITS;
	  dw2 > 0;
	  dw2 >>= 1, r++ ) {}
    fp = l4_fpage(dw0, r, 0, 0);

    r = l4_ipc_call(idedrv_id,
		    (void *) 2, /* Map fpage */
		    (dword_t) buf, (dword_t) fp.fpage, (dword_t) arg.raw,
		    (void *) 0,
		    &dw0, &dw1, &dw2,
		    L4_IPC_NEVER, &result);

    return r;
}
示例#3
0
static void l4x_flush_page(struct mm_struct *mm,
                           unsigned long address,
                           unsigned long vaddr,
                           int size,
                           unsigned long flush_rights, unsigned long caller)
{
	l4_msgtag_t tag;

	if (IS_ENABLED(CONFIG_ARM))
		return;

	if (mm && mm->context.l4x_unmap_mode == L4X_UNMAP_MODE_SKIP)
		return;

	if ((address & PAGE_MASK) == 0)
		address = PAGE0_PAGE_ADDRESS;

	if (likely(mm)) {
		unmap_log_add(mm, vaddr, size, flush_rights, caller);
		return;
	}

	/* do the real flush */
	if (mm && !l4_is_invalid_cap(mm->context.task)) {
		/* Direct flush in the child, use virtual address in the
		 * child address space */
		tag = L4XV_FN(l4_msgtag_t,
		              l4_task_unmap(mm->context.task,
		                           l4_fpage(vaddr & PAGE_MASK, size,
		                                    flush_rights),
		                           L4_FP_ALL_SPACES));
	} else {
		/* Flush all pages in all childs using the 'physical'
		 * address known in the Linux server */
		tag = L4XV_FN(l4_msgtag_t,
		              l4_task_unmap(L4RE_THIS_TASK_CAP,
			                    l4_fpage(address & PAGE_MASK, size,
		                                     flush_rights),
			                    L4_FP_OTHER_SPACES));
	}

	if (l4_error(tag))
		l4x_printf("l4_task_unmap error %ld\n", l4_error(tag));
}
示例#4
0
static inline void
l4x_unmap_self(unsigned long a)
{
	l4_msgtag_t t;

	if (0)
		printk("dma-self-unmap: %08lx\n", a);

	a &= PAGE_MASK;

	t = L4XV_FN(l4_msgtag_t,
	            l4_task_unmap(L4_BASE_TASK_CAP,
	                          l4_fpage(a, PAGE_SHIFT, L4_FPAGE_RWX),
	                          L4_FP_ALL_SPACES));

	if (l4_error(t))
		printk("dma-remap: internal unmapping of %08lx failed\n", a);
}
示例#5
0
static inline void
l4x_map_self(unsigned long src, unsigned long dst, unsigned mapflags)
{
	l4_msgtag_t t;

	if (0)
		printk("dma-self-map: %08lx -> %08lx [%x]\n",
		       src, dst, mapflags);

	src &= PAGE_MASK;
	dst &= PAGE_MASK;

	t = L4XV_FN(l4_msgtag_t,
	            l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
	                        l4_fpage(src, PAGE_SHIFT, L4_FPAGE_RWX),
	                        dst | L4_MAP_ITEM_MAP | mapflags));

	if (l4_error(t))
		printk("dma-remap: internal mapping failed: %08lx -> %08lx\n",
		       src, dst);
}
示例#6
0
void l4x_unmap_log_flush(void)
{
	unsigned i;
	struct unmap_log_t *log;
	unsigned long flags;

	local_irq_save(flags);

	log = this_cpu_ptr(&unmap_log);

	for (i = 0; i < log->cnt; ++i) {
		l4_msgtag_t tag;
		struct mm_struct *mm = log->log[i].mm;

		if (unlikely(l4_is_invalid_cap(mm->context.task)))
			continue;

		tag = L4XV_FN(l4_msgtag_t,
		              l4_task_unmap(mm->context.task,
		                            l4_fpage(log->log[i].addr,
		                                     log->log[i].size,
		                                     log->log[i].rights),
		                            L4_FP_ALL_SPACES));
		if (unlikely(l4_error(tag))) {
			l4x_printf("l4_task_unmap error %ld: t=%lx\n",
			           l4_error(tag), mm->context.task);
			WARN_ON(1);
		} else if (0)
			l4x_printf("flushing(%d) %lx:%08lx[%d,%x]\n",
			           i, mm->context.task,
			           log->log[i].addr, log->log[i].size,
			           log->log[i].rights);
	}

	log->cnt = 0;
	local_irq_restore(flags);
}
示例#7
0
static void get_fb(void)
{
  l4_addr_t fpage_addr;
  l4_size_t fpage_size;
  l4dm_dataspace_t ds;
  CORBA_Environment env = dice_default_environment;
  int i, pages, error;
  struct stat st;

  /* check if we're running under L4Linux */
  if (stat("/proc/l4", &st) == -1) {
    fprintf(stderr, "Error: /proc/l4 doesn't exist, not running on L4Linux?!\n");
    exit(1);
  }

  /* ask for 'con' (timeout = 5000 ms) */
  if (names_waitfor_name(CON_NAMES_STR, &con_l4id, 5000) == 0) {
    fprintf(stderr, "PANIC: %s not registered at names", CON_NAMES_STR);
    exit(1);
  }
  INFO("Found my console through names, it's at "l4util_idfmt".\n",
       l4util_idstr(con_l4id));

  PRINT("Screenshot'ing, please smile... ;-)\n");
  /* get screenshot */
  if (con_if_screenshot_call(&con_l4id, get_vc, &ds, 
			&xres, &yres, &bpp, &env)) {
    fprintf(stderr, "Could not get screenshot\n");
    exit(1);
  }
  INFO("Got screenshot: res: %dx%d, bpp: %d\n", xres, yres, bpp);

  if (l4dm_mem_size(&ds, &fb_size)) {
    fprintf(stderr, "Couldn't get size of data space\n");
    exit(1);
  }
  INFO("Size of data space: %d\n", fb_size);

  if ((fb_mem = malloc(fb_size)) == NULL) {
    fprintf(stderr, "Couldn't malloc %d Bytes of memory!\n", fb_size);
    exit(1);
  }
  raw_pic_size = xres*yres*3;
  if ((raw_pic_mem = malloc(raw_pic_size)) == NULL) {
    fprintf(stderr, "Couldn't malloc %d bytes of memory!\n", raw_pic_size);
    exit(1);
  }
  
  pages = fb_size / L4_PAGESIZE; // size is always a multiple of L4_PAGESIZE?
  for (i = 0; i < pages; i++) {
    /* unmap memory */
    l4_fpage_unmap(l4_fpage((l4_umword_t)map_page, L4_LOG2_PAGESIZE,
	  	   L4_FPAGE_RW, L4_MAP_ITEM_MAP),
                   L4_FP_FLUSH_PAGE|L4_FP_ALL_SPACES);

    /* page in L4 page */
    if ((error = l4dm_map_pages(&ds, i*L4_PAGESIZE, L4_PAGESIZE,
			        (l4_addr_t)map_page, L4_LOG2_PAGESIZE,
				0, L4DM_RO, &fpage_addr,&fpage_size)) < 0) {
      fprintf(stderr, "Error %d requesting ds %d at ds_manager "
	      l4util_idfmt"\n",
	  error, ds.id, l4util_idstr(ds.manager));
      l4dm_close(&ds);
      exit(error);
    }

    memcpy(fb_mem + i*L4_PAGESIZE, map_page, L4_PAGESIZE);
  }

  if (l4dm_close(&ds)) {
    fprintf(stderr, "Error on closing dataspace, expect memory leakage...\n");
  }
}
示例#8
0
文件: pte.c 项目: soap-DEIM/l4android
static void l4x_flush_page(struct mm_struct *mm,
                           unsigned long address,
                           unsigned long vaddr,
                           int size,
                           unsigned long flush_rights)
{
	l4_msgtag_t tag;

	if (mm && mm->context.l4x_unmap_mode == L4X_UNMAP_MODE_SKIP)
		return;

	/* some checks: */
	if (address > 0x80000000UL) {
		unsigned long remap;
		remap = find_ioremap_entry(address);

		/* VU: it may happen, that memory is not remapped but mapped in
		 * user space, if a task mmaps /dev/mem but never accesses it.
		 * Therefore, we fail silently...
		 */
		if (!remap)
			return;

		address = remap;

	} else if ((address & PAGE_MASK) == 0)
		address = PAGE0_PAGE_ADDRESS;

#if 0
	/* only for debugging */
	else {
		if ((address >= (unsigned long)high_memory)
		    && (address < 0x80000000UL)) {
			printk("flushing non physical page (0x%lx)\n",
				    address);
			enter_kdebug("flush_page: non physical page");
		}
	}
#endif

	/* do the real flush */
	if (mm && !l4_is_invalid_cap(mm->context.task)) {
		L4XV_V(f);
		if (!mm->context.task)
			l4x_printf("%s: Ups, task == 0\n", __func__);
		/* Direct flush in the child, use virtual address in the
		 * child address space */
		L4XV_L(f);
		tag = l4_task_unmap(mm->context.task,
		                    l4_fpage(vaddr & PAGE_MASK, size, flush_rights),
		                    L4_FP_ALL_SPACES);
		L4XV_U(f);
	} else {
		L4XV_V(f);
		/* Flush all pages in all childs using the 'physical'
		 * address known in the Linux server */
		L4XV_L(f);
		tag = l4_task_unmap(L4RE_THIS_TASK_CAP,
			            l4_fpage(address & PAGE_MASK, size, flush_rights),
			            L4_FP_OTHER_SPACES);
		L4XV_U(f);
	}
	if (l4_error(tag))
		l4x_printf("l4_task_unmap error %ld\n", l4_error(tag));
}
示例#9
0
文件: main.c 项目: B-Rich/idl4
int main(dword_t mb_magic, struct multiboot_info *mbi)

{
  CORBA_Environment env = idl4_default_environment;
  int i,j,msg[8] = { 0,0x6100,0x0100,0,0,0,0,0 };
  struct mod_list *mods;
  l4_msgdope_t result;
  Elf32_Phdr *phdr;
  l4_threadid_t msvr;
  int mobj, pagerid, tobj;
  int blockID=0;
  int found_root=0;
  int totalBlock=0;
  
  init_global_data();
  printf("Booter task (%x) starting, pager is %X\n", booter.raw, sigma0.raw);

  check_multiboot_header(mb_magic,&mbi);
    
  printf("Multiboot header found at %X\n", (dword_t) mbi);

  mods = (mod_list*) mbi->mods_addr;
  secure_modules(mods, (int)mbi->mods_count);

  launch_aux_pager();

  task[0].active=1;
  task[0].root.svr.raw=0;
  task[0].root.obj=0;
  task[0].memory.svr=sigma0;
  task[0].memory.obj=DEFAULT_OBJECT;
  strncpy(task[0].cmdline,(char*)mods[BOOTER_MODULE_NR].cmdline,MAXLENGTH);
  task[0].task_id=booter;
  task[0].owner=booter;

  // *************************************************************************
  // *** bootup sequence

  if (mbi->mods_count < (BOOTER_MODULE_NR+2)) 
    enter_kdebug("nothing to load");

  mods = (struct mod_list *) mbi->mods_addr;
  nexttask = booter;
  (void)nexttask.id.task++;
 
  for (j=BOOTER_MODULE_NR+1;j<(int)mbi->mods_count;j++)
    {
      Elf32_Ehdr *file_hdr;

      // *** check sanity of elf file
    
      file_hdr = (Elf32_Ehdr *) mods[j].mod_start;
      if (file_hdr->e_ident[EI_MAG0] !=  ELFMAG0
          || file_hdr->e_ident[EI_MAG1] !=  ELFMAG1
          || file_hdr->e_ident[EI_MAG2] !=  ELFMAG2
          || file_hdr->e_ident[EI_MAG3] !=  ELFMAG3) 
        {  
          i=0;
          while ((i<MAXBLOCKS) && (block[i].active)) i++;
          if (i<MAXBLOCKS)
            {
              block[i].active=1;
              block[i].phys_addr=(int)mods[j].mod_start;
              block[i].capacity=((int)mods[j].mod_end-(int)mods[j].mod_start)/512;
              block[i].blocksize=512;
	      totalBlock++;

              if (found_root)
                {
                  char name[20];
                  sprintf(name,"hd%c",'a'+(blockID++));
                  directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env);
                } 
              
            }
          continue;
        }  
    
      if (file_hdr->e_type != ET_EXEC) 
        enter_kdebug("unexpected e_type");

      if (file_hdr->e_machine != EM_386) 
        enter_kdebug("not an intel binary");

      if (file_hdr->e_version != EV_CURRENT)
        enter_kdebug("version mismatch?");

      if (file_hdr->e_flags != 0)
        enter_kdebug("unexpected flags?");

      if (file_hdr->e_phnum <= 0)
        enter_kdebug("No loadable program sections");

      // *** create the task. this will map the trampoline code into page 0
      //     of the newly created address space
      
      printf("Task %d: %s\n",(int)nexttask.id.task,(char*)mods[j].cmdline);
      l4_task_new(nexttask, 255, 0, 0, auxpager);

      // *** if the memory server is already running, make it the new task's
      //     pager. (should be replaced by dynamic object creation)
      
      if (j>(BOOTER_MODULE_NR+1))
        {
          if (creator_create(memsvr,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int),
                             (sdword*)&api_mem,&msvr,&mobj,&env)!=ESUCCESS)
            enter_kdebug("Memory object creation failed");
            
          memory_set_maxpages(msvr,mobj,99999999,&env);
          memory_attach(msvr,mobj,&nexttask,&env);
          memory_get_pagerid(msvr,mobj,&pagerid,&env);
          
          l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,pagerid,0,L4_IPC_NEVER,&result);
        } else {
                 msvr = sigma0;mobj=DEFAULT_OBJECT;
               }  

      // *** allocate struct for the task
      
      tobj=0;
      while ((tobj<MAXTASKS) && (task[tobj].active))
        tobj++;
      if (tobj==MAXTASKS)
        enter_kdebug("Too many tasks");
      task[tobj].active=1;
      if (found_root)
        {
          task[tobj].root.svr=root.svr;
          task[tobj].root.obj=root.obj;
        } else {
                 task[tobj].root.svr.raw=0;
                 task[tobj].root.obj=0;
               }  

      task[tobj].memory.svr=msvr;
      task[tobj].memory.obj=mobj;
      strncpy(task[tobj].cmdline,(char*)mods[j].cmdline,MAXLENGTH);
      task[tobj].cmdline[MAXLENGTH-1]=0;
      task[tobj].task_id=nexttask;
      task[tobj].owner=booter;
  
      // *** parse all the headers

      phdr = (Elf32_Phdr *) (file_hdr->e_phoff + (unsigned int) file_hdr);

      for (i=0;i<file_hdr->e_phnum;i++) 
        if (phdr[i].p_type == PT_LOAD) 
          {
            // *** notify the trampoline

            l4_ipc_send(nexttask,0,TRAMPOLINE_RECEIVE,(int)phdr[i].p_vaddr,
                        (int)phdr[i].p_filesz,L4_IPC_NEVER,&result);
            msg[6]=(int)phdr[i].p_filesz;
            msg[7]=(int)file_hdr + phdr[i].p_offset;

            // *** send the string ipc. this will cause a bunch of pagefaults,
            //     which will be handled by the child's pager

            #ifdef DEBUG
            printf("Copying segment of size %x from address %x to %x\n",msg[6],msg[7],(int)phdr[i].p_vaddr);
            #endif
            l4_ipc_send(nexttask,&msg,0,0,0,L4_IPC_NEVER,&result);
  
            // *** zero out any bss segments
  
            if (phdr[i].p_memsz>phdr[i].p_filesz)
              { 
                int zero_base = phdr[i].p_vaddr+phdr[i].p_filesz;
                int zero_size = phdr[i].p_memsz-phdr[i].p_filesz;
                
                #ifdef DEBUG
                printf("Erasing zone at %x, size %x\n",zero_base,zero_size);
                #endif
                l4_ipc_send(nexttask,0,TRAMPOLINE_ZERO_ZONE,
                            zero_base,zero_size,L4_IPC_NEVER,&result);
              }
        }
        
      // *** if this is the memory server, change the pager to sigma0

      if (j==(BOOTER_MODULE_NR+1))
        l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,sigma0.raw,0,L4_IPC_NEVER,&result);

      // *** start the program
      
      #ifdef DEBUG
      printf("Jumping to program entry point at %x [objID=%d]\n\n",(int)file_hdr->e_entry,tobj);
      #endif
      l4_ipc_send(nexttask,0,TRAMPOLINE_LAUNCH,tobj,file_hdr->e_entry,L4_IPC_NEVER,&result);

      // *** wait until thread leaves the trampoline code

      for (i=0;i<3;i++)
        l4_thread_switch(nexttask);
        
      // *** flush the trampoline  

      l4_fpage_unmap(l4_fpage((int)&_trampoline,L4_LOG2_PAGESIZE,0,0),L4_FP_FLUSH_PAGE);
      
      // *** see about the supported interfaces
      
      if (j==(BOOTER_MODULE_NR+1))
        {
          memsvr=nexttask; 

          if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)!=EYES)
            enter_kdebug("Memory server does not support Creator API");
          if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int),(sdword*)&api_mem,&env)!=EYES)
            enter_kdebug("Memory server cannot create memory objects");  
        }
        
      if (!found_root)  
        if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)==EYES)
          if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)==EYES)
            {
              root.svr=nexttask;found_root=1;
              #ifdef DEBUG
              printf("Found root nameserver (%X), creating /...\n",root.svr.raw);
              #endif
              if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&root.svr,&root.obj,&env)!=ESUCCESS)
                enter_kdebug("Root directory creation failed");
              if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&dev.svr,&dev.obj,&env)!=ESUCCESS)
                enter_kdebug("/dev directory creation failed");
              if (generic_implements(root.svr,root.obj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=EYES)
                enter_kdebug("Defective root directory");
              if (directory_link(root.svr,root.obj,3,"dev",&dev.svr,dev.obj,&env)!=ESUCCESS)
                enter_kdebug("Cannot link dev into /");
              if (directory_link(dev.svr,dev.obj,7,"tasksvr",&booter,0,&env)!=ESUCCESS)
                enter_kdebug("Cannot link tasksvr into /dev/");
              
              for (int i=0;i<MAXBLOCKS;i++)
                if (block[i].active)
                  {
                    char name[20];
                    sprintf(name,"hd%c",'a'+(blockID++));
                    directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env);
                  }  
              
              for (int k=0;k<MAXTASKS;k++)
                if ((task[k].active) && (!task[k].root.svr.raw))
                  {
                    task[k].root.svr=root.svr;
                    task[k].root.obj=root.obj;
                  }  
              #ifdef DEBUG    
              printf("Root creation completed, all servers notified\n\n");
              #endif
            }  
	    
      (void)nexttask.id.task++;    
    }

  // *** modify the trampoline to work with elf launcher
  // *** this is BAD magic!
  
  int *m1=(int*)(((int)&_m1)+1);
  int *m2=(int*)(((int)&_m2)+1);
  *m1=0x04041001;
  *m2=0x04041001;

  if (totalBlock)
    printf("Created %d block device(s)\n",totalBlock);

  // *** enter server loop

  booter_server();  
}