patch-2.2.14 linux/arch/alpha/kernel/process.c
Next file: linux/arch/alpha/kernel/proto.h
Previous file: linux/arch/alpha/kernel/machvec.h
Back to the patch index
Back to the overall index
- Lines: 170
- Date:
Tue Jan 4 10:12:11 2000
- Orig file:
v2.2.13/linux/arch/alpha/kernel/process.c
- Orig date:
Tue Oct 19 17:10:36 1999
diff -u --recursive --new-file v2.2.13/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
@@ -117,58 +117,44 @@
}
}
-void
-generic_kill_arch (int mode, char *restart_cmd)
-{
- /* The following currently only has any effect on SRM. We should
- fix MILO to understand it. Should be pretty easy. Also we can
- support RESTART2 via the ipc_buffer machinations pictured below,
- which SRM ignores. */
-
- if (alpha_using_srm) {
- struct percpu_struct *cpup;
- unsigned long flags;
-
- cpup = (struct percpu_struct *)
- ((unsigned long)hwrpb + hwrpb->processor_offset);
-
- flags = cpup->flags;
-
- /* Clear reason to "default"; clear "bootstrap in progress". */
- flags &= ~0x00ff0001UL;
-
- if (mode == LINUX_REBOOT_CMD_RESTART) {
- if (!restart_cmd) {
- flags |= 0x00020000UL; /* "cold bootstrap" */
- cpup->ipc_buffer[0] = 0;
- } else {
- flags |= 0x00030000UL; /* "warm bootstrap" */
- strncpy((char *)cpup->ipc_buffer, restart_cmd,
- sizeof(cpup->ipc_buffer));
- }
- } else {
- flags |= 0x00040000UL; /* "remain halted" */
- }
-
- cpup->flags = flags;
- mb();
-
- reset_for_srm();
- set_hae(srm_hae);
+struct halt_info {
+ int mode;
+ char * restart_cmd;
+};
-#ifdef CONFIG_DUMMY_CONSOLE
- /* This has the effect of reseting the VGA video origin. */
- take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
-#endif
+static void
+halt_processor(void * generic_ptr)
+{
+ struct percpu_struct * cpup;
+ struct halt_info * how = (struct halt_info *)generic_ptr;
+ unsigned long *flags;
+ int cpuid = smp_processor_id();
+
+ /* No point in taking interrupts anymore. */
+ __cli();
+
+ cpup = (struct percpu_struct *)
+ ((unsigned long)hwrpb + hwrpb->processor_offset
+ + hwrpb->processor_size * cpuid);
+ flags = &cpup->flags;
+
+ /* Clear reason to "default"; clear "bootstrap in progress". */
+ *flags &= ~0x00ff0001UL;
+
+#ifdef __SMP__
+ /* Secondaries halt here. */
+ if (cpuid != smp_boot_cpuid) {
+ *flags |= 0x00040000UL; /* "remain halted" */
+ clear_bit(cpuid, &cpu_present_mask);
+ halt();
}
+#endif /* __SMP__ */
#ifdef CONFIG_RTC
/* Reset rtc to defaults. */
{
unsigned char control;
- cli();
-
/* Reset periodic interrupt frequency. */
CMOS_WRITE(0x26, RTC_FREQ_SELECT);
@@ -177,22 +163,73 @@
control |= RTC_PIE;
CMOS_WRITE(control, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
-
- sti();
}
-#endif
+#endif /* CONFIG_RTC */
- if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
+ if (how->mode == LINUX_REBOOT_CMD_RESTART) {
+ if (!how->restart_cmd) {
+ *flags |= 0x00020000UL; /* "cold bootstrap" */
+ cpup->ipc_buffer[0] = 0;
+ } else {
+ /* NOTE: this could really only work when returning
+ into MILO, rather than SRM console. The latter
+ does NOT look at the ipc_buffer to get a new
+ boot command. It could be done by using callbacks
+ to change some of the SRM environment variables,
+ but that is beyond our capabilities at this time.
+ At the moment, SRM will use the last boot device,
+ but the file and flags will be the defaults, when
+ doing a "warm" bootstrap.
+ */
+ *flags |= 0x00030000UL; /* "warm bootstrap" */
+ strncpy((char *)cpup->ipc_buffer,
+ how->restart_cmd,
+ sizeof(cpup->ipc_buffer));
+ }
+ } else
+ *flags |= 0x00040000UL; /* "remain halted" */
+
+#ifdef __SMP__
+ /* Wait for the secondaries to halt. */
+ clear_bit(smp_boot_cpuid, &cpu_present_mask);
+ while (cpu_present_mask)
+ /* Make sure we sample memory and not a register. */
+ barrier();
+#endif /* __SMP__ */
+
+ /* If booted from SRM, reset some of the original environment. */
+ if (alpha_using_srm) {
+#ifdef CONFIG_DUMMY_CONSOLE
+ /* This has the effect of resetting the VGA video origin. */
+ take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
+#endif
+ reset_for_srm();
+ set_hae(srm_hae);
+ }
+ else if (how->mode != LINUX_REBOOT_CMD_RESTART &&
+ how->mode != LINUX_REBOOT_CMD_RESTART2) {
/* Unfortunately, since MILO doesn't currently understand
the hwrpb bits above, we can't reliably halt the
processor and keep it halted. So just loop. */
return;
}
- if (alpha_using_srm)
- srm_paging_stop();
-
+ /* PRIMARY */
halt();
+}
+
+void
+generic_kill_arch(int mode, char * restart_cmd)
+{
+ struct halt_info copy_of_args;
+
+ copy_of_args.mode = mode;
+ copy_of_args.restart_cmd = restart_cmd;
+#ifdef __SMP__
+ /* A secondary can't wait here for the primary to finish, can it now? */
+ smp_call_function(halt_processor, (void *)©_of_args, 1, 0);
+#endif /* __SMP__ */
+ halt_processor(©_of_args);
}
void
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)