Ejemplo n.º 1
0
void *phys_map(phys_addr_t addr, size_t size, int mmflag)
{
	phys_addr_t base;
	phys_addr_t end;
	void *ret = NULL;

	if (!size) {
		/* What do you want to do??? */
		ASSERT(0);
		goto out;
	}

	/* Use the physical map area if the range lies within it. For more
	 * information please refer to the memory layout of our system.
	 */
	if (PMAP_CONTAINS(addr, size)) {
		ret = (void *)addr;
		goto out;
	}

	base = ROUND_DOWN(addr, PAGE_SIZE);
	end = ROUND_UP(addr + size, PAGE_SIZE);
	ASSERT(end > base);
	
	/* Map pages from kernel memory */
	ret = kmem_map(base, end - base, mmflag);
	if (ret) {
		ret = (char *)ret + (addr - base);	// Don't miss the offset
	}
	
	DEBUG(DL_DBG, ("addr(%x), size(%x), ret(%p).\n", addr, size, ret));

 out:
	return ret;
}
Ejemplo n.º 2
0
Archivo: main.c Proyecto: nielh/dragon
void kmain(s64 magic, s64 info)
{
	//vga_clear(COLOR_BLACK);
    idt_init();
    isr_init();

    serial_init();
	set_debug_traps();
    BREAKPOINT();

	cpuid_print();
	multiboot(magic, info);
	kmem_map();
    page_init();
    kmalloc_init();
    //vesa_init();

    root_init();
    pci_init();
    vm_init();
    syscall_init();
    timer_init();
    kbd_init();
    //mouse_init();

    console_init();

 	create_kthread(NULL, idle_thread, THREAD_PRI_LOW, NULL, NULL);
 	create_kthread(NULL, init_thread, THREAD_PRI_NORMAL, NULL, NULL);

    thread_schedule();
}
Ejemplo n.º 3
0
/** Map physical memory into the kernel address space.
 * @param addr		Physical address to map.
 * @param size		Size of range to map.
 * @param mmflag	Allocation flags.
 * @return		Pointer to mapped data. */
void *phys_map(phys_ptr_t addr, size_t size, unsigned mmflag) {
	phys_ptr_t base, end;

	if(unlikely(!size))
		return NULL;

	/* Use the physical map area if the range lies within it. */
	if(PMAP_CONTAINS(addr, size))
		return (void *)(KERNEL_PMAP_BASE + (addr - KERNEL_PMAP_OFFSET));

	/* Outside the physical map area. Must instead allocate some kernel
	 * memory space and map there. */
	base = round_down(addr, PAGE_SIZE);
	end = round_up(addr + size, PAGE_SIZE);
	return kmem_map(base, end - base, mmflag);
}
Ejemplo n.º 4
0
Archivo: msg.c Proyecto: uiv/Lerdu
/*
 * Send a message.
 *
 * The current thread will be blocked until any other thread
 * receives and reply the message.  A thread can send a
 * message to any object if it knows the object id.
 */
