Beispiel #1
0
void l4x_evict_tasks(struct task_struct *exclude)
{
	struct task_struct *p;
	int cnt = 0;

	rcu_read_lock();
	for_each_process(p) {
		l4_cap_idx_t t;
		struct mm_struct *mm;

		if (p == exclude)
			continue;

		task_lock(p);
		mm = p->mm;
		if (!mm) {
			task_unlock(p);
			continue;
		}

		t = ACCESS_ONCE(mm->context.task);

		if (l4_is_invalid_cap(t)) {
			task_unlock(p);
			continue;
		}

		if (down_read_trylock(&mm->mmap_sem)) {
			struct vm_area_struct *vma;
			for (vma = mm->mmap; vma; vma = vma->vm_next)
				if (vma->vm_flags & VM_LOCKED) {
					t = L4_INVALID_CAP;
					break;
				}
			up_read(&mm->mmap_sem);
			if (!vma)
				if (cmpxchg(&mm->context.task, t, L4_INVALID_CAP) != t)
					t = L4_INVALID_CAP;
		} else
			t = L4_INVALID_CAP;

		task_unlock(p);

		if (!l4_is_invalid_cap(t)) {
			l4lx_task_delete_task(t);
			l4lx_task_number_free(t);

			if (++cnt > 10)
				break;
		}
	}
	rcu_read_unlock();

	if (cnt == 0)
		pr_info_ratelimited("l4x-evict: Found no process to free.\n");
}
Beispiel #2
0
static ssize_t onda_pwm_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t size)
{
	ssize_t status;
	l4_msgtag_t tag;
	l4_umword_t label;
	l4_cap_idx_t comm_cap;
	int value = 0;
	int ipc_error;

	mutex_lock(&sysfs_lock);
	
	comm_cap = l4re_get_env_cap("comm");

	/* Get a free capability slot for the comm capability */
	if (l4_is_invalid_cap(comm_cap)) {
		printk("Did not find an comm\n");
		mutex_unlock(&sysfs_lock);
		return 0;
    }

	/* To an L4 IPC call, i.e. send a message to thread2 and wait for a
	* reply from thread2. The '1' in the msgtag denotes that we want to
	* transfer one word of our message registers (i.e. MR0). No timeout. */
	if (sscanf(buf,"%d\n", &value) > 0) {
		l4_utcb_mr()->mr[0] = 0x67;
		l4_utcb_mr()->mr[1] = value;
		tag = l4_ipc_call(comm_cap, l4_utcb(), l4_msgtag(0x67, 2, 0, 0), L4_IPC_NEVER);
	}

	mutex_unlock(&sysfs_lock);
	return size;
}
Beispiel #3
0
static int __init l4vpci_init(void)
{
	int err;

	vbus = l4re_env_get_cap("vbus");
	if (l4_is_invalid_cap(vbus))
		return -ENOENT;

	err = L4XV_FN_i(l4vbus_get_device_by_hid(vbus, 0, &root_bridge,
	                                         "PNP0A03", 0, 0));
	if (err < 0) {
		printk(KERN_INFO "l4vPCI: no root bridge found, no PCI\n");
		return err;
	}

	printk(KERN_INFO "l4vPCI: L4 root bridge is device %lx\n", root_bridge);

#ifdef CONFIG_X86
	return l4vpci_x86_init();
#endif

#ifdef CONFIG_ARM
	pci_common_init(&l4vpci_pci);
	return 0;
#endif
}
Beispiel #4
0
static int allocate_memory(void ** virt_addr, unsigned long virt_base,
        unsigned long size_in_bytes, unsigned long flags)
{
  int r;
  l4re_ds_t ds;

  /* Allocate a free capability index for our data space */
  ds = l4re_util_cap_alloc();
  if (l4_is_invalid_cap(ds))
    return -L4_ENOMEM;

  /* Allocate memory via a dataspace */
  if ((r = l4re_ma_alloc(size_in_bytes, ds, flags)))
  {
    printf("Memory allocation failed.\n");
    return r;
  }

  /* Make the dataspace visible in our address space */
  *virt_addr = (void *)virt_base;
  if ((r = l4re_rm_attach(virt_addr, size_in_bytes,
    L4RE_RM_SEARCH_ADDR, ds, 0, L4_PAGESHIFT)))
  {
    printf("Memory mapping failed.\n");
    return r;
  }
  
  /* Done, virtual address is in virt_addr */
  return 0;
}
Beispiel #5
0
void l4x_exit_thread(void)
{
#ifndef CONFIG_L4_VCPU
	int i;

	if (unlikely(current->thread.is_hybrid)) {
		l4_cap_idx_t hybgate;
		l4_msgtag_t tag;
		l4_umword_t o = 0;

		hybgate = L4LX_KERN_CAP_HYBRID_BASE
		           + (current->pid << L4_CAP_SHIFT);

		tag = l4_ipc_gate_get_infos(hybgate, &o);
		if (l4_error(tag))
			printk("hybrid: Could not get gate info, leaking mem.\n");
		else
			kfree((void *)o);

		tag = l4_task_unmap(L4_BASE_TASK_CAP,
		                    l4_obj_fpage(hybgate, 0, L4_FPAGE_RWX),
		                    L4_FP_ALL_SPACES);
		if (l4_error(tag))
			printk("hybrid: Delete of gate failed.\n");
	}

	for (i = 0; i < NR_CPUS; i++) {
		l4_cap_idx_t thread_id = current->thread.user_thread_ids[i];

		/* check if we were a non-user thread (i.e., have no
		   user-space partner) */
		if (unlikely(l4_is_invalid_cap(thread_id) || !thread_id))
			continue;

#ifdef DEBUG
		LOG_printf("exit_thread: trying to delete %s(%d, " PRINTF_L4TASK_FORM ")\n",
		           current->comm, current->pid, PRINTF_L4TASK_ARG(thread_id));
#endif

		/* If task_delete fails we don't free the task number so that it
		 * won't be used again. */

		if (likely(!l4lx_task_delete_thread(thread_id))) {
			l4x_hybrid_remove(current);
			current->thread.user_thread_ids[i] = L4_INVALID_CAP;
			l4lx_task_number_free(thread_id);
			current->thread.started = 0;
		} else
			printk("%s: failed to delete task " PRINTF_L4TASK_FORM "\n",
			       __func__, PRINTF_L4TASK_ARG(thread_id));

	}
#endif

#ifdef CONFIG_X86_DS
	ds_exit_thread(current);
#endif
}
Beispiel #6
0
int kthreads_seq_show(struct seq_file *m, void *v)
{
	int i = *(int *)v;

	if (!l4_is_invalid_cap(l4lx_thread_names[i].id))
		seq_printf(m, PRINTF_L4TASK_FORM ": %s\n",
		           PRINTF_L4TASK_ARG(l4lx_thread_names[i].id),
		           l4lx_thread_names[i].name);
	return 0;
}
Beispiel #7
0
/* kernel-internal execve() */
asmlinkage int
l4_kernelinternal_execve(const char * file,
                         const char * const * argv,
                         const char * const * envp)
{
	int ret;
	struct thread_struct *t = &current->thread;

	ASSERT(l4_is_invalid_cap(t->user_thread_id));

	/* we are going to become a real user task now, so prepare a real
	 * pt_regs structure. */
	/* Enable Interrupts, Set IOPL (needed for X, hwclock etc.) */
	t->regs.flags = 0x3200; /* XXX hardcoded */

	/* do_execve() will create the user task for us in start_thread()
	   and call set_fs(USER_DS) in flush_thread. I know this sounds
	   strange but there are places in the kernel (kernel/kmod.c) which
	   call execve with parameters inside the kernel. They set fs to
	   KERNEL_DS before calling execve so we can't set it back to
	   USER_DS before execve had a chance to look at the name of the
	   executable. */

	ASSERT(segment_eq(get_fs(), KERNEL_DS));
	ret = do_execve(file, argv, envp, &t->regs);

	if (ret < 0) {
		/* we failed -- become a kernel thread again */
		if (!l4_is_invalid_cap(t->user_thread_id))
			l4lx_task_number_free(t->user_thread_id);
		set_fs(KERNEL_DS);
		t->user_thread_id = L4_INVALID_CAP;
		return -1;
	}

	l4x_user_dispatcher();

	/* not reached */
	return 0;
}
Beispiel #8
0
/* Delete a key */
int pthread_key_delete(pthread_key_t key)
{
  pthread_descr self = thread_self();

  pthread_mutex_lock(&pthread_keys_mutex);
  if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) {
    pthread_mutex_unlock(&pthread_keys_mutex);
    return EINVAL;
  }
  pthread_keys[key].in_use = 0;
  pthread_keys[key].destr = NULL;

  /* Set the value of the key to NULL in all running threads, so
     that if the key is reallocated later by pthread_key_create, its
     associated values will be NULL in all threads.

     If no threads have been created yet, or if we are exiting, clear
     it just in the current thread.  */

  struct pthread_key_delete_helper_args args;
  args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
  args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
  if (!l4_is_invalid_cap(__pthread_manager_request)
      && !(__builtin_expect (__pthread_exit_requested, 0)))
    {
      struct pthread_request request;

      args.self = 0;

      request.req_thread = self;
      request.req_kind = REQ_FOR_EACH_THREAD;
      request.req_args.for_each.arg = &args;
      request.req_args.for_each.fn = pthread_key_delete_helper;
#if 1
      __pthread_send_manager_rq(&request, 1);
#else
      TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
					  (char *) &request, sizeof(request)));
