#include <i386/misc_protos.h>
#include <i386/proc_reg.h>
#include <i386/pmap.h>
#include <i386/mtrr.h>
#include <i386/acpi.h>
#include <i386/mp.h>
#include <kern/cpu_data.h>
#include <IOKit/IOHibernatePrivate.h>
#include <IOKit/IOPlatformExpert.h>
extern void acpi_sleep_cpu(acpi_sleep_callback, void * refcon);
extern char acpi_wake_start[];
extern char acpi_wake_end[];
extern int serial_init(void);
extern unsigned int disableSerialOuput;
extern void set_kbd_leds(int leds);
vm_offset_t
acpi_install_wake_handler(void)
{
bcopy_phys((addr64_t) kvtophys((vm_offset_t)acpi_wake_start),
(addr64_t) ACPI_WAKE_ADDR,
acpi_wake_end - acpi_wake_start);
wbinvd();
return ACPI_WAKE_ADDR;
}
typedef struct acpi_hibernate_callback_data {
acpi_sleep_callback func;
void *refcon;
} acpi_hibernate_callback_data;
static void
acpi_hibernate(void *refcon)
{
boolean_t hib;
acpi_hibernate_callback_data *data = (acpi_hibernate_callback_data *)refcon;
if (current_cpu_datap()->cpu_hibernate) {
hib = hibernate_write_image();
}
(data->func)(data->refcon);
}
void
acpi_sleep_kernel(acpi_sleep_callback func, void *refcon)
{
acpi_hibernate_callback_data data;
boolean_t did_hibernate;
lapic_shutdown();
data.func = func;
data.refcon = refcon;
acpi_sleep_cpu(acpi_hibernate, &data);
if (FALSE == disableSerialOuput)
serial_init();
if (current_cpu_datap()->cpu_hibernate) {
* (int *) CM1 = 0;
* (int *) CM2 = 0;
* (int *) CM3 = 0;
current_cpu_datap()->cpu_hibernate = 0;
did_hibernate = TRUE;
} else {
did_hibernate = FALSE;
}
mtrr_update_cpu();
pat_init();
if (did_hibernate) {
hibernate_machine_init();
}
if (lapic_probe())
lapic_init();
rtc_sleep_wakeup();
if (did_hibernate) {
enable_preemption();
}
}