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
- Lines: 205
- Date:
Fri Apr 21 12:45:45 2000
- Orig file:
v2.2.14/arch/i386/kernel/process.c
- Orig date:
Wed Oct 20 01:12:33 1999
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)