patch-2.2.15 linux/arch/i386/kernel/process.c

Next file: linux/arch/i386/kernel/ptrace.c
Previous file: linux/arch/i386/kernel/mtrr.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
@@ -31,9 +31,6 @@
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
-#include <linux/apm_bios.h>
-#endif
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -52,15 +49,20 @@
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
-#ifdef CONFIG_APM
-extern int  apm_do_idle(void);
-extern void apm_do_busy(void);
-#endif
-
-static int hlt_counter=0;
+int hlt_counter=0;
 
 #define HARD_IDLE_TIMEOUT (HZ / 3)
 
+/*
+ * Powermanagement idle function, if any..
+ */
+void (*acpi_idle)(void) = NULL;
+
+/*
+ * Power off function, if any
+ */
+void (*acpi_power_off)(void) = NULL;
+
 void disable_hlt(void)
 {
 	hlt_counter++;
@@ -71,34 +73,7 @@
 	hlt_counter--;
 }
 
-#ifndef __SMP__
-
-static void hard_idle(void)
-{
-	while (!current->need_resched) {
-		if (boot_cpu_data.hlt_works_ok && !hlt_counter) {
-#ifdef CONFIG_APM
-				/* If the APM BIOS is not enabled, or there
-				 is an error calling the idle routine, we
-				 should hlt if possible.  We need to check
-				 need_resched again because an interrupt
-				 may have occurred in apm_do_idle(). */
-			start_bh_atomic();
-			if (!apm_do_idle() && !current->need_resched)
-				__asm__("hlt");
-			end_bh_atomic();
-#else
-			__asm__("hlt");
-#endif
-	        }
- 		if (current->need_resched) 
- 			break;
-		schedule();
-	}
-#ifdef CONFIG_APM
-	apm_do_busy();
-#endif
-}
+#ifndef CONFIG_SMP
 
 /*
  * The idle loop on a uniprocessor i386..
@@ -116,8 +91,8 @@
 		if (work)
 			start_idle = jiffies;
 
-		if (jiffies - start_idle > HARD_IDLE_TIMEOUT) 
-			hard_idle();
+		if (acpi_idle && (jiffies - start_idle > HARD_IDLE_TIMEOUT))
+			acpi_idle();
 		else  {
 			if (boot_cpu_data.hlt_works_ok && !hlt_counter && !current->need_resched)
 		        	__asm__("hlt");
@@ -255,7 +230,10 @@
 	0x74, 0x02,				/*    jz    f                */
 	0x0f, 0x08,				/*    invd                   */
 	0x24, 0x10,				/* f: andb  $0x10,al         */
-	0x66, 0x0f, 0x22, 0xc0,			/*    movl  %eax,%cr0        */
+	0x66, 0x0f, 0x22, 0xc0			/*    movl  %eax,%cr0        */
+};
+static unsigned char jump_to_bios [] =
+{
 	0xea, 0x00, 0x00, 0xff, 0xff		/*    ljmp  $0xffff,$0x0000  */
 };
 
@@ -268,32 +246,13 @@
 			break;
 }
 
-void machine_restart(char * __unused)
+/*
+ * Switch to real mode and then execute the code
+ * specified by the code and length parameters.
+ * We assume that length will aways be less that 100!
+ */
+void machine_real_restart(unsigned char *code, int length)
 {
-#if __SMP__
-	/*
-	 * turn off the IO-APIC, so we can do a clean reboot
-	 */
-	init_pic_mode();
-#endif
-
-	if(!reboot_thru_bios) {
-		/* rebooting needs to touch the page at absolute addr 0 */
-		*((unsigned short *)__va(0x472)) = reboot_mode;
-		for (;;) {
-			int i;
-			for (i=0; i<100; i++) {
-				kb_wait();
-				udelay(50);
-				outb(0xfe,0x64);         /* pulse reset low */
-				udelay(50);
-			}
-			/* That didn't work - force a triple fault.. */
-			__asm__ __volatile__("lidt %0": :"m" (no_idt));
-			__asm__ __volatile__("int3");
-		}
-	}
-
 	cli();
 
 	/* Write zero to CMOS register number 0x0f, which the BIOS POST
@@ -343,8 +302,9 @@
 	   off paging.  Copy it near the end of the first page, out of the way
 	   of BIOS variables. */
 
-	memcpy ((void *) (0x1000 - sizeof (real_mode_switch)),
+	memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
 		real_mode_switch, sizeof (real_mode_switch));
+	memcpy ((void *) (0x1000 - 100), code, length);
 
 	/* Set up the IDT for real mode. */
 
@@ -375,7 +335,36 @@
 
 	__asm__ __volatile__ ("ljmp $0x0008,%0"
 				:
-				: "i" ((void *) (0x1000 - sizeof (real_mode_switch))));
+				: "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
+}
+
+void machine_restart(char * __unused)
+{
+#if CONFIG_SMP
+	/*
+	 * turn off the IO-APIC, so we can do a clean reboot
+	 */
+	init_pic_mode();
+#endif
+
+	if(!reboot_thru_bios) {
+		/* rebooting needs to touch the page at absolute addr 0 */
+		*((unsigned short *)__va(0x472)) = reboot_mode;
+		for (;;) {
+			int i;
+			for (i=0; i<100; i++) {
+				kb_wait();
+				udelay(50);
+				outb(0xfe,0x64);         /* pulse reset low */
+				udelay(50);
+			}
+			/* That didn't work - force a triple fault.. */
+			__asm__ __volatile__("lidt %0": :"m" (no_idt));
+			__asm__ __volatile__("int3");
+		}
+	}
+
+	machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
 }
 
 void machine_halt(void)
@@ -384,9 +373,8 @@
 
 void machine_power_off(void)
 {
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
-	apm_power_off();
-#endif
+	if (acpi_power_off)
+		acpi_power_off();
 }
 
 
@@ -432,7 +420,7 @@
  *  - if you use SMP you have a beefy enough machine that
  *    this shouldn't matter..
  */
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 #define EXTRA_TASK_STRUCT	16
 static struct task_struct * task_struct_stack[EXTRA_TASK_STRUCT];
 static int task_struct_stack_ptr = -1;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)