#endif
      suspend(self);
    }
  else
    {
      if (self->p_specific[args.idx1st] != NULL)
	self->p_specific[args.idx1st][args.idx2nd] = NULL;
    }

  pthread_mutex_unlock(&pthread_keys_mutex);
  return 0;
}
Beispiel #9
0
static void setup_memory(void)
{
	int ret;

	l4_size_t phys_size;

	if (fb_vaddr)
		return;

	ret = l4io_request_iomem(0x48050000, 0x1000, 0, &omap_dss_virt_base);
	if (ret)
	{
		printf("[LCD] Error: Could not map device memory\n");
		return;
	}

	// get some frame buffer
	l4re_ds_t mem = l4re_util_cap_alloc();
	if (l4_is_invalid_cap(mem))
		return;

	if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED))
	{
		printf("[LCD] Error: Could not allocate memory\n");
		return;
	}

	fb_vaddr = 0;
	if (l4re_rm_attach(&fb_vaddr, fbmem_size(),
		L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
		mem, 0, L4_PAGESHIFT))
	{
		printf("[LCD] Error: Could not attach memory\n");
		return;
	}

	printf("[LCD] Info: Video memory is at virtual %p (size: 0x%x Bytes)\n",
	fb_vaddr, fbmem_size());

	// get physical address
	if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size) || phys_size != fbmem_size())
	{
		printf("[LCD] Error: Could not get physical address\n");
		return;
	}
	printf("[LCD] Info: Physical video memory is at %p\n", (void *)fb_paddr);
}
Beispiel #10
0
void destroy_context(struct mm_struct *mm)
{
	l4_cap_idx_t task_id;

	destroy_context_origarch(mm);

	if (!mm || !mm->context.task ||
	    l4_is_invalid_cap(task_id = mm->context.task))
		return;

	if (l4lx_task_delete_task(task_id))
		do_exit(9);

	mm->context.task = L4_INVALID_CAP;

	l4lx_task_number_free(task_id);
}
Beispiel #11
0
static int __init l4vpci_init(void)
{
	struct pci_dev *dev = NULL;
#ifdef CONFIG_ARM
	struct pci_sys_data *sd;
#else
	struct pci_sysdata *sd;
#endif
	int err;
	L4XV_V(f);

	vbus = l4re_get_env_cap("vbus");
	if (l4_is_invalid_cap(vbus))
		return -ENOENT;

	L4XV_L(f);

	err = l4vbus_get_device_by_hid(vbus, 0, &root_bridge, "PNP0A03", 0, 0);
	if (err < 0) {
		printk(KERN_INFO "PCI: no root bridge found, no PCI\n");
		L4XV_U(f);
		return err;
	}

	L4XV_U(f);

	printk(KERN_INFO "PCI: L4 root bridge is device %lx\n", root_bridge);

	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
	if (!sd)
		return -ENOMEM;

	pci_scan_bus(0, &l4vpci_ops, sd);

	printk(KERN_INFO "PCI: Using L4-IO for IRQ routing\n");

	for_each_pci_dev(dev)
		l4vpci_irq_enable(dev);

#ifdef CONFIG_X86
	pcibios_resource_survey();
#endif

	return 0;
}
Beispiel #12
0
static ssize_t onda_interval_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
	ssize_t status;
	l4_msgtag_t tag;
	l4_umword_t label;
	l4_cap_idx_t comm_cap;
	int value = 0;
	int ipc_error;

	mutex_lock(&sysfs_lock);
	
	comm_cap = l4re_get_env_cap("comm");

	/* Get a free capability slot for the comm capability */
	if (l4_is_invalid_cap(comm_cap)) {
		printk("Did not find an comm\n");
		mutex_unlock(&sysfs_lock);
		return 0;
    }

	/* To an L4 IPC call, i.e. send a message to thread2 and wait for a
	* reply from thread2. The '1' in the msgtag denotes that we want to
	* transfer one word of our message registers (i.e. MR0). No timeout. */
	l4_utcb_mr()->mr[0] = 0x56;
	tag = l4_ipc_call(comm_cap, l4_utcb(), l4_msgtag(0x56, 1, 0, 0), L4_IPC_NEVER);
	
	/* Check for IPC error, if yes, print out the IPC error code, if not,
	* print the received result. */
	ipc_error = l4_ipc_error(tag, l4_utcb());
	if (ipc_error) {
		printk("IPC error: %x\n", ipc_error);
		return 0;
		buf[0] = '\n';
		buf[1] = '\0';
		status = 1;
	} else {
		value = (int)(l4_utcb_mr()->mr[0]);
		status = sprintf(buf, "%d\n", value);
	}

	mutex_unlock(&sysfs_lock);

	return status;
}
Beispiel #13
0
static
int kp_init(void)
{
  vbus = l4re_get_env_cap("vbus");

  if (l4_is_invalid_cap(vbus))
    {
      printf("[KEYP] Failed to query vbus\n");
      return -1;
    }

  if (l4vbus_get_device_by_hid(vbus, 0, &i2c_handle, "i2c", 0, 0))
    {
      printf("[KEYP] ##### Cannot find I2C\n");
    }

  return init_keypad();
}
Beispiel #14
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));
}
Beispiel #15
0
int l4x_register_irq(l4_cap_idx_t irqcap)
{
	unsigned long flags;
	int i, ret = -1;

	if (!init_done)
		init_array();

	spin_lock_irqsave(&lock, flags);

	for (i = 0; i < NR_REQUESTABLE; ++i) {
		if (l4_is_invalid_cap(caps[i])) {
			caps[i] = irqcap;
			ret = i + BASE;
			break;
		}
	}
	spin_unlock_irqrestore(&lock, flags);

	return ret;
}
Beispiel #16
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);
}
Beispiel #17
0
static int clcd_init_overo(void)
{
	vbus = l4re_get_env_cap("vbus");

	if (l4_is_invalid_cap(vbus))
	{
		printf("[LCD] Error: Could not query <vbus> capability\n");
		return -1;
	}

	if (l4vbus_get_device_by_hid(vbus, 0, &i2c_handle, "i2c", 0, 0))
	{
		printf("[LCD] Error: Could not find <i2c> vbus device\n");
		return -1;
	}

	if (l4vbus_get_device_by_hid(vbus, 0, &gpio_handle, "gpio", 0, 0))
	{
		printf("[LCD] Error: Could not find <gpio> vbus device\n");
		return -L4_ENODEV;
	}

	return 0;
}
Beispiel #18
0
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));
}
Beispiel #19
0
int main(void)
{
  l4_msgtag_t tag;
#ifdef MEASURE
  l4_cpu_time_t s, e;
#endif
  l4_utcb_t *u = l4_utcb();
  l4_exc_regs_t exc;
  l4_umword_t mr0, mr1;

  printf("Alien feature testing\n");

  l4_debugger_set_object_name(l4re_env()->main_thread, "alientest");

  /* Start alien thread */
  if (l4_is_invalid_cap(alien = l4re_util_cap_alloc()))
    return 1;

  l4_touch_rw(alien_thread_stack, sizeof(alien_thread_stack));

  tag = l4_factory_create_thread(l4re_env()->factory, alien);
  if (l4_error(tag))
    return 1;

  l4_debugger_set_object_name(alien, "alienth");

  l4_thread_control_start();
  l4_thread_control_pager(l4re_env()->main_thread);
  l4_thread_control_exc_handler(l4re_env()->main_thread);
  l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP);
  l4_thread_control_alien(1);
  tag = l4_thread_control_commit(alien);
  if (l4_error(tag))
    return 2;

  tag = l4_thread_ex_regs(alien,
                          (l4_umword_t)alien_thread,
                          (l4_umword_t)alien_thread_stack + sizeof(alien_thread_stack),
                          0);
  if (l4_error(tag))
    return 3;

  l4_sched_param_t sp = l4_sched_param(1, 0);
  tag = l4_scheduler_run_thread(l4re_env()->scheduler, alien, &sp);
  if (l4_error(tag))
    return 4;

