+ printk(BIOS_DEBUG, "Looking on %p for valid checksum\n", rsdp);
+
+ if (acpi_checksum((void *)rsdp, 20) != 0)
+ return NULL;
+ printk(BIOS_DEBUG, "Checksum 1 passed\n");
+
+ if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp,
+ rsdp->length) != 0))
+ return NULL;
+
+ printk(BIOS_DEBUG, "Checksum 2 passed all OK\n");
+
+ return rsdp;
+}
+
+static acpi_rsdp_t *rsdp;
+
+void *acpi_get_wakeup_rsdp(void)
+{
+ return rsdp;
+}
+
+void *acpi_find_wakeup_vector(void)
+{
+ char *p, *end;
+
+ acpi_rsdt_t *rsdt;
+ acpi_facs_t *facs;
+ acpi_fadt_t *fadt;
+ void *wake_vec;
+ int i;
+
+ rsdp = NULL;
+
+ if (!acpi_is_wakeup())
+ return NULL;
+
+ printk(BIOS_DEBUG, "Trying to find the wakeup vector ...\n");
+
+ /* find RSDP */
+ for (p = (char *) 0xe0000; p < (char *) 0xfffff; p+=16) {
+ if ((rsdp = valid_rsdp((acpi_rsdp_t *) p)))
+ break;
+ }
+
+ if (rsdp == NULL)
+ return NULL;
+
+ printk(BIOS_DEBUG, "RSDP found at %p\n", rsdp);
+ rsdt = (acpi_rsdt_t *) rsdp->rsdt_address;
+
+ end = (char *) rsdt + rsdt->header.length;
+ printk(BIOS_DEBUG, "RSDT found at %p ends at %p\n", rsdt, end);
+
+ for (i = 0; ((char *) &rsdt->entry[i]) < end; i++) {
+ fadt = (acpi_fadt_t *) rsdt->entry[i];
+ if (strncmp((char *)fadt, "FACP", 4) == 0)
+ break;
+ fadt = NULL;
+ }
+
+ if (fadt == NULL)
+ return NULL;
+
+ printk(BIOS_DEBUG, "FADT found at %p\n", fadt);
+ facs = (acpi_facs_t *)fadt->firmware_ctrl;
+
+ if (facs == NULL) {
+ printk(BIOS_DEBUG, "No FACS found, wake up from S3 not possible.\n");
+ return NULL;
+ }
+
+ printk(BIOS_DEBUG, "FACS found at %p\n", facs);
+ wake_vec = (void *) facs->firmware_waking_vector;
+ printk(BIOS_DEBUG, "OS waking vector is %p\n", wake_vec);
+ return wake_vec;
+}
+
+extern char *lowmem_backup;
+extern char *lowmem_backup_ptr;
+extern int lowmem_backup_size;
+
+#define WAKEUP_BASE 0x600
+
+void (*acpi_do_wakeup)(u32 vector, u32 backup_source, u32 backup_target, u32
+ backup_size) __attribute__((regparm(0))) = (void *)WAKEUP_BASE;
+
+extern unsigned char __wakeup, __wakeup_size;
+
+void acpi_jump_to_wakeup(void *vector)
+{
+ u32 acpi_backup_memory = (u32) cbmem_find(CBMEM_ID_RESUME);
+
+ if (!acpi_backup_memory) {
+ printk(BIOS_WARNING, "ACPI: Backup memory missing. No S3 Resume.\n");
+ return;
+ }
+
+ // FIXME this should go into the ACPI backup memory, too. No pork saussages.
+ /* just restore the SMP trampoline and continue with wakeup on assembly level */
+ memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size);
+
+ /* copy wakeup trampoline in place */
+ memcpy((void *)WAKEUP_BASE, &__wakeup, (size_t)&__wakeup_size);
+
+ acpi_do_wakeup((u32)vector, acpi_backup_memory, CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
+}
+#endif