patch-2.3.34 linux/arch/i386/kernel/process.c
Next file: linux/arch/i386/kernel/setup.c
Previous file: linux/arch/i386/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 170
- Date:
Mon Dec 20 15:43:01 1999
- Orig file:
v2.3.33/linux/arch/i386/kernel/process.c
- Orig date:
Tue Dec 14 01:27:23 1999
diff -u --recursive --new-file v2.3.33/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
@@ -69,6 +69,16 @@
void (*acpi_power_off)(void) = NULL;
/*
+ * We use this if we don't have any better
+ * idle routine..
+ */
+static void default_idle(void)
+{
+ if (current_cpu_data.hlt_works_ok && !hlt_counter)
+ asm volatile("sti ; hlt" : : : "memory");
+}
+
+/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* low exit latency (ie sit in a loop waiting for
@@ -82,26 +92,16 @@
current->counter = -100;
while (1) {
- while (!current->need_resched) {
- if (!current_cpu_data.hlt_works_ok)
- continue;
- if (hlt_counter)
- continue;
- asm volatile("sti ; hlt" : : : "memory");
- }
+ void (*idle)(void) = acpi_idle;
+ if (!idle)
+ idle = default_idle;
+ while (!current->need_resched)
+ idle();
schedule();
check_pgt_cache();
- if (acpi_idle)
- acpi_idle();
}
}
-/*
- * This routine reboots the machine by asking the keyboard
- * controller to pulse the reset-line low. We try that for a while,
- * and if it doesn't work, we do some other stupid things.
- */
-
static long no_idt[2] = {0, 0};
static int reboot_mode = 0;
static int reboot_thru_bios = 0;
@@ -187,7 +187,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 */
};
@@ -200,34 +203,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__
- /*
- * Stop all CPUs and turn off local APICs and the IO-APIC, so
- * other OSs see a clean IRQ state.
- */
- smp_send_stop();
- disable_IO_APIC();
-#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
@@ -273,8 +255,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. */
@@ -293,11 +276,11 @@
the values are consistent for real mode operation already. */
__asm__ __volatile__ ("movl $0x0010,%%eax\n"
- "\tmovl %%ax,%%ds\n"
- "\tmovl %%ax,%%es\n"
- "\tmovl %%ax,%%fs\n"
- "\tmovl %%ax,%%gs\n"
- "\tmovl %%ax,%%ss" : : : "eax");
+ "\tmovl %%eax,%%ds\n"
+ "\tmovl %%eax,%%es\n"
+ "\tmovl %%eax,%%fs\n"
+ "\tmovl %%eax,%%gs\n"
+ "\tmovl %%eax,%%ss" : : : "eax");
/* Jump to the 16-bit code that we copied earlier. It disables paging
and the cache, switches to real mode, and jumps to the BIOS reset
@@ -305,7 +288,38 @@
__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 __SMP__
+ /*
+ * Stop all CPUs and turn off local APICs and the IO-APIC, so
+ * other OSs see a clean IRQ state.
+ */
+ smp_send_stop();
+ disable_IO_APIC();
+#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)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)