#ifdef MEASURE
  l4_calibrate_tsc(l4re_kip());
#endif

  /* Pager/Exception loop */
  if (l4_msgtag_has_error(tag = l4_ipc_receive(alien, u, L4_IPC_NEVER)))
    {
      printf("l4_ipc_receive failed");
      return 1;
    }

  memcpy(&exc, l4_utcb_exc(), sizeof(exc));
  mr0 = l4_utcb_mr()->mr[0];
  mr1 = l4_utcb_mr()->mr[1];

  for (;;)
    {
#ifdef MEASURE
      s = l4_rdtsc();
#endif

      if (l4_msgtag_is_exception(tag))
        {
#ifndef MEASURE
          printf("PC=%08lx SP=%08lx Err=%08lx Trap=%lx, %s syscall, SC-Nr: %lx\n",
                 l4_utcb_exc_pc(&exc), exc.sp, exc.err,
                 exc.trapno, (exc.err & 4) ? " after" : "before",
                 exc.err >> 3);
#endif
          tag = l4_msgtag((exc.err & 4) ? 0 : L4_PROTO_ALLOW_SYSCALL,
                          L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
        }
      else
        printf("Umm, non-handled request (like PF): %lx %lx\n", mr0, mr1);

      memcpy(l4_utcb_exc(), &exc, sizeof(exc));

      /* Reply and wait */
      if (l4_msgtag_has_error(tag = l4_ipc_call(alien, u, tag, L4_IPC_NEVER)))
        {
          printf("l4_ipc_call failed\n");
          return 1;
        }
      memcpy(&exc, l4_utcb_exc(), sizeof(exc));
      mr0 = l4_utcb_mr()->mr[0];
      mr1 = l4_utcb_mr()->mr[1];
#ifdef MEASURE
      e = l4_rdtsc();
      printf("time %lld\n", l4_tsc_to_ns(e - s));
#endif
    }
Beispiel #20
0
static int l4x_rtc_platform_probe(struct platform_device *pdev)
{
	int r;

	if (l4x_re_resolve_name("rtc", &rtc_server)) {
		pr_err("l4x-rtc: Could not find 'rtc' cap.\n");
		return -ENOENT;
	}

	irq_cap = l4x_cap_alloc();
	if (l4_is_invalid_cap(irq_cap)) {
		pr_err("l4x-rtc: Could not allocate irq cap.\n");
		return -ENOMEM;
	}

	if (L4XV_FN_e(l4_factory_create_irq(l4re_env()->factory, irq_cap))) {
		pr_err("l4x-rtc: Could not create user irq.\n");
		r = -ENOMEM;
		goto free_cap;
	}

	if (L4XV_FN_e(l4_icu_bind(rtc_server, 0, irq_cap))) {
		pr_err("l4x-rtc: Error registering for time updates.\n");
		r = -ENOSYS;
		goto free_irq_cap;
	}

	irq = l4x_register_irq(irq_cap);
	if (irq < 0) {
		pr_err("l4x-rtc: Error registering IRQ with L4Linux.\n");
		r = irq;
		goto free_irq_cap;
	}

	r = request_irq(irq, l4x_rtc_int, IRQF_TRIGGER_RISING, "l4x_rtc", NULL);
	if (r) {
		pr_err("l4x-rtc: Could not register IRQ.\n");
		goto unregister_irq;
	}

	if (l4x_rtc_update_offset()) {
		pr_err("l4x-rtc: Could not get the time offset to real time.\n");
		r = -ENOSYS;
		goto free_irq;
	}

	rtc_dev = rtc_device_register(driver_name, &(pdev->dev),
	                              &l4x_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc_dev)) {
		pr_err("l4x-rtc: Could not register as rtc device.\n");
		r = PTR_ERR(rtc_dev);
		goto free_irq;
	}

	INIT_WORK(&w_update_time, l4x_rtc_update_time);

	return 0;

free_irq:
	free_irq(irq, NULL);
unregister_irq:
	l4x_unregister_irq(irq);
free_irq_cap:
	L4XV_FN_v(l4_task_release_cap(L4RE_THIS_TASK_CAP, irq_cap));
free_cap:
	l4x_cap_free(irq_cap);
	return r;
}
Beispiel #21
0
static void setup_memory(void)
{
  l4_size_t phys_size;
  l4io_device_handle_t dh;
  l4io_resource_handle_t hdl;

  if (fb_vaddr)
    return;

  if (l4io_lookup_device("System Control", &dh, 0, &hdl))
    {
      printf("Could not get system controller space\n");
      return;
    }

  /* System controller -- XXX Wrong Place XXX */
  amba_pl110_sys_base_virt
    = l4io_request_resource_iomem(dh, &hdl);
  if (amba_pl110_sys_base_virt == 0)
    {
      printf("Could not map system controller space\n");
      return;
    }

  if (l4io_lookup_device("AMBA PL110", &dh, 0, &hdl))
    {
      printf("Could not get PL110 LCD device\n");
      return;
    }

  amba_pl110_lcd_control_virt_base
    = l4io_request_resource_iomem(dh, &hdl);
  if (amba_pl110_lcd_control_virt_base == 0)
    {
      printf("Could not map controller space for '%s'\n", arm_lcd_get_info());
      return;
    }

  setup_type();

  if ((read_sys_reg(Reg_sys_clcd) & Sys_clcd_idmask) == 0x1000)
    {
      is_qemu = 1; // remember if we run on qemu because of the different
                   // handling of the bpp16 mode with PL110: my hardware has
                   // 5551 mode, qemu does 565
      type = PL111; // also set the type to PL111 because qemu only
                    // announces a PL110 but can do the 1024 resolution too
      printf("Running on QEmu (assuming PL111).\n");
    }

  if (config_request_xga && type == PL111)
    use_xga = 1;

  // get some frame buffer
  l4re_ds_t mem = l4re_util_cap_alloc();
  if (l4_is_invalid_cap(mem))
    return;

  if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED))
    {
      printf("Error allocating memory\n");
      return;
    }

  fb_vaddr = 0;
  if (l4re_rm_attach(&fb_vaddr, fbmem_size(),
                     L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
                     mem, 0, L4_PAGESHIFT))
    {
      printf("Error getting memory\n");
      return;
    }

  printf("Video memory is at virtual %p (size: 0x%x Bytes)\n",
         fb_vaddr, fbmem_size());

  // get physical address
  if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size)
      || phys_size != fbmem_size())
    {
      printf("Getting the physical address failed or not contiguous\n");
      return;
    }
  printf("Physical video memory is at %p\n", (void *)fb_paddr);
}
Beispiel #22
0
/* Our main function */
int main(void)
{
  /* Get a capability slot for our new thread. */
  l4_cap_idx_t t1 = l4re_util_cap_alloc();
  l4_utcb_t *u = l4_utcb();
  l4_exc_regs_t *e = l4_utcb_exc_u(u);
  l4_msgtag_t tag;
  int err;
  extern char _start[], _end[], _etext[];

  if (l4_is_invalid_cap(t1))
    return 1;

  /* Prevent pagefaults of our new thread because we do not want to
   * implement a pager as well. */
  l4_touch_ro(_start, _end - _start + 1);
  l4_touch_rw(_etext, _end - _etext);

  /* Create the thread using our default factory */
  tag = l4_factory_create_thread(l4re_env()->factory, t1);
  if (l4_msgtag_has_error(tag))
    return 1;

  /* Setup the thread by setting the pager and task. */
  l4_thread_control_start();
  l4_thread_control_pager(l4re_env()->main_thread);
  l4_thread_control_exc_handler(l4re_env()->main_thread);
  l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb,
                          L4RE_THIS_TASK_CAP);
  tag = l4_thread_control_commit(t1);
  if (l4_msgtag_has_error(tag))
    return 2;

  /* Start the thread by finally setting instruction and stack pointer */
  tag = l4_thread_ex_regs(t1,
                          (l4_umword_t)thread,
                          (l4_umword_t)thread_stack + sizeof(thread_stack),
                          L4_THREAD_EX_REGS_TRIGGER_EXCEPTION);
  if (l4_msgtag_has_error(tag))
    return 3;

  /* Receive initial exception from just started thread */
  tag = l4_ipc_receive(t1, u, L4_IPC_NEVER);
  if ((err = l4_ipc_error(tag, u)))
    {
      printf("Umm, ipc error: %x\n", err);
      return 1;
    }
  /* We expect an exception IPC */
  if (!l4_msgtag_is_exception(tag))
    {
      printf("PF?: %lx %lx (not prepared to handle this) %ld\n",
	     l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag));
      return 1;
    }

  /* Fill out the complete register set of the new thread */
  e->ip = (l4_umword_t)thread;
  e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack));
  e->eax = 1;
  e->ebx = 4;
  e->ecx = 2;
  e->edx = 3;
  e->esi = 6;
  e->edi = 7;
  e->ebp = 5;
  /* Send a complete exception */
  tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);

  /* Send reply and start the thread with the defined CPU register set */
  tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER);
  if ((err = l4_ipc_error(tag, u)))
    printf("Error sending IPC: %x\n", err);

  /* Idle around */
  while (1)
    l4_sleep(10000);

  return 0;
}
SDL_Surface *L4FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) {
	char* apptitle = APPTITLE;
	char* wintitle = WINTITLE;

	printf("L4FB_SetVideoMode: %dx%d@%d:\n", width, height, bpp);
	/*
	 * is requested resolution higher than the framebuffer's one?
	 */

	if( width > (int)this->hidden->vvi.width
		|| height > (int)this->hidden->vvi.height)
	{
		return (NULL);
	}
	
	/*
	 * calc the offsets for current resolution the center the image 
	 */
	
	this->hidden->x_offset = (this->hidden->vvi.width - width ) / 2;
	this->hidden->y_offset = (this->hidden->vvi.height - height) / 2;

	// make sure to have correct scale
	if (L4FB_video_scale_factor<=0) L4FB_video_scale_factor = 1.0;
	
	// reject unsupported bpp
	if (bpp != 16) return NULL;
	// reject unsupported flags
	if (flags & SDL_OPENGL) return NULL;

	/* Allocate the new pixel format for the screen */
	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
		SDL_SetError("Couldn't allocate new pixel format for requested mode");
		return(NULL);
	}

	// if we were double buffered clear shadow buffer
	if (current->flags & SDL_DOUBLEBUF) {
		FreeAndNull(current->pixels);
	}

	// init new window
	if (this->wm_title) wintitle = this->wm_title;
	if (this->wm_icon)  apptitle = this->wm_icon;



