Skip to contentSkip to conversation

Adeos nanokernel for 2.5.38 2/2: i386 code

PATCH New Karim Yaghmour 1 participant 1 message Sep 23, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Adeos nanokernel for 2.5.38 2/2: i386 code

This is the i386 specific portion of the nanokernel.

Here are the files added:

 arch/i386/kernel/adeos.c          |  330 ++++++++++++++++++
 arch/i386/kernel/ipipe.c          |  686 ++++++++++++++++++++++++++++++++++++++
 include/asm-i386/adeos.h          |  242 +++++++++++++

Here are the files modified:

 arch/i386/kernel/Makefile         |    3
 arch/i386/kernel/apic.c           |    9
 arch/i386/kernel/bluesmoke.c      |    3
 arch/i386/kernel/entry.S          |  127 ++++++-
 arch/i386/kernel/i386_ksyms.c     |   21 +
 arch/i386/kernel/i8259.c          |   36 +
 arch/i386/kernel/irq.c            |    3
 arch/i386/kernel/process.c        |    3
 arch/i386/kernel/smp.c            |   25 +
 arch/i386/kernel/time.c           |   11
 arch/i386/kernel/traps.c          |   68 +++
 arch/i386/mach-generic/do_timer.h |    9
 arch/i386/mach-visws/do_timer.h   |    9
 arch/i386/mm/fault.c              |    6
 include/asm-i386/system.h         |   49 ++
 18 files changed, 1636 insertions, 4 deletions    

Again, these modifications ensure that Linux plays nice with the other domains in the ipipe.

arch/i386/kernel/Makefile +2 -1
diff -urpN linux-2.5.38/arch/i386/kernel/Makefile linux-2.5.38-adeos/arch/i386/kernel/Makefile
@@ -4,7 +4,7 @@
 
 EXTRA_TARGETS := head.o init_task.o
 
-export-objs     := mca.o i386_ksyms.o time.o
+export-objs     := mca.o i386_ksyms.o time.o ipipe.o adeos.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
@@ -26,6 +26,7 @@ obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o n
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend.o
 obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
+obj-$(CONFIG_ADEOS)		+= ipipe.o adeos.o
 
 EXTRA_AFLAGS   := -traditional
 
arch/i386/kernel/adeos.c +330 -0

330 lines not on this page · raw message

