Here are the files added:
include/linux/adeos.h | 188 ++++++++++++
kernel/adeos.c | 712 ++++++++++++++++++++++++++++++++++++++++++++++
Here are the files modified:
include/linux/init_task.h | 51 +++
include/linux/sched.h | 4
init/Config.in | 1
init/main.c | 3
kernel/Makefile | 3
kernel/fork.c | 8
kernel/ksyms.c | 32 ++
kernel/printk.c | 114 +++++++
kernel/sched.c | 8
kernel/sysctl.c | 3
12 files changed, 1125 insertions, 2 deletions
These modifications are only aimed at making sure that Linux plays nice
with the other domains in the pipeline.
The project's web site is located here:
http://www.nongnu.org/adeos/
Any feedback is appreciated.
diff -urpN linux-2.5.38/include/linux/adeos.h linux-2.5.38-adeos/include/linux/adeos.h
--- linux-2.5.38/include/linux/adeos.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.38-adeos/include/linux/adeos.h Sun Sep 22 21:57:19 2002
@@ -0,0 +1,188 @@
+/*
+ * include/linux/adeos.h
+ *
+ * Copyright (C) 2002 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LINUX_ADEOS_H
+#define __LINUX_ADEOS_H
+
+#include <asm/adeos.h>
+
+#define ADEOS_VERSION_STRING "2.5r1c4/x86"
+
+#define ADEOS_ROOT_PRI 100
+#define ADEOS_ROOT_ID 0
+#define ADEOS_ROOT_NPTDKEYS 4 /* Must be <= 32 */
+
+#define ADEOS_OTHER_CPUS (-1)
+#define ADEOS_RESET_TIMER 0x1
+
+#define IPIPE_STALL_FLAG 0 /* Stalls a pipeline stage */
+#define IPIPE_SYNC_FLAG 1 /* IRQ sync is undergoing */
+#define IPIPE_XPEND_FLAG 2 /* Exception notification is pending */
+#define IPIPE_SLEEP_FLAG 3 /* Domain has suspended itself */
+
+#define IPIPE_HANDLE_FLAG 0
+#define IPIPE_PASS_FLAG 1
+#define IPIPE_CALLASM_FLAG 2
+#define IPIPE_ENABLE_FLAG 3
+#define IPIPE_DYNAMIC_FLAG IPIPE_HANDLE_FLAG
+#define IPIPE_EXCLUSIVE_FLAG 4
+
+#define IPIPE_HANDLE_MASK (1 << IPIPE_HANDLE_FLAG)
+#define IPIPE_PASS_MASK (1 << IPIPE_PASS_FLAG)
+#define IPIPE_CALLASM_MASK (1 << IPIPE_CALLASM_FLAG)
+#define IPIPE_ENABLE_MASK (1 << IPIPE_ENABLE_FLAG)
+#define IPIPE_DYNAMIC_MASK IPIPE_HANDLE_MASK
+#define IPIPE_EXCLUSIVE_MASK (1 << IPIPE_EXCLUSIVE_FLAG)
+
+#define IPIPE_DEFAULT_MASK (IPIPE_HANDLE_MASK|IPIPE_PASS_MASK)
+
+typedef struct adattr {
+
+ unsigned domid; /* Domain identifier -- Magic value set by caller */
+ const char *name; /* Domain name -- Warning: won't be dup'ed! */
+ int priority; /* Priority in interrupt pipeline */
+ void (*entry)(void); /* Domain entry point */
+ int estacksz; /* Stack size for entry context -- 0 means unspec */
+ void (*dswitch)(void); /* Handler called each time the domain is switched in */
+ int nptdkeys; /* Max. number of per-thread data keys */
+ void (*ptdset)(int,void *); /* Routine to set pt values */
+ void *(*ptdget)(int); /* Routine to get pt values */
+
+} adattr_t;
+
+extern adomain_t *adp_cpu_current[],
+ *adp_root;
+
+#define adp_current (adp_cpu_current[adeos_processor_id()])
+
+int adeos_register_domain(adomain_t *adp,
+ adattr_t *attr);
+
+int adeos_unregister_domain(adomain_t *adp);
+
+void adeos_renice_domain(adomain_t *adp,
+ int newpri);
+
+void adeos_suspend_domain(void);
+
+int adeos_virtualize_irq(unsigned irq,
+ void (*handler)(unsigned irq),
+ int (*acknowledge)(unsigned irq),
+ unsigned modemask);
+
+int adeos_control_irq(unsigned irq,
+ unsigned clrmask,
+ unsigned setmask);
+
+int FASTCALL(adeos_propagate_irq(unsigned irq));
+
+unsigned adeos_alloc_irq(void);
+
+int adeos_free_irq(unsigned irq);
+
+int FASTCALL(adeos_trigger_irq(unsigned irq));
+
+int FASTCALL(adeos_trigger_ipi(int cpuid));
+
+void adeos_stall_ipipe(void);
+
+static inline void adeos_stall_ipipe_from (adomain_t *adp) {
+
+ ipipe_declare_cpuid;
+ set_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);
+}
+
+void adeos_unstall_ipipe(void);
+
+void adeos_unstall_ipipe_from(adomain_t *adp);
+
+static inline unsigned long adeos_test_ipipe_from (adomain_t *adp) {
+
+ return test_bit(IPIPE_STALL_FLAG,&adp->cpudata[adeos_processor_id()].status);
+}
+
+static inline unsigned long adeos_test_ipipe (void) {
+
+ return adeos_test_ipipe_from(adp_current);
+}
+
+static inline unsigned long adeos_test_and_stall_ipipe_from (adomain_t *adp) {
+
+ return test_and_set_bit(IPIPE_STALL_FLAG,&adp->cpudata[adeos_processor_id()].status);
+}
+
+static inline unsigned long adeos_test_and_stall_ipipe (void) {
+
+ return adeos_test_and_stall_ipipe_from(adp_current);
+}
+
+static inline void adeos_restore_ipipe_from (adomain_t *adp, unsigned long flags) {
+
+ ipipe_declare_cpuid;
+
+ if (flags)
+ set_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);
+ else
+ {
+ clear_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);
+
+ if (adp == adp_current &&
+ adp->cpudata[cpuid].irq_pending_hi != 0)
+ ipipe_sync_irqs();
+ }
+}
+
+static inline void adeos_restore_ipipe (unsigned long flags) {
+
+ adeos_restore_ipipe_from(adp_current,flags);
+}
+
+int adeos_catch_event(unsigned event,
+ void (*handler)(adevinfo_t *));
+
+static inline void adeos_propagate_event(adevinfo_t *evinfo) {
+
+ evinfo->propagate = 1;
+}
+
+void (*adeos_hook_dswitch(void (*handler)(void)))(void);
+
+void adeos_init_attr(adattr_t *attr);
+
+int adeos_get_sysinfo(adsysinfo_t *sysinfo);
+
+int adeos_tune_timer(unsigned long ns,
+ int flags);
+
+int adeos_alloc_ptdkey(void);
+
+int adeos_free_ptdkey(int key);
+
+int adeos_set_ptd(int key,
+ void *value);
+
+void *adeos_get_ptd(int key);
+
+unsigned long adeos_critical_enter(void (*syncfn)(void));
+
+void adeos_critical_exit(unsigned long flags);
+
+#endif /* !__LINUX_ADEOS_H */
diff -urpN linux-2.5.38/include/linux/init_task.h linux-2.5.38-adeos/include/linux/init_task.h
--- linux-2.5.38/include/linux/init_task.h Sun Sep 22 00:25:00 2002
+++ linux-2.5.38-adeos/include/linux/init_task.h Sun Sep 22 21:57:19 2002
@@ -54,6 +54,8 @@
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
*/
+#ifdef CONFIG_ADEOS
+
#define INIT_TASK(tsk) \
{ \
.state = 0, \
@@ -98,8 +100,57 @@
.alloc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
+ .ptd = { [ 0 ... ADEOS_ROOT_NPTDKEYS - 1] = 0 }, \
}
+#else /* !CONFIG_ADEOS */
+
+#define INIT_TASK(tsk) \
+{ \
+ .state = 0, \
+ .thread_info = &init_thread_info, \
+ .flags = 0, \
+ .lock_depth = -1, \
+ .prio = MAX_PRIO-20, \
+ .static_prio = MAX_PRIO-20, \
+ .policy = SCHED_NORMAL, \
+ .cpus_allowed = -1, \
+ .mm = NULL, \
+ .active_mm = &init_mm, \
+ .run_list = LIST_HEAD_INIT(tsk.run_list), \
+ .time_slice = HZ, \
+ .tasks = LIST_HEAD_INIT(tsk.tasks), \
+ .ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \
+ .ptrace_list = LIST_HEAD_INIT(tsk.ptrace_list), \
+ .real_parent = &tsk, \
+ .parent = &tsk, \
+ .children = LIST_HEAD_INIT(tsk.children), \
+ .sibling = LIST_HEAD_INIT(tsk.sibling), \
+ .group_leader = &tsk, \
+ .thread_group = LIST_HEAD_INIT(tsk.thread_group), \
+ .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
+ .real_timer = { \
+ .function = it_real_fn \
+ }, \
+ .cap_effective = CAP_INIT_EFF_SET, \
+ .cap_inheritable = CAP_INIT_INH_SET, \
+ .cap_permitted = CAP_FULL_SET, \
+ .keep_capabilities = 0, \
+ .rlim = INIT_RLIMITS, \
+ .user = INIT_USER, \
+ .comm = "swapper", \
+ .thread = INIT_THREAD, \
+ .fs = &init_fs, \
+ .files = &init_files, \
+ .sigmask_lock = SPIN_LOCK_UNLOCKED, \
+ .sig = &init_signals, \
+ .pending = { NULL, &tsk.pending.head, {{0}}}, \
+ .blocked = {{0}}, \
+ .alloc_lock = SPIN_LOCK_UNLOCKED, \
+ .switch_lock = SPIN_LOCK_UNLOCKED, \
+ .journal_info = NULL, \
+}
+#endif /* CONFIG_ADEOS */
#endif
diff -urpN linux-2.5.38/include/linux/sched.h linux-2.5.38-adeos/include/linux/sched.h
--- linux-2.5.38/include/linux/sched.h Sun Sep 22 00:25:00 2002
+++ linux-2.5.38-adeos/include/linux/sched.h Sun Sep 22 21:57:19 2002
@@ -398,6 +398,10 @@ struct task_struct {
/* journalling filesystem info */
void *journal_info;
struct dentry *proc_dentry;
+
+#ifdef CONFIG_ADEOS
+ void *ptd[ADEOS_ROOT_NPTDKEYS];
+#endif /* CONFIG_ADEOS */
};
extern void __put_task_struct(struct task_struct *tsk);
diff -urpN linux-2.5.38/init/Config.in linux-2.5.38-adeos/init/Config.in
--- linux-2.5.38/init/Config.in Sun Sep 22 00:25:01 2002
+++ linux-2.5.38-adeos/init/Config.in Sun Sep 22 21:57:19 2002
@@ -5,6 +5,7 @@ endmenu
mainmenu_option next_comment
comment 'General setup'
+bool 'Adaptive Domain Environment support' CONFIG_ADEOS
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
diff -urpN linux-2.5.38/init/main.c linux-2.5.38-adeos/init/main.c
--- linux-2.5.38/init/main.c Sun Sep 22 00:25:02 2002
+++ linux-2.5.38-adeos/init/main.c Sun Sep 22 21:57:19 2002
@@ -396,6 +396,9 @@ asmlinkage void __init start_kernel(void
build_all_zonelists();
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
+#ifdef CONFIG_ADEOS
+ __adeos_init();
+#endif /* CONFIG_ADEOS */
trap_init();
init_IRQ();
sched_init();
diff -urpN linux-2.5.38/kernel/Makefile linux-2.5.38-adeos/kernel/Makefile
--- linux-2.5.38/kernel/Makefile Sun Sep 22 00:25:03 2002
+++ linux-2.5.38-adeos/kernel/Makefile Sun Sep 22 21:57:19 2002
@@ -3,7 +3,7 @@
#
export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
- printk.o platform.o suspend.o dma.o
+ printk.o platform.o suspend.o dma.o adeos.o
obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o time.o softirq.o resource.o \
@@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += ksyms.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_ADEOS) += adeos.o
ifneq ($(CONFIG_IA64),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -urpN linux-2.5.38/kernel/adeos.c linux-2.5.38-adeos/kernel/adeos.c
--- linux-2.5.38/kernel/adeos.c Wed Dec 31 19:00:00 1969
+++ linux-2.5.38-adeos/kernel/adeos.c Sun Sep 22 21:57:19 2002
@@ -0,0 +1,712 @@
+/*
+ * linux/kernel/adeos.c
+ *
+ * Copyright (C) 2002 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * This code implements the architecture-independent ADEOS support.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+
+/* The pre-defined domain slot for the root domain. */
+static adomain_t adeos_root_domain;
+
+/* A constant pointer to the root domain. */
+adomain_t *adp_root = &adeos_root_domain;
+
+/* A pointer to the current domain. */
+adomain_t *adp_cpu_current[ADEOS_NR_CPUS] = { [ 0 ... ADEOS_NR_CPUS - 1] = &adeos_root_domain };
+
+/* The spinlock protecting from races while modifying the pipeline. */
+spinlock_t adeos_pipelock = SPIN_LOCK_UNLOCKED;
+
+/* The pipeline data structure. Enqueues adomain_t objects by priority. */
+struct list_head adeos_pipeline;
+
+/* An array of global counters tracking domains monitoring events. */
+int __adeos_event_monitors[ADEOS_NR_EVENTS] = { [ 0 ... ADEOS_NR_EVENTS - 1] = 0 };
+
+/* Number of on-line CPUS. */
+int __adeos_online_cpus = 1;
+
+/* adeos_init() -- Initialization routine of the ADEOS layer. Called
+ by the host kernel early during the boot procedure. */
+
+void __adeos_init (void)
+
+{
+ adattr_t attr;
+
+ printk("ADEOS %s enabled.\n",ADEOS_VERSION_STRING);
+
+ INIT_LIST_HEAD(&adeos_pipeline);
+ __adeos_online_cpus = smp_num_cpus;
+
+ attr.domid = ADEOS_ROOT_ID;
+ attr.name = "Linux";
+ attr.entry = NULL;
+ attr.priority = ADEOS_ROOT_PRI;
+ attr.estacksz = 0; /* Unused. */
+ attr.dswitch = NULL;
+ attr.nptdkeys = ADEOS_ROOT_NPTDKEYS;
+ attr.ptdset = &__adeos_set_root_ptd;
+ attr.ptdget = &__adeos_get_root_ptd;
+
+ adeos_register_domain(&adeos_root_domain,&attr);
+}
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/proc_fs.h>
+
+static struct proc_dir_entry *adeos_proc_entry;
+
+static int __adeos_read_proc (char *page,
+ char **start,
+ off_t off,
+ int count,
+ int *eof,
+ void *data)
+{
+ struct list_head *pos;
+ unsigned long flags;
+ char *p = page;
+ int len;
+
+ p += sprintf(p,"Prio\tID\t\tDomain\n\n");
+
+ ipipe_hw_save_flags_and_cli(flags);
+
+ list_for_each(pos,&adeos_pipeline) {
+ adomain_t *adp = list_entry(pos,adomain_t,link);
+ p += sprintf(p," %d\t0x%.8x\t%s\n",
+ adp->priority,
+ adp->domid,
+ adp->name);
+ }
+
+ ipipe_hw_restore_flags(flags);
+
+ len = p - page;
+
+ if (len <= off + count)
+ *eof = 1;
+
+ *start = page + off;
+
+ len -= off;
+
+ if (len > count)
+ len = count;
+
+ if (len < 0)
+ len = 0;
+
+ return len;
+}
+
+void __adeos_init_proc (void) {
+
+ adeos_proc_entry = create_proc_read_entry("adeos",
+ 0444,
+ NULL,
+ &__adeos_read_proc,
+ NULL);
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/* adeos_register_domain() -- Add a new domain to the system. All
+ client domains must call this routine to register themselves to
+ ADEOS before using its services. */
+
+int adeos_register_domain (adomain_t *adp, adattr_t *attr)
+
+{
+ struct list_head *pos;
+ unsigned long flags;
+ ipipe_declare_cpuid;
+ int n;
+
+ if (adp_current != adp_root)
+ {
+ printk(KERN_WARNING "ADEOS: Only the root domain may register a new domain.\n");
+ return -EPERM;
+ }
+
+ for (n = 0; n < ADEOS_NR_CPUS; n++)
+ {
+ adp->cpudata[n].status = 0;
+
+ /* A special case for domains who won't process events. We
+ need to act as if they had suspended themselves. */
+
+ if (attr->entry == NULL && adp != adp_root)
+ set_bit(IPIPE_SLEEP_FLAG,&adp->cpudata[n].status);
+ }
+
+ /* A special case for domains who won't process events (i.e. no
+ entry). We have to mark them as suspended so that
+ adeos_suspend_domain() won't consider them, unless they
+ _actually_ receive events, which would lead to a panic
+ situation since they have no stack context... :o> */
+
+ if (attr->entry == NULL && adp != adp_root)
+ for (n = 0; n < ADEOS_NR_CPUS; n++)
+ set_bit(IPIPE_SLEEP_FLAG,&adp->cpudata[n].status);
+
+ adp->name = attr->name;
+ adp->priority = attr->priority;
+ adp->domid = attr->domid;
+ adp->dswitch = attr->dswitch;
+ adp->ptd_setfun = attr->ptdset;
+ adp->ptd_getfun = attr->ptdget;
+ adp->ptd_keymap = 0;
+ adp->ptd_keycount = 0;
+ adp->ptd_keymax = attr->nptdkeys;
+
+ for (n = 0; n < ADEOS_NR_EVENTS; n++)
+ /* Event handlers must be cleared before the i-pipe stage is
+ inserted since an exception may occur on behalf of the new
+ emerging domain. */
+ adp->events[n].handler = NULL;
+
+ if (attr->entry != NULL)
+ __adeos_bootstrap_domain(adp,attr);
+
+ printk("ADEOS: Domain %s registered.\n",adp->name);
+
+ /* Insert the domain in the interrupt pipeline last, so it won't
+ be resumed for processing interrupts until it has a valid stack
+ context. */
+
+ ipipe_init_stage(adp);
+
+ INIT_LIST_HEAD(&adp->link);
+
+ flags = __adeos_critical_enter(NULL);
+
+ list_for_each(pos,&adeos_pipeline) {
+ adomain_t *_adp = list_entry(pos,adomain_t,link);
+ if (adp->priority > _adp->priority)
+ break;
+ }
+
+ list_add_tail(&adp->link,pos);
+
+ __adeos_critical_exit(flags);
+
+ /* Finally, allow the new domain to perform its initialization
+ chores on behalf of its own stack context. */
+
+ if (attr->entry != NULL)
+ {
+ __adeos_switch_domain(adp);
+
+ ipipe_reload_cpuid(); /* Processor might have changed. */
+
+ if (!test_bit(IPIPE_STALL_FLAG,&adp_root->cpudata[cpuid].status) &&
+ adp_root->cpudata[cpuid].irq_pending_hi != 0)
+ ipipe_sync_irqs();
+ }
+
+ return 0;
+}
+
+/* adeos_unregister_domain() -- Remove a domain from the system. All
+ client domains must call this routine to unregister themselves from
+ the ADEOS layer. */
+
+int adeos_unregister_domain (adomain_t *adp)
+
+{
+ unsigned long flags;
+ unsigned event;
+
+ if (adp_current != adp_root)
+ {
+ printk(KERN_WARNING "ADEOS: Only the root domain may unregister a domain.\n");
+ return -EPERM;
+ }
+
+ if (adp == adp_root)
+ {
+ printk(KERN_WARNING "ADEOS: Cannot unregister the root domain.\n");
+ return -EPERM;
+ }
+
+ for (event = 0; event < ADEOS_NR_EVENTS; event++)
+ /* Need this to update the monitor count. */
+ adeos_catch_event(event,NULL);
+
+ /* Simply remove the domain from the pipeline and we are almost
+ done. */
+
+ flags = __adeos_critical_enter(NULL);
+ list_del_init(&adp->link);
+ __adeos_critical_exit(flags);
+
+ __adeos_cleanup_domain(adp);
+
+ printk("ADEOS: Domain %s unregistered.\n",adp->name);
+
+ return 0;
+}
+
+/* adeos_renice_domain() -- Change a domain's priority. This affects
+ the position of the domain in the interrupt pipeline. The greater
+ the priority value, the earlier the domain is informed of incoming
+ events when the pipeline is processed. */
+
+void adeos_renice_domain (adomain_t *adp, int newpri)
+
+{
+ struct list_head *pos;
+ unsigned long flags;
+
+ /* Allows round-robin effect if newpri == oldpri. */
+
+ flags = __adeos_critical_enter(NULL);
+
+ list_del_init(&adp->link);
+
+ list_for_each(pos,&adeos_pipeline) {
+ adomain_t *_adp = list_entry(pos,adomain_t,link);
+ if (newpri > _adp->priority)
+ break;
+ }
+
+ list_add_tail(&adp->link,pos);
+ adp->priority = newpri;
+
+ __adeos_critical_exit(flags);
+}
+
+/* adeos_suspend_domain() -- tell the ADEOS layer that the current
+ domain is now dormant. The calling domain is switched out, while
+ the next domain with work in progress or pending in the pipeline is
+ switched in. */
+
+void adeos_suspend_domain (void)
+
+{
+ struct adcpudata *cpudata;
+ adomain_t *adp, *nadp;
+ struct list_head *ln;
+ unsigned long flags;
+ ipipe_declare_cpuid;
+
+ adp = nadp = adp_cpu_current[cpuid];
+ cpudata = &adp->cpudata[cpuid];
+
+ ipipe_hw_local_irq_save(flags);
+
+ for (;;)
+ {
+ ln = nadp->link.next;
+
+ if (ln == &adeos_pipeline) /* End of pipeline reached? */
+ {
+ /* Caller should loop on its idle task on return. */
+ ipipe_hw_local_irq_restore(flags);
+
+ if (test_and_clear_bit(IPIPE_STALL_FLAG,&cpudata->status) &&
+ cpudata->irq_pending_hi != 0)
+ ipipe_sync_irqs();
+
+ return;
+ }
+
+ nadp = list_entry(ln,adomain_t,link);
+
+ /* Make sure the domain was preempted (i.e. not sleeping) or
+ has some event to process before switching to it. */
+
+ if (!test_bit(IPIPE_SLEEP_FLAG,&nadp->cpudata[cpuid].status) ||
+ nadp->cpudata[cpuid].irq_pending_hi != 0 ||
+ test_bit(IPIPE_XPEND_FLAG,&nadp->cpudata[cpuid].status))
+ break;
+ }
+
+ /* A suspending domain implicitely unstalls the pipeline. */
+ clear_bit(IPIPE_STALL_FLAG,&cpudata->status);
+
+ /* Mark the outgoing domain as aslept (i.e. not preempted). */
+ set_bit(IPIPE_SLEEP_FLAG,&cpudata->status);
+
+ /* Conversely, clear the sleep bit for the incoming domain. */
+ clear_bit(IPIPE_SLEEP_FLAG,&nadp->cpudata[cpuid].status);
+
+ /* Suspend the calling domain, switching to the next one. */
+ __adeos_switch_domain(nadp);
+
+ ipipe_hw_local_irq_restore(flags);
+
+#ifdef CONFIG_SMP
+ ipipe_reload_cpuid(); /* Processor might have changed. */
+ adp = adp_cpu_current[cpuid];
+ cpudata = &adp->cpudata[cpuid];
+#endif
+
+ /* Now, we are back into the calling domain. Flush the interrupt
+ log and fire the event interposition handler if needed. */
+
+ if (cpudata->irq_pending_hi != 0)
+ ipipe_sync_irqs();
+
+ /* Caution: CPU migration is allowed in SMP-mode on behalf of an
+ event handler provided that the current domain raised
+ it. Otherwise, it's not. */
+
+ if (test_and_clear_bit(IPIPE_XPEND_FLAG,&cpudata->status))
+ adp->events[cpudata->event_data.event].handler(&cpudata->event_data);
+
+ /* Return to the point of suspension in the calling domain. */
+}
+
+/* adeos_virtualize_irq() -- Attach a handler (and optionally an hw
+ acknowledge routine) to an interrupt for the current domain. */
+
+int adeos_virtualize_irq (unsigned irq,
+ void (*handler)(unsigned irq),
+ int (*acknowledge)(unsigned irq),
+ unsigned modemask)
+{
+ if (irq >= IPIPE_NR_IRQS)
+ return -EINVAL;
+
+ return ipipe_hook_irq(irq,handler,acknowledge,modemask);
+}
+
+/* adeos_control_irq() -- Change an interrupt mode. This affects the
+ way a given interrupt is handled by ADEOS for the current
+ domain. setmask is a bitmask telling whether:
+ - the interrupt should be passed to the domain (IPIPE_HANDLE_MASK),
+ and/or
+ - the interrupt should be passed down to the lower priority domain(s)
+ in the pipeline (IPIPE_PASS_MASK).
+ This leads to four possibilities:
+ - PASS only => Ignore the interrupt
+ - HANDLE only => Terminate the interrupt (process but don't pass down)
+ - PASS + HANDLE => Accept the interrupt (process and pass down)
+ - <none> => Discard the interrupt
+ - DYNAMIC is currently an alias of HANDLE since it marks an interrupt
+ which is processed by the current domain but not implicitely passed
+ down to the pipeline, letting the domain's handler choose on a case-
+ by-case basis whether the interrupt propagation should be forced
+ using adeos_propagate_irq().
+ clrmask clears the corresponding bits from the control field before
+ setmask is applied.
+*/
+
+int adeos_control_irq (unsigned irq,
+ unsigned clrmask,
+ unsigned setmask) {
+
+ if (irq >= IPIPE_NR_IRQS)
+ return -EINVAL;
+
+ return ipipe_control_irq(irq,clrmask,setmask);
+}
+
+/* adeos_propagate_irq() -- Force a given IRQ propagation on behalf of
+ a running interrupt handler to the next domain down the pipeline.
+ Returns non-zero if a domain has received the interrupt
+ notification, zero otherwise.
+ This call is useful for handling shared interrupts among domains.
+ e.g. pipeline = [domain-A]---[domain-B]...
+ Both domains share IRQ #X.
+ - domain-A handles IRQ #X but does not pass it down (i.e. Terminate
+ or Dynamic interrupt control mode)
+ - domain-B handles IRQ #X (i.e. Terminate or Accept interrupt
+ control modes).
+ When IRQ #X is raised, domain-A's handler determines whether it
+ should process the interrupt by identifying its source. If not,
+ adeos_propagate_irq() is called so that the next domain down the
+ pipeline which handles IRQ #X is given a chance to process it. This
+ process can be repeated until the end of the pipeline is
+ reached. */
+
+int adeos_propagate_irq (unsigned irq) {
+
+ return irq < IPIPE_NR_IRQS ? ipipe_propagate_irq(irq) : -EINVAL;
+}
+
+/* adeos_alloc_irq() -- Allocate a virtual/soft pipelined interrupt.
+ Virtual interrupts are handled in exactly the same way than their
+ hw-generated counterparts. This is a very basic, one-way only,
+ inter-domain communication system (see adeos_trigger_irq()). Note:
+ it is not necessary for a domain to allocate a virtual interrupt to
+ trap it using adeos_virtualize_irq(). The newly allocated VIRQ
+ number which can be passed to other IRQ-related services is
+ returned on success, zero otherwise (i.e. no more virtual interrupt
+ channel is available). */
+
+unsigned adeos_alloc_irq (void) {
+
+ return ipipe_alloc_irq();
+}
+
+/* adeos_free_irq() -- Return a previously allocated virtual/soft
+ pipelined interrupt to the pool of allocatable interrupts. */
+
+int adeos_free_irq (unsigned irq)
+
+{
+ if (irq >= IPIPE_NR_IRQS)
+ return -EINVAL;
+
+ ipipe_free_irq(irq);
+
+ return 0;
+}
+
+/* adeos_trigger_irq() -- Push the interrupt to the pipeline entry
+ just like if it has been actually received from a hw source. This
+ both works for real and virtual interrupts. This also means that
+ the current domain might be immediately preempted by a more
+ prioritary domain who happens to handle this interrupt. */
+
+int adeos_trigger_irq (unsigned irq) {
+
+ return irq < IPIPE_NR_IRQS ? ipipe_trigger_irq(irq) : -EINVAL;
+}
+
+/* adeos_trigger_ipi() -- Send the ADEOS service IPI to other
+ processors. This leads to */
+
+int adeos_trigger_ipi (int cpuid) {
+
+ return ipipe_trigger_ipi(cpuid);
+}
+
+int adeos_get_sysinfo (adsysinfo_t *info) {
+
+ return __adeos_get_sysinfo(info);
+}
+
+/* adeos_stall_ipipe() -- Stall the interrupt pipeline. Must be
+ callable from C and assembly language. */
+
+void adeos_stall_ipipe (void) {
+
+ ipipe_declare_cpuid;
+
+ set_bit(IPIPE_STALL_FLAG,&adp_current->cpudata[cpuid].status);
+}
+
+/* adeos_unstall_ipipe() -- Unstall the interrupt pipeline and
+ synchronize pending events. Must be callable from C and assembly
+ language. */
+
+void adeos_unstall_ipipe (void)
+
+{
+ ipipe_declare_cpuid;
+
+ clear_bit(IPIPE_STALL_FLAG,&adp_current->cpudata[cpuid].status);
+ ipipe_hw_sti();
+
+ if (adp_current->cpudata[cpuid].irq_pending_hi != 0)
+ ipipe_sync_irqs();
+}
+
+/* adeos_unstall_ipipe() -- Unstall the interrupt pipeline and
+ synchronize pending events from a given domain. */
+
+void adeos_unstall_ipipe_from (adomain_t *adp)
+
+{
+ struct list_head *pos;
+ ipipe_declare_cpuid;
+
+ clear_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);
+
+ if (adp == adp_cpu_current[cpuid])
+ {
+ ipipe_hw_sti();
+
+ if (adp->cpudata[cpuid].irq_pending_hi != 0)
+ ipipe_sync_irqs();
+
+ return;
+ }
+
+ /* Attempt to flush all events that might be pending at the
+ unstalled domain level. This code is roughly lifted from
+ ipipe.c:ipipe_handle_irq(). */
+
+ list_for_each(pos,&adeos_pipeline) {
+
+ adomain_t *_adp = list_entry(pos,adomain_t,link);
+
+ if (test_bit(IPIPE_STALL_FLAG,&_adp->cpudata[cpuid].status))
+ break; /* Stalled stage -- do not go further. */
+
+ if (_adp->cpudata[cpuid].irq_pending_hi != 0)
+ {
+ /* Since the critical IPI might be serviced by the
+ following actions, the current domain might not be
+ linked to the pipeline anymore after its handler
+ returns on SMP boxes, even if the domain remains valid
+ (see adeos_unregister_domain()), so don't make any
+ hazardous assumptions here. */
+
+ ipipe_hw_sti();
+
+ if (_adp == adp_cpu_current[cpuid])
+ ipipe_sync_irqs();
+ else
+ {
+ __adeos_switch_domain(_adp);
+ ipipe_reload_cpuid(); /* Processor might have changed. */
+ }
+
+ break;
+ }
+ else if (_adp == adp_cpu_current[cpuid])
+ break;
+ }
+}
+
+/* adeos_catch_event() -- Interpose an event handler for the
+ current domain. */
+
+int adeos_catch_event (unsigned event, void (*handler)(adevinfo_t *))
+
+{
+ if (event >= ADEOS_NR_EVENTS)
+ return -EINVAL;
+
+ if (!xchg(&adp_current->events[event].handler,handler))
+ {
+ if (handler)
+ __adeos_event_monitors[event]++;
+ }
+ else if (!handler)
+ __adeos_event_monitors[event]--;
+
+ return 0;
+}
+
+void (*adeos_hook_dswitch(void (*handler)(void))) (void) {
+
+ return (void (*)(void))xchg(&adp_current->dswitch,handler);
+}
+
+void adeos_init_attr (adattr_t *attr)
+
+{
+ attr->name = "Anonymous";
+ attr->domid = 1;
+ attr->entry = NULL;
+ attr->estacksz = 0; /* Let ADEOS choose a reasonable stack size */
+ attr->priority = ADEOS_ROOT_PRI;
+ attr->dswitch = NULL;
+ attr->nptdkeys = 0;
+ attr->ptdset = NULL;
+ attr->ptdget = NULL;
+}
+
+int adeos_tune_timer (unsigned long ns, int flags) {
+
+ return __adeos_tune_timer(ns,flags);
+}
+
+int adeos_alloc_ptdkey (void)
+
+{
+ unsigned long flags;
+ int key = -1;
+
+ ipipe_hw_spin_lock(&adeos_pipelock,flags);
+
+ if (adp_current->ptd_keycount < adp_current->ptd_keymax)
+ {
+ key = ffz(adp_current->ptd_keymap);
+ set_bit(key,&adp_current->ptd_keymap);
+ adp_current->ptd_keycount++;
+ }
+
+ ipipe_hw_spin_unlock(&adeos_pipelock,flags);
+
+ return key;
+}
+
+int adeos_free_ptdkey (int key)
+
+{
+ unsigned long flags;
+
+ if (key < 0 || key >= adp_current->ptd_keymax)
+ return -EINVAL;
+
+ ipipe_hw_spin_lock(&adeos_pipelock,flags);
+
+ if (test_and_clear_bit(key,&adp_current->ptd_keymap))
+ adp_current->ptd_keycount--;
+
+ ipipe_hw_spin_unlock(&adeos_pipelock,flags);
+
+ return 0;
+}
+
+int adeos_set_ptd (int key, void *value)
+
+{
+ if (key < 0 || key >= adp_current->ptd_keymax)
+ return -EINVAL;
+
+ if (!adp_current->ptd_setfun)
+ {
+ printk(KERN_WARNING "ADEOS: not ptdset hook for %s\n",adp_current->name);
+ return -EINVAL;
+ }
+
+ adp_current->ptd_setfun(key,value);
+
+ return 0;
+}
+
+void *adeos_get_ptd (int key)
+
+{
+ if (key < 0 || key >= adp_current->ptd_keymax)
+ return NULL;
+
+ if (!adp_current->ptd_getfun)
+ {
+ printk(KERN_WARNING "ADEOS: not ptdget hook for %s\n",adp_current->name);
+ return NULL;
+ }
+
+ return adp_current->ptd_getfun(key);
+}
+
+unsigned long adeos_critical_enter (void (*syncfn)(void)) {
+
+ return __adeos_critical_enter(syncfn);
+}
+
+void adeos_critical_exit (unsigned long flags) {
+
+ __adeos_critical_exit(flags);
+}
diff -urpN linux-2.5.38/kernel/fork.c linux-2.5.38-adeos/kernel/fork.c
--- linux-2.5.38/kernel/fork.c Sun Sep 22 00:25:00 2002
+++ linux-2.5.38-adeos/kernel/fork.c Sun Sep 22 21:57:19 2002
@@ -846,6 +846,14 @@ static struct task_struct *copy_process(
nr_threads++;
write_unlock_irq(&tasklist_lock);
+#ifdef CONFIG_ADEOS
+ {
+ int k;
+
+ for (k = 0; k < ADEOS_ROOT_NPTDKEYS; k++)
+ p->ptd[k] = NULL;
+ }
+#endif /* CONFIG_ADEOS */
retval = 0;
fork_out:
diff -urpN linux-2.5.38/kernel/ksyms.c linux-2.5.38-adeos/kernel/ksyms.c
--- linux-2.5.38/kernel/ksyms.c Sun Sep 22 00:24:58 2002
+++ linux-2.5.38-adeos/kernel/ksyms.c Sun Sep 22 21:57:19 2002
@@ -612,3 +612,35 @@ EXPORT_SYMBOL(__per_cpu_offset);
/* debug */
EXPORT_SYMBOL(dump_stack);
+
+#ifdef CONFIG_ADEOS
+EXPORT_SYMBOL(adeos_register_domain);
+EXPORT_SYMBOL(adeos_unregister_domain);
+EXPORT_SYMBOL(adeos_renice_domain);
+EXPORT_SYMBOL(adeos_suspend_domain);
+EXPORT_SYMBOL(adeos_virtualize_irq);
+EXPORT_SYMBOL(adeos_control_irq);
+EXPORT_SYMBOL(adeos_propagate_irq);
+EXPORT_SYMBOL(adeos_alloc_irq);
+EXPORT_SYMBOL(adeos_free_irq);
+EXPORT_SYMBOL(adeos_trigger_irq);
+EXPORT_SYMBOL(adeos_trigger_ipi);
+EXPORT_SYMBOL(adeos_stall_ipipe);
+EXPORT_SYMBOL(adeos_unstall_ipipe);
+EXPORT_SYMBOL(adeos_unstall_ipipe_from);
+EXPORT_SYMBOL(adeos_catch_event);
+EXPORT_SYMBOL(adeos_hook_dswitch);
+EXPORT_SYMBOL(adeos_init_attr);
+EXPORT_SYMBOL(adeos_get_sysinfo);
+EXPORT_SYMBOL(adeos_tune_timer);
+EXPORT_SYMBOL(adeos_alloc_ptdkey);
+EXPORT_SYMBOL(adeos_free_ptdkey);
+EXPORT_SYMBOL(adeos_set_ptd);
+EXPORT_SYMBOL(adeos_get_ptd);
+EXPORT_SYMBOL(adeos_critical_enter);
+EXPORT_SYMBOL(adeos_critical_exit);
+EXPORT_SYMBOL(adp_cpu_current);
+EXPORT_SYMBOL(adp_root);
+/* Private symbols. */
+EXPORT_SYMBOL(__adeos_online_cpus);
+#endif /* CONFIG_ADEOS */
diff -urpN linux-2.5.38/kernel/printk.c linux-2.5.38-adeos/kernel/printk.c
--- linux-2.5.38/kernel/printk.c Sun Sep 22 00:25:31 2002
+++ linux-2.5.38-adeos/kernel/printk.c Sun Sep 22 21:57:19 2002
@@ -194,17 +194,33 @@ int do_syslog(int type, char * buf, int
if (error)
goto out;
i = 0;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
while ((log_start != log_end) && i < len) {
c = LOG_BUF(log_start);
log_start++;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
__put_user(c,buf);
buf++;
i++;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
}
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
error = i;
break;
case 4: /* Read/clear last kernel messages */
@@ -223,7 +239,11 @@ int do_syslog(int type, char * buf, int
count = len;
if (count > LOG_BUF_LEN)
count = LOG_BUF_LEN;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
if (count > logged_chars)
count = logged_chars;
if (do_clear)
@@ -240,11 +260,23 @@ int do_syslog(int type, char * buf, int
if (j+LOG_BUF_LEN < log_end)
break;
c = LOG_BUF(j);
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
__put_user(c,&buf[count-1-i]);
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
}
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
error = i;
if(i != count) {
int offset = count-error;
@@ -257,19 +289,43 @@ int do_syslog(int type, char * buf, int
break;
case 5: /* Clear ring buffer */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
logged_chars = 0;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
break;
case 6: /* Disable logging to console */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
console_loglevel = minimum_console_loglevel;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
break;
case 7: /* Enable logging to console */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
console_loglevel = default_console_loglevel;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
break;
case 8: /* Set level of messages printed to console */
error = -EINVAL;
@@ -277,15 +333,31 @@ int do_syslog(int type, char * buf, int
goto out;
if (len < minimum_console_loglevel)
len = minimum_console_loglevel;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
console_loglevel = len;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
error = 0;
break;
case 9: /* Number of chars in the log buffer */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_disable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
error = log_end - log_start;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock_enable(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_unlock_irq(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
break;
case 10:
lbuf = kmalloc(len + 1, GFP_KERNEL);
@@ -430,13 +502,21 @@ asmlinkage int printk(const char *fmt, .
if (oops_in_progress) {
/* If a crash is occurring, make sure we can't deadlock */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock_init(&logbuf_lock);
+#else /* !CONFIG_ADEOS */
spin_lock_init(&logbuf_lock);
+#endif /* CONFIG_ADEOS */
/* And make sure that we print immediately */
init_MUTEX(&console_sem);
}
/* This stops the holder of console_sem just where we want him */
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_lock_irqsave(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
/* Emit the output into the temporary buffer */
va_start(args, fmt);
@@ -466,7 +546,11 @@ asmlinkage int printk(const char *fmt, .
* On some architectures, the consoles are not usable
* on secondary CPUs early in the boot process.
*/
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
goto out;
}
if (!down_trylock(&console_sem)) {
@@ -474,7 +558,11 @@ asmlinkage int printk(const char *fmt, .
* We own the drivers. We can drop the spinlock and let
* release_console_sem() print the text
*/
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
console_may_schedule = 0;
release_console_sem();
} else {
@@ -483,7 +571,11 @@ asmlinkage int printk(const char *fmt, .
* allows the semaphore holder to proceed and to call the
* console drivers with the output which we just produced.
*/
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
}
out:
return printed_len;
@@ -528,19 +620,31 @@ void release_console_sem(void)
unsigned long wake_klogd = 0;
for ( ; ; ) {
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_lock_irqsave(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
wake_klogd |= log_start - log_end;
if (con_start == log_end)
break; /* Nothing to print */
_con_start = con_start;
_log_end = log_end;
con_start = log_end; /* Flush */
- spin_unlock_irqrestore(&logbuf_lock, flags);
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
+ spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
call_console_drivers(_con_start, _log_end);
}
console_may_schedule = 0;
up(&console_sem);
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
wake_up_interruptible(&log_wait);
}
@@ -653,9 +757,17 @@ void register_console(struct console * c
/*
* release_cosole_sem() will print out the buffered messages for us.
*/
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_lock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_lock_irqsave(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
con_start = log_start;
+#ifdef CONFIG_ADEOS
+ ipipe_hw_spin_unlock(&logbuf_lock, flags);
+#else /* !CONFIG_ADEOS */
spin_unlock_irqrestore(&logbuf_lock, flags);
+#endif /* CONFIG_ADEOS */
}
release_console_sem();
}
diff -urpN linux-2.5.38/kernel/sched.c linux-2.5.38-adeos/kernel/sched.c
--- linux-2.5.38/kernel/sched.c Sun Sep 22 00:25:17 2002
+++ linux-2.5.38-adeos/kernel/sched.c Sun Sep 22 21:57:19 2002
@@ -1041,6 +1041,14 @@ asmlinkage void preempt_schedule(void)
{
struct thread_info *ti = current_thread_info();
+#ifdef CONFIG_ADEOS
+ /* The in-kernel preemption routine might be indirectly called
+ from code running in other domains, so we must ensure that
+ scheduling only takes place on behalf of the root (Linux)
+ one. */
+ if (adp_current != adp_root)
+ return;
+#endif /* CONFIG_ADEOS */
/*
* If there is a non-zero preempt_count or interrupts are disabled,
* we do not want to preempt the current task. Just return..
diff -urpN linux-2.5.38/kernel/sysctl.c linux-2.5.38-adeos/kernel/sysctl.c
--- linux-2.5.38/kernel/sysctl.c Sun Sep 22 00:25:00 2002
+++ linux-2.5.38-adeos/kernel/sysctl.c Sun Sep 22 21:57:19 2002
@@ -362,6 +362,9 @@ void __init sysctl_init(void)
#ifdef CONFIG_PROC_FS
register_proc_table(root_table, proc_sys_root);
init_irq_proc();
+#ifdef CONFIG_ADEOS
+ __adeos_init_proc();
+#endif /* CONFIG_ADEOS */
#endif
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/