int
msg_send(object_t obj, void *msg, size_t size)
{
	struct msg_header *hdr;
	thread_t t;
	void *kmsg;
	int rc;

	if (!user_area(msg))
		return EFAULT;

	if (size < sizeof(struct msg_header))
		return EINVAL;

	sched_lock();

	if (!object_valid(obj)) {
		sched_unlock();
		return EINVAL;
	}
	/*
	 * A thread can not send a message when it is
	 * already receiving from the target object.
	 * It will obviously cause a deadlock.
	 */
	if (obj == curthread->recvobj) {
		sched_unlock();
		return EDEADLK;
	}
	/*
	 * Translate message address to the kernel linear
	 * address.  So that a receiver thread can access
	 * the message via kernel pointer. We can catch
	 * the page fault here.
	 */
	if ((kmsg = kmem_map(msg, size)) == NULL) {
		sched_unlock();
		return EFAULT;
	}
	curthread->msgaddr = kmsg;
	curthread->msgsize = size;

	/*
	 * The sender ID is filled in the message header
	 * by the kernel. So, the receiver can trust it.
	 */
	hdr = (struct msg_header *)kmsg;
	hdr->task = curtask;

	/*
	 * If receiver already exists, wake it up.
	 * The highest priority thread can get the message.
	 */
	if (!queue_empty(&obj->recvq)) {
		t = msg_dequeue(&obj->recvq);
		sched_unsleep(t, 0);
	}
	/*
	 * Sleep until we get a reply message.
	 * Note: Do not touch any data in the object
	 * structure after we wakeup. This is because the
	 * target object may be deleted while we are sleeping.
	 */
	curthread->sendobj = obj;
	msg_enqueue(&obj->sendq, curthread);
	rc = sched_sleep(&ipc_event);
	if (rc == SLP_INTR)
		queue_remove(&curthread->ipc_link);
	curthread->sendobj = NULL;

	sched_unlock();

	/*
	 * Check sleep result.
	 */
	switch (rc) {
	case SLP_BREAK:
		return EAGAIN;	/* Receiver has been terminated */
	case SLP_INVAL:
		return EINVAL;	/* Object has been deleted */
	case SLP_INTR:
		return EINTR;	/* Exception */
	default:
		/* DO NOTHING */
		break;
	}
	return 0;
}
Ejemplo n.º 5
0
Archivo: msg.c Proyecto: AndrewD/prex
/*
 * Send a message.
 *
 * The current thread will be blocked until any other thread
 * receives the message and calls msg_reply() for the target
 * object. When new message has been reached to the object, it
 * will be received by highest priority thread waiting for
 * that message. A thread can send a message to any object if
 * it knows the object id.
 */
int
msg_send(object_t obj, void *msg, size_t size, u_long timeout)
{
	struct msg_header *hdr;
	thread_t th;
	void *kmsg;
	int rc;

	if (!user_area(msg))
		return EFAULT;

	if (size < sizeof(struct msg_header))
		return EINVAL;

	sched_lock();

	if (!object_valid(obj)) {
		sched_unlock();
		return EINVAL;
	}
	if (obj->owner != cur_task() && !task_capable(CAP_IPC)) {
		sched_unlock();
		return EPERM;
	}
	/*
	 * A thread can not send a message when the
	 * thread is already receiving from the target
	 * object. This will obviously cause a deadlock.
	 */
	if (obj == cur_thread->recvobj) {
		sched_unlock();
		return EDEADLK;
	}
	/*
	 * Translate message address to the kernel linear
	 * address.  So that a receiver thread can access
	 * the message via kernel pointer. We can catch
	 * the page fault here.
	 */
	if ((kmsg = kmem_map(msg, size)) == NULL) {
		/* Error - no physical address for the message */
		sched_unlock();
		return EFAULT;
	}
	/*
	 * The sender ID in the message header is filled
	 * by the kernel. So, the receiver can trust it.
	 */
	hdr = (struct msg_header *)kmsg;
	hdr->task = cur_task();

	/* Save information about the message block. */
	cur_thread->msgaddr = kmsg;
	cur_thread->msgsize = size;

	/*
	 * If receiver already exists, wake it up.
	 * Highest priority thread will get this message.
	 */
	if (!queue_empty(&obj->recvq)) {
		th = msg_dequeue(&obj->recvq);
		sched_unsleep(th, 0);
	}
	/*
	 * Sleep until we get a reply message.
	 * Note: Do not touch any data in the object
	 * structure after we wakeup. This is because the
	 * target object may be deleted during we were
	 * sleeping.
	 */
	cur_thread->sendobj = obj;
	msg_enqueue(&obj->sendq, cur_thread);
	rc = sched_tsleep(&ipc_event, timeout);
	if (rc == SLP_INTR)
		queue_remove(&cur_thread->ipc_link);
	cur_thread->sendobj = NULL;

	sched_unlock();

	/*
	 * Check sleep result.
	 */
	switch (rc) {
	case SLP_BREAK:
		return EAGAIN;	/* Receiver has been terminated */
	case SLP_INVAL:
		return EINVAL;	/* Object has been deleted */
	case SLP_INTR:
		return EINTR;	/* Exception */
	case SLP_TIMEOUT:
		return ETIMEDOUT;	/* Timeout */
	default:
		/* DO NOTHING */
		break;
	}
	return 0;
}