Going to suspend
Jordan Crouse
jordan.crouse at amd.com
Fri Mar 9 20:48:21 EST 2007
I just pushed a new patch (attached), that once again changes how we
suspend the board. I am ashamed to admit that I thought that the virtual
to physical mapping was 1:1 under 1MB. It is actually not (it lives in
0xc0000000 or wherever PAGE_OFFSET is set) - and things really started
to work better when I figured that out.
I slightly re-factored the way we go to the OFW hole based on how the
PCIBIOS code operates - it seems more robust and intelligent then the
way I was doing it before.
So at least now, when you suspend (echo mem > /sys/power/state), it at
least jumps into the OFW subroutine, but unfortunately, thats as far as
it gets, since OFW also didn't expect us to be mapped clear up in the
C zillion space, so it gets tripped up on these two lines:
cs:0xC00F0018u BD00080F00 mov ebp,0xf0800
cs:0xC00F001Du 896500 mov [ebp+0x0],esp
I trust Mitch will have that banged into shape in no time. Have
a happy weekend.
Jordan
--
Jordan Crouse
Senior Linux Engineer
Advanced Micro Devices, Inc.
<www.amd.com/embeddedprocessors>
-------------- next part --------------
[PATCH]: olpc: Change the suspend method once again
From: Jordan Crouse <jordan.crouse at amd.com>
Change the suspend method - this time its a lot cleaner and more
intellegent about how memory is organized.
Signed-off-by: Jordan Crouse <jordan.crouse at amd.com>
---
arch/i386/kernel/olpc-pm.c | 23 +++++++++++++++--------
arch/i386/kernel/olpc-wakeup.S | 8 +-------
arch/i386/kernel/setup.c | 3 +++
3 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/arch/i386/kernel/olpc-pm.c b/arch/i386/kernel/olpc-pm.c
index 7178161..014dde7 100644
--- a/arch/i386/kernel/olpc-pm.c
+++ b/arch/i386/kernel/olpc-pm.c
@@ -32,7 +32,11 @@ #define CS5536_PM_RTC (1 << 10)
/* Enable this when the EC firmare is updated to support SCIs */
#undef ENABLE_EC_SCI
-unsigned long olpc_wakeup_address;
+struct {
+ unsigned long address;
+ unsigned short segment;
+} ofw_bios_entry = { 0, __KERNEL_CS };
+
extern char wakeup_start, wakeup_end;
extern void do_olpc_suspend_lowlevel(void);
extern unsigned long FASTCALL(olpc_copy_wakeup_routine(unsigned long));
@@ -108,7 +112,7 @@ #endif
static int olpc_pm_state_valid (suspend_state_t pm_state)
{
- if (olpc_wakeup_address && pm_state == PM_SUSPEND_MEM)
+ if (pm_state == PM_SUSPEND_MEM)
return 1;
return 0;
@@ -117,7 +121,7 @@ static int olpc_pm_state_valid (suspend_
static int olpc_pm_enter (suspend_state_t pm_state)
{
/* Only STR is supported */
- if (olpc_wakeup_address && pm_state != PM_SUSPEND_MEM)
+ if (pm_state != PM_SUSPEND_MEM)
return -EINVAL;
/* Save CPU state */
@@ -125,12 +129,8 @@ static int olpc_pm_enter (suspend_state_
return 0;
}
-/* This function handles any last minute configuration that we want
- to do before we go to sleep. Mainly this will involve setting
- wake events. This is called from do_olpc_suspend_lowlevel */
-
int asmlinkage
-olpc_setup_sleep_state(u8 sleep_state)
+olpc_do_sleep(u8 sleep_state)
{
/* FIXME: Set the SCI bits we want to wake up on here */
@@ -140,6 +140,12 @@ olpc_setup_sleep_state(u8 sleep_state)
/* FIXME: Set the GPE0 bits we want to wake on here */
+
+ /* Call the OFW hole */
+
+ __asm__("call *(%%edi); cld"
+ : : "D" (&ofw_bios_entry));
+
return 0;
}
@@ -314,6 +320,7 @@ #endif
/* Clear pending interrupt */
outl(inl(acpi_base) | 0xFFFF, acpi_base);
+ ofw_bios_entry.address = 0xF0000 + PAGE_OFFSET;
pm_set_ops(&olpc_pm_ops);
return 0;
diff --git a/arch/i386/kernel/olpc-wakeup.S b/arch/i386/kernel/olpc-wakeup.S
index c344a7f..b0ecac9 100644
--- a/arch/i386/kernel/olpc-wakeup.S
+++ b/arch/i386/kernel/olpc-wakeup.S
@@ -32,14 +32,8 @@ ENTRY(do_olpc_suspend_lowlevel)
call save_processor_state
call save_registers
pushl $3
- call olpc_setup_sleep_state
- addl $4, %esp
+ call olpc_do_sleep
-# We're ready to sleep - go, go, gadget sleep
- mov $0xf0000,%eax
- lcall *(%eax)
-
-# We are back - restore the stack
movl saved_context_esp, %esp
# Jump to the return point and restore our state
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index abd3b30..f380eb7 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -439,6 +439,9 @@ #ifdef CONFIG_ACPI_SLEEP
*/
acpi_reserve_bootmem();
#endif
+#ifdef CONFIG_OLPC_PM
+ reserve_bootmem(0xf0000, PAGE_SIZE);
+#endif
#ifdef CONFIG_X86_FIND_SMP_CONFIG
/*
* Find and reserve possible boot-time SMP configuration:
More information about the Devel
mailing list