From b1614191b36e6c00516f5772ea984f96c951d43c Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 11 Dec 2009 19:27:46 +0200 Subject: [PATCH] Reverted all changes - userspace devices mapped at initialization. This is much simpler, no device map/unmap maintenance at run-time, no lazy device mapping etc. --- include/l4/api/irq.h | 1 + include/l4/generic/capability.h | 2 +- include/l4/generic/irq.h | 8 +---- include/l4/glue/arm/message.h | 4 ++- include/l4/lib/addr.h | 24 --------------- include/l4/platform/pb926/offsets.h | 1 + src/api/irq.c | 22 ++++++++----- src/generic/capability.c | 9 +++--- src/generic/irq.c | 42 +------------------------ src/generic/resource.c | 16 ---------- src/lib/addr.c | 48 ----------------------------- src/lib/wait.c | 8 ++--- src/platform/pb926/irq.c | 10 +++--- src/platform/pb926/platform.c | 8 +++++ 14 files changed, 42 insertions(+), 161 deletions(-) delete mode 100644 include/l4/lib/addr.h delete mode 100644 src/lib/addr.c diff --git a/include/l4/api/irq.h b/include/l4/api/irq.h index 9bfcfe2..f94a0ba 100644 --- a/include/l4/api/irq.h +++ b/include/l4/api/irq.h @@ -4,6 +4,7 @@ #define IRQ_CONTROL_REGISTER 0 #define IRQ_CONTROL_RELEASE 1 +#define IRQ_CONTROL_WAIT 2 #endif /* __API_IRQ_H__ */ diff --git a/include/l4/generic/capability.h b/include/l4/generic/capability.h index 93382d3..e11a0bc 100644 --- a/include/l4/generic/capability.h +++ b/include/l4/generic/capability.h @@ -105,6 +105,6 @@ int cap_cap_check(struct ktcb *task, unsigned int req, unsigned int flags); int cap_mutex_check(unsigned long mutex_address, int mutex_op); int cap_irq_check(struct ktcb *registrant, unsigned int req, - unsigned int flags, l4id_t irq, struct capability **cap); + unsigned int flags, l4id_t irq); #endif /* __GENERIC_CAPABILITY_H__ */ diff --git a/include/l4/generic/irq.h b/include/l4/generic/irq.h index a52fb0c..0ddc830 100644 --- a/include/l4/generic/irq.h +++ b/include/l4/generic/irq.h @@ -45,12 +45,6 @@ struct irq_desc { /* Notification slot for this irq */ int task_notify_slot; - /* Device virtual address */ - unsigned long device_virtual; - - /* Device capability */ - struct capability *devcap; - /* NOTE: This could be a list for multiple handlers for shared irqs */ irq_handler_t handler; }; @@ -74,8 +68,8 @@ static inline void irq_disable(int irq_index) this_chip->ops.ack_and_mask(irq_index - this_chip->start); } -void irq_generic_map_device(struct irq_desc *desc); int irq_register(struct ktcb *task, int notify_slot, l4id_t irq_index); +int irq_thread_notify(struct irq_desc *desc); void do_irq(void); void irq_controllers_init(void); diff --git a/include/l4/glue/arm/message.h b/include/l4/glue/arm/message.h index 8a4ad4b..f89dd23 100644 --- a/include/l4/glue/arm/message.h +++ b/include/l4/glue/arm/message.h @@ -73,6 +73,8 @@ #define MR0_REGISTER r3 #define MR_RETURN_REGISTER r3 +#define TASK_NOTIFY_MAX 8 + /* Primaries aren't used for memcopy. Those ops use this as a parameter */ #define L4_UTCB_FULL_BUFFER_SIZE (MR_REST * sizeof(int)) @@ -83,7 +85,7 @@ struct utcb { u32 mr[MR_TOTAL]; /* MRs that are mapped to real registers */ u32 saved_tag; /* Saved tag field for stacked ipcs */ u32 saved_sender; /* Saved sender field for stacked ipcs */ - u8 notify_slot[8]; /* Irq notification slots */ + u8 notify[TASK_NOTIFY_MAX]; /* Irq notification slots */ u32 mr_rest[MR_REST]; /* Complete the utcb for up to 64 words */ }; #endif diff --git a/include/l4/lib/addr.h b/include/l4/lib/addr.h deleted file mode 100644 index dc1ddcf..0000000 --- a/include/l4/lib/addr.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Address allocation pool - * - * Copyright (C) 2007 - 2009 Bahadir Balban - */ -#ifndef __KERNEL_ADDR_H__ -#define __KERNEL_ADDR_H__ - -#include - -/* Address pool to allocate from a range of addresses */ -struct address_pool { - struct id_pool idpool; - unsigned long start; - unsigned long end; -}; - -void *kernel_new_address(int npages); -int kernel_delete_address(void *addr, int npages); - -void *address_new(struct address_pool *pool, int npages); -int address_del(struct address_pool *, void *addr, int npages); - -#endif /* __KERNEL_ADDR_H__ */ diff --git a/include/l4/platform/pb926/offsets.h b/include/l4/platform/pb926/offsets.h index 36bb21c..ef769a3 100644 --- a/include/l4/platform/pb926/offsets.h +++ b/include/l4/platform/pb926/offsets.h @@ -43,6 +43,7 @@ #define PB926_SIC_VOFFSET 0x00003000 #define PB926_SYSREGS_VOFFSET 0x00004000 #define PB926_SYSCTRL_VOFFSET 0x00005000 +#define PB926_TIMER23_VOFFSET 0x00006000 #define PLATFORM_CONSOLE_VIRTUAL (IO_AREA0_VADDR + PB926_UART0_VOFFSET) #define PLATFORM_TIMER0_VIRTUAL (IO_AREA0_VADDR + PB926_TIMER01_VOFFSET) diff --git a/src/api/irq.c b/src/api/irq.c index 8593714..9e0a982 100644 --- a/src/api/irq.c +++ b/src/api/irq.c @@ -69,9 +69,7 @@ int irq_thread_notify(struct irq_desc *desc) * Register the given globally unique irq number with the * current thread with given flags */ -int irq_control_register(struct ktcb *task, int slot, l4id_t irqnum, - unsigned long device_virtual, - struct capability *devcap) +int irq_control_register(struct ktcb *task, int slot, l4id_t irqnum) { int err; @@ -87,12 +85,18 @@ int irq_control_register(struct ktcb *task, int slot, l4id_t irqnum, return err; /* Register the irq for thread notification */ - if ((err = irq_register(current, slot, irqnum, devcap)) < 0) + if ((err = irq_register(current, slot, irqnum)) < 0) return err; return 0; } +int irq_wait() +{ + return 0; +} + + /* * Register/deregister device irqs. Optional synchronous and * asynchronous irq handling. @@ -101,17 +105,19 @@ int sys_irq_control(unsigned int req, unsigned int flags, l4id_t irqno) { /* Currently a task is allowed to register only for itself */ struct ktcb *task = current; - struct capability *devcap; int err; - if ((err = cap_irq_check(task, req, flags, irqno, &devcap)) < 0) + if ((err = cap_irq_check(task, req, flags, irqno)) < 0) return err; switch (req) { case IRQ_CONTROL_REGISTER: - if ((err = irq_control_register(task, slot, flags, - irqno, devcap)) < 0) + if ((err = irq_control_register(task, flags, irqno)) < 0) return err; + break; + case IRQ_CONTROL_WAIT: + irq_wait(); + break; default: return -EINVAL; } diff --git a/src/generic/capability.c b/src/generic/capability.c index 2174419..d339331 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -877,8 +877,7 @@ int cap_thread_check(struct ktcb *task, int cap_irq_check(struct ktcb *registrant, unsigned int req, - unsigned int flags, l4id_t irq, - struct capability **device_cap) + unsigned int flags, l4id_t irq) { struct sys_irqctrl_args args = { .registrant = registrant, @@ -896,8 +895,8 @@ int cap_irq_check(struct ktcb *registrant, unsigned int req, * Find the device capability and * check that it allows irq registration */ - if (!(*device_cap = cap_find(current, cap_match_devmem, - &args, CAP_TYPE_MAP_PHYSMEM))) + if (!cap_find(current, cap_match_devmem, + &args, CAP_TYPE_MAP_PHYSMEM)) return -ENOCAP; return 0; @@ -940,7 +939,7 @@ int cap_thread_check(struct ktcb *task, } int cap_irq_check(struct ktcb *registrant, unsigned int req, - unsigned int flags, l4id_t irq, struct capability **cap) + unsigned int flags, l4id_t irq) { return 0; } diff --git a/src/generic/irq.c b/src/generic/irq.c index 4708726..caef511 100644 --- a/src/generic/irq.c +++ b/src/generic/irq.c @@ -15,34 +15,6 @@ #include INC_PLAT(irq.h) #include INC_ARCH(exception.h) -/* - * Checks that a device was validly registered for the irq, - * and lazily maps it to currently interrupted process. - */ -void irq_generic_map_device(struct irq_desc *desc) -{ - /* - * Check that irq is registered with a - * valid device capability and virtual address - */ - if (!desc->devcap || !KERN_ADDR(devcap->device_virtual)) { - printk("Spurious irq. %s irq occured but " - "no device capability or valid virtual device " - "address associated with the irq.\n", - desc->name); - BUG(); - } - - /* Check and lazy map device */ - if (check_access(desc->device_virtual, - desc->devcap->end - desc->devcap->start, - MAP_SVC_RW_FLAGS, 0) < 0) { - add_mapping(__pfn_to_addr(devcap->start), - desc->device_virtual, MAP_SVC_RW_FLAGS, - desc->devcap->end - desc->devcap->start); - } -} - /* * Registers a userspace thread as an irq handler. * @@ -54,8 +26,7 @@ void irq_generic_map_device(struct irq_desc *desc) * If the irq does not have these set up, we cannot allow * the irq registry. */ -int irq_register(struct ktcb *task, int notify_slot, - l4id_t irq_index, struct capability *device) +int irq_register(struct ktcb *task, int notify_slot, l4id_t irq_index) { struct irq_desc *this_desc = irq_desc_array + irq_index; @@ -67,17 +38,6 @@ int irq_register(struct ktcb *task, int notify_slot, this_desc->task = task; this_desc->task_notify_slot = notify_slot; - /* - * Setup capability and allocate virtual kernel address. - * - * This is required so that the irq handler may reach - * the device from the kernel at any runnable process. - */ - this_desc->devcap = device; - if (!(this_desc->device_virtual = - kernel_new_address(device->end - device->start))) - return -ENOMEM; - /* Enable the irq */ irq_enable(irq_index); diff --git a/src/generic/resource.c b/src/generic/resource.c index 9f78cdd..2060032 100644 --- a/src/generic/resource.c +++ b/src/generic/resource.c @@ -416,19 +416,6 @@ int free_boot_memory(struct kernel_resources *kres) return 0; } -void kernel_address_pool_init(struct kernel_resources *kres) -{ - /* Initialize id pool spinlock */ - spin_lock_init(&kres->kernel_address_pool.idpool.lock); - - /* Initialize id pool number of words */ - kres->kernel_address_pool.idpool.nwords = SYSTEM_IDS_MAX; - - /* Initialize address pool start and end ranges */ - kres->kernel_address_pool.start = page_align_up(_end); - kres->kernel_address_pool.end = KERNEL_AREA_END; -} - /* * Initializes kernel caplists, and sets up total of physical * and virtual memory as single capabilities of the kernel. @@ -448,9 +435,6 @@ void init_kernel_resources(struct kernel_resources *kres) kres->mutex_ids.nwords = SYSTEM_IDS_MAX; kres->capability_ids.nwords = SYSTEM_IDS_MAX; - /* Initialize kernel's virtual address pool */ - kernel_address_pool_init(kres); - /* Initialize container head */ container_head_init(&kres->containers); diff --git a/src/lib/addr.c b/src/lib/addr.c deleted file mode 100644 index c12a67b..0000000 --- a/src/lib/addr.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This module allocates an unused address range from - * a given memory region defined as the pool range. - * - * Copyright (C) 2007 - 2009 Bahadir Balban - */ -#include -#include -#include -#include INC_GLUE(memory.h) -#include -#include - - -extern struct kernel_resources kres; - -void *address_new(struct address_pool *pool, int npages) -{ - unsigned int pfn; - - if ((int)(pfn = ids_new_contiguous(pool->idpool, npages)) < 0) - return 0; - - return (void *)__pfn_to_addr(pfn) + pool->start; -} - -int address_del(struct address_pool *pool, void *addr, int npages) -{ - unsigned long pfn = __pfn(page_align(addr) - pool->start); - - if (ids_del_contiguous(pool->idpool, pfn, npages) < 0) { - printf("%s: Invalid address range returned to " - "virtual address pool.\n", __FUNCTION__); - return -1; - } - return 0; -} - -void *kernel_new_address(int npages) -{ - return address_new(&kres->kernel_address_pool, npages); -} - -int kernel_delete_address(void *addr, int npages) -{ - address_del(&kres->kernel_address_pool, addr, npages); -} - diff --git a/src/lib/wait.c b/src/lib/wait.c index 48955ff..c368b74 100644 --- a/src/lib/wait.c +++ b/src/lib/wait.c @@ -139,13 +139,13 @@ void wake_up_all(struct waitqueue_head *wqh, unsigned int flags) /* Wake up single waiter */ void wake_up(struct waitqueue_head *wqh, unsigned int flags) { - unsigned int irqflags; + unsigned long irqflags; BUG_ON(wqh->sleepers < 0); /* Irq version */ if (flags & WAKEUP_IRQ) - spin_lock_irq(&wqh->lock, &irqflags); + spin_lock_irq(&wqh->slock, &irqflags); else spin_lock(&wqh->slock); if (wqh->sleepers > 0) { @@ -161,7 +161,7 @@ void wake_up(struct waitqueue_head *wqh, unsigned int flags) sleeper->flags |= TASK_INTERRUPTED; //printk("(%d) Waking up (%d)\n", current->tid, sleeper->tid); if (flags & WAKEUP_IRQ) - spin_unlock_irqrestore(&wqh->slock, irqflags); + spin_unlock_irq(&wqh->slock, irqflags); else spin_unlock(&wqh->slock); @@ -172,7 +172,7 @@ void wake_up(struct waitqueue_head *wqh, unsigned int flags) return; } if (flags & WAKEUP_IRQ) - spin_unlock_irqrestore(&wqh->slock, irqflags); + spin_unlock_irq(&wqh->slock, irqflags); else spin_unlock(&wqh->slock); } diff --git a/src/platform/pb926/irq.c b/src/platform/pb926/irq.c index ce2d5f9..f4d58b2 100644 --- a/src/platform/pb926/irq.c +++ b/src/platform/pb926/irq.c @@ -54,13 +54,10 @@ static int platform_timer_handler(struct irq_desc *desc) /* * Timer handler for userspace */ -static int platform_user_timer_irq_handler(struct irq_desc *desc) +static int platform_timer_user_handler(struct irq_desc *desc) { - /* Lazily map the device to process kernel tables */ - irq_generic_map_device(desc); - /* Ack the device irq */ - sp804_irq_handler(desc->device_virtual); + sp804_irq_handler(PLATFORM_TIMER1_VIRTUAL); /* Notify the userspace */ irq_thread_notify(desc); @@ -82,7 +79,8 @@ struct irq_desc irq_desc_array[IRQS_MAX] = { [IRQ_TIMER1] = { .name = "Timer1", .chip = &irq_chip_array[0], - .handler = platform_user_timer_handler + .handler = platform_timer_user_handler, + }, }; diff --git a/src/platform/pb926/platform.c b/src/platform/pb926/platform.c index 5ecdeee..be6102c 100644 --- a/src/platform/pb926/platform.c +++ b/src/platform/pb926/platform.c @@ -121,10 +121,18 @@ void init_platform_irq_controller() irq_controllers_init(); } +void init_platform_devices() +{ + /* Add userspace devices here as you develop their irq handlers */ + add_boot_mapping(PB926_TIMER23_BASE, PLATFORM_TIMER1_VIRTUAL, + PAGE_SIZE, MAP_IO_DEFAULT_FLAGS); +} + void platform_init(void) { init_platform_console(); init_platform_timer(); init_platform_irq_controller(); + init_platform_devices(); }