//	L4FB_SetCaption(this, wintitle, apptitle);

	if (l4_is_invalid_cap(this->hidden->ev_ds) || !this->hidden->ev_ds)
		L4FB_InstallEventHandler(this);

	/* Set up the new mode framebuffer */
	current->w = width;
	current->h = height;
	current->pitch = SDL_CalculatePitch(current);
	this->hidden->pitch =  current->pitch;
	current->flags =  SDL_PREALLOC | SDL_ASYNCBLIT;


//	if (current->pixels)
//	{
//		/* TODO: ERROR HANDLING */
//	}

//	memset(current->pixels, 0, current->h*current->pitch);


	/* since we want to center image in fb we allway have to use doublebuf... */

	this->hidden->fb_start = this->hidden->fbmem_vaddr + this->hidden->vvi.buffer_offset;

	current->pixels = malloc(current->h*current->pitch);

	if (current->pixels) {
		// success!
		printf("allocated shadow buffer\n");
		this->hidden->pixels = current->pixels;
		memset(current->pixels, 0, current->h*current->pitch);
	} else
		return NULL;


	if (flags&SDL_DOUBLEBUF) {

		current->flags |= SDL_DOUBLEBUF|SDL_HWSURFACE;
		// try to alloc shadow buffer
	}
 
	/* We're done */
	return(current);
}
Beispiel #24
0
/* Our main function */
int main(void)
{
  /* Get a capability slot for our new thread. */
  l4_cap_idx_t t1 = l4re_util_cap_alloc();
  l4_utcb_t *u = l4_utcb();
  l4_exc_regs_t *e = l4_utcb_exc_u(u);
  l4_msgtag_t tag;
  int err;

  printf("Example showing how to start a thread with an exception.\n");
  /* We do not want to implement a pager here, take the shortcut. */
  printf("Make sure to start this program with ldr-flags=eager_map\n");

  if (l4_is_invalid_cap(t1))
    return 1;

  /* Create the thread using our default factory */
  tag = l4_factory_create_thread(l4re_env()->factory, t1);
  if (l4_error(tag))
    return 1;

  /* Setup the thread by setting the pager and task. */
  l4_thread_control_start();
  l4_thread_control_pager(l4re_env()->main_thread);
  l4_thread_control_exc_handler(l4re_env()->main_thread);
  l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb,
                          L4RE_THIS_TASK_CAP);
  tag = l4_thread_control_commit(t1);
  if (l4_error(tag))
    return 2;

  /* Start the thread by finally setting instruction and stack pointer */
  tag = l4_thread_ex_regs(t1,
                          (l4_umword_t)thread,
                          (l4_umword_t)thread_stack + sizeof(thread_stack),
                          L4_THREAD_EX_REGS_TRIGGER_EXCEPTION);
  if (l4_error(tag))
    return 3;

  l4_sched_param_t sp = l4_sched_param(1, 0);
  tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp);
  if (l4_error(tag))
    return 4;


  /* Receive initial exception from just started thread */
  tag = l4_ipc_receive(t1, u, L4_IPC_NEVER);
  if ((err = l4_ipc_error(tag, u)))
    {
      printf("Umm, ipc error: %x\n", err);
      return 1;
    }
  /* We expect an exception IPC */
  if (!l4_msgtag_is_exception(tag))
    {
      printf("PF?: %lx %lx (not prepared to handle this) %ld\n",
	     l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag));
      return 1;
    }

  /* Fill out the complete register set of the new thread */
  e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack));
