3 # Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
6 --- linux-2.4.28/CREDITS~colinux-0.6.1 2004-11-17 06:54:20.000000000 -0500
7 +++ linux-2.4.28/CREDITS 2004-11-27 15:59:21.283010512 -0500
15 +D: Various kernel patches
19 E: tim_alpaerts@toyota-motor-europe.com
20 D: 802.2 class II logical link control layer,
21 --- linux-2.4.28/Documentation/devices.txt~colinux-0.6.1 2004-02-18 08:36:30.000000000 -0500
22 +++ linux-2.4.28/Documentation/devices.txt 2004-11-27 15:59:21.285010208 -0500
23 @@ -1926,6 +1926,13 @@
24 17 = /dev/cosa1c1 2nd board, 2nd channel
27 + block coLinux Block devices
28 + 0 = /dev/cobd0 First coLinux device
29 + 1 = /dev/cobd1 Second coLinux device
32 + These block devices map to files or devices in the host FS.
37 --- linux-2.4.28/Makefile~colinux-0.6.1 2004-11-17 06:54:22.000000000 -0500
38 +++ linux-2.4.28/Makefile 2004-11-27 15:59:30.235649504 -0500
44 +EXTRAVERSION = -co-0.6.1
46 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
50 AS = $(CROSS_COMPILE)as
51 LD = $(CROSS_COMPILE)ld
52 -CC = $(CROSS_COMPILE)gcc
54 +CC = $(CROSS_COMPILE)$(COLINUX_ROOT)/bin/tracewrapper.py gcc
56 +CC = $(CROSS_COMPILE)gcc
59 AR = $(CROSS_COMPILE)ar
60 NM = $(CROSS_COMPILE)nm
61 --- linux-2.4.28/arch/i386/config.in~colinux-0.6.1 2004-11-17 06:54:21.000000000 -0500
62 +++ linux-2.4.28/arch/i386/config.in 2004-11-27 15:59:21.286010056 -0500
64 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
65 bool 'Symmetric multi-processing support' CONFIG_SMP
66 if [ "$CONFIG_SMP" != "y" ]; then
67 - bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
68 - dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
69 - if [ "$CONFIG_X86_UP_APIC" = "y" ]; then
70 - define_bool CONFIG_X86_LOCAL_APIC y
72 - if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
73 - define_bool CONFIG_X86_IO_APIC y
74 + if [ "$CONFIG_COOPERATIVE" = "y" ]; then
75 + bool 'Cooperative PIC (COPIC) support' CONFIG_X86_UP_COPIC
76 + if [ "$CONFIG_X86_UP_COPIC" = "y" ]; then
77 + define_bool CONFIG_X86_COPIC y
80 + bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
81 + dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
82 + if [ "$CONFIG_X86_UP_APIC" = "y" ]; then
83 + define_bool CONFIG_X86_LOCAL_APIC y
85 + if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
86 + define_bool CONFIG_X86_IO_APIC y
90 int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
92 bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
95 +bool 'Cooperative Mode' CONFIG_COOPERATIVE
97 source drivers/acpi/Config.in
101 source drivers/mtd/Config.in
103 source drivers/parport/Config.in
105 source drivers/pnp/Config.in
107 if [ "$CONFIG_VT" = "y" ]; then
108 mainmenu_option next_comment
109 comment 'Console drivers'
110 - bool 'VGA text console' CONFIG_VGA_CONSOLE
111 + if [ "$CONFIG_COOPERATIVE" = "n" ]; then
112 + bool 'VGA text console' CONFIG_VGA_CONSOLE
114 + bool 'coLinux Pseudo-VGA text console' CONFIG_COOPERATIVE_CONSOLE
116 bool 'Video mode selection support' CONFIG_VIDEO_SELECT
117 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
118 tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
119 --- linux-2.4.28/arch/i386/kernel/Makefile~colinux-0.6.1 2003-11-28 13:26:19.000000000 -0500
120 +++ linux-2.4.28/arch/i386/kernel/Makefile 2004-11-27 15:59:21.287009904 -0500
123 obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
124 ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
125 - pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o
126 + pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o cooperative.o \
130 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
131 +++ linux-2.4.28/arch/i386/kernel/cooperative.c 2004-11-27 15:59:21.287009904 -0500
133 +#include <linux/kernel.h>
134 +#include <linux/string.h>
135 +#include <linux/interrupt.h>
136 +#include <linux/mm.h>
138 +#include <asm/keyboard.h>
139 +#include <linux/kbd_ll.h>
140 +#include <linux/cooperative.h>
141 +#include <asm/smp.h>
142 +#include <asm/desc.h>
148 + * The next asm code is the first Linux code that runs in the
149 + * coLinux kernel context. It receives %ecx which contains the
150 + * address of the passage page. The passage page code sets %ecx
151 + * to this value in its context restore part.
157 + ".globl colinux_start\n"
159 + " call colinux_start_arch\n"
163 +static void colinux_early_cpu_init(void)
166 + * On the first switch to Linux we must set up a valid TR because
167 + * the passage page code assumes such one exists. This is basically
168 + * copied code from cpu_init().
170 + * P.S this is protected by CO_TRACE_STOP so that we don't
171 + * have a monitor context switch.
174 + int nr = smp_processor_id();
175 + struct tss_struct * t = &init_tss[nr];
177 + set_tss_desc(nr,t);
178 + gdt_table[__TSS(nr)].b &= 0xfffffdff;
180 + gdt_table[__TSS(nr)].b &= 0xfffffdff;
182 + __asm__ __volatile__("movl %%cr4, %0" : "=r" (mmu_cr4_features));
185 +void colinux_start_arch()
187 + colinux_early_cpu_init();
191 +extern void ctrl_alt_del(void);
193 +void co_handle_device_interrupt(co_linux_message_t *message)
195 + unsigned long flags;
197 + local_irq_save(flags);
199 + switch (message->device) {
200 + case CO_DEVICE_TIMER: {
201 + co_linux_message_idle_t data = *(co_linux_message_idle_t *)message->data;
203 + if (data.tick_count > HZ) {
204 + xtime.tv_sec += data.tick_count / HZ;
205 + data.tick_count -= ((data.tick_count / HZ) * HZ);
209 + while (data.tick_count > 0) {
210 + struct pt_regs regs = {0, };
211 + regs.orig_eax = TIMER_IRQ;
218 + case CO_DEVICE_POWER: {
219 + co_linux_message_power_t *type = (co_scan_code_t *)message->data;
220 + switch (type->type) {
221 + case CO_LINUX_MESSAGE_POWER_ALT_CTRL_DEL: {
229 + case CO_DEVICE_KEYBOARD: {
230 + struct pt_regs regs;
231 + co_received_message(message);
232 + regs.orig_eax = KEYBOARD_IRQ;
237 + case CO_DEVICE_NETWORK: {
238 + struct pt_regs regs;
239 + if (message->size > 1600) {
240 + printk("co_handle_device_interrupt: warning, packet len: %d\n", message->size);
243 + co_received_message(message);
244 + regs.orig_eax = NETWORK_IRQ;
252 + local_irq_restore(flags);
255 +void co_switch_wrapper_protected(void)
258 + * We don't trust the passage page code to safely restore %gs and %fs.
260 + * This wrapper ensures that if %fs or %gs are invalid, the processes
261 + * exits with a segmentation fault rather than bringing down the
264 + unsigned long fs = 0;
265 + unsigned long gs = 0;
267 + asm volatile("movl %%fs,%0": "=m" (fs));
268 + asm volatile("movl %%gs,%0": "=m" (gs));
271 + * Nullify the registers so the passage page code restores to
272 + * null segment values on return.
274 + asm volatile("movl %0, %%fs; movl %0, %%gs" : : "r" (0));
276 + /* And switch... */
280 + * Safely restore the registers.
282 + loadsegment(fs, fs);
283 + loadsegment(gs, gs);
286 +void co_switch_wrapper(void)
288 + co_switch_wrapper_protected();
293 --- linux-2.4.28/arch/i386/kernel/head.S~colinux-0.6.1 2003-11-28 13:26:19.000000000 -0500
294 +++ linux-2.4.28/arch/i386/kernel/head.S 2004-11-27 15:59:21.287009904 -0500
299 - .long SYMBOL_NAME(init_task_union)+8192
300 + .long SYMBOL_NAME(init_task_union)+8192-100
303 /* This is the default interrupt "handler" :-) */
304 @@ -361,12 +361,14 @@
310 .word IDT_ENTRIES*8-1 # idt contains 256 entries
312 .long SYMBOL_NAME(idt_table)
317 .word GDT_ENTRIES*8-1
319 --- linux-2.4.28/arch/i386/kernel/i387.c~colinux-0.6.1 2003-08-25 07:44:39.000000000 -0400
320 +++ linux-2.4.28/arch/i386/kernel/i387.c 2004-11-27 15:59:21.288009752 -0500
327 int save_i387( struct _fpstate *buf )
329 if ( !current->used_math )
336 static inline int restore_i387_fsave( struct _fpstate *buf )
338 struct task_struct *tsk = current;
340 return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
345 int restore_i387( struct _fpstate *buf )
355 * ptrace request handlers.
357 --- linux-2.4.28/arch/i386/kernel/i8259.c~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
358 +++ linux-2.4.28/arch/i386/kernel/i8259.c 2004-11-27 15:59:21.288009752 -0500
360 #include <asm/apic.h>
362 #include <linux/irq.h>
363 +#include <linux/cooperative.h>
366 * Common place to define all x86 IRQ vectors
371 +#ifdef CONFIG_COOPERATIVE
375 +void proxy_interrupt_handler(unsigned long interrupt, struct pt_regs regs)
377 + co_passage_page->operation = CO_OPERATION_FORWARD_INTERRUPT;
378 + co_passage_page->params[0] = interrupt + 0x20;
379 + co_passage_page->params[1] = regs.eip;
380 + co_passage_page->params[2] = (unsigned long)(&((&interrupt)[10]));
381 + co_passage_page->host_state.flags &= ~(1 << 9); /* Turn IF off */
383 + co_switch_wrapper();
389 +#define IRQLIST_16(x) \
390 + IRQ(x,0) IRQ(x,1) IRQ(x,2) IRQ(x,3) \
391 + IRQ(x,4) IRQ(x,5) IRQ(x,6) IRQ(x,7) \
392 + IRQ(x,8) IRQ(x,9) IRQ(x,a) IRQ(x,b) \
393 + IRQ(x,c) IRQ(x,d) IRQ(x,e) IRQ(x,f)
395 +#define IRQLIST_224 \
396 + IRQLIST_16(0x0) IRQLIST_16(0x1) IRQLIST_16(0x2) IRQLIST_16(0x3) \
397 + IRQLIST_16(0x4) IRQLIST_16(0x5) IRQLIST_16(0x6) IRQLIST_16(0x7) \
398 + IRQLIST_16(0x8) IRQLIST_16(0x9) IRQLIST_16(0xa) IRQLIST_16(0xb) \
399 + IRQLIST_16(0xc) IRQLIST_16(0xd)
402 + extern asmlinkage void IRQ_proxy_##x##y##_interrupt(void);
406 +struct _fpstate co_interrupt_register_state;
410 + "\n"__ALIGN_STR"\n" \
411 + ".section .text\n" \
412 + ".globl IRQ_proxy_" #id "_interrupt\n" \
413 + "IRQ_proxy_" #id "_interrupt:\n" \
417 + "pushl $co_interrupt_register_state\n\t" \
418 + "call save_i387\n\t" \
420 + "pushl $" #id "\n\t" \
421 + "call proxy_interrupt_handler\n\t" \
423 + "pushl $co_interrupt_register_state\n\t" \
424 + "call restore_i387\n\t" \
427 + "jmp ret_from_intr\n" \
431 +#define IRQ(x,y) BIRQ(x##y)
435 +#define IRQ(x,y) &IRQ_proxy_##x##y##_interrupt,
436 +void (*proxy_interrupt[NR_IRQS])(void) = {
447 * This is the 'legacy' 8259A Programmable Interrupt Controller,
448 * present in the majority of PC/AT boxes.
449 @@ -441,15 +517,74 @@
453 +#ifdef CONFIG_X86_COPIC
456 + * Not like you have any other choice other than using
457 + * COPIC in Cooperative mode.
460 +static void end_COPIC_irq(unsigned int irq)
464 +#define shutdown_COPIC_irq disable_COPIC_irq
466 +static void mask_and_ack_COPIC(unsigned int irq)
470 +static unsigned int startup_COPIC_irq(unsigned int irq)
475 +void disable_COPIC_irq(unsigned int irq)
479 +void enable_COPIC_irq(unsigned int irq)
483 +static struct hw_interrupt_type co_pic_irq_type = {
486 + shutdown_COPIC_irq,
489 + mask_and_ack_COPIC,
494 +void __init init_COPIC_irqs(void)
498 + for (i = 0; i < NR_IRQS; i++) {
499 + irq_desc[i].status = IRQ_DISABLED;
500 + irq_desc[i].action = 0;
501 + irq_desc[i].depth = 1;
503 + irq_desc[i].handler = &co_pic_irq_type;
510 void __init init_IRQ(void)
514 +#ifndef CONFIG_COOPERATIVE
515 #ifndef CONFIG_X86_VISWS_APIC
518 init_VISWS_APIC_irqs();
522 * Cover the whole vector space, no vector can escape
523 * us. (some of these will be overridden and become
525 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
529 +#ifndef CONFIG_COOPERATIVE
531 * Set the clock to HZ Hz, we already have a valid
535 if (boot_cpu_data.hard_math && !cpu_has_fpu)
536 setup_irq(13, &irq13);
540 + printk("Setting proxy interrupt vectors\n");
542 +#ifdef CONFIG_X86_COPIC
546 + for (i = 0; i < NR_IRQS; i++) {
547 + int vector = FIRST_EXTERNAL_VECTOR + i;
548 + if (vector != SYSCALL_VECTOR) {
549 + set_intr_gate(vector, proxy_interrupt[i]);
554 --- linux-2.4.28/arch/i386/kernel/ioport.c~colinux-0.6.1 2003-06-13 10:51:29.000000000 -0400
555 +++ linux-2.4.28/arch/i386/kernel/ioport.c 2004-11-27 15:59:21.289009600 -0500
558 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
560 +#ifndef CONFIG_COOPERATIVE
561 struct thread_struct * t = ¤t->thread;
562 struct tss_struct * tss = init_tss + smp_processor_id();
569 + /* No ports for yer VM */
577 asmlinkage int sys_iopl(unsigned long unused)
579 +#ifndef CONFIG_COOPERATIVE
580 struct pt_regs * regs = (struct pt_regs *) &unused;
581 unsigned int level = regs->ebx;
582 unsigned int old = (regs->eflags >> 12) & 3;
585 regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
588 + /* No IPL for yer VM */
592 --- linux-2.4.28/arch/i386/kernel/process.c~colinux-0.6.1 2004-11-17 06:54:21.000000000 -0500
593 +++ linux-2.4.28/arch/i386/kernel/process.c 2004-11-27 15:59:21.289009600 -0500
595 #include <asm/apic.h>
597 #include <linux/irq.h>
598 +#include <linux/cooperative.h>
600 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
602 @@ -131,11 +132,15 @@
603 current->counter = -100;
606 +#ifdef CONFIG_COOPERATIVE
607 + co_idle_processor();
609 void (*idle)(void) = pm_idle;
612 while (!current->need_resched)
620 void machine_real_restart(unsigned char *code, int length)
622 +#ifndef CONFIG_COOPERATIVE
626 @@ -363,10 +369,14 @@
627 __asm__ __volatile__ ("ljmp $0x0008,%0"
629 : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
631 + co_terminate(CO_TERMINATE_REBOOT);
635 void machine_restart(char * __unused)
637 +#ifndef CONFIG_COOPERATIVE
641 @@ -430,16 +440,26 @@
644 machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
646 + co_terminate(CO_TERMINATE_REBOOT);
650 void machine_halt(void)
652 +#ifdef CONFIG_COOPERATIVE
653 + co_terminate(CO_TERMINATE_HALT);
657 void machine_power_off(void)
659 +#ifndef CONFIG_COOPERATIVE
663 + co_terminate(CO_TERMINATE_POWEROFF);
667 extern void show_trace(unsigned long* esp);
668 @@ -657,12 +677,20 @@
670 tss->esp0 = next->esp0;
672 +#ifdef CONFIG_COOPERATIVE
674 + * We would save %fs and %gs using an atomic operation in the
675 + * just before the LDT of the next process is loaded. It is
676 + * not here, it's in...
680 * Save away %fs and %gs. No need to save %es and %ds, as
681 * those are always kernel segments while inside the kernel.
683 asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs));
684 asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs));
688 * Restore %fs and %gs.
689 --- linux-2.4.28/arch/i386/kernel/setup.c~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
690 +++ linux-2.4.28/arch/i386/kernel/setup.c 2004-11-27 15:59:21.291009296 -0500
692 #include <asm/processor.h>
693 #include <linux/console.h>
694 #include <linux/module.h>
695 +#include <linux/cooperative.h>
696 #include <asm/mtrr.h>
697 #include <asm/uaccess.h>
698 #include <asm/system.h>
703 +#ifdef CONFIG_COOPERATIVE
705 + * Better to have 'root=/dev/cobd0' here.
707 + from = co_boot_parameters;
708 + snprintf(saved_command_line, COMMAND_LINE_SIZE, "%s",
709 + co_boot_parameters);
711 /* Save unparsed command line copy for /proc/cmdline */
712 memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
713 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
718 @@ -1044,16 +1054,23 @@
719 static unsigned long __init setup_memory(void)
721 unsigned long bootmap_size, start_pfn, max_low_pfn;
723 +#ifdef CONFIG_COOPERATIVE
724 + unsigned long bootmem_size;
725 + unsigned long bootmem_start;
728 * partially used pages are not usable - thus
729 * we are rounding upwards:
731 start_pfn = PFN_UP(__pa(&_end));
733 +#ifdef CONFIG_COOPERATIVE
734 + max_low_pfn = max_pfn = co_memory_size / PAGE_SIZE;
738 max_low_pfn = find_max_low_pfn();
741 #ifdef CONFIG_HIGHMEM
742 highstart_pfn = highend_pfn = max_pfn;
743 @@ -1065,12 +1082,19 @@
745 printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
746 pages_to_mb(max_low_pfn));
749 * Initialize the boot-time allocator (with low memory only):
751 bootmap_size = init_bootmem(start_pfn, max_low_pfn);
753 - register_bootmem_low_pages(max_low_pfn);
754 +#ifdef CONFIG_COOPERATIVE
755 + bootmap_size = (bootmap_size + PAGE_SIZE - 1) & PAGE_MASK;
756 + bootmem_size = (0x800 << PAGE_SHIFT) - bootmap_size;
757 + bootmem_start = co_core_end + bootmap_size;
759 + free_bootmem(__pa(bootmem_start), bootmem_size);
763 * Reserve the bootmem bitmap itself as well. We do this in two
764 @@ -1124,7 +1148,7 @@
773 @@ -1176,7 +1200,9 @@
775 void __init setup_arch(char **cmdline_p)
777 +#ifndef CONFIG_COOPERATIVE
778 unsigned long max_low_pfn;
782 visws_get_board_type_and_rev();
783 @@ -1186,6 +1212,7 @@
787 + boot_cpu_data.hard_math = 1;
788 ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
789 drive_info = DRIVE_INFO;
790 screen_info = SCREEN_INFO;
791 @@ -1203,7 +1230,10 @@
792 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
793 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
796 +#ifndef CONFIG_COOPERATIVE
797 setup_memory_region();
801 if (!MOUNT_ROOT_RDONLY)
802 @@ -1230,8 +1260,10 @@
804 smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
809 +#ifndef CONFIG_COOPERATIVE
813 @@ -1248,14 +1280,19 @@
816 register_memory(max_low_pfn);
820 +#ifdef CONFIG_COOPERATIVE_CONSOLE
821 + conswitchp = &colinux_con;
823 #if defined(CONFIG_VGA_CONSOLE)
824 conswitchp = &vga_con;
825 #elif defined(CONFIG_DUMMY_CONSOLE)
826 conswitchp = &dummy_con;
832 static int cachesize_override __initdata = -1;
833 @@ -3216,29 +3253,41 @@
836 enter_lazy_tlb(&init_mm, current, nr);
838 t->esp0 = current->thread.esp0;
841 gdt_table[__TSS(nr)].b &= 0xfffffdff;
844 load_LDT(&init_mm.context);
847 * Clear all 6 debug registers:
850 +#ifndef CONFIG_COOPERATIVE
851 #define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) );
853 CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
859 * Force FPU initialization:
861 current->flags &= ~PF_USEDFPU;
862 current->used_math = 0;
863 +#ifndef CONFIG_COOPERATIVE
867 + clear_in_cr4(X86_CR4_PVI);
868 + clear_in_cr4(X86_CR4_DE);
869 + clear_in_cr4(X86_CR4_MCE);
870 + clear_in_cr4(X86_CR4_PGE);
872 + clear_in_cr4(X86_CR4_OSXMMEXCPT);
878 --- linux-2.4.28/arch/i386/kernel/time.c~colinux-0.6.1 2004-02-18 08:36:30.000000000 -0500
879 +++ linux-2.4.28/arch/i386/kernel/time.c 2004-11-27 15:59:21.292009144 -0500
882 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
884 -static inline unsigned long do_fast_gettimeoffset(void)
885 +static inline unsigned long long rdtsc_u64(void)
887 + register unsigned long eax, edx;
891 + return ((((unsigned long long)edx) << 32) | eax);
894 +#ifdef CONFIG_COOPERATIVE
895 +static unsigned long long co_last_interrupt_time;
896 +static unsigned long co_tsc_per_5_ticks;
897 +static long co_last_time_offset;
900 +static inline long do_fast_gettimeoffset(void)
902 +#ifndef CONFIG_COOPERATIVE
903 register unsigned long eax, edx;
905 /* Read the Time Stamp Counter */
908 /* our adjusted time offset in microseconds */
909 return delay_at_last_interrupt + edx;
912 + unsigned long long ll_var;
913 + struct { unsigned long low, high; };
916 + unsigned long ret = 0;
918 + differential.ll_var = rdtsc_u64() - co_last_interrupt_time;
919 + if (differential.high)
922 + if (co_tsc_per_5_ticks == 0)
925 + differential.ll_var *= 50000;
928 + :"=a" (ret), "=d" (edx)
929 + :"r" (co_tsc_per_5_ticks),
930 + "0" (differential.low), "1" (differential.high));
932 + ret += co_last_time_offset;
938 #define TICK_SIZE tick
941 extern spinlock_t i8259A_lock;
943 +#ifndef CONFIG_COOPERATIVE
945 #ifndef CONFIG_X86_TSC
947 /* This function must be called with interrupts disabled
952 -static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
955 +static unsigned long do_slow_gettimeoffset(void)
962 +static long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
965 /* IBM Summit (EXA) Cyclone Timer code*/
967 delay_at_last_interrupt = (count + LATCH/2) / LATCH;
970 -static unsigned long do_gettimeoffset_cyclone(void)
971 +static long do_gettimeoffset_cyclone(void)
976 void do_gettimeofday(struct timeval *tv)
979 - unsigned long usec, sec;
983 read_lock_irqsave(&xtime_lock, flags);
984 usec = do_gettimeoffset();
990 + usec = usec + 1000000;
999 static int set_rtc_mmss(unsigned long nowtime)
1001 +#ifndef CONFIG_COOPERATIVE
1003 int real_seconds, real_minutes, cmos_minutes;
1004 unsigned char save_control, save_freq_select;
1005 @@ -554,8 +614,13 @@
1006 CMOS_WRITE(save_control, RTC_CONTROL);
1007 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
1008 spin_unlock(&rtc_lock);
1013 + * Don't let Linux change the system time of the host machine.
1019 /* last time the cmos clock got updated */
1021 smp_local_timer_interrupt(regs);
1024 +#ifndef CONFIG_COOPERATIVE
1026 * If we have an externally synchronized Linux clock, then update
1027 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
1030 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
1038 write_lock(&xtime_lock);
1040 +#ifndef CONFIG_COOPERATIVE
1042 mark_timeoffset_cyclone();
1044 @@ -706,7 +774,15 @@
1045 count = ((LATCH-1) - count) * TICK_SIZE;
1046 delay_at_last_interrupt = (count + LATCH/2) / LATCH;
1051 + if (co_last_interrupt_time == 0)
1052 + co_last_time_offset = 0;
1054 + co_last_time_offset = ((long)do_fast_gettimeoffset()) - 10000;
1055 + co_last_interrupt_time = rdtsc_u64();
1058 do_timer_interrupt(irq, NULL, regs);
1060 write_unlock(&xtime_lock);
1062 /* not static: needed by APM */
1063 unsigned long get_cmos_time(void)
1065 +#ifndef CONFIG_COOPERATIVE
1066 unsigned int year, mon, day, hour, min, sec;
1070 if ((year += 1900) < 1970)
1072 return mktime(year, mon, day, hour, min, sec);
1074 + return co_get_host_time();
1078 static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
1079 @@ -818,6 +898,10 @@
1080 if (endlow <= CALIBRATE_TIME)
1083 +#ifdef CONFIG_COOPERATIVE
1084 + co_tsc_per_5_ticks = endlow;
1088 :"=a" (endlow), "=d" (endhigh)
1089 :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
1090 @@ -870,7 +954,13 @@
1093 init_cyclone_clock();
1096 +#ifdef CONFIG_COOPERATIVE
1098 + * We pretty much depend on this at the moment...
1100 + set_bit(X86_FEATURE_TSC, &boot_cpu_data.x86_capability);
1103 unsigned long tsc_quotient = calibrate_tsc();
1105 --- linux-2.4.28/arch/i386/kernel/traps.c~colinux-0.6.1 2002-11-28 18:53:09.000000000 -0500
1106 +++ linux-2.4.28/arch/i386/kernel/traps.c 2004-11-27 15:59:21.293008992 -0500
1107 @@ -852,11 +852,20 @@
1109 : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
1114 + * We use this in colinux_early_cpu_init(), so it must be protected
1118 void set_tss_desc(unsigned int n, void *addr)
1120 _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
1125 void set_ldt_desc(unsigned int n, void *addr, unsigned int size)
1127 _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82);
1128 --- linux-2.4.28/arch/i386/mm/fault.c~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
1129 +++ linux-2.4.28/arch/i386/mm/fault.c 2004-11-27 15:59:21.293008992 -0500
1130 @@ -380,7 +380,11 @@
1133 asm("movl %%cr3,%0":"=r" (pgd));
1134 +#ifndef CONFIG_COOPERATIVE
1135 pgd = offset + (pgd_t *)__va(pgd);
1137 + pgd = offset + (pgd_t *)CO_VA(((unsigned long)pgd));
1139 pgd_k = init_mm.pgd + offset;
1141 if (!pgd_present(*pgd_k))
1142 --- linux-2.4.28/arch/i386/mm/init.c~colinux-0.6.1 2004-04-14 09:05:25.000000000 -0400
1143 +++ linux-2.4.28/arch/i386/mm/init.c 2004-11-27 15:59:21.294008840 -0500
1145 #include <asm/apic.h>
1146 #include <asm/tlb.h>
1148 +#include <linux/cooperative.h>
1150 mmu_gather_t mmu_gathers[NR_CPUS];
1151 unsigned long highstart_pfn, highend_pfn;
1152 static unsigned long totalram_pages;
1155 /* References to section boundaries */
1157 -extern char _text, _etext, _edata, __bss_start, _end;
1158 +extern char _text, _etext, _edata, _sdata, __bss_start, _end;
1159 extern char __init_begin, __init_end;
1161 static inline void set_pte_phys (unsigned long vaddr,
1164 static void __init pagetable_init (void)
1166 +#ifndef CONFIG_COOPERATIVE
1167 unsigned long vaddr, end;
1168 pgd_t *pgd, *pgd_base;
1172 pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
1178 void __init zap_low_mappings (void)
1180 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
1181 unsigned int max_dma, high, low;
1183 +#ifndef CONFIG_COOPERATIVE
1184 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
1187 @@ -338,6 +344,11 @@
1188 zones_size[ZONE_HIGHMEM] = high - low;
1192 + zones_size[ZONE_DMA] = 0;
1193 + zones_size[ZONE_NORMAL] = max_low_pfn;
1194 + zones_size[ZONE_HIGHMEM] = 0;
1196 free_area_init(zones_size);
1199 @@ -485,6 +496,22 @@
1201 bad_ppro = ppro_with_ram_bug();
1203 +#ifdef CONFIG_COOPERATIVE
1205 + * Only at this stage, after the buddy allocator's maps
1206 + * have been allocated, we can let the kernel use its
1207 + * other pseudo physical space.
1210 + unsigned long bootmem_end = co_core_end +
1211 + (0x800 << PAGE_SHIFT);
1212 + unsigned long physical_end = __PAGE_OFFSET +
1213 + (max_low_pfn << PAGE_SHIFT);
1215 + free_bootmem(__pa(bootmem_end), physical_end - bootmem_end);
1219 /* this will put all low memory onto the freelists */
1220 totalram_pages += free_all_bootmem();
1223 reservedpages = free_pages_init();
1225 codesize = (unsigned long) &_etext - (unsigned long) &_text;
1226 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
1227 + datasize = (unsigned long) &_edata - (unsigned long) &_sdata;
1228 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
1230 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
1231 @@ -546,19 +573,21 @@
1233 panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
1235 +#ifndef CONFIG_COOPERATIVE
1236 if (boot_cpu_data.wp_works_ok < 0)
1241 * Subtle. SMP is doing it's boot stuff late (because it has to
1242 * fork idle threads) - but it also needs low mappings for the
1243 * protected-mode entry to work. We zap these entries only after
1244 * the WP-bit has been tested.
1246 +#ifndef CONFIG_COOPERATIVE
1254 /* Put this after the callers, so that it cannot be inlined */
1255 --- linux-2.4.28/arch/i386/vmlinux.lds~colinux-0.6.1 2002-02-25 14:37:53.000000000 -0500
1256 +++ linux-2.4.28/arch/i386/vmlinux.lds 2004-11-27 15:59:21.294008840 -0500
1260 . = 0xC0000000 + 0x100000;
1261 - _text = .; /* Text and read-only data */
1262 + _kernel_start = .;
1264 + _text = .; /* Text and read-only data */
1270 - _etext = .; /* End of text section */
1271 + _etext = .; /* End of text section */
1274 .rodata : { *(.rodata) *(.rodata.*) }
1275 .kstrtab : { *(.kstrtab) }
1277 . = ALIGN(16); /* Exception table */
1278 - __start___ex_table = .;
1279 - __ex_table : { *(__ex_table) }
1280 - __stop___ex_table = .;
1282 + __start___ex_table = .;
1284 + __stop___ex_table = .;
1287 - __start___ksymtab = .; /* Kernel symbol table */
1288 - __ksymtab : { *(__ksymtab) }
1289 - __stop___ksymtab = .;
1291 + __import_table_address : {
1292 + __start_import_address = .;
1293 + *(__im_table_address)
1294 + __stop_import_address = .;
1298 + __start___ksymtab = .; /* Kernel symbol table */
1300 + __stop___ksymtab = .;
1302 .data : { /* Data */
1303 + _sdata = .; /* Start of data section */
1307 + _edata = .; /* End of data section */
1310 - _edata = .; /* End of data section */
1311 + . = ALIGN(4096); /* gdt */
1319 . = ALIGN(8192); /* init_task */
1320 - .data.init_task : { *(.data.init_task) }
1321 + .data.init_task : {
1322 + *(.data.init_task)
1325 . = ALIGN(4096); /* Init code and data */
1327 - .text.init : { *(.text.init) }
1328 - .data.init : { *(.data.init) }
1330 - __setup_start = .;
1331 - .setup.init : { *(.setup.init) }
1333 - __initcall_start = .;
1334 - .initcall.init : { *(.initcall.init) }
1335 - __initcall_end = .;
1343 + __setup_start = .;
1346 + __initcall_start = .;
1348 + __initcall_end = .;
1354 .data.page_aligned : { *(.data.idt) }
1357 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1359 - __bss_start = .; /* BSS */
1361 + __bss_start = .; /* BSS */
1368 /* Sections to be discarded */
1370 --- linux-2.4.28/drivers/block/Config.in~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
1371 +++ linux-2.4.28/drivers/block/Config.in 2004-11-27 15:59:21.294008840 -0500
1374 dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
1376 +if [ "$CONFIG_COOPERATIVE" = "y" ]; then
1377 + tristate 'coLinux block device support' CONFIG_BLK_DEV_PBD
1380 bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS
1383 --- linux-2.4.28/drivers/block/Makefile~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
1384 +++ linux-2.4.28/drivers/block/Makefile 2004-11-27 15:59:21.295008688 -0500
1386 obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
1387 obj-$(CONFIG_BLK_DEV_UMEM) += umem.o
1388 obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
1389 +obj-$(CONFIG_BLK_DEV_PBD) += cobd.o
1390 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
1392 subdir-$(CONFIG_PARIDE) += paride
1393 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
1394 +++ linux-2.4.28/drivers/block/cobd.c 2004-11-27 15:59:21.295008688 -0500
1397 + * Copyright (C) 2003 Dan Aloni <da-x@gmx.net>
1399 + * Cooperative Linux Block Device implementation
1402 +#include <linux/config.h>
1403 +#include <linux/module.h>
1404 +#include <linux/fs.h>
1405 +#include <linux/errno.h>
1406 +#include <linux/major.h>
1407 +#include <linux/slab.h>
1408 +#include <linux/devfs_fs_kernel.h>
1410 +#define MAJOR_NR COLINUX_MAJOR
1411 +#define DEVICE_NR(device) MINOR(device) /* has no partition bits */
1412 +#define DEVICE_NAME "cobd" /* name for messaging */
1413 +#define DEVICE_NO_RANDOM /* no entropy to contribute */
1414 +#define DEVICE_REQUEST cobd_request
1415 +#define DEVICE_OFF(d) /* do-nothing */
1417 +#include <linux/blk.h>
1418 +#include <linux/blkpg.h>
1419 +#include <linux/hdreg.h>
1420 +#include <linux/cooperative.h>
1422 +#include <asm/uaccess.h>
1424 +#define PBD_BLOCK_SIZE 512
1426 +static int *cobd_sizes;
1427 +static int *cobd_blksizes;
1428 +static int *cobd_hardsects;
1429 +static int cobd_devs;
1430 +static int cobd_rahead = 1;
1432 +struct cobd_device_aliases_minor {
1436 +struct cobd_device_aliases_major {
1438 + int blksizes[0x100];
1439 + int cobd_hardsects[0x100];
1440 + struct cobd_device_aliases_minor *minors[0x100];
1443 +static struct cobd_device_aliases_major *alias_majors;
1445 +static int cobd_stat(int dev, co_block_request_t *out_request)
1447 + co_block_request_t *request;
1448 + unsigned long flags;
1451 + local_irq_save(flags);
1452 + co_passage_page->operation = CO_OPERATION_DEVICE;
1453 + co_passage_page->params[0] = CO_DEVICE_BLOCK;
1454 + co_passage_page->params[1] = dev;
1455 + request = (co_block_request_t *)&co_passage_page->params[2];
1456 + request->type = CO_BLOCK_STAT;
1457 + co_switch_wrapper();
1459 + *out_request = *request;
1460 + local_irq_restore(flags);
1465 +static int cobd_ioctl(struct inode * inode, struct file * file,
1466 + unsigned int cmd, unsigned long arg)
1471 + dev = MINOR(inode->i_rdev);
1475 + case BLKGETSIZE: {
1476 + unsigned long size;
1478 + /* Return the device size, expressed in sectors */
1480 + return -EINVAL; /* NULL pointer: not valid */
1482 + err = !access_ok (VERIFY_WRITE, arg, sizeof(long));
1486 + size = (cobd_sizes[dev]) * (1024 / cobd_hardsects[dev]);
1487 + if (copy_to_user((unsigned long *) arg, &size, sizeof (unsigned long)))
1493 + case BLKGETSIZE64: {
1494 + unsigned long long size;
1496 + /* Return the device size, expressed in sectors */
1498 + return -EINVAL; /* NULL pointer: not valid */
1500 + err = !access_ok (VERIFY_WRITE, arg, sizeof(unsigned long long));
1504 + size = cobd_sizes[dev];
1505 + size = size * 1024;
1506 + if (copy_to_user((unsigned long long *) arg, &size, sizeof (unsigned long long)))
1512 + case BLKRRPART: /* reread partition table: can't do it */
1517 + * For ioctls we don't understand, let the block layer
1520 + return blk_ioctl(inode->i_rdev, cmd, arg);
1523 + return -ENOTTY; /* unknown command */
1526 +static int cobd_open(struct inode *inode, struct file *file)
1528 + co_block_request_t *co_request;
1529 + co_block_request_t stat_request;
1530 + unsigned long flags;
1532 + int dev = MINOR(inode->i_rdev);
1534 + if (dev >= cobd_devs)
1537 + if (!cobd_stat(dev, &stat_request)) {
1538 + unsigned long long size;
1540 + /* Request succeeded */
1541 + size = stat_request.disk_size;
1542 + cobd_sizes[dev] = size / 1024;
1544 + cobd_sizes[dev] = 0;
1547 + local_irq_save(flags);
1548 + co_passage_page->operation = CO_OPERATION_DEVICE;
1549 + co_passage_page->params[0] = CO_DEVICE_BLOCK;
1550 + co_passage_page->params[1] = DEVICE_NR(inode->i_rdev);
1551 + co_request = (co_block_request_t *)&co_passage_page->params[2];
1552 + co_request->type = CO_BLOCK_OPEN;
1553 + co_switch_wrapper();
1554 + if (co_request->rc)
1556 + local_irq_restore(flags);
1561 +static int cobd_release(struct inode *inode, struct file *file)
1563 + co_block_request_t *co_request;
1564 + unsigned long flags;
1566 + local_irq_save(flags);
1568 + co_passage_page->operation = CO_OPERATION_DEVICE;
1569 + co_passage_page->params[0] = CO_DEVICE_BLOCK;
1570 + co_passage_page->params[1] = DEVICE_NR(inode->i_rdev);
1571 + co_request = (co_block_request_t *)&co_passage_page->params[2];
1572 + co_request->type = CO_BLOCK_CLOSE;
1573 + co_switch_wrapper();
1574 + if (co_request->rc)
1576 + local_irq_restore(flags);
1581 +static int cobd_transfer(int dev, const struct request *req)
1583 + co_block_request_t *co_request;
1584 + unsigned long flags;
1587 + local_irq_save(flags);
1589 + co_passage_page->operation = CO_OPERATION_DEVICE;
1590 + co_passage_page->params[0] = CO_DEVICE_BLOCK;
1591 + co_passage_page->params[1] = dev;
1592 + co_request = (co_block_request_t *)&co_passage_page->params[2];
1593 + if (req->cmd == READ)
1594 + co_request->type = CO_BLOCK_READ;
1596 + co_request->type = CO_BLOCK_WRITE;
1597 + co_request->offset = ((unsigned long long)req->sector) * PBD_BLOCK_SIZE;
1598 + co_request->size = req->current_nr_sectors * PBD_BLOCK_SIZE;
1599 + co_request->address = req->buffer;
1600 + co_request->rc = 0;
1602 + co_switch_wrapper();
1604 + if (!co_request->rc)
1607 + local_irq_restore(flags);
1612 +static void cobd_request(request_queue_t *q)
1618 + INIT_REQUEST; /* returns when queue is empty */
1620 + devno = DEVICE_NR(CURRENT->rq_dev);
1622 + status = cobd_transfer(devno, CURRENT);
1624 + end_request(status);
1628 +static int cobd_check_change(kdev_t dev)
1633 +static struct block_device_operations cobd_fops = {
1634 + owner: THIS_MODULE,
1636 + release: cobd_release,
1637 + ioctl: cobd_ioctl,
1638 + check_media_change: cobd_check_change,
1641 +int __init cobd_init(void)
1646 + if (devfs_register_blkdev(MAJOR_NR, "cobd", &cobd_fops)) {
1647 + printk(KERN_WARNING "Unable to get major number %d for cobd device\n", MAJOR_NR);
1651 + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), cobd_request);
1653 + read_ahead[MAJOR_NR] = cobd_rahead;
1654 + result = -ENOMEM; /* for the possible errors */
1656 + cobd_devs = CO_MODULE_MAX_COBD;
1658 + cobd_sizes = kmalloc(cobd_devs * sizeof(int), GFP_KERNEL);
1662 + cobd_blksizes = kmalloc(cobd_devs * sizeof(int), GFP_KERNEL);
1663 + if (!cobd_blksizes)
1664 + goto fail_malloc_1;
1666 + cobd_hardsects = kmalloc(cobd_devs * sizeof(int), GFP_KERNEL);
1667 + if (!cobd_hardsects)
1668 + goto fail_malloc_2;
1670 + for (i=0; i < cobd_devs; i++) {
1671 + co_block_request_t request;
1672 + unsigned long long size = 0;
1674 + if (!cobd_stat(i, &request)) {
1675 + /* Request successed */
1676 + size = request.disk_size;
1677 + cobd_sizes[i] = size >> 10;
1679 + cobd_sizes[i] = 0;
1682 + if (cobd_sizes[i] != 0)
1683 + printk(KERN_DEBUG "cobd%d size: %d kb\n", i, cobd_sizes[i]);
1685 + cobd_blksizes[i] = PAGE_SIZE;
1686 + cobd_hardsects[i] = PBD_BLOCK_SIZE;
1689 + blk_size[MAJOR_NR] = cobd_sizes;
1690 + blksize_size[MAJOR_NR] = cobd_blksizes;
1691 + hardsect_size[MAJOR_NR] = cobd_hardsects;
1693 + devfs_register_series(NULL, "cobd%u", cobd_devs, DEVFS_FL_DEFAULT,
1695 + S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
1696 + &cobd_fops, NULL);
1698 + printk(KERN_DEBUG "cobd: loaded (max %d devices)\n", cobd_devs);
1703 + kfree(cobd_blksizes);
1705 + kfree(cobd_sizes);
1708 + if (devfs_unregister_blkdev(MAJOR_NR, "cobd"))
1709 + printk(KERN_WARNING "loop: cannot unregister blkdev\n");
1714 +void cobd_exit(void)
1716 + blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1718 + if (devfs_unregister_blkdev(MAJOR_NR, "cobd"))
1719 + printk(KERN_WARNING "cobd: cannot unregister blkdev\n");
1721 + kfree(blk_size[MAJOR_NR]);
1722 + kfree(blksize_size[MAJOR_NR]);
1723 + kfree(hardsect_size[MAJOR_NR]);
1726 +module_init(cobd_init);
1727 +module_exit(cobd_exit);
1730 --- linux-2.4.28/drivers/block/ll_rw_blk.c~colinux-0.6.1 2004-11-17 06:54:21.000000000 -0500
1731 +++ linux-2.4.28/drivers/block/ll_rw_blk.c 2004-11-27 15:59:21.298008232 -0500
1732 @@ -1576,7 +1576,7 @@
1733 #ifdef CONFIG_BLK_DEV_FD
1736 -#if defined(__i386__) /* Do we even need this? */
1737 +#if defined(__i386__) && !defined(CONFIG_COOPERATIVE) /* Do we even need this? */
1741 --- linux-2.4.28/drivers/char/Makefile~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
1742 +++ linux-2.4.28/drivers/char/Makefile 2004-11-27 15:59:21.298008232 -0500
1743 @@ -169,6 +169,10 @@
1744 KEYBD = dummy_keyb.o
1747 +ifeq ($(CONFIG_COOPERATIVE),y)
1748 + KEYBD = colx_keyb.o
1751 obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
1752 obj-$(CONFIG_SERIAL) += $(SERIAL)
1753 obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o
1754 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
1755 +++ linux-2.4.28/drivers/char/colx_keyb.c 2004-11-27 15:59:21.299008080 -0500
1758 + * linux/drivers/char/pc_keyb.c
1760 + * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
1761 + * See keyboard.c for the whole history.
1763 + * Major cleanup by Martin Mares, May 1997
1765 + * Combined the keyboard and PS/2 mouse handling into one file,
1766 + * because they share the same hardware.
1767 + * Johan Myreen <jem@iki.fi> 1998-10-08.
1769 + * Code fixes to handle mouse ACKs properly.
1770 + * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
1774 +#include <linux/config.h>
1776 +#include <linux/spinlock.h>
1777 +#include <linux/sched.h>
1778 +#include <linux/interrupt.h>
1779 +#include <linux/tty.h>
1780 +#include <linux/mm.h>
1781 +#include <linux/signal.h>
1782 +#include <linux/init.h>
1783 +#include <linux/kbd_ll.h>
1784 +#include <linux/delay.h>
1785 +#include <linux/random.h>
1786 +#include <linux/poll.h>
1787 +#include <linux/miscdevice.h>
1788 +#include <linux/slab.h>
1789 +#include <linux/kbd_kern.h>
1790 +#include <linux/vt_kern.h>
1791 +#include <linux/smp_lock.h>
1792 +#include <linux/kd.h>
1793 +#include <linux/pm.h>
1795 +#include <asm/keyboard.h>
1796 +#include <asm/bitops.h>
1797 +#include <asm/uaccess.h>
1798 +#include <asm/irq.h>
1799 +#include <asm/system.h>
1801 +#include <asm/io.h>
1803 +/* Some configuration switches are present in the include file... */
1805 +#include <linux/pc_keyb.h>
1807 +/* Simple translation table for the SysRq keys */
1809 +#ifdef CONFIG_MAGIC_SYSRQ
1810 +unsigned char pckbd_sysrq_xlate[128] =
1811 + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
1812 + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
1813 + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
1814 + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
1815 + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
1816 + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
1817 + "\r\000/"; /* 0x60 - 0x6f */
1820 +static void kbd_write_command_w(int data);
1821 +static void kbd_write_output_w(int data);
1822 +#ifdef CONFIG_PSMOUSE
1823 +static void aux_write_ack(int val);
1824 +static void __aux_write_ack(int val);
1825 +static int aux_reconnect = 0;
1828 +#ifndef kbd_controller_present
1829 +#define kbd_controller_present() 1
1831 +static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
1832 +static unsigned char handle_kbd_event(void);
1834 +/* used only by send_data - set by keyboard_interrupt */
1835 +static volatile unsigned char reply_expected;
1836 +static volatile unsigned char acknowledge;
1837 +static volatile unsigned char resend;
1840 +#if defined CONFIG_PSMOUSE
1842 + * PS/2 Auxiliary Device
1845 +static int __init psaux_init(void);
1847 +#define AUX_RECONNECT1 0xaa /* scancode1 when ps2 device is plugged (back) in */
1848 +#define AUX_RECONNECT2 0x00 /* scancode2 when ps2 device is plugged (back) in */
1850 +static struct aux_queue *queue; /* Mouse data buffer. */
1851 +static int aux_count;
1852 +/* used when we send commands to the mouse that expect an ACK. */
1853 +static unsigned char mouse_reply_expected;
1855 +#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
1856 +#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
1858 +#define MAX_RETRIES 60 /* some aux operations take long time*/
1859 +#endif /* CONFIG_PSMOUSE */
1862 + * Wait for keyboard controller input buffer to drain.
1864 + * Don't use 'jiffies' so that we don't depend on
1867 + * Quote from PS/2 System Reference Manual:
1869 + * "Address hex 0060 and address hex 0064 should be written only when
1870 + * the input-buffer-full bit and output-buffer-full bit in the
1871 + * Controller Status register are set 0."
1874 +static void kb_wait(void)
1876 + unsigned long timeout = KBC_TIMEOUT;
1880 + * "handle_kbd_event()" will handle any incoming events
1881 + * while we wait - keypresses or mouse movement.
1883 + unsigned char status = handle_kbd_event();
1885 + if (! (status & KBD_STAT_IBF))
1889 + } while (timeout);
1890 +#ifdef KBD_REPORT_TIMEOUTS
1891 + printk(KERN_WARNING "Keyboard timed out[1]\n");
1896 + * Translation of escaped scancodes to keycodes.
1897 + * This is now user-settable.
1898 + * The keycodes 1-88,96-111,119 are fairly standard, and
1899 + * should probably not be changed - changing might confuse X.
1900 + * X also interprets scancode 0x5d (KEY_Begin).
1902 + * For 1-88 keycode equals scancode.
1905 +#define E0_KPENTER 96
1906 +#define E0_RCTRL 97
1907 +#define E0_KPSLASH 98
1908 +#define E0_PRSCR 99
1909 +#define E0_RALT 100
1910 +#define E0_BREAK 101 /* (control-pause) */
1911 +#define E0_HOME 102
1913 +#define E0_PGUP 104
1914 +#define E0_LEFT 105
1915 +#define E0_RIGHT 106
1917 +#define E0_DOWN 108
1918 +#define E0_PGDN 109
1922 +#define E1_PAUSE 119
1925 + * The keycodes below are randomly located in 89-95,112-118,120-127.
1926 + * They could be thrown away (and all occurrences below replaced by 0),
1927 + * but that would force many users to use the `setkeycodes' utility, where
1928 + * they needed not before. It does not matter that there are duplicates, as
1929 + * long as no duplication occurs for any single keyboard.
1933 +#define FOCUS_PF1 85 /* actual code! */
1934 +#define FOCUS_PF2 89
1935 +#define FOCUS_PF3 90
1936 +#define FOCUS_PF4 91
1937 +#define FOCUS_PF5 92
1938 +#define FOCUS_PF6 93
1939 +#define FOCUS_PF7 94
1940 +#define FOCUS_PF8 95
1941 +#define FOCUS_PF9 120
1942 +#define FOCUS_PF10 121
1943 +#define FOCUS_PF11 122
1944 +#define FOCUS_PF12 123
1947 +/* tfj@olivia.ping.dk:
1948 + * The four keys are located over the numeric keypad, and are
1949 + * labelled A1-A4. It's an rc930 keyboard, from
1950 + * Regnecentralen/RC International, Now ICL.
1951 + * Scancodes: 59, 5a, 5b, 5c.
1958 +static unsigned char high_keys[128 - SC_LIM] = {
1959 + RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
1960 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
1961 + 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
1962 + 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
1963 + FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
1964 + FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
1968 +#define E0_MACRO 112
1972 +#define E0_HELP 115
1975 +#define E0_KPMINPLUS 118
1977 + * My OmniKey generates e0 4c for the "OMNI" key and the
1978 + * right alt key does nada. [kkoller@nyx10.cs.du.edu]
1982 + * New microsoft keyboard is rumoured to have
1983 + * e0 5b (left window button), e0 5c (right window button),
1984 + * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
1985 + * [or: Windows_L, Windows_R, TaskMan]
1987 +#define E0_MSLW 125
1988 +#define E0_MSRW 126
1989 +#define E0_MSTM 127
1991 +static unsigned char e0_keys[128] = {
1992 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
1993 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
1994 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
1995 + 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
1996 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
1997 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
1998 + 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
1999 + E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
2000 + E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
2001 + E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
2002 + E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
2003 + 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
2004 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
2005 + 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
2006 + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
2007 + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
2010 +int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
2012 + if (scancode < SC_LIM || scancode > 255 || keycode > 127)
2014 + if (scancode < 128)
2015 + high_keys[scancode - SC_LIM] = keycode;
2017 + e0_keys[scancode - 128] = keycode;
2021 +int pckbd_getkeycode(unsigned int scancode)
2024 + (scancode < SC_LIM || scancode > 255) ? -EINVAL :
2025 + (scancode < 128) ? high_keys[scancode - SC_LIM] :
2026 + e0_keys[scancode - 128];
2029 +static int do_acknowledge(unsigned char scancode)
2031 + if (reply_expected) {
2032 + /* Unfortunately, we must recognise these codes only if we know they
2033 + * are known to be valid (i.e., after sending a command), because there
2034 + * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
2035 + * keys with such codes :(
2037 + if (scancode == KBD_REPLY_ACK) {
2039 + reply_expected = 0;
2041 + } else if (scancode == KBD_REPLY_RESEND) {
2043 + reply_expected = 0;
2046 + /* Should not happen... */
2048 + printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
2055 +int pckbd_translate(unsigned char scancode, unsigned char *keycode,
2058 + static int prev_scancode;
2060 + /* special prefix scancodes.. */
2061 + if (scancode == 0xe0 || scancode == 0xe1) {
2062 + prev_scancode = scancode;
2066 + /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
2067 + if (scancode == 0x00 || scancode == 0xff) {
2068 + prev_scancode = 0;
2074 + if (prev_scancode) {
2076 + * usually it will be 0xe0, but a Pause key generates
2077 + * e1 1d 45 e1 9d c5 when pressed, and nothing when released
2079 + if (prev_scancode != 0xe0) {
2080 + if (prev_scancode == 0xe1 && scancode == 0x1d) {
2081 + prev_scancode = 0x100;
2083 + } else if (prev_scancode == 0x100 && scancode == 0x45) {
2084 + *keycode = E1_PAUSE;
2085 + prev_scancode = 0;
2087 +#ifdef KBD_REPORT_UNKN
2089 + printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
2091 + prev_scancode = 0;
2095 + prev_scancode = 0;
2097 + * The keyboard maintains its own internal caps lock and
2098 + * num lock statuses. In caps lock mode E0 AA precedes make
2099 + * code and E0 2A follows break code. In num lock mode,
2100 + * E0 2A precedes make code and E0 AA follows break code.
2101 + * We do our own book-keeping, so we will just ignore these.
2104 + * For my keyboard there is no caps lock mode, but there are
2105 + * both Shift-L and Shift-R modes. The former mode generates
2106 + * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
2107 + * So, we should also ignore the latter. - aeb@cwi.nl
2109 + if (scancode == 0x2a || scancode == 0x36)
2112 + if (e0_keys[scancode])
2113 + *keycode = e0_keys[scancode];
2115 +#ifdef KBD_REPORT_UNKN
2117 + printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
2123 + } else if (scancode >= SC_LIM) {
2124 + /* This happens with the FOCUS 9000 keyboard
2125 + Its keys PF1..PF12 are reported to generate
2126 + 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
2127 + Moreover, unless repeated, they do not generate
2128 + key-down events, so we have to zero up_flag below */
2129 + /* Also, Japanese 86/106 keyboards are reported to
2130 + generate 0x73 and 0x7d for \ - and \ | respectively. */
2131 + /* Also, some Brazilian keyboard is reported to produce
2132 + 0x73 and 0x7e for \ ? and KP-dot, respectively. */
2134 + *keycode = high_keys[scancode - SC_LIM];
2138 +#ifdef KBD_REPORT_UNKN
2139 + printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
2140 + " - ignored\n", scancode);
2146 + *keycode = scancode;
2150 +char pckbd_unexpected_up(unsigned char keycode)
2152 + /* unexpected, but this can happen: maybe this was a key release for a
2153 + FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
2154 + if (keycode >= SC_LIM || keycode == 85)
2160 +int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data)
2162 +#if defined CONFIG_PSMOUSE
2163 + unsigned long flags;
2165 + if (rqst == PM_RESUME) {
2166 + if (queue) { /* Aux port detected */
2167 + if (aux_count == 0) { /* Mouse not in use */
2168 + spin_lock_irqsave(&kbd_controller_lock, flags);
2170 + * Dell Lat. C600 A06 enables mouse after resume.
2171 + * When user touches the pad, it posts IRQ 12
2172 + * (which we do not process), thus holding keyboard.
2174 + kbd_write_command(KBD_CCMD_MOUSE_DISABLE);
2175 + /* kbd_write_cmd(AUX_INTS_OFF); */ /* Config & lock */
2177 + kbd_write_command(KBD_CCMD_WRITE_MODE);
2179 + kbd_write_output(AUX_INTS_OFF);
2180 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2189 +static inline void handle_mouse_event(unsigned char scancode)
2191 +#ifdef CONFIG_PSMOUSE
2192 + static unsigned char prev_code;
2193 + if (mouse_reply_expected) {
2194 + if (scancode == AUX_ACK) {
2195 + mouse_reply_expected--;
2198 + mouse_reply_expected = 0;
2200 + else if(scancode == AUX_RECONNECT2 && prev_code == AUX_RECONNECT1
2201 + && aux_reconnect) {
2202 + printk (KERN_INFO "PS/2 mouse reconnect detected\n");
2203 + queue->head = queue->tail = 0; /* Flush input queue */
2204 + __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
2208 + prev_code = scancode;
2209 + add_mouse_randomness(scancode);
2211 + int head = queue->head;
2213 + queue->buf[head] = scancode;
2214 + head = (head + 1) & (AUX_BUF_SIZE-1);
2215 + if (head != queue->tail) {
2216 + queue->head = head;
2217 + kill_fasync(&queue->fasync, SIGIO, POLL_IN);
2218 + wake_up_interruptible(&queue->proc_list);
2224 +static unsigned char kbd_exists = 1;
2226 +void handle_keyboard_event(unsigned char scancode)
2230 + if (do_acknowledge(scancode))
2231 + handle_scancode(scancode, !(scancode & 0x80));
2233 + tasklet_schedule(&keyboard_tasklet);
2237 + * This reads the keyboard status port, and does the
2238 + * appropriate action.
2240 + * It requires that we hold the keyboard controller
2243 +static unsigned char handle_kbd_event(void)
2245 + unsigned char scancode;
2246 + co_linux_message_t *message;
2248 + while (co_get_message(&message, CO_DEVICE_KEYBOARD)) {
2249 + co_scan_code_t *sc = (co_scan_code_t *)message->data;
2250 + unsigned long scancode = sc->code;
2255 + handle_keyboard_event(scancode);
2257 + co_free_message(message);
2264 +static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2267 + kbd_pt_regs = regs;
2270 + spin_lock_irq(&kbd_controller_lock);
2271 + handle_kbd_event();
2272 + spin_unlock_irq(&kbd_controller_lock);
2276 + * send_data sends a character to the keyboard and waits
2277 + * for an acknowledge, possibly retrying if asked to. Returns
2278 + * the success status.
2280 + * Don't use 'jiffies', so that we don't depend on interrupts
2282 +static int send_data(unsigned char data)
2287 +void pckbd_leds(unsigned char leds)
2289 + if (kbd_exists && (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))) {
2290 + send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
2295 +#define DEFAULT_KEYB_REP_DELAY 250
2296 +#define DEFAULT_KEYB_REP_RATE 30 /* cps */
2298 +static struct kbd_repeat kbdrate={
2299 + DEFAULT_KEYB_REP_DELAY,
2300 + DEFAULT_KEYB_REP_RATE
2303 +static unsigned char parse_kbd_rate(struct kbd_repeat *r)
2305 + static struct r2v{
2307 + unsigned char val;
2308 + } kbd_rates[]={ {5,0x14},
2316 + static struct d2v{
2318 + unsigned char val;
2319 + } kbd_delays[]={{250,0},
2324 + int rate=0,delay=0;
2326 + int i,new_rate=30,new_delay=250;
2328 + r->rate=kbdrate.rate;
2329 + if (r->delay <= 0)
2330 + r->delay=kbdrate.delay;
2331 + for (i=0; i < sizeof(kbd_rates)/sizeof(struct r2v); i++)
2332 + if (kbd_rates[i].rate == r->rate){
2333 + new_rate=kbd_rates[i].rate;
2334 + rate=kbd_rates[i].val;
2337 + for (i=0; i < sizeof(kbd_delays)/sizeof(struct d2v); i++)
2338 + if (kbd_delays[i].delay == r->delay){
2339 + new_delay=kbd_delays[i].delay;
2340 + delay=kbd_delays[i].val;
2344 + r->delay=new_delay;
2346 + return (delay << 5) | rate;
2349 +static int write_kbd_rate(unsigned char r)
2351 + if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)){
2352 + send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
2358 +static int pckbd_rate(struct kbd_repeat *rep)
2363 + unsigned char r=parse_kbd_rate(rep);
2364 + struct kbd_repeat old_rep;
2365 + memcpy(&old_rep,&kbdrate,sizeof(struct kbd_repeat));
2366 + if (write_kbd_rate(r)){
2367 + memcpy(&kbdrate,rep,sizeof(struct kbd_repeat));
2368 + memcpy(rep,&old_rep,sizeof(struct kbd_repeat));
2376 + * In case we run on a non-x86 hardware we need to initialize both the
2377 + * keyboard controller and the keyboard. On a x86, the BIOS will
2378 + * already have initialized them.
2380 + * Some x86 BIOSes do not correctly initialize the keyboard, so the
2381 + * "kbd-reset" command line options can be given to force a reset.
2385 + int kbd_startup_reset __initdata = 0;
2387 + int kbd_startup_reset __initdata = 1;
2390 +/* for "kbd-reset" cmdline param */
2391 +static int __init kbd_reset_setup(char *str)
2393 + kbd_startup_reset = 1;
2397 +__setup("kbd-reset", kbd_reset_setup);
2399 +#define KBD_NO_DATA (-1) /* No data */
2400 +#define KBD_BAD_DATA (-2) /* Parity or other error */
2402 +static int __init kbd_read_data(void)
2404 + int retval = KBD_NO_DATA;
2407 + status = kbd_read_status();
2408 + if (status & KBD_STAT_OBF) {
2409 + unsigned char data = kbd_read_input();
2412 + if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
2413 + retval = KBD_BAD_DATA;
2419 +static void __init kbd_clear_input(void)
2421 + int maxread = 100; /* Random number */
2424 + if (kbd_read_data() == KBD_NO_DATA)
2426 + } while (--maxread);
2429 +static int __init kbd_wait_for_input(void)
2431 + long timeout = KBD_INIT_TIMEOUT;
2434 + int retval = kbd_read_data();
2438 + } while (--timeout);
2442 +static void kbd_write_command_w(int data)
2444 + unsigned long flags;
2446 + spin_lock_irqsave(&kbd_controller_lock, flags);
2448 + kbd_write_command(data);
2449 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2452 +static void kbd_write_output_w(int data)
2454 + unsigned long flags;
2456 + spin_lock_irqsave(&kbd_controller_lock, flags);
2458 + kbd_write_output(data);
2459 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2462 +#if defined(__alpha__)
2464 + * Some Alphas cannot mask some/all interrupts, so we have to
2465 + * make sure not to allow interrupts AT ALL when polling for
2466 + * specific return values from the keyboard.
2468 + * I think this should work on any architecture, but for now, only Alpha.
2470 +static int kbd_write_command_w_and_wait(int data)
2472 + unsigned long flags;
2475 + spin_lock_irqsave(&kbd_controller_lock, flags);
2477 + kbd_write_command(data);
2478 + input = kbd_wait_for_input();
2479 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2483 +static int kbd_write_output_w_and_wait(int data)
2485 + unsigned long flags;
2488 + spin_lock_irqsave(&kbd_controller_lock, flags);
2490 + kbd_write_output(data);
2491 + input = kbd_wait_for_input();
2492 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2496 +static int kbd_write_command_w_and_wait(int data)
2498 + kbd_write_command_w(data);
2499 + return kbd_wait_for_input();
2502 +static int kbd_write_output_w_and_wait(int data)
2504 + kbd_write_output_w(data);
2505 + return kbd_wait_for_input();
2507 +#endif /* __alpha__ */
2509 +#if defined CONFIG_PSMOUSE
2510 +static void kbd_write_cmd(int cmd)
2512 + unsigned long flags;
2514 + spin_lock_irqsave(&kbd_controller_lock, flags);
2516 + kbd_write_command(KBD_CCMD_WRITE_MODE);
2518 + kbd_write_output(cmd);
2519 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2521 +#endif /* CONFIG_PSMOUSE */
2523 +static char * __init initialize_kbd(void)
2528 + * Test the keyboard interface.
2529 + * This seems to be the only way to get it going.
2530 + * If the test is successful a x55 is placed in the input buffer.
2532 + kbd_write_command_w(KBD_CCMD_SELF_TEST);
2533 + if (kbd_wait_for_input() != 0x55)
2534 + return "Keyboard failed self test";
2537 + * Perform a keyboard interface test. This causes the controller
2538 + * to test the keyboard clock and data lines. The results of the
2539 + * test are placed in the input buffer.
2541 + kbd_write_command_w(KBD_CCMD_KBD_TEST);
2542 + if (kbd_wait_for_input() != 0x00)
2543 + return "Keyboard interface failed self test";
2546 + * Enable the keyboard by allowing the keyboard clock to run.
2548 + kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
2551 + * Reset keyboard. If the read times out
2552 + * then the assumption is that no keyboard is
2553 + * plugged into the machine.
2554 + * This defaults the keyboard to scan-code set 2.
2556 + * Set up to try again if the keyboard asks for RESEND.
2559 + kbd_write_output_w(KBD_CMD_RESET);
2560 + status = kbd_wait_for_input();
2561 + if (status == KBD_REPLY_ACK)
2563 + if (status != KBD_REPLY_RESEND)
2564 + return "Keyboard reset failed, no ACK";
2567 + if (kbd_wait_for_input() != KBD_REPLY_POR)
2568 + return "Keyboard reset failed, no POR";
2571 + * Set keyboard controller mode. During this, the keyboard should be
2572 + * in the disabled state.
2574 + * Set up to try again if the keyboard asks for RESEND.
2577 + kbd_write_output_w(KBD_CMD_DISABLE);
2578 + status = kbd_wait_for_input();
2579 + if (status == KBD_REPLY_ACK)
2581 + if (status != KBD_REPLY_RESEND)
2582 + return "Disable keyboard: no ACK";
2585 + kbd_write_command_w(KBD_CCMD_WRITE_MODE);
2586 + kbd_write_output_w(KBD_MODE_KBD_INT
2588 + | KBD_MODE_DISABLE_MOUSE
2591 + /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
2592 + if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
2595 + * If the controller does not support conversion,
2596 + * Set the keyboard to scan-code set 1.
2598 + kbd_write_output_w(0xF0);
2599 + kbd_wait_for_input();
2600 + kbd_write_output_w(0x01);
2601 + kbd_wait_for_input();
2604 + if (kbd_write_output_w_and_wait(KBD_CMD_ENABLE) != KBD_REPLY_ACK)
2605 + return "Enable keyboard: no ACK";
2608 + * Finally, set the typematic rate to maximum.
2610 + if (kbd_write_output_w_and_wait(KBD_CMD_SET_RATE) != KBD_REPLY_ACK)
2611 + return "Set rate: no ACK";
2612 + if (kbd_write_output_w_and_wait(0x00) != KBD_REPLY_ACK)
2613 + return "Set rate: no 2nd ACK";
2618 +void __init pckbd_init_hw(void)
2620 + if (!kbd_controller_present()) {
2625 + kbd_request_region();
2627 + /* Flush any pending input. */
2628 + kbd_clear_input();
2630 + if (kbd_startup_reset) {
2631 + char *msg = initialize_kbd();
2633 + printk(KERN_WARNING "initialize_kbd: %s\n", msg);
2636 +#if defined CONFIG_PSMOUSE
2640 + kbd_rate = pckbd_rate;
2642 + /* Ok, finally allocate the IRQ, and off we go.. */
2643 + kbd_request_irq(keyboard_interrupt);
2646 +#if defined CONFIG_PSMOUSE
2648 +static int __init aux_reconnect_setup (char *str)
2650 + aux_reconnect = 1;
2654 +__setup("psaux-reconnect", aux_reconnect_setup);
2657 + * Check if this is a dual port controller.
2659 +static int __init detect_auxiliary_port(void)
2661 + unsigned long flags;
2665 + /* Check if the BIOS detected a device on the auxiliary port. */
2666 + if (aux_device_present == 0xaa)
2669 + spin_lock_irqsave(&kbd_controller_lock, flags);
2671 + /* Put the value 0x5A in the output buffer using the "Write
2672 + * Auxiliary Device Output Buffer" command (0xD3). Poll the
2673 + * Status Register for a while to see if the value really
2674 + * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
2675 + * bit is also set to 1 in the Status Register, we assume this
2676 + * controller has an Auxiliary Port (a.k.a. Mouse Port).
2679 + kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
2682 + kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
2685 + unsigned char status = kbd_read_status();
2687 + if (status & KBD_STAT_OBF) {
2688 + (void) kbd_read_input();
2689 + if (status & KBD_STAT_MOUSE_OBF) {
2690 + printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
2696 + } while (--loops);
2697 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2703 + * Send a byte to the mouse.
2705 +static void aux_write_dev(int val)
2707 + unsigned long flags;
2709 + spin_lock_irqsave(&kbd_controller_lock, flags);
2711 + kbd_write_command(KBD_CCMD_WRITE_MOUSE);
2713 + kbd_write_output(val);
2714 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2718 + * Send a byte to the mouse & handle returned ack
2720 +static void __aux_write_ack(int val)
2723 + kbd_write_command(KBD_CCMD_WRITE_MOUSE);
2725 + kbd_write_output(val);
2726 + /* we expect an ACK in response. */
2727 + mouse_reply_expected++;
2731 +static void aux_write_ack(int val)
2733 + unsigned long flags;
2735 + spin_lock_irqsave(&kbd_controller_lock, flags);
2736 + __aux_write_ack(val);
2737 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2740 +static unsigned char get_from_queue(void)
2742 + unsigned char result;
2743 + unsigned long flags;
2745 + spin_lock_irqsave(&kbd_controller_lock, flags);
2746 + result = queue->buf[queue->tail];
2747 + queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
2748 + spin_unlock_irqrestore(&kbd_controller_lock, flags);
2753 +static inline int queue_empty(void)
2755 + return queue->head == queue->tail;
2758 +static int fasync_aux(int fd, struct file *filp, int on)
2762 + retval = fasync_helper(fd, filp, on, &queue->fasync);
2770 + * Random magic cookie for the aux device
2772 +#define AUX_DEV ((void *)queue)
2774 +static int release_aux(struct inode * inode, struct file * file)
2777 + fasync_aux(-1, file, 0);
2778 + if (--aux_count) {
2782 + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
2783 + kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
2784 + aux_free_irq(AUX_DEV);
2790 + * Install interrupt handler.
2791 + * Enable auxiliary device.
2794 +static int open_aux(struct inode * inode, struct file * file)
2796 + if (aux_count++) {
2799 + queue->head = queue->tail = 0; /* Flush input queue */
2800 + if (aux_request_irq(keyboard_interrupt, AUX_DEV)) {
2804 + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the
2807 + aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
2808 + kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
2810 + mdelay(2); /* Ensure we follow the kbc access delay rules.. */
2812 + send_data(KBD_CMD_ENABLE); /* try to workaround toshiba4030cdt problem */
2818 + * Put bytes from input queue to buffer.
2821 +static ssize_t read_aux(struct file * file, char * buffer,
2822 + size_t count, loff_t *ppos)
2824 + DECLARE_WAITQUEUE(wait, current);
2825 + ssize_t i = count;
2828 + if (queue_empty()) {
2829 + if (file->f_flags & O_NONBLOCK)
2831 + add_wait_queue(&queue->proc_list, &wait);
2833 + set_current_state(TASK_INTERRUPTIBLE);
2834 + if (queue_empty() && !signal_pending(current)) {
2838 + current->state = TASK_RUNNING;
2839 + remove_wait_queue(&queue->proc_list, &wait);
2841 + while (i > 0 && !queue_empty()) {
2842 + c = get_from_queue();
2843 + put_user(c, buffer++);
2847 + file->f_dentry->d_inode->i_atime = CURRENT_TIME;
2850 + if (signal_pending(current))
2851 + return -ERESTARTSYS;
2856 + * Write to the aux device.
2859 +static ssize_t write_aux(struct file * file, const char * buffer,
2860 + size_t count, loff_t *ppos)
2862 + ssize_t retval = 0;
2865 + ssize_t written = 0;
2868 + count = 32; /* Limit to 32 bytes. */
2871 + get_user(c, buffer++);
2874 + } while (--count);
2878 + file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
2885 +/* No kernel lock held - fine */
2886 +static unsigned int aux_poll(struct file *file, poll_table * wait)
2888 + poll_wait(file, &queue->proc_list, wait);
2889 + if (!queue_empty())
2890 + return POLLIN | POLLRDNORM;
2894 +struct file_operations psaux_fops = {
2899 + release: release_aux,
2900 + fasync: fasync_aux,
2904 + * Initialize driver.
2906 +static struct miscdevice psaux_mouse = {
2907 + PSMOUSE_MINOR, "psaux", &psaux_fops
2910 +static int __init psaux_init(void)
2914 + if (!detect_auxiliary_port())
2917 + if ((retval = misc_register(&psaux_mouse)))
2920 + queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
2921 + if (queue == NULL) {
2922 + printk(KERN_ERR "psaux_init(): out of memory\n");
2923 + misc_deregister(&psaux_mouse);
2926 + memset(queue, 0, sizeof(*queue));
2927 + queue->head = queue->tail = 0;
2928 + init_waitqueue_head(&queue->proc_list);
2930 +#ifdef INITIALIZE_MOUSE
2931 + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
2932 + aux_write_ack(AUX_SET_SAMPLE);
2933 + aux_write_ack(100); /* 100 samples/sec */
2934 + aux_write_ack(AUX_SET_RES);
2935 + aux_write_ack(3); /* 8 counts per mm */
2936 + aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
2937 +#endif /* INITIALIZE_MOUSE */
2938 + kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
2939 + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
2944 +#endif /* CONFIG_PSMOUSE */
2947 +static int blink_frequency = HZ/2;
2949 +/* Tell the user who may be running in X and not see the console that we have
2950 + panic'ed. This is to distingush panics from "real" lockups.
2951 + Could in theory send the panic message as morse, but that is left as an
2952 + exercise for the reader. */
2953 +void panic_blink(void)
2955 + static unsigned long last_jiffie;
2957 + /* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is
2959 + if (!blink_frequency)
2961 + if (jiffies - last_jiffie > blink_frequency) {
2962 + led ^= 0x01 | 0x04;
2963 + while (kbd_read_status() & KBD_STAT_IBF) mdelay(1);
2964 + kbd_write_output(KBD_CMD_SET_LEDS);
2966 + while (kbd_read_status() & KBD_STAT_IBF) mdelay(1);
2968 + kbd_write_output(led);
2969 + last_jiffie = jiffies;
2973 +static int __init panicblink_setup(char *str)
2976 + if (get_option(&str,&par))
2977 + blink_frequency = par*(1000/HZ);
2981 +/* panicblink=0 disables the blinking as it caused problems with some console
2982 + switches. otherwise argument is ms of a blink period. */
2983 +__setup("panicblink=", panicblink_setup);
2985 --- linux-2.4.28/drivers/char/mem.c~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
2986 +++ linux-2.4.28/drivers/char/mem.c 2004-11-27 15:59:21.304007320 -0500
2987 @@ -667,20 +667,24 @@
2988 static int memory_open(struct inode * inode, struct file * filp)
2990 switch (MINOR(inode->i_rdev)) {
2991 +#ifndef CONFIG_COOPERATIVE
2993 filp->f_op = &mem_fops;
2996 filp->f_op = &kmem_fops;
3000 filp->f_op = &null_fops;
3002 +#ifndef CONFIG_COOPERATIVE
3003 #if defined(CONFIG_ISA) || !defined(__mc68000__)
3005 filp->f_op = &port_fops;
3010 filp->f_op = &zero_fops;
3012 @@ -710,12 +714,16 @@
3014 struct file_operations *fops;
3015 } list[] = { /* list of minor devices */
3016 +#ifndef CONFIG_COOPERATIVE
3017 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
3018 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
3020 {3, "null", S_IRUGO | S_IWUGO, &null_fops},
3021 +#ifndef CONFIG_COOPERATIVE
3022 #if defined(CONFIG_ISA) || !defined(__mc68000__)
3023 {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
3026 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
3027 {7, "full", S_IRUGO | S_IWUGO, &full_fops},
3028 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
3029 --- linux-2.4.28/drivers/char/vt.c~colinux-0.6.1 2002-11-28 18:53:12.000000000 -0500
3030 +++ linux-2.4.28/drivers/char/vt.c 2004-11-27 15:59:21.305007168 -0500
3032 * comments - KDMKTONE doesn't put the process to sleep.
3035 -#if defined(__i386__) || defined(__alpha__) || defined(CONFIG_PPC_ISATIMER) \
3036 - || (defined(__mips__) && defined(CONFIG_ISA)) \
3037 - || (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
3038 - || defined(__x86_64__)
3039 +#if (defined(__i386__) || defined(__alpha__) || defined(CONFIG_PPC_ISATIMER) \
3040 + || (defined(__mips__) && defined(CONFIG_ISA)) \
3041 + || (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
3042 + || defined(__x86_64__)) && !defined(CONFIG_COOPERATIVE)
3045 kd_nosound(unsigned long ignored)
3046 --- linux-2.4.28/drivers/net/Config.in~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
3047 +++ linux-2.4.28/drivers/net/Config.in 2004-11-27 15:59:21.306007016 -0500
3048 @@ -287,6 +287,10 @@
3049 dep_tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH $CONFIG_PPC_ISERIES
3052 +if [ "$CONFIG_COOPERATIVE" = "y" ]; then
3053 + tristate 'Coooperative Virtual Ethernet driver support' CONFIG_COOPERATIVE_CONET
3056 if [ "$CONFIG_4xx" = "y" ]; then
3057 source drivers/net/ibm_emac/Config.in
3059 --- linux-2.4.28/drivers/net/Makefile~colinux-0.6.1 2004-08-07 19:26:04.000000000 -0400
3060 +++ linux-2.4.28/drivers/net/Makefile 2004-11-27 15:59:21.306007016 -0500
3063 # This is also a 82596 and should probably be merged
3064 obj-$(CONFIG_LP486E) += lp486e.o
3065 +obj-$(CONFIG_COOPERATIVE_CONET) += conet.o
3067 obj-$(CONFIG_ETH16I) += eth16i.o
3068 obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
3069 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
3070 +++ linux-2.4.28/drivers/net/conet.c 2004-11-27 15:59:21.307006864 -0500
3073 + * Copyright (C) 2003-2004 Dan Aloni <da-x@gmx.net>
3074 + * Copyright (C) 2004 Pat Erley
3075 + * Copyright (C) 2004 George Boutwell
3077 + * Cooperative Linux Network Device implementation
3080 +#include <linux/config.h>
3081 +#include <linux/version.h>
3082 +#include <linux/module.h>
3084 +#include <linux/kernel.h>
3086 +#include <linux/netdevice.h>
3087 +#include <linux/etherdevice.h>
3088 +#include <linux/skbuff.h>
3089 +#include <linux/ethtool.h>
3091 +#include <linux/cooperative.h>
3092 +#include <asm/irq.h>
3094 +struct conet_priv {
3095 + struct net_device_stats stats;
3096 + co_linux_message_t *message;
3102 +struct net_device *conet_dev[CO_MODULE_MAX_CONET];
3104 +void conet_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr);
3106 +static int conet_get_mac(int unit, char *address)
3108 + unsigned long flags = 0;
3109 + co_network_request_t *net_request;
3112 + local_irq_save(flags);
3113 + co_passage_page->operation = CO_OPERATION_DEVICE;
3114 + co_passage_page->params[0] = CO_DEVICE_NETWORK;
3115 + net_request = (typeof(net_request))&co_passage_page->params[1];
3116 + net_request->unit = unit;
3117 + net_request->type = CO_NETWORK_GET_MAC;
3118 + co_switch_wrapper();
3119 + memcpy(address, net_request->mac_address, ETH_ALEN);
3120 + result = net_request->result;
3121 + local_irq_restore(flags);
3126 +int conet_open(struct net_device *dev)
3128 + struct conet_priv *priv = (struct conet_priv *)dev->priv;
3130 + if (priv->enabled)
3133 + MOD_INC_USE_COUNT;
3135 + conet_get_mac(priv->unit, dev->dev_addr);
3137 + priv->enabled = 1;
3139 + netif_start_queue(dev);
3144 +int conet_stop(struct net_device *dev)
3146 + struct conet_priv *priv = (struct conet_priv *)dev->priv;
3148 + priv->enabled = 0;
3150 + netif_stop_queue(dev); /* can't transmit any more */
3152 + MOD_DEC_USE_COUNT;
3157 +int conet_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
3161 + struct conet_priv *priv = (struct conet_priv *)dev->priv;
3163 + len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
3166 + dev->trans_start = jiffies; /* save the timestamp */
3168 + co_send_message(CO_MODULE_LINUX,
3169 + CO_MODULE_CONET0 + priv->unit,
3170 + CO_PRIORITY_DISCARDABLE,
3171 + CO_MESSAGE_TYPE_OTHER,
3175 + priv->stats.tx_bytes+=skb->len;
3176 + priv->stats.tx_packets++;
3178 + dev_kfree_skb(skb);
3183 +void conet_rx(struct net_device *dev)
3185 + struct sk_buff *skb;
3186 + struct conet_priv *priv = (struct conet_priv *)dev->priv;
3188 + unsigned char *buf;
3189 + co_linux_message_t *message;
3191 + message = priv->message;
3192 + if (message == NULL) {
3193 + printk("conet rx: no message\n");
3197 + priv->message = NULL;
3199 + len = message->size;
3200 + buf = message->data;
3203 + * The packet has been retrieved from the transmission
3204 + * medium. Build an skb around it, so upper layers can handle it
3206 + skb = dev_alloc_skb(len+2);
3208 + printk("conet rx: low on mem - packet dropped\n");
3209 + priv->stats.rx_dropped++;
3210 + co_free_message(message);
3214 + memcpy(skb_put(skb, len), buf, len);
3216 + /* Write metadata, and then pass to the receive level */
3218 + skb->protocol = eth_type_trans(skb, dev);
3219 + skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
3221 + priv->stats.rx_bytes += len;
3222 + priv->stats.rx_packets++;
3226 + co_free_message(message);
3230 +void conet_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
3232 + co_linux_message_t *message;
3234 + while (co_get_message(&message, CO_DEVICE_NETWORK)) {
3235 + struct net_device *dev;
3236 + struct conet_priv *priv;
3238 + if (message->unit < 0 || message->unit >= CO_MODULE_MAX_CONET) {
3239 + printk("conet intrrupt: buggy network reception\n");
3243 + dev = conet_dev[message->unit];
3244 + if (!netif_running(dev)) {
3245 + co_free_message(message);
3249 + priv = (struct conet_priv *)dev->priv;
3250 + if (priv->message != NULL) {
3251 + printk("conet intrrupt: freeing unhandled packet\n");
3252 + co_free_message(message);
3256 + priv->message = message;
3261 +struct net_device_stats* conet_get_stats(struct net_device *dev)
3263 + return (struct net_device_stats *)dev->priv;
3266 +int conet_init(struct net_device *dev)
3268 + struct conet_priv *priv = (struct conet_priv *)dev->priv;
3270 + memset(&priv->stats, 0, sizeof(priv->stats));
3274 + dev->open = conet_open;
3275 + dev->stop = conet_stop;
3276 + dev->hard_start_xmit = conet_hard_start_xmit;
3277 + dev->get_stats = conet_get_stats;
3278 + dev->irq = NETWORK_IRQ;
3280 + SET_MODULE_OWNER(dev);
3285 +void conet_uninit(struct net_device *dev)
3289 +static struct net_device *conet_create(int unit)
3291 + struct net_device *dev;
3292 + struct conet_priv *priv;
3295 + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
3297 + return ERR_PTR(-ENOMEM);
3300 + memset(dev, 0, sizeof(struct net_device));
3302 + priv = kmalloc(sizeof(struct conet_priv), GFP_KERNEL);
3303 + if (priv == NULL) {
3305 + return ERR_PTR(-ENOMEM);
3308 + memset(priv, 0, sizeof(struct conet_priv));
3309 + priv->unit = unit;
3312 + dev->init = conet_init;
3313 + dev->uninit = conet_uninit;
3314 + strcpy(dev->name, "eth%d");
3316 + result = register_netdev(dev);
3318 + printk("conet: error %d registering device \"%s\"\n", result, dev->name);
3321 + return ERR_PTR(-ENODEV);
3324 + printk("conet%d: initialized\n", priv->unit);
3329 +static void conet_destroy(struct net_device *dev)
3331 + struct conet_priv *priv = (struct conet_priv *) dev->priv;
3333 + printk("conet%d: freed\n", priv->unit);
3335 + unregister_netdev(dev);
3340 +static int __init conet_init_module(void)
3342 + int unit = 0, result;
3343 + struct net_device *dev;
3344 + char mac_address[6];
3346 + result = request_irq(NETWORK_IRQ, &conet_interrupt, 0, "conet", NULL);
3348 + printk("conet: loaded (max %d devices)\n", CO_MODULE_MAX_CONET);
3350 + for (unit=0; unit < CO_MODULE_MAX_CONET; unit++) {
3351 + conet_dev[unit] = NULL;
3353 + result = conet_get_mac(unit, mac_address);
3357 + dev = conet_create(unit);
3359 + conet_dev[unit] = dev;
3365 +static void __exit conet_cleanup_module(void)
3369 + free_irq(NETWORK_IRQ, NULL);
3371 + for (unit=0; unit < CO_MODULE_MAX_CONET; unit++) {
3372 + if (!conet_dev[unit])
3375 + conet_destroy(conet_dev[unit]);
3379 +module_init(conet_init_module);
3380 +module_exit(conet_cleanup_module);
3381 --- linux-2.4.28/drivers/video/Makefile~colinux-0.6.1 2004-02-18 08:36:31.000000000 -0500
3382 +++ linux-2.4.28/drivers/video/Makefile 2004-11-27 15:59:21.307006864 -0500
3384 fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
3385 fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
3386 fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
3387 - cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
3388 + cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o cocon.o \
3391 # Each configuration option enables a list of files.
3394 obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
3395 obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
3396 obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
3397 +obj-$(CONFIG_COOPERATIVE_CONSOLE) += cocon.o
3398 obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
3400 obj-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
3401 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
3402 +++ linux-2.4.28/drivers/video/cocon.c 2004-11-27 15:59:21.308006712 -0500
3405 + * linux/drivers/video/cocon.c -- Cooperative Linux console VGA driver
3407 + * This file is subject to the terms and conditions of the GNU General Public
3408 + * License. See the file COPYING in the main directory of this archive for
3411 + * Based on code copied from vgacon.c.
3413 + * Dan Aloni <da-x@gmx.net>, 2003-2004 (c)
3416 +#include <linux/config.h>
3417 +#include <linux/module.h>
3418 +#include <linux/types.h>
3419 +#include <linux/sched.h>
3420 +#include <linux/fs.h>
3421 +#include <linux/kernel.h>
3422 +#include <linux/tty.h>
3423 +#include <linux/console.h>
3424 +#include <linux/console_struct.h>
3425 +#include <linux/string.h>
3426 +#include <linux/kd.h>
3427 +#include <linux/slab.h>
3428 +#include <linux/vt_kern.h>
3429 +#include <linux/selection.h>
3430 +#include <linux/init.h>
3432 +#include <linux/cooperative.h>
3435 + * Interface used by the world
3438 +static const char *cocon_startup(void);
3439 +static void cocon_init(struct vc_data *c, int init);
3440 +static void cocon_deinit(struct vc_data *c);
3441 +static void cocon_clear(struct vc_data *c, int, int, int, int);
3442 +static void cocon_cursor(struct vc_data *c, int mode);
3443 +static int cocon_switch(struct vc_data *c);
3444 +static int cocon_blank(struct vc_data *c, int blank);
3445 +static int cocon_font_op(struct vc_data *c, struct console_font_op *op);
3446 +static int cocon_set_palette(struct vc_data *c, unsigned char *table);
3447 +static int cocon_scrolldelta(struct vc_data *c, int lines);
3448 +static int cocon_set_origin(struct vc_data *c);
3449 +static void cocon_save_screen(struct vc_data *c);
3450 +static int cocon_scroll(struct vc_data *c, int t, int b, int dir, int lines);
3451 +static u8 cocon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);
3452 +static void cocon_invert_region(struct vc_data *c, u16 *p, int count);
3454 +static const char __init *cocon_startup(void)
3456 + unsigned long flags;
3457 + co_console_message_t *message;
3458 + co_message_t *co_message;
3460 + co_message = co_send_message_save(&flags);
3461 + message = (co_console_message_t *)co_message->data;
3462 + co_message->from = CO_MODULE_LINUX;
3463 + co_message->to = CO_MODULE_CONSOLE;
3464 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3465 + co_message->type = CO_MESSAGE_TYPE_STRING;
3466 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3467 + message->type = CO_OPERATION_CONSOLE_STARTUP;
3468 + co_send_message_restore(flags);
3473 +static void cocon_init(struct vc_data *c, int init)
3475 + unsigned long flags;
3476 + co_console_message_t *message;
3477 + co_message_t *co_message;
3479 + /* We cannot be loaded as a module, therefore init is always 1 */
3480 + c->vc_can_do_color = 1;
3483 + c->vc_complement_mask = 0x7700;
3484 + c->vc_visible_origin = 0;
3487 + co_message = co_send_message_save(&flags);
3488 + message = (co_console_message_t *)co_message->data;
3489 + co_message->from = CO_MODULE_LINUX;
3490 + co_message->to = CO_MODULE_CONSOLE;
3491 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3492 + co_message->type = CO_MESSAGE_TYPE_STRING;
3493 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3494 + message->type = CO_OPERATION_CONSOLE_INIT;
3495 + co_send_message_restore(flags);
3498 +static void cocon_deinit(struct vc_data *c)
3500 + unsigned long flags;
3501 + co_console_message_t *message;
3502 + co_message_t *co_message;
3504 + co_message = co_send_message_save(&flags);
3505 + message = (co_console_message_t *)co_message->data;
3506 + co_message->from = CO_MODULE_LINUX;
3507 + co_message->to = CO_MODULE_CONSOLE;
3508 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3509 + co_message->type = CO_MESSAGE_TYPE_STRING;
3510 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3511 + message->type = CO_OPERATION_CONSOLE_DEINIT;
3512 + co_send_message_restore(flags);
3516 +static void cocon_clear(struct vc_data *c, int top, int left, int rows, int cols)
3518 + unsigned long flags;
3519 + co_console_message_t *message;
3520 + co_message_t *co_message;
3522 + co_message = co_send_message_save(&flags);
3523 + message = (co_console_message_t *)co_message->data;
3524 + co_message->from = CO_MODULE_LINUX;
3525 + co_message->to = CO_MODULE_CONSOLE;
3526 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3527 + co_message->type = CO_MESSAGE_TYPE_STRING;
3528 + co_message->size = ((char *)(&message->clear + 1)) - ((char *)message);
3529 + message->type = CO_OPERATION_CONSOLE_CLEAR;
3530 + message->clear.top = top;
3531 + message->clear.left = left;
3532 + message->clear.bottom = top + rows - 1;
3533 + message->clear.right = left + cols - 1;
3534 + message->clear.charattr = c->vc_video_erase_char;
3535 + co_send_message_restore(flags);
3538 +static void cocon_putc(struct vc_data *c, int charattr, int y, int x)
3540 + unsigned long flags;
3541 + co_message_t *co_message;
3542 + co_console_message_t *message;
3544 + co_message = co_send_message_save(&flags);
3545 + message = (co_console_message_t *)co_message->data;
3546 + co_message->from = CO_MODULE_LINUX;
3547 + co_message->to = CO_MODULE_CONSOLE;
3548 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3549 + co_message->type = CO_MESSAGE_TYPE_STRING;
3550 + co_message->size = ((char *)(&message->putc + 1)) - ((char *)message);
3551 + message->type = CO_OPERATION_CONSOLE_PUTC;
3552 + message->putc.x = x;
3553 + message->putc.y = y;
3554 + message->putc.charattr = charattr;
3555 + co_send_message_restore(flags);
3559 +static void cocon_putcs(struct vc_data *conp,
3560 + const unsigned short *s, int count, int yy, int xx)
3562 + unsigned long flags;
3563 + co_console_message_t *message;
3564 + co_message_t *co_message;
3566 + if (count > CO_MAX_PARAM_SIZE/2 - 16)
3569 + co_message = co_send_message_save(&flags);
3570 + message = (co_console_message_t *)co_message->data;
3571 + co_message->from = CO_MODULE_LINUX;
3572 + co_message->to = CO_MODULE_CONSOLE;
3573 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3574 + co_message->type = CO_MESSAGE_TYPE_STRING;
3575 + co_message->size = ((char *)(&message->putcs + 1)) - ((char *)message) +
3576 + count * sizeof(unsigned short);
3577 + message->type = CO_OPERATION_CONSOLE_PUTCS;
3578 + message->putcs.x = xx;
3579 + message->putcs.y = yy;
3580 + message->putcs.count = count;
3581 + memcpy(&message->putcs.data, s, count * sizeof(unsigned short));
3582 + co_send_message_restore(flags);
3585 +static u8 cocon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse)
3590 + attr = (attr & 0xf0) | c->vc_ulcolor;
3591 + else if (intensity == 0)
3592 + attr = (attr & 0xf0) | c->vc_halfcolor;
3594 + attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77);
3597 + if (intensity == 2)
3603 +static void cocon_invert_region(struct vc_data *c, u16 *p, int count)
3605 + unsigned long flags;
3606 + co_message_t *co_message;
3607 + co_console_message_t *message;
3608 + unsigned x = p - c->vc_origin ; // UPDATE: vc_origin = 0; but not yet
3610 + co_message = co_send_message_save(&flags);
3611 + message = (co_console_message_t *)co_message->data;
3612 + co_message->from = CO_MODULE_LINUX;
3613 + co_message->to = CO_MODULE_CONSOLE;
3614 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3615 + co_message->type = CO_MESSAGE_TYPE_STRING;
3616 + co_message->size = ((char *)(&message->invert + 1)) - ((char *)message);
3617 + message->type = CO_OPERATION_CONSOLE_INVERT_REGION;
3618 + message->invert.y = ((unsigned)x)/c->vc_cols;
3619 + message->invert.x = ((unsigned)x)-(message->invert.y);
3620 + message->invert.count = count;
3621 + co_send_message_restore(flags);
3624 + u16 a = scr_readw(p);
3625 + a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
3626 + scr_writew(a, p++);
3631 +static void cocon_cursor(struct vc_data *c, int mode)
3633 + unsigned long flags;
3634 + co_console_message_t *message;
3635 + co_message_t *co_message;
3637 + co_message = co_send_message_save(&flags);
3638 + message = (co_console_message_t *)co_message->data;
3639 + co_message->from = CO_MODULE_LINUX;
3640 + co_message->to = CO_MODULE_CONSOLE;
3641 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3642 + co_message->type = CO_MESSAGE_TYPE_STRING;
3643 + co_message->size = ((char *)(&message->cursor + 1)) - ((char *)message);;
3644 + if (mode==CM_ERASE) {
3645 + message->type = CO_OPERATION_CONSOLE_CURSOR_ERASE;
3646 + message->cursor.height = 0;
3647 + co_send_message_restore(flags);
3651 + if(mode==CM_MOVE) {
3652 + message->type = CO_OPERATION_CONSOLE_CURSOR_MOVE;
3653 + } else /*(mode==CM_DRAW)*/ {
3654 + message->type = CO_OPERATION_CONSOLE_CURSOR_DRAW;
3656 + message->cursor.x = c->vc_x;
3657 + message->cursor.y = c->vc_y;
3659 + switch (c->vc_cursor_type & CUR_HWMASK) {
3660 + case CUR_UNDERLINE:
3661 + message->cursor.height = 5;
3663 + case CUR_TWO_THIRDS:
3664 + message->cursor.height = 66;
3666 + case CUR_LOWER_THIRD:
3667 + message->cursor.height = 33;
3669 + case CUR_LOWER_HALF:
3670 + message->cursor.height = 50;
3673 + message->cursor.height = 0;
3676 + message->cursor.height = 5;
3680 + co_send_message_restore(flags);
3683 +static int cocon_switch(struct vc_data *c)
3685 + unsigned long flags;
3686 + co_console_message_t *message;
3687 + co_message_t *co_message;
3689 + co_message = co_send_message_save(&flags);
3690 + message = (co_console_message_t *)co_message->data;
3691 + co_message->from = CO_MODULE_LINUX;
3692 + co_message->to = CO_MODULE_CONSOLE;
3693 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3694 + co_message->type = CO_MESSAGE_TYPE_STRING;
3695 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3696 + message->type = CO_OPERATION_CONSOLE_SWITCH;
3697 + co_send_message_restore(flags);
3699 + return 1; /* Redrawing not needed */
3702 +static int cocon_set_palette(struct vc_data *c, unsigned char *table)
3704 + unsigned long flags;
3705 + co_console_message_t *message;
3706 + co_message_t *co_message;
3708 + co_message = co_send_message_save(&flags);
3709 + message = (co_console_message_t *)co_message->data;
3710 + co_message->from = CO_MODULE_LINUX;
3711 + co_message->to = CO_MODULE_CONSOLE;
3712 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3713 + co_message->type = CO_MESSAGE_TYPE_STRING;
3714 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3715 + message->type = CO_OPERATION_CONSOLE_SET_PALETTE;
3716 + co_send_message_restore(flags);
3721 +static int cocon_blank(struct vc_data *c, int blank)
3723 + unsigned long flags;
3724 + co_console_message_t *message;
3725 + co_message_t *co_message;
3727 + co_message = co_send_message_save(&flags);
3728 + message = (co_console_message_t *)co_message->data;
3729 + co_message->from = CO_MODULE_LINUX;
3730 + co_message->to = CO_MODULE_CONSOLE;
3731 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3732 + co_message->type = CO_MESSAGE_TYPE_STRING;
3733 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3734 + message->type = CO_OPERATION_CONSOLE_BLANK;
3735 + co_send_message_restore(flags);
3740 +static int cocon_font_op(struct vc_data *c, struct console_font_op *op)
3742 + unsigned long flags;
3743 + co_console_message_t *message;
3744 + co_message_t *co_message;
3746 + co_message = co_send_message_save(&flags);
3747 + message = (co_console_message_t *)co_message->data;
3748 + co_message->from = CO_MODULE_LINUX;
3749 + co_message->to = CO_MODULE_CONSOLE;
3750 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3751 + co_message->type = CO_MESSAGE_TYPE_STRING;
3752 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3753 + message->type = CO_OPERATION_CONSOLE_FONT_OP;
3754 + co_send_message_restore(flags);
3759 +static int cocon_scrolldelta(struct vc_data *c, int lines)
3761 + unsigned long flags;
3762 + co_console_message_t *message;
3763 + co_message_t *co_message;
3765 + co_message = co_send_message_save(&flags);
3766 + message = (co_console_message_t *)co_message->data;
3767 + co_message->from = CO_MODULE_LINUX;
3768 + co_message->to = CO_MODULE_CONSOLE;
3769 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3770 + co_message->type = CO_MESSAGE_TYPE_STRING;
3771 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3772 + message->type = CO_OPERATION_CONSOLE_SCROLLDELTA;
3773 + co_send_message_restore(flags);
3778 +static int cocon_set_origin(struct vc_data *c)
3780 + unsigned long flags;
3781 + co_console_message_t *message;
3782 + co_message_t *co_message;
3784 + co_message = co_send_message_save(&flags);
3785 + message = (co_console_message_t *)co_message->data;
3786 + co_message->from = CO_MODULE_LINUX;
3787 + co_message->to = CO_MODULE_CONSOLE;
3788 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3789 + co_message->type = CO_MESSAGE_TYPE_STRING;
3790 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3791 + message->type = CO_OPERATION_CONSOLE_SET_ORIGIN;
3792 + co_send_message_restore(flags);
3797 +static void cocon_save_screen(struct vc_data *c)
3799 + unsigned long flags;
3800 + co_console_message_t *message;
3801 + co_message_t *co_message;
3803 + co_message = co_send_message_save(&flags);
3804 + message = (co_console_message_t *)co_message->data;
3805 + co_message->from = CO_MODULE_LINUX;
3806 + co_message->to = CO_MODULE_CONSOLE;
3807 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3808 + co_message->type = CO_MESSAGE_TYPE_STRING;
3809 + co_message->size = ((char *)(&message->type + 1)) - ((char *)message);
3810 + message->type = CO_OPERATION_CONSOLE_SAVE_SCREEN;
3811 + co_send_message_restore(flags);
3814 +static int cocon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
3816 + unsigned long flags;
3817 + co_console_message_t *message;
3818 + co_message_t *co_message;
3820 + co_message = co_send_message_save(&flags);
3821 + message = (co_console_message_t *)co_message->data;
3822 + co_message->from = CO_MODULE_LINUX;
3823 + co_message->to = CO_MODULE_CONSOLE;
3824 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3825 + co_message->type = CO_MESSAGE_TYPE_STRING;
3826 + co_message->size = ((char *)(&message->scroll + 1)) - ((char *)message);
3828 + message->type = CO_OPERATION_CONSOLE_SCROLL_UP;
3830 + message->type = CO_OPERATION_CONSOLE_SCROLL_DOWN;
3831 + message->scroll.top = t;
3832 + message->scroll.bottom = b-1;
3833 + message->scroll.lines = lines;
3834 + co_send_message_restore(flags);
3839 +static void cocon_bmove(struct vc_data *c, int sy, int sx, int dy, int dx, int h, int w)
3841 + unsigned long flags;
3842 + co_console_message_t *message;
3843 + co_message_t *co_message;
3845 + co_message = co_send_message_save(&flags);
3846 + message = (co_console_message_t *)co_message->data;
3847 + co_message->from = CO_MODULE_LINUX;
3848 + co_message->to = CO_MODULE_CONSOLE;
3849 + co_message->priority = CO_PRIORITY_DISCARDABLE;
3850 + co_message->type = CO_MESSAGE_TYPE_STRING;
3851 + co_message->size = ((char *)(&message->bmove + 1)) - ((char *)message);
3852 + message->type = CO_OPERATION_CONSOLE_BMOVE;
3853 + message->bmove.row = dy;
3854 + message->bmove.column = dx;
3855 + message->bmove.top = sy;
3856 + message->bmove.left = sx;
3857 + message->bmove.bottom = sy + h - 1;
3858 + message->bmove.right = sx + w - 1;
3859 + co_send_message_restore(flags);
3863 + * The console `switch' structure for the VGA based console
3866 +const struct consw colinux_con = {
3867 + con_startup: cocon_startup,
3868 + con_init: cocon_init,
3869 + con_deinit: cocon_deinit,
3870 + con_clear: cocon_clear,
3871 + con_putc: cocon_putc,
3872 + con_putcs: cocon_putcs,
3873 + con_cursor: cocon_cursor,
3874 + con_scroll: cocon_scroll,
3875 + con_bmove: cocon_bmove,
3876 + con_switch: cocon_switch,
3877 + con_blank: cocon_blank,
3878 + con_font_op: cocon_font_op,
3879 + con_set_palette: cocon_set_palette,
3880 + con_scrolldelta: cocon_scrolldelta,
3881 + con_set_origin: cocon_set_origin,
3882 + con_save_screen: cocon_save_screen,
3883 + con_build_attr: cocon_build_attr,
3884 + con_invert_region: cocon_invert_region,
3887 +MODULE_LICENSE("GPL");
3888 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
3889 +++ linux-2.4.28/include/asm-i386/cooperative.h 2004-11-27 15:59:21.308006712 -0500
3891 +#ifndef __LINUX_ASM_COOPERATIVE_H__
3892 +#define __LINUX_ASM_COOPERATIVE_H__
3895 + unsigned short size;
3896 + struct x86_idt_entry *table;
3897 +} __attribute__((packed)) x86_idt_t;
3900 + unsigned short limit;
3901 + struct x86_dt_entry *base;
3902 +} __attribute__((packed)) x86_gdt_t;
3905 + unsigned char border2[0x4];
3908 + #define CO_ARCH_STATE_STACK_CS "0x04"
3911 + #define CO_ARCH_STATE_STACK_DS "0x08"
3914 + #define CO_ARCH_STATE_STACK_ES "0x0C"
3916 + unsigned long cr3;
3917 + #define CO_ARCH_STATE_STACK_CR3 "0x10"
3919 + unsigned long cr4;
3920 + #define CO_ARCH_STATE_STACK_CR4 "0x14"
3922 + unsigned long cr2;
3923 + #define CO_ARCH_STATE_STACK_CR2 "0x18"
3925 + unsigned long cr0;
3926 + #define CO_ARCH_STATE_STACK_CR0 "0x1C"
3929 + #define CO_ARCH_STATE_STACK_GDT "0x20"
3932 + #define CO_ARCH_STATE_STACK_FS "0x26"
3935 + #define CO_ARCH_STATE_STACK_GS "0x2A"
3937 + unsigned short ldt;
3938 + #define CO_ARCH_STATE_STACK_LDT "0x2E"
3941 + #define CO_ARCH_STATE_STACK_IDT "0x30"
3943 + unsigned short tr;
3944 + #define CO_ARCH_STATE_STACK_TR "0x36"
3946 + unsigned long return_eip;
3947 + #define CO_ARCH_STATE_STACK_RETURN_EIP "0x38"
3949 + unsigned long flags;
3950 + #define CO_ARCH_STATE_STACK_FLAGS "0x3C"
3952 + unsigned long esp;
3953 + #define CO_ARCH_STATE_STACK_ESP "0x40"
3956 + #define CO_ARCH_STATE_STACK_SS "0x44"
3958 + unsigned long dr0;
3959 + #define CO_ARCH_STATE_STACK_DR0 "0x48"
3961 + unsigned long dr1;
3962 + #define CO_ARCH_STATE_STACK_DR1 "0x4C"
3964 + unsigned long dr2;
3965 + #define CO_ARCH_STATE_STACK_DR2 "0x50"
3967 + unsigned long dr3;
3968 + #define CO_ARCH_STATE_STACK_DR3 "0x54"
3970 + unsigned long dr6;
3971 + #define CO_ARCH_STATE_STACK_DR6 "0x58"
3973 + unsigned long dr7;
3974 + #define CO_ARCH_STATE_STACK_DR7 "0x5C"
3976 + unsigned long other_map;
3977 + #define CO_ARCH_STATE_STACK_OTHERMAP "0x60"
3979 + unsigned long relocate_eip;
3980 + #define CO_ARCH_STATE_STACK_RELOCATE_EIP "0x64"
3981 + #define CO_ARCH_STATE_STACK_RELOCATE_EIP_AFTER "0x68"
3983 + unsigned long pad1;
3984 + unsigned long pad2;
3986 + unsigned char fxstate[0x200];
3987 + #define CO_ARCH_STATE_STACK_FXSTATE "0x70"
3988 +} __attribute__((packed)) co_arch_state_stack_t;
3990 +extern void co_debug(const char *fmt, ...);
3992 +static inline void co_passage_page_dump_state(co_arch_state_stack_t *state)
3994 + co_debug("cs: %04x ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
3995 + state->cs, state->ds, state->es, state->fs, state->gs, state->ss);
3997 + co_debug("cr0: %08x cr2: %08x cr3: %08x cr4: %08x\n",
3998 + state->cr0, state->cr2, state->cr3, state->cr4);
4000 + co_debug("dr0: %08x dr1: %08x dr2: %08x dr3: %08x dr6: %08x dr7: %08x\n",
4001 + state->dr0, state->dr1, state->dr2, state->dr3, state->dr6, state->dr7);
4003 + co_debug("gdt: %08x:%04x idt:%08x:%04x ldt:%04x tr:%04x\n",
4004 + state->gdt.base, state->gdt.limit, state->idt.table, state->idt.size,
4005 + state->ldt, state->tr);
4007 + co_debug("return_eip: %08x flags: %08x esp: %8x\n",
4008 + state->return_eip, state->flags, state->esp);
4010 + co_debug("other_map: %08x relocate_eip: %08x\n",
4011 + state->other_map, state->relocate_eip);
4014 +#define CO_MAX_PARAM_SIZE 0x400
4016 +typedef struct co_arch_passage_page {
4021 + unsigned long temp_pgd_physical;
4022 + unsigned long dr0;
4023 + unsigned long dr1;
4024 + unsigned long dr2;
4025 + unsigned long dr3;
4026 + unsigned long dr6;
4027 + unsigned long dr7;
4028 + unsigned char code[0x1c0];
4029 + } __attribute__((packed));
4030 + unsigned char pad[0x210];
4031 + } __attribute__((packed));
4033 + /* Machine states */
4034 + co_arch_state_stack_t host_state;
4035 + co_arch_state_stack_t linuxvm_state;
4037 + /* Control parameters */
4038 + unsigned long operation;
4039 + unsigned long params[];
4040 + } __attribute__((packed));
4041 + unsigned char first_page[0x1000];
4043 + unsigned long temp_pgd[0x400];
4044 + unsigned long temp_pte[2][0x400];
4045 +} co_arch_passage_page_t;
4047 +static inline void co_passage_page_dump(co_arch_passage_page_t *page)
4049 + co_debug("Host state\n");
4050 + co_passage_page_dump_state(&page->host_state);
4052 + co_debug("Linux state\n");
4053 + co_passage_page_dump_state(&page->linuxvm_state);
4057 + * Address space layout:
4060 +#define CO_VPTR_PHYSICAL_TO_PSEUDO_PFN_MAP (0xff000000)
4061 +#define CO_VPTR_PSEUDO_RAM_PAGE_TABLES (0xfef00000)
4062 +#define CO_VPTR_PASSAGE_PAGE (0xfeeff000)
4063 +#define CO_VPTR_SELF_MAP (0xfec00000)
4066 --- linux-2.4.28/include/asm-i386/dma.h~colinux-0.6.1 2003-08-25 07:44:43.000000000 -0400
4067 +++ linux-2.4.28/include/asm-i386/dma.h 2004-11-27 15:59:21.309006560 -0500
4070 * Assumes DMA flip-flop is clear.
4073 +#ifndef CONFIG_COOPERATIVE
4074 static __inline__ int get_dma_residue(unsigned int dmanr)
4076 unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
4079 return (dmanr<=3)? count : (count<<1);
4084 /* These are in kernel/dma.c: */
4085 extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
4086 --- linux-2.4.28/include/asm-i386/io.h~colinux-0.6.1 2003-06-13 10:51:38.000000000 -0400
4087 +++ linux-2.4.28/include/asm-i386/io.h 2004-11-27 15:59:21.309006560 -0500
4091 #include <linux/config.h>
4092 +#include <linux/cooperative.h>
4095 * This file contains the definitions for the x86 IO instructions
4099 #include <linux/vmalloc.h>
4100 +#include <linux/cooperative.h>
4103 * Temporary debugging check to catch old code using
4106 static inline void * ioremap (unsigned long offset, unsigned long size)
4108 +#ifdef CONFIG_COOPERATIVE
4109 + panic("ioremap %ld:%ld\n", offset, size);
4111 return __ioremap(offset, size, 0);
4116 static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
4118 +#ifdef CONFIG_COOPERATIVE
4119 + panic("ioremap_nocache %ld:%ld\n", offset, size);
4121 return __ioremap(offset, size, _PAGE_PCD);
4126 #endif /* __KERNEL__ */
4128 +#ifndef CONFIG_COOPERATIVE_NOT
4130 #ifdef SLOW_IO_BY_JUMPING
4131 #define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
4133 @@ -427,4 +437,21 @@
4139 +static inline unsigned long badio(const char *file, int line)
4141 +#ifdef CONFIG_COOPERATIVE
4142 + panic("badio %s:%d\n", file, line);
4147 +#define outb(port, data) badio(__FILE__, __LINE__)
4148 +#define inb(port) badio(__FILE__, __LINE__)
4149 +#define outb_p(port, data) badio(__FILE__, __LINE__)
4150 +#define inb_p(port) badio(__FILE__, __LINE__)
4155 --- linux-2.4.28/include/asm-i386/irq.h~colinux-0.6.1 2002-08-02 20:39:45.000000000 -0400
4156 +++ linux-2.4.28/include/asm-i386/irq.h 2004-11-27 15:59:21.310006408 -0500
4161 +#ifdef CONFIG_COOPERATIVE
4162 +#define NETWORK_IRQ 2
4166 * 16 8259A IRQ's, 208 potential APIC interrupt sources.
4167 * Right now the APIC is mostly only used for SMP.
4169 * Since vectors 0x00-0x1f are used/reserved for the CPU,
4170 * the usable vector space is 0x20-0xff (224 vectors)
4172 -#ifdef CONFIG_X86_IO_APIC
4173 +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_COPIC)
4177 --- linux-2.4.28/include/asm-i386/mc146818rtc.h~colinux-0.6.1 2001-11-22 14:46:58.000000000 -0500
4178 +++ linux-2.4.28/include/asm-i386/mc146818rtc.h 2004-11-27 15:59:21.310006408 -0500
4180 #ifndef _ASM_MC146818RTC_H
4181 #define _ASM_MC146818RTC_H
4183 +#include <linux/config.h>
4188 #define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
4191 +#ifndef CONFIG_COOPERATIVE
4193 * The yet supported machines all access the RTC index register via
4194 * an ISA port access but the way to access the date register differs ...
4196 outb_p((val),RTC_PORT(1)); \
4200 +#define CMOS_READ(addr) (0)
4201 +#define CMOS_WRITE(val, addr) (0)
4206 #endif /* _ASM_MC146818RTC_H */
4207 --- linux-2.4.28/include/asm-i386/page.h~colinux-0.6.1 2002-08-02 20:39:45.000000000 -0400
4208 +++ linux-2.4.28/include/asm-i386/page.h 2004-11-27 15:59:21.310006408 -0500
4210 #ifndef _I386_PAGE_H
4211 #define _I386_PAGE_H
4213 +#ifdef CONFIG_COOPERATIVE
4214 +#define WANT_PAGE_VIRTUAL
4217 /* PAGE_SHIFT determines the page size */
4218 #define PAGE_SHIFT 12
4219 #define PAGE_SIZE (1UL << PAGE_SHIFT)
4221 #ifndef __ASSEMBLY__
4223 #include <linux/config.h>
4224 +#include <asm/cooperative.h>
4226 #ifdef CONFIG_X86_USE_3DNOW
4230 #define __PAGE_OFFSET (0xC0000000)
4232 +#ifdef CONFIG_COOPERATIVE
4234 +#define CO_PPTM_OFFSET (CO_VPTR_PSEUDO_RAM_PAGE_TABLES)
4235 +#define CO_RPPTM_OFFSET (CO_VPTR_PHYSICAL_TO_PSEUDO_PFN_MAP)
4237 +#define CO_PFN(vaddr) ((((unsigned long)vaddr) - __PAGE_OFFSET) >> PAGE_SHIFT)
4238 +#define CO_PA(pfn) (((unsigned long *)CO_PPTM_OFFSET)[pfn])
4239 +#define CO_PFN_PA(vaddr) CO_PA(CO_PFN(vaddr))
4240 +#define CO_PPTM_SIZE (max_low_pfn * sizeof(pte_t))
4242 +#define CO_VA_PFN(pa) (((unsigned long *)CO_RPPTM_OFFSET)[((pa) >> PAGE_SHIFT)])
4243 +#define CO_VA_PAGE(pa) (mem_map + CO_VA_PFN(pa))
4244 +#define CO_VA(pa) ((CO_VA_PFN(pa) << PAGE_SHIFT) + __PAGE_OFFSET)
4249 * This much address space is reserved for vmalloc() and iomap()
4250 * as well as fixmap mappings.
4251 @@ -96,11 +117,16 @@
4254 #if 1 /* Set to zero for a slightly smaller kernel */
4255 +#ifdef CONFIG_COOPERATIVE
4256 +#define BUG() do { panic("BUG %s:%d\n", __FILE__, __LINE__); } while(0)
4259 __asm__ __volatile__( "ud2\n" \
4262 : : "i" (__LINE__), "i" (__FILE__))
4266 #define BUG() __asm__ __volatile__("ud2\n")
4268 @@ -129,9 +155,11 @@
4269 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
4270 #define __MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE)
4271 #define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
4272 -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
4273 #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
4274 +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
4276 #define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
4278 #define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
4280 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
4281 --- linux-2.4.28/include/asm-i386/pgalloc.h~colinux-0.6.1 2003-08-25 07:44:43.000000000 -0400
4282 +++ linux-2.4.28/include/asm-i386/pgalloc.h 2004-11-27 15:59:21.313005952 -0500
4284 #define pte_quicklist (current_cpu_data.pte_quick)
4285 #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
4287 +#ifndef CONFIG_COOPERATIVE
4288 #define pmd_populate(mm, pmd, pte) \
4289 - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
4290 + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
4292 +#define pmd_populate(mm, pmd, pte) \
4293 + set_pmd(pmd, __pmd(_PAGE_TABLE + (CO_PFN_PA(pte) & PAGE_MASK)))
4297 * Allocate and free page tables.
4298 --- linux-2.4.28/include/asm-i386/pgtable-2level.h~colinux-0.6.1 2002-11-28 18:53:15.000000000 -0500
4299 +++ linux-2.4.28/include/asm-i386/pgtable-2level.h 2004-11-27 15:59:21.313005952 -0500
4302 #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0))
4303 #define pte_same(a, b) ((a).pte_low == (b).pte_low)
4304 -#define pte_page(x) (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT))))
4305 #define pte_none(x) (!(x).pte_low)
4307 +#ifndef CONFIG_COOPERATIVE
4308 +#define pte_page(x) (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT))))
4309 #define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
4311 +#define pte_page(x) CO_VA_PAGE((x).pte_low)
4312 +#define __mk_pte(page_nr,pgprot) __pte((CO_PA(page_nr) & PAGE_MASK) | pgprot_val(pgprot))
4315 #endif /* _I386_PGTABLE_2LEVEL_H */
4316 --- linux-2.4.28/include/asm-i386/pgtable.h~colinux-0.6.1 2002-11-28 18:53:15.000000000 -0500
4317 +++ linux-2.4.28/include/asm-i386/pgtable.h 2004-11-27 15:59:21.313005952 -0500
4318 @@ -320,8 +320,13 @@
4320 #define page_pte(page) page_pte_prot(page, __pgprot(0))
4322 +#ifndef CONFIG_COOPERATIVE
4323 #define pmd_page(pmd) \
4324 -((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
4325 + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
4327 +#define pmd_page(pmd) \
4328 + (CO_VA(pmd_val(pmd)))
4331 /* to find an entry in a page-table-directory. */
4332 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
4333 --- linux-2.4.28/include/asm-i386/processor.h~colinux-0.6.1 2004-02-18 08:36:32.000000000 -0500
4334 +++ linux-2.4.28/include/asm-i386/processor.h 2004-11-27 15:59:21.314005800 -0500
4335 @@ -181,8 +181,18 @@
4336 #define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
4337 #define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
4339 +#ifndef CONFIG_COOPERATIVE
4340 #define load_cr3(pgdir) \
4341 - asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir)));
4342 +asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir)));
4345 + * In coLinux Mode we can't load CR3 with the pseudo physical
4346 + * address. Instead, we need to translate the pseudo physical address
4347 + * to the real physical address.
4349 +#define load_cr3(pgdir) \
4350 +asm volatile("movl %0,%%cr3": :"r" (CO_PFN_PA(pgdir)));
4354 * Save the cr4 feature set we're using (ie
4355 --- linux-2.4.28/include/asm-i386/system.h~colinux-0.6.1 2004-04-14 09:05:40.000000000 -0400
4356 +++ linux-2.4.28/include/asm-i386/system.h 2004-11-27 15:59:21.314005800 -0500
4358 struct task_struct; /* one of the stranger aspects of C forward declarations.. */
4359 extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
4361 +#ifdef CONFIG_COOPERATIVE
4362 +#define prepare_to_switch() { \
4363 + asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->thread.fs)); \
4364 + asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->thread.gs)); \
4367 #define prepare_to_switch() do { } while(0)
4370 #define switch_to(prev,next,last) do { \
4371 asm volatile("pushl %%esi\n\t" \
4373 --- linux-2.4.28/include/linux/console.h~colinux-0.6.1 2004-02-18 08:36:32.000000000 -0500
4374 +++ linux-2.4.28/include/linux/console.h 2004-11-27 15:59:21.315005648 -0500
4376 extern const struct consw dummy_con; /* dummy console buffer */
4377 extern const struct consw fb_con; /* frame buffer based console */
4378 extern const struct consw vga_con; /* VGA text console */
4379 +extern const struct consw colinux_con; /* coLinux Mode text console */
4380 extern const struct consw newport_con; /* SGI Newport console */
4381 extern const struct consw prom_con; /* SPARC PROM console */
4383 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
4384 +++ linux-2.4.28/include/linux/cooperative.h 2004-11-27 15:59:21.315005648 -0500
4386 +#ifndef __LINUX_COOPERATIVE_H__
4387 +#define __LINUX_COOPERATIVE_H__
4391 +#define CO_COLINUX_KERNEL
4396 +extern void co_debug(const char *fmt, ...);
4398 +#include <asm/cooperative.h>
4400 +#define CO_LINUX_ABI_VERSION 1
4404 +#define CO_BOOTPARAM_STRING_LENGTH 0x100
4406 +extern char co_boot_parameters[CO_BOOTPARAM_STRING_LENGTH];
4409 + CO_OPERATION_EMPTY=0,
4410 + CO_OPERATION_START,
4411 + CO_OPERATION_IDLE,
4412 + CO_OPERATION_TERMINATE,
4413 + CO_OPERATION_MESSAGE_TO_MONITOR,
4414 + CO_OPERATION_MESSAGE_FROM_MONITOR,
4415 + CO_OPERATION_FORWARD_INTERRUPT,
4416 + CO_OPERATION_DEVICE,
4417 + CO_OPERATION_GET_TIME,
4418 + CO_OPERATION_DEBUG_LINE,
4419 + CO_OPERATION_GET_HIGH_PREC_QUOTIENT,
4420 + CO_OPERATION_TRACE_POINT,
4423 +#define CO_MODULE_MAX_CONET 16
4424 +#define CO_MODULE_MAX_COBD 32
4428 + CO_MODULE_MONITOR,
4431 + CO_MODULE_KERNEL_SWITCH,
4432 + CO_MODULE_USER_SWITCH,
4433 + CO_MODULE_CONSOLE,
4437 + CO_MODULE_CONET_END=CO_MODULE_CONET0+CO_MODULE_MAX_CONET-1,
4440 + CO_MODULE_COBD_END=CO_MODULE_COBD0+CO_MODULE_MAX_COBD-1,
4444 + CO_PRIORITY_DISCARDABLE=0,
4445 + CO_PRIORITY_IMPORTANT,
4449 + CO_MESSAGE_TYPE_STRING=0,
4450 + CO_MESSAGE_TYPE_OTHER=1,
4451 +} co_message_type_t;
4456 + co_priority_t priority;
4457 + co_message_type_t type;
4458 + unsigned long size;
4460 +} __attribute__((packed)) co_message_t;
4463 + CO_DEVICE_BLOCK=0,
4464 + CO_DEVICE_CONSOLE,
4465 + CO_DEVICE_KEYBOARD,
4466 + CO_DEVICE_NETWORK,
4474 + unsigned char code;
4479 + CO_LINUX_MESSAGE_POWER_ALT_CTRL_DEL=0,
4480 +} co_linux_message_power_type_t;
4483 + co_linux_message_power_type_t type;
4484 +} __attribute__((packed)) co_linux_message_power_t;
4487 + unsigned long tick_count;
4488 +} __attribute__((packed)) co_linux_message_idle_t;
4491 + co_device_t device;
4492 + unsigned long unit;
4493 + unsigned long size;
4495 +} __attribute__((packed)) co_linux_message_t;
4498 + CO_TERMINATE_END=0,
4499 + CO_TERMINATE_REBOOT,
4500 + CO_TERMINATE_POWEROFF,
4501 + CO_TERMINATE_PANIC,
4502 + CO_TERMINATE_HALT,
4503 + CO_TERMINATE_FORCED_OFF,
4504 + CO_TERMINATE_FORCED_END,
4505 + CO_TERMINATE_INVALID_OPERATION,
4506 +} co_termination_reason_t;
4508 +typedef void (*co_switcher_t)(co_arch_passage_page_t *page,
4509 + unsigned char *from,
4510 + unsigned char *to);
4512 +#define co_passage_page_func_low(_from_,_to_) \
4513 + (((co_switcher_t)(co_passage_page->code)) \
4514 + (co_passage_page, \
4515 + (char *)&_from_.border2, \
4516 + (char *)&_to_.border2))
4518 +#define co_passage_page_func(_from_,_to_) \
4519 + co_passage_page_func_low(co_passage_page->_from_, co_passage_page->_to_)
4522 +# ifdef CO_COLINUX_KERNEL
4523 +# define co_passage_page ((co_arch_passage_page_t *)(CO_VPTR_PASSAGE_PAGE))
4524 +# define co_current (co_passage_page->linuxvm_state)
4525 +# define co_other (co_passage_page->host_state)
4527 +# define co_passage_page (cmon->passage_page)
4528 +# define co_other (co_passage_page->linuxvm_state)
4529 +# define co_current (co_passage_page->host_state)
4532 +# define co_switch() co_passage_page_func_low(co_current, co_other)
4536 + * Defines operations on various virtual devices.
4540 + CO_OPERATION_CONSOLE_STARTUP=0,
4541 + CO_OPERATION_CONSOLE_INIT=1,
4542 + CO_OPERATION_CONSOLE_DEINIT,
4543 + CO_OPERATION_CONSOLE_CLEAR,
4544 + CO_OPERATION_CONSOLE_PUTC,
4545 + CO_OPERATION_CONSOLE_PUTCS,
4546 + CO_OPERATION_CONSOLE_CURSOR_DRAW,
4547 + CO_OPERATION_CONSOLE_CURSOR_ERASE,
4548 + CO_OPERATION_CONSOLE_CURSOR_MOVE,
4549 + CO_OPERATION_CONSOLE_SCROLL_UP,
4550 + CO_OPERATION_CONSOLE_SCROLL_DOWN,
4551 + CO_OPERATION_CONSOLE_BMOVE,
4552 + CO_OPERATION_CONSOLE_SWITCH,
4553 + CO_OPERATION_CONSOLE_BLANK,
4554 + CO_OPERATION_CONSOLE_FONT_OP,
4555 + CO_OPERATION_CONSOLE_SET_PALETTE,
4556 + CO_OPERATION_CONSOLE_SCROLLDELTA,
4557 + CO_OPERATION_CONSOLE_SET_ORIGIN,
4558 + CO_OPERATION_CONSOLE_SAVE_SCREEN,
4559 + CO_OPERATION_CONSOLE_INVERT_REGION,
4560 +} co_operation_console_t;
4563 +typedef char co_console_code;
4564 +typedef unsigned short co_console_character;
4565 +typedef unsigned short co_console_unit;
4568 + co_console_unit x;
4569 + co_console_unit y;
4570 + co_console_unit height;
4571 +} __attribute__((packed)) co_cursor_pos_t;
4574 + co_operation_console_t type;
4577 + co_console_unit top;
4578 + co_console_unit bottom;
4579 + co_console_unit lines;
4582 + co_console_unit y;
4583 + co_console_unit x;
4584 + co_console_unit count;
4585 + co_console_character data[];
4588 + co_console_unit x;
4589 + co_console_unit y;
4590 + co_console_character charattr;
4593 + co_console_unit top;
4594 + co_console_unit left;
4595 + co_console_unit bottom;
4596 + co_console_unit right;
4597 + co_console_character charattr;
4600 + co_console_unit y;
4601 + co_console_unit x;
4602 + co_console_unit count;
4605 + co_console_unit row;
4606 + co_console_unit column;
4607 + co_console_unit top;
4608 + co_console_unit left;
4609 + co_console_unit bottom;
4610 + co_console_unit right;
4612 + co_cursor_pos_t cursor;
4614 +} __attribute__((packed)) co_console_message_t;
4617 + unsigned long index;
4618 + unsigned long flags;
4619 + unsigned long func;
4620 + unsigned long pid;
4621 +} __attribute__((packed)) co_trace_point_info_t;
4623 +extern void co_printk(char *line);
4624 +extern void co_callback(void);
4625 +extern void co_switch_wrapper(void);
4626 +extern void co_idle_processor(void);
4627 +extern void co_terminate(co_termination_reason_t reason);
4629 +extern void co_send_message(co_module_t from,
4631 + co_priority_t priority,
4632 + co_message_type_t type,
4633 + unsigned long size,
4635 +extern co_message_t *co_send_message_save(unsigned long *flags);
4636 +extern co_message_t *co_get_message_save(unsigned long *flags);
4637 +extern void co_send_message_restore(unsigned long flags);
4639 +extern void co_handle_device_interrupt(co_linux_message_t *message);
4640 +extern void co_received_message(co_linux_message_t *message);
4641 +extern int co_get_message(co_linux_message_t **message, co_device_t device);
4642 +extern void co_free_message(co_linux_message_t *message);
4644 +extern unsigned long co_bootmem_pages;
4645 +extern unsigned long co_core_end;
4646 +extern unsigned long co_memory_size;
4647 +extern unsigned long co_rpptm_size;
4649 +extern unsigned long co_get_host_time(void);
4650 +extern void handle_keyboard_event(unsigned char scancode);
4658 + CO_BLOCK_GET_ALIAS,
4659 +} co_block_request_type_t;
4662 + CO_NETWORK_GET_MAC=0,
4663 +} co_network_request_type_t;
4666 +/* If we are compiling kernel code (Linux or Host Driver) */
4667 +# ifdef CO_COLINUX_KERNEL
4668 +/* Inside Linux, vm_ptr_t considered a valid pointer in its virtual address space */
4669 +typedef void *vm_ptr_t;
4671 +/* But inside the host, the type is considered not to be a pointer in its own address space */
4672 +typedef unsigned long vm_ptr_t;
4676 + co_block_request_type_t type;
4680 + unsigned long long offset;
4681 + unsigned long long size;
4682 + unsigned long long disk_size;
4689 +} __attribute__((packed)) co_block_request_t;
4692 + co_network_request_type_t type;
4693 + unsigned long unit;
4694 + char mac_address[6];
4697 +} __attribute__((packed)) co_network_request_t;
4701 +#ifndef COLINUX_TRACE
4702 +#define CO_TRACE_STOP
4703 +#define CO_TRACE_CONTINUE
4709 --- linux-2.4.28/include/linux/major.h~colinux-0.6.1 2003-06-13 10:51:38.000000000 -0400
4710 +++ linux-2.4.28/include/linux/major.h 2004-11-27 15:59:21.315005648 -0500
4712 #define LVM_CHAR_MAJOR 109 /* Logical Volume Manager */
4714 #define UMEM_MAJOR 116 /* http://www.umem.com/ Battery Backed RAM */
4715 +#define COLINUX_MAJOR 117
4717 #define RTF_MAJOR 150
4718 #define RAW_MAJOR 162
4719 --- linux-2.4.28/init/do_mounts.c~colinux-0.6.1 2003-11-28 13:26:21.000000000 -0500
4720 +++ linux-2.4.28/init/do_mounts.c 2004-11-27 15:59:21.316005496 -0500
4723 { "mtdblock", 0x1f00 },
4725 +#ifdef CONFIG_COOPERATIVE
4726 + { "cobd", 0x7500 },
4731 --- linux-2.4.28/init/main.c~colinux-0.6.1 2004-11-17 06:54:22.000000000 -0500
4732 +++ linux-2.4.28/init/main.c 2004-11-27 15:59:21.317005344 -0500
4734 #include <asm/smp.h>
4737 +#include <linux/cooperative.h>
4740 * Versions of gcc older than that listed below may actually compile
4741 * and link okay, but the end product can have subtle run time bugs.
4742 @@ -305,7 +307,14 @@
4743 #ifdef CONFIG_X86_LOCAL_APIC
4744 static void __init smp_init(void)
4746 +#ifdef CONFIG_COOPERATIVE
4748 + * It doesn't work yet because I haven't implemented the
4749 + * timer interrupt yet
4752 APIC_init_uniprocessor();
4756 #define smp_init() do { } while (0)
4757 --- linux-2.4.28/kernel/Makefile~colinux-0.6.1 2001-09-17 00:22:40.000000000 -0400
4758 +++ linux-2.4.28/kernel/Makefile 2004-11-27 15:59:21.317005344 -0500
4760 obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
4761 module.o exit.o itimer.o info.o time.o softirq.o resource.o \
4762 sysctl.o acct.o capability.o ptrace.o timer.o user.o \
4763 - signal.o sys.o kmod.o context.o
4764 + signal.o sys.o kmod.o context.o cooperative.o
4766 obj-$(CONFIG_UID16) += uid16.o
4767 obj-$(CONFIG_MODULES) += ksyms.o
4768 --- /dev/null 2004-04-06 13:56:48.000000000 -0400
4769 +++ linux-2.4.28/kernel/cooperative.c 2004-11-27 15:59:21.318005192 -0500
4772 + * linux/kernel/cooperative.c
4774 + * Code for Cooperative mode (coLinux)
4776 + * Dan Aloni <da-x@gmx.net>, 2003 (C).
4780 +#include <linux/kernel.h>
4781 +#include <linux/string.h>
4782 +#include <linux/interrupt.h>
4783 +#include <linux/mm.h>
4784 +#include <linux/slab.h>
4785 +#include <linux/cooperative.h>
4789 +void start_kernel(void);
4790 +extern char _kernel_start, _end;
4792 +unsigned long co_core_end = 0;
4793 +unsigned long co_memory_size = 0;
4794 +char co_boot_parameters[CO_BOOTPARAM_STRING_LENGTH];
4796 +void colinux_start_c()
4798 + co_core_end = co_passage_page->params[0];
4799 + co_memory_size = co_passage_page->params[1];
4800 + memcpy(co_boot_parameters, &co_passage_page->params[2],
4801 + sizeof(co_boot_parameters));
4805 + co_terminate(CO_TERMINATE_END);
4808 +co_message_t *co_send_message_save(unsigned long *flags)
4810 + local_irq_save(*flags);
4811 + co_passage_page->operation = CO_OPERATION_MESSAGE_TO_MONITOR;
4812 + co_passage_page->params[0] = 1;
4813 + return (co_message_t *)(&co_passage_page->params[1]);
4816 +void co_send_message_restore(unsigned long flags)
4818 + co_switch_wrapper();
4819 + local_irq_restore(flags);
4822 +void co_send_message_s(co_message_t *message, char *data)
4824 + if ((sizeof(co_message_t) + message->size) < 2000) {
4825 + co_message_t *params;
4826 + unsigned long flags;
4828 + local_irq_save(flags);
4829 + co_passage_page->operation = CO_OPERATION_MESSAGE_TO_MONITOR;
4830 + co_passage_page->params[0] = 1;
4831 + params = (co_message_t *)(&co_passage_page->params[1]);
4832 + *params = *message;
4833 + memcpy(params->data, data, message->size);
4834 + co_switch_wrapper();
4835 + local_irq_restore(flags);
4840 +void co_send_message(co_module_t from,
4842 + co_priority_t priority,
4843 + co_message_type_t type,
4844 + unsigned long size,
4847 + co_message_t params;
4849 + params.from = from;
4851 + params.priority = priority;
4852 + params.type = type;
4853 + params.size = size;
4855 + co_send_message_s(¶ms, data);
4858 +void co_receive_message(co_message_t *message)
4861 + co_message_t message;
4862 + co_linux_message_t linux_part;
4865 + linux_message = (typeof(linux_message))message;
4867 + co_handle_device_interrupt(&linux_message->linux_part);
4870 +void co_callback(void)
4872 + while (co_passage_page->operation == CO_OPERATION_MESSAGE_FROM_MONITOR) {
4873 + co_receive_message((co_message_t *)&co_passage_page->params[1]);
4874 + if (co_passage_page->params[0] == 0) {
4878 + co_passage_page->operation = CO_OPERATION_MESSAGE_FROM_MONITOR;
4879 + co_switch_wrapper();
4883 +void co_idle_processor(void)
4885 + unsigned long flags;
4887 + local_irq_save(flags);
4888 + co_passage_page->operation = CO_OPERATION_IDLE;
4889 + co_switch_wrapper();
4891 + local_irq_restore(flags);
4894 +void co_printk(char *line)
4896 + co_send_message(CO_MODULE_LINUX,
4898 + CO_PRIORITY_DISCARDABLE,
4899 + CO_MESSAGE_TYPE_STRING,
4904 +void co_debug_line(char *line)
4906 + unsigned long flags;
4911 + if (strlen(line) > 0x200)
4914 + local_irq_save(flags);
4915 + co_passage_page->operation = CO_OPERATION_DEBUG_LINE;
4916 + strcpy((char *)&co_passage_page->params[0], line);
4917 + co_switch_wrapper();
4918 + local_irq_restore(flags);
4921 +void co_trace_ent_name(void *func, const char *name)
4923 + static int reenterent = 0;
4924 + static int count = 0;
4925 + static char private_buffer[0x100];
4926 + unsigned long flags;
4933 + local_irq_save(flags);
4936 + if (count > 1900000) {
4937 + snprintf(private_buffer, sizeof(private_buffer), "%d: %d: %x %s\n", count, current->pid, func, name);
4938 + co_debug_line(private_buffer);
4941 + local_irq_restore(flags);
4946 +static unsigned long trace_index = 0;
4948 +void co_trace_ent(void *func)
4950 + unsigned long flags;
4951 + co_trace_point_info_t *trace_point;
4953 + local_irq_save(flags);
4955 + co_passage_page->operation = CO_OPERATION_TRACE_POINT;
4956 + trace_point = (co_trace_point_info_t *)&co_passage_page->params[0];
4957 + trace_point->pid = 0;
4959 + trace_point->pid = current->pid;
4960 + trace_point->index = trace_index;
4961 + trace_point->flags = 1;
4962 + trace_point->func = (unsigned long)(func);
4963 + co_switch_wrapper();
4964 + local_irq_restore(flags);
4967 +void co_trace_ret(void *func)
4969 + unsigned long flags;
4970 + co_trace_point_info_t *trace_point;
4972 + local_irq_save(flags);
4974 + co_passage_page->operation = CO_OPERATION_TRACE_POINT;
4975 + trace_point = (co_trace_point_info_t *)&co_passage_page->params[0];
4976 + trace_point->pid = 0;
4978 + trace_point->pid = current->pid;
4979 + trace_point->index = trace_index;
4980 + trace_point->flags = 0;
4981 + trace_point->func = (unsigned long)(func);
4982 + co_switch_wrapper();
4983 + local_irq_restore(flags);
4986 +void co_debug(const char *fmt, ...)
4988 + static char co_buf[1024];
4989 + unsigned long flags;
4992 + local_irq_save(flags);
4993 + va_start(args, fmt);
4994 + vsnprintf(co_buf, sizeof(co_buf), fmt, args);
4996 + co_debug_line(co_buf);
4997 + local_irq_restore(flags);
5000 +void co_terminate(co_termination_reason_t reason)
5002 + unsigned long flags;
5004 + local_irq_save(flags);
5005 + co_passage_page->operation = CO_OPERATION_TERMINATE;
5006 + co_passage_page->params[0] = reason;
5007 + co_switch_wrapper();
5008 + local_irq_restore(flags);
5011 +unsigned long co_get_host_time(void)
5013 + unsigned long flags;
5014 + unsigned long time;
5016 + local_irq_save(flags);
5017 + co_passage_page->operation = CO_OPERATION_GET_TIME;
5018 + co_switch_wrapper();
5019 + time = co_passage_page->params[0];
5020 + local_irq_restore(flags);
5026 + struct list_head node;
5027 + co_linux_message_t msg;
5028 +} co_linux_message_node_t;
5031 + struct list_head list;
5033 +} co_linux_message_queue_t;
5035 +co_linux_message_queue_t *co_msgqueues = NULL;
5037 +void co_received_message(co_linux_message_t *message)
5039 + co_linux_message_node_t *copy;
5040 + co_linux_message_queue_t *queue;
5042 + if (!co_msgqueues)
5045 + if (message->device < 0 || (message->device >= CO_DEVICES_TOTAL))
5048 + copy = (co_linux_message_node_t *)kmalloc(sizeof(co_linux_message_node_t) + message->size, GFP_ATOMIC);
5052 + queue = &co_msgqueues[message->device];
5053 + memcpy(©->msg, message, sizeof(co_linux_message_t) + message->size);
5054 + list_add(©->node, &queue->list);
5055 + queue->num_messages++;
5058 +static int __init initcall_message_queues(void)
5062 + co_msgqueues = kmalloc(sizeof(co_linux_message_queue_t) * CO_DEVICES_TOTAL, GFP_KERNEL);
5063 + if (!co_msgqueues) {
5064 + panic("Unable to allocate message queues\n");
5067 + for (queue_index=0; queue_index < CO_DEVICES_TOTAL; queue_index++) {
5068 + co_linux_message_queue_t *queue = &co_msgqueues[queue_index];
5069 + queue->num_messages = 0;
5070 + INIT_LIST_HEAD(&queue->list);
5076 +__initcall(initcall_message_queues);
5078 +int co_get_message(co_linux_message_t **message, co_device_t device)
5080 + co_linux_message_queue_t *queue;
5081 + co_linux_message_node_t *node;
5083 + if (!co_msgqueues)
5086 + queue = &co_msgqueues[device];
5087 + if (list_empty(&queue->list))
5090 + node = list_entry(queue->list.prev, co_linux_message_node_t, node);
5091 + list_del(&node->node);
5092 + queue->num_messages--;
5093 + *message = &node->msg;
5097 +void co_free_message(co_linux_message_t *message)
5099 + co_linux_message_node_t *node = NULL;
5101 + node = (co_linux_message_node_t *)(((char *)message) - ((long)&node->msg));
5108 --- linux-2.4.28/kernel/panic.c~colinux-0.6.1 2004-11-17 06:54:22.000000000 -0500
5109 +++ linux-2.4.28/kernel/panic.c 2004-11-27 15:59:21.318005192 -0500
5111 #include <linux/interrupt.h>
5112 #include <linux/console.h>
5114 +#include <linux/cooperative.h>
5116 asmlinkage void sys_sync(void); /* it's really int */
5123 + co_terminate(CO_TERMINATE_PANIC);
5128 --- linux-2.4.28/kernel/printk.c~colinux-0.6.1 2004-11-17 06:54:22.000000000 -0500
5129 +++ linux-2.4.28/kernel/printk.c 2004-11-27 15:59:21.319005040 -0500
5132 #include <asm/uaccess.h>
5134 +#include <linux/cooperative.h>
5136 #if !defined(CONFIG_LOG_BUF_SHIFT) || (CONFIG_LOG_BUF_SHIFT == 0)
5137 #if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
5138 #define LOG_BUF_LEN (65536)
5140 printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
5143 +#ifdef CONFIG_COOPERATIVE
5144 + co_printk(printk_buf);
5147 * Copy the output into log_buf. If the caller didn't provide
5148 * appropriate log level tags, we insert them here
5150 spin_unlock_irqrestore(&logbuf_lock, flags);
5154 if (!down_trylock(&console_sem)) {
5156 * We own the drivers. We can drop the spinlock and let