arch/i386/kernel/apic.c +9 -0
diff -urpN linux-2.5.38/arch/i386/kernel/apic.c linux-2.5.38-adeos/arch/i386/kernel/apic.c
@@ -1095,7 +1095,10 @@ void smp_apic_timer_interrupt(struct pt_
 	 * NOTE! We'd better ACK the irq immediately,
 	 * because timer handling can be slow.
 	 */
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	ack_APIC_irq();
+#endif
 	/*
 	 * update_process_times() expects us to have done irq_enter().
 	 * Besides, if we don't timer interrupts ignore the global
@@ -1120,8 +1123,11 @@ asmlinkage void smp_spurious_interrupt(v
 	 * Spurious interrupts should not be ACKed.
 	 */
 	v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
 		ack_APIC_irq();
+#endif
 
 	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
 	printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
@@ -1142,7 +1148,10 @@ asmlinkage void smp_error_interrupt(void
 	v = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
 	v1 = apic_read(APIC_ESR);
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	ack_APIC_irq();
+#endif
 	atomic_inc(&irq_err_count);
 
 	/* Here is what the APIC error bits mean:
arch/i386/kernel/bluesmoke.c +3 -0
diff -urpN linux-2.5.38/arch/i386/kernel/bluesmoke.c linux-2.5.38-adeos/arch/i386/kernel/bluesmoke.c
@@ -53,7 +53,10 @@ static void intel_thermal_interrupt(stru
 	u32 l, h;
 	unsigned int cpu = smp_processor_id();
 
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	ack_APIC_irq();
+#endif
 
 	rdmsr(MSR_IA32_THERM_STATUS, l, h);
 	if (l & 1) {
arch/i386/kernel/entry.S +125 -2

253 lines not on this page · raw message

arch/i386/kernel/i386_ksyms.c +21 -0
diff -urpN linux-2.5.38/arch/i386/kernel/i386_ksyms.c linux-2.5.38-adeos/arch/i386/kernel/i386_ksyms.c
@@ -176,3 +176,24 @@ extern int is_sony_vaio_laptop;
 EXPORT_SYMBOL(is_sony_vaio_laptop);
 
 EXPORT_SYMBOL(__PAGE_KERNEL);
+ 
+#ifdef CONFIG_ADEOS
+EXPORT_SYMBOL(ipipe_sync_irqs);
+/* The following are per-platform convenience exports which might be
+   needed by some Adeos domains loaded as kernel modules. */
+extern irq_desc_t irq_desc[];
+EXPORT_SYMBOL(irq_desc);
+extern struct desc_struct idt_table[];
+EXPORT_SYMBOL(idt_table);
+extern struct tty_driver console_driver;
+EXPORT_SYMBOL(console_driver);
+extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
+EXPORT_SYMBOL(kd_mksound);
+#ifdef CONFIG_SMP
+#ifdef CONFIG_MULTIQUAD
+EXPORT_SYMBOL(logical_apicid_2_cpu);
+#else
+EXPORT_SYMBOL(physical_apicid_2_cpu);
+#endif /* CONFIG_MULTIQUAD */
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_ADEOS */
arch/i386/kernel/i8259.c +36 -0
diff -urpN linux-2.5.38/arch/i386/kernel/i8259.c linux-2.5.38-adeos/arch/i386/kernel/i8259.c
@@ -93,13 +93,21 @@ void disable_8259A_irq(unsigned int irq)
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock_irqsave(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 	cached_irq_mask |= mask;
 	if (irq & 8)
 		outb(cached_A1,0xA1);
 	else
 		outb(cached_21,0x21);
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock_irqrestore(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 }
 
 void enable_8259A_irq(unsigned int irq)
@@ -107,13 +115,21 @@ void enable_8259A_irq(unsigned int irq)
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock_irqsave(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 	cached_irq_mask &= mask;
 	if (irq & 8)
 		outb(cached_A1,0xA1);
 	else
 		outb(cached_21,0x21);
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock_irqrestore(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 }
 
 int i8259A_irq_pending(unsigned int irq)
@@ -122,12 +138,20 @@ int i8259A_irq_pending(unsigned int irq)
 	unsigned long flags;
 	int ret;
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock_irqsave(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 	if (irq < 8)
 		ret = inb(0x20) & mask;
 	else
 		ret = inb(0xA0) & (mask >> 8);
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock_irqrestore(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 
 	return ret;
 }
@@ -196,12 +220,16 @@ void mask_and_ack_8259A(unsigned int irq
 
 handle_real_irq:
 	if (irq & 8) {
+#ifndef CONFIG_ADEOS
 		inb(0xA1);		/* DUMMY - (do we need this?) */
+#endif
 		outb(cached_A1,0xA1);
 		outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
 		outb(0x62,0x20);	/* 'Specific EOI' to master-IRQ2 */
 	} else {
+#ifndef CONFIG_ADEOS
 		inb(0x21);		/* DUMMY - (do we need this?) */
+#endif
 		outb(cached_21,0x21);
 		outb(0x60+irq,0x20);	/* 'Specific EOI' to master */
 	}
@@ -267,7 +295,11 @@ void init_8259A(int auto_eoi)
 {
 	unsigned long flags;
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock_irqsave(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 
 	outb(0xff, 0x21);	/* mask all of 8259A-1 */
 	outb(0xff, 0xA1);	/* mask all of 8259A-2 */
@@ -303,7 +335,11 @@ void init_8259A(int auto_eoi)
 	outb(cached_21, 0x21);	/* restore master IRQ mask */
 	outb(cached_A1, 0xA1);	/* restore slave IRQ mask */
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock_irqrestore(&i8259A_lock, flags);
+#endif /* CONFIG_ADEOS */
 }
 
 /*
arch/i386/kernel/ipipe.c +686 -0

686 lines not on this page · raw message

arch/i386/kernel/irq.c +3 -0
diff -urpN linux-2.5.38/arch/i386/kernel/irq.c linux-2.5.38-adeos/arch/i386/kernel/irq.c
@@ -332,7 +332,10 @@ asmlinkage unsigned int do_IRQ(struct pt
 	irq_enter();
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	desc->handler->ack(irq);
+#endif
 	/*
 	   REPLAY is when Linux resends an IRQ that was dropped earlier
 	   WAITING is used by probe to mark irqs that are being tested
arch/i386/kernel/process.c +3 -0
diff -urpN linux-2.5.38/arch/i386/kernel/process.c linux-2.5.38-adeos/arch/i386/kernel/process.c
@@ -137,6 +137,9 @@ void cpu_idle (void)
 		if (!idle)
 			idle = default_idle;
 		irq_stat[smp_processor_id()].idle_timestamp = jiffies;
+#ifdef CONFIG_ADEOS
+		adeos_suspend_domain();
+#endif /* CONFIG_ADEOS */
 		while (!need_resched())
 			idle();
 		schedule();
arch/i386/kernel/smp.c +25 -0
diff -urpN linux-2.5.38/arch/i386/kernel/smp.c linux-2.5.38-adeos/arch/i386/kernel/smp.c
@@ -159,7 +159,11 @@ static inline void send_IPI_mask_bitmask
 	unsigned long cfg;
 	unsigned long flags;
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_save_flags_and_cli(flags);
+#else
 	local_irq_save(flags);
+#endif
 		
 	/*
 	 * Wait for idle.
@@ -182,7 +186,11 @@ static inline void send_IPI_mask_bitmask
 	 */
 	apic_write_around(APIC_ICR, cfg);
 
+#ifdef CONFIG_ADEOS
+	ipipe_hw_restore_flags(flags);
+#else
 	local_irq_restore(flags);
+#endif
 }
 
 static inline void send_IPI_mask_sequence(int mask, int vector)
@@ -625,7 +633,10 @@ void smp_send_stop(void)
  */
 asmlinkage void smp_reschedule_interrupt(void)
 {
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	ack_APIC_irq();
+#endif
 }
 
 asmlinkage void smp_call_function_interrupt(void)
@@ -634,7 +645,10 @@ asmlinkage void smp_call_function_interr
 	void *info = call_data->info;
 	int wait = call_data->wait;
 
+#ifndef CONFIG_ADEOS
+	/* IRQ acknowledging is in the hands of the IPIPE exclusively. */
 	ack_APIC_irq();
+#endif
 	/*
 	 * Notify initiating CPU that I've grabbed the data and am
 	 * about to execute the function
@@ -654,3 +668,14 @@ asmlinkage void smp_call_function_interr
 	}
 }
 
+#ifdef CONFIG_ADEOS
+
+void __adeos_send_IPI_allbutself (int vector) {
+    send_IPI_allbutself(vector);
+}
+
+void __adeos_send_IPI_other (int cpu, int vector) {
+    send_IPI_mask(1 << cpu,vector);
+}
+
+#endif /* CONFIG_ADEOS */
arch/i386/kernel/time.c +11 -0
diff -urpN linux-2.5.38/arch/i386/kernel/time.c linux-2.5.38-adeos/arch/i386/kernel/time.c
@@ -370,11 +370,20 @@ static inline void do_timer_interrupt(in
 		 * This will also deassert NMI lines for the watchdog if run
 		 * on an 82489DX-based system.
 		 */
+#ifdef CONFIG_ADEOS
+		unsigned long flags;
+		ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 		spin_lock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 		outb(0x0c, 0x20);
 		/* Ack the IRQ; AEOI will end it automatically. */
 		inb(0x20);
+#ifdef CONFIG_ADEOS
+		ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 		spin_unlock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 	}
 #endif
 
@@ -450,6 +459,7 @@ void timer_interrupt(int irq, void *dev_
 
 		rdtscl(last_tsc_low);
 
+#ifndef CONFIG_ADEOS
 		spin_lock(&i8253_lock);
 		outb_p(0x00, 0x43);     /* latch the count ASAP */
 
@@ -459,6 +469,7 @@ void timer_interrupt(int irq, void *dev_
 
 		count = ((LATCH-1) - count) * TICK_SIZE;
 		delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+#endif /* !CONFIG_ADEOS */
 	}
  
 	do_timer_interrupt(irq, NULL, regs);
arch/i386/kernel/traps.c +68 -0

80 lines not on this page · raw message

arch/i386/mach-generic/do_timer.h +9 -0
diff -urpN linux-2.5.38/arch/i386/mach-generic/do_timer.h linux-2.5.38-adeos/arch/i386/mach-generic/do_timer.h
@@ -46,13 +46,22 @@ static inline int do_timer_overflow(int 
 {
 	int i;
 
+#ifdef CONFIG_ADEOS
+	unsigned long flags;
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 	/*
 	 * This is tricky when I/O APICs are used;
 	 * see do_timer_interrupt().
 	 */
 	i = inb(0x20);
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 	
 	/* assumption about timer being IRQ0 */
 	if (i & 0x01) {
arch/i386/mach-visws/do_timer.h +9 -0
diff -urpN linux-2.5.38/arch/i386/mach-visws/do_timer.h linux-2.5.38-adeos/arch/i386/mach-visws/do_timer.h
@@ -27,13 +27,22 @@ static inline int do_timer_overflow(int 
 {
 	int i;
 
+#ifdef CONFIG_ADEOS
+	unsigned long flags;
+	ipipe_hw_spin_lock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_lock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 	/*
 	 * This is tricky when I/O APICs are used;
 	 * see do_timer_interrupt().
 	 */
 	i = inb(0x20);
+#ifdef CONFIG_ADEOS
+	ipipe_hw_spin_unlock(&i8259A_lock, flags);
+#else /* !CONFIG_ADEOS */
 	spin_unlock(&i8259A_lock);
+#endif /* CONFIG_ADEOS */
 	
 	/* assumption about timer being IRQ0 */
 	if (i & 0x01) {
arch/i386/mm/fault.c +5 -1
diff -urpN linux-2.5.38/arch/i386/mm/fault.c linux-2.5.38-adeos/arch/i386/mm/fault.c
@@ -157,7 +157,11 @@ asmlinkage void do_page_fault(struct pt_
 
 	/* It's safe to allow irq's after cr2 has been saved */
 	if (regs->eflags & X86_EFLAGS_IF)
-		local_irq_enable();
+#ifdef CONFIG_ADEOS
+	    ipipe_hw_sti();
+#else
+	    local_irq_enable();
+#endif
 
 	tsk = current;
 
include/asm-i386/adeos.h +242 -0

242 lines not on this page · raw message

include/asm-i386/system.h +49 -0

61 lines not on this page · raw message