#ifdef ARCH_x86
  e->ip = (l4_umword_t)thread;
  e->eax = 1;
  e->ebx = 4;
  e->ecx = 2;
  e->edx = 3;
  e->esi = 6;
  e->edi = 7;
  e->ebp = 5;
#endif
#ifdef ARCH_arm
  e->pc = (l4_umword_t)thread;
  e->r[0] = 0;
  e->r[1] = 1;
  e->r[2] = 2;
  e->r[3] = 3;
  e->r[4] = 4;
  e->r[5] = 5;
  e->r[6] = 6;
  e->r[7] = 7;
#endif
  /* Send a complete exception */
  tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);

  /* Send reply and start the thread with the defined CPU register set */
  tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER);
  if ((err = l4_ipc_error(tag, u)))
    printf("Error sending IPC: %x\n", err);

  /* Idle around */
  while (1)
    l4_sleep(10000);

  return 0;
}
Beispiel #25
0
static int __init l4x_timer_init_ret(void)
{
    int r;
    l4lx_thread_t thread;
    int irq;
    L4XV_V(f);

    timer_irq_cap = l4x_cap_alloc();
    if (l4_is_invalid_cap(timer_irq_cap)) {
        printk(KERN_ERR "l4timer: Failed to alloc\n");
        return -ENOMEM;
    }

    r = L4XV_FN_i(l4_error(l4_factory_create_irq(l4re_env()->factory,
                           timer_irq_cap)));
    if (r) {
        printk(KERN_ERR "l4timer: Failed to create irq: %d\n", r);
        goto out1;
    }

    if ((irq = l4x_register_irq(timer_irq_cap)) < 0) {
        r = -ENOMEM;
        goto out2;
    }

    printk("l4timer: Using IRQ%d\n", irq);

    setup_irq(irq, &l4timer_irq);

    L4XV_L(f);
    thread = l4lx_thread_create
             (timer_thread,                /* thread function */
              smp_processor_id(),          /* cpu */
              NULL,                        /* stack */
              &timer_irq_cap, sizeof(timer_irq_cap), /* data */
              l4x_cap_alloc(),             /* cap */
              PRIO_TIMER,                  /* prio */
              0,                           /* vcpup */
              "timer",                     /* name */
              NULL);
    L4XV_U(f);

    timer_srv = l4lx_thread_get_cap(thread);

    if (!l4lx_thread_is_valid(thread)) {
        printk(KERN_ERR "l4timer: Failed to create thread\n");
        r = -ENOMEM;
        goto out3;
    }


    l4timer_clockevent.irq = irq;
    l4timer_clockevent.mult =
        div_sc(1000000, NSEC_PER_SEC, l4timer_clockevent.shift);
    l4timer_clockevent.max_delta_ns =
        clockevent_delta2ns(0xffffffff, &l4timer_clockevent);
    l4timer_clockevent.min_delta_ns =
        clockevent_delta2ns(0xf, &l4timer_clockevent);
    l4timer_clockevent.cpumask = cpumask_of(0);
    clockevents_register_device(&l4timer_clockevent);

    return 0;

out3:
    l4x_unregister_irq(irq);
out2:
    L4XV_FN_v(l4_task_delete_obj(L4RE_THIS_TASK_CAP, timer_irq_cap));
out1:
    l4x_cap_free(timer_irq_cap);
    return r;
}