public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* Fix S3 resume when kernel is big
@ 2002-11-20 15:11 Pavel Machek
       [not found] ` <20021120151136.GA862-I/5MKhXcvmPrBKCeMvbIDA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2002-11-20 15:11 UTC (permalink / raw)
  To: kernel list, ACPI mailing list, Andrew Grover

Hi!

When kernel is big enough, S3 stops working because page table with
low mappings is not big enough. This fixes it, along with possible %ds
problem. (I believe our method of setting %ds was not robust). Code
from mm/init.c is reused, so this actually deletes code.

Please apply (or tell me to push it to the Linus myself),

								Pavel
								

--- clean/arch/i386/kernel/acpi.c	2002-09-22 23:46:52.000000000 +0200
+++ linux-swsusp/arch/i386/kernel/acpi.c	2002-11-20 15:30:31.000000000 +0100
@@ -446,74 +446,11 @@
 
 #ifdef CONFIG_ACPI_SLEEP
 
-#define DEBUG
-
-#ifdef DEBUG
-#include <linux/serial.h>
-#endif
-
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
 
-/* new page directory that we will be using */
-static pmd_t *pmd;
-
-/* saved page directory */
-static pmd_t saved_pmd;
-
-/* page which we'll use for the new page directory */
-static pte_t *ptep;
-
 extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
 
-/*
- * acpi_create_identity_pmd
- *
- * Create a new, identity mapped pmd.
- *
- * Do this by creating new page directory, and marking all the pages as R/W
- * Then set it as the new Page Middle Directory.
- * And, of course, flush the TLB so it takes effect.
- *
- * We save the address of the old one, for later restoration.
- */
-static void acpi_create_identity_pmd (void)
-{
-	pgd_t *pgd;
-	int i;
-
-	ptep = (pte_t*)__get_free_page(GFP_KERNEL);
-
-	/* fill page with low mapping */
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(ptep + i, pfn_pte(i, PAGE_SHARED));
-
-	pgd = pgd_offset(current->active_mm, 0);
-	pmd = pmd_alloc(current->mm,pgd, 0);
-
-	/* save the old pmd */
-	saved_pmd = *pmd;
-
-	/* set the new one */
-	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep)));
-
-	/* flush the TLB */
-	local_flush_tlb();
-}
-
-/*
- * acpi_restore_pmd
- *
- * Restore the old pmd saved by acpi_create_identity_pmd and
- * free the page that said function alloc'd
- */
-static void acpi_restore_pmd (void)
-{
-	set_pmd(pmd, saved_pmd);
-	local_flush_tlb();
-	free_page((unsigned long)ptep);
-}
-
 /**
  * acpi_save_state_mem - save kernel state
  *
@@ -522,7 +459,15 @@
  */
 int acpi_save_state_mem (void)
 {
-	acpi_create_identity_pmd();
+	if (!cpu_has_pse) {
+		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
+		return 1;
+	}
+#if CONFIG_X86_PAE
+	panic("S3 and PAE do not like each other for now.");
+	return 1;
+#endif
+	init_physical_mapping(swapper_pg_dir, 0, USER_PTRS_PER_PGD);
 	acpi_copy_wakeup_routine(acpi_wakeup_address);
 
 	return 0;
@@ -542,7 +487,7 @@
  */
 void acpi_restore_state_mem (void)
 {
-	acpi_restore_pmd();
+	zap_low_mappings();
 }
 
 /**
@@ -555,7 +500,10 @@
  */
 void __init acpi_reserve_bootmem(void)
 {
+	extern long wakeup_start, wakeup_end;
 	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
+		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
 	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
 }
 
--- clean/arch/i386/kernel/acpi_wakeup.S	2002-11-19 16:45:58.000000000 +0100
+++ linux-swsusp/arch/i386/kernel/acpi_wakeup.S	2002-11-20 14:56:23.000000000 +0100
@@ -1,12 +1,17 @@
-
 .text
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
-# Do we need to deal with A20?
+#
+# wakeup_code runs in real mode, and at unknown address (determined at run-time).
+# Therefore it must only use relative jumps/calls. 
+#
+# Do we need to deal with A20? It seems okay
 
 ALIGN
-wakeup_start:
+	.align	4096
+ENTRY(wakeup_start)
 wakeup_code:
 	wakeup_code_start = .
 	.code16
@@ -14,49 +19,73 @@
  	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'L', %fs:(0x10)
+	
 	cli
 	cld
-	  
-	# setup data segment
-	movw	%cs, %ax
 
-	addw	$(wakeup_data - wakeup_code) >> 4, %ax
-	movw	%ax, %ds
-	movw	%ax, %ss
-	mov	$(wakeup_stack - wakeup_data), %sp		# Private stack is needed for ASUS board
+# We are now probably running at something like 0x0000 : 0x1000
+	call here
+here:
+	pop	 %bx
+	subw	$(here-wakeup_start), %bx
+	shrw	$4, %bx
+	
+        # setup data segment
+        movw    %cs, %ax
+	addw    %bx, %ax
+	movw    %ax, %ds					# Make ds:0 point to wakeup_start
+	movw    %ax, %ss
+	mov	$(wakeup_stack-wakeup_code), %sp		# Private stack is needed for ASUS board
 	movw	$0x0e00 + 'S', %fs:(0x12)	
 
-	movl	real_magic - wakeup_data, %eax
+	pushl	$0						# Kill any dangerous flags
+	popfl
+	cli
+	cld
+	
+	movl	real_magic-wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
-
-	mov	video_mode - wakeup_data, %ax
+	mov	video_mode, %ax
 	call	mode_set
 
 	# set up page table
-	movl	(real_save_cr3 - wakeup_data), %eax
+#	movl	real_save_cr3-wakeup_code, %eax
+	movl	$swapper_pg_dir-__PAGE_OFFSET,%eax
 	movl	%eax, %cr3
 
 	# make sure %cr4 is set correctly (features, etc)
-	movl	(real_save_cr4 - wakeup_data), %eax
+	movl	real_save_cr4-wakeup_code, %eax
 	movl	%eax, %cr4
 	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'i', %fs:(0x12)
-
+	
 	# need a gdt
-	lgdt	real_save_gdt - wakeup_data
+	lgdt	real_save_gdt-wakeup_code
 
-	movl	(real_save_cr0 - wakeup_data), %eax
+	movl	real_save_cr0-wakeup_code, %eax
 	movl	%eax, %cr0
+	jmp 1f
+1:
 	movw	$0x0e00 + 'n', %fs:(0x14)
 
-	movl	real_magic - wakeup_data, %eax
+	movl	real_magic-wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
 	ljmpl	$__KERNEL_CS,$wakeup_pmode_return
 
+wakeup_data:
+		.word 0
+real_save_gdt:	.word 0
+		.long 0
+real_save_cr0:	.long 0
+real_save_cr3:	.long 0
+real_save_cr4:	.long 0
+real_magic:	.long 0
+video_mode:	.long 0
+
 bogus_real_magic:
 	movw	$0x0e00 + 'B', %fs:(0x12)
 	jmp bogus_real_magic
@@ -129,20 +164,12 @@
 	.code32
 	ALIGN
 
-.org	0x300
-wakeup_data:
-		.word 0
-real_save_gdt:	.word 0
-		.long 0
-real_save_cr0:	.long 0
-real_save_cr3:	.long 0
-real_save_cr4:	.long 0
-real_magic:	.long 0
-video_mode:	.long 0
 
-.org	0x500
+.org	0x2000
 wakeup_stack:
-wakeup_end:
+.org	0x3000
+ENTRY(wakeup_end)
+.org	0x4000
 
 wakeup_pmode_return:
 	movl	$__KERNEL_DS, %eax
--- clean/arch/i386/mm/init.c	2002-11-19 16:45:26.000000000 +0100
+++ linux-swsusp/arch/i386/mm/init.c	2002-11-20 15:05:29.000000000 +0100
@@ -117,24 +117,18 @@
 	}
 }
 
-/*
- * This maps the physical memory to kernel virtual address space, a total 
- * of max_low_pfn pages, by creating page tables starting from address 
- * PAGE_OFFSET.
- */
-static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+void init_physical_mapping(pgd_t *pgd_base, int pgd_ofs, int pgd_limit)
 {
 	unsigned long pfn;
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte;
-	int pgd_ofs, pmd_ofs, pte_ofs;
+	int pmd_ofs, pte_ofs;
 
-	pgd_ofs = __pgd_offset(PAGE_OFFSET);
 	pgd = pgd_base + pgd_ofs;
 	pfn = 0;
 
-	for (; pgd_ofs < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_ofs++) {
+	for (; pgd_ofs < pgd_limit && pfn < max_low_pfn; pgd++, pgd_ofs++) {
 		pmd = one_md_table_init(pgd);
 		for (pmd_ofs = 0; pmd_ofs < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_ofs++) {
 			/* Map with big pages if possible, otherwise create normal page tables. */
@@ -151,6 +145,16 @@
 	}	
 }
 
+/*
+ * This maps the physical memory to kernel virtual address space, a total 
+ * of max_low_pfn pages, by creating page tables starting from address 
+ * PAGE_OFFSET.
+ */
+static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+{
+	init_physical_mapping(pgd_base, __pgd_offset(PAGE_OFFSET), PTRS_PER_PGD);
+}
+
 static inline int page_kills_ppro(unsigned long pagenr)
 {
 	if (pagenr >= 0x70000 && pagenr <= 0x7003F)
@@ -299,7 +303,7 @@
 #endif
 }
 
-void __init zap_low_mappings (void)
+void zap_low_mappings (void)
 {
 	int i;
 	/*



-- 
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found] ` <20021120151136.GA862-I/5MKhXcvmPrBKCeMvbIDA@public.gmane.org>
@ 2002-11-20 15:38   ` Dave Jones
       [not found]     ` <20021120153833.GA4344-l3A5Bk7waGM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Dave Jones @ 2002-11-20 15:38 UTC (permalink / raw)
  To: Pavel Machek; +Cc: kernel list, ACPI mailing list, Andrew Grover

On Wed, Nov 20, 2002 at 04:11:37PM +0100, Pavel Machek wrote:
 > -	acpi_create_identity_pmd();
 > +	if (!cpu_has_pse) {
 > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
 > +		return 1;
 > +	}

Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
dropped into various laptops.

		Dave

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]         ` <1037809055.3702.43.camel-MMxVpc8zpTQVh3rx8e9g/fyykp6/JSeS3vcXtXqGYxw@public.gmane.org>
@ 2002-11-20 15:52           ` Dave Jones
       [not found]             ` <20021120155223.GA5678-l3A5Bk7waGM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Dave Jones @ 2002-11-20 15:52 UTC (permalink / raw)
  To: Alan Cox
  Cc: Pavel Machek, Linux Kernel Mailing List, ACPI mailing list,
	Andrew Grover

On Wed, Nov 20, 2002 at 04:17:35PM +0000, Alan Cox wrote:
 > On Wed, 2002-11-20 at 15:38, Dave Jones wrote:
 > > On Wed, Nov 20, 2002 at 04:11:37PM +0100, Pavel Machek wrote:
 > >  > -	acpi_create_identity_pmd();
 > >  > +	if (!cpu_has_pse) {
 > >  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
 > >  > +		return 1;
 > >  > +	}
 > > 
 > > Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
 > > dropped into various laptops.
 > 
 > Plenty of desktop machines have S3 

Indeed, that too. So the above assertion seems bogus.

		Dave

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]     ` <20021120153833.GA4344-l3A5Bk7waGM@public.gmane.org>
@ 2002-11-20 16:17       ` Alan Cox
       [not found]         ` <1037809055.3702.43.camel-MMxVpc8zpTQVh3rx8e9g/fyykp6/JSeS3vcXtXqGYxw@public.gmane.org>
  2002-11-21 12:45       ` Pavel Machek
  2002-11-24 19:40       ` Pavel Machek
  2 siblings, 1 reply; 8+ messages in thread
From: Alan Cox @ 2002-11-20 16:17 UTC (permalink / raw)
  To: Dave Jones
  Cc: Pavel Machek, Linux Kernel Mailing List, ACPI mailing list,
	Andrew Grover

On Wed, 2002-11-20 at 15:38, Dave Jones wrote:
> On Wed, Nov 20, 2002 at 04:11:37PM +0100, Pavel Machek wrote:
>  > -	acpi_create_identity_pmd();
>  > +	if (!cpu_has_pse) {
>  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
>  > +		return 1;
>  > +	}
> 
> Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
> dropped into various laptops.

Plenty of desktop machines have S3 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]             ` <20021120155223.GA5678-l3A5Bk7waGM@public.gmane.org>
@ 2002-11-21 12:44               ` Pavel Machek
  0 siblings, 0 replies; 8+ messages in thread
From: Pavel Machek @ 2002-11-21 12:44 UTC (permalink / raw)
  To: Dave Jones, Alan Cox, Pavel Machek, Linux Kernel Mailing List,
	ACPI mailing list, Andrew Grover

Hi!

>  > >  > -	acpi_create_identity_pmd();
>  > >  > +	if (!cpu_has_pse) {
>  > >  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
>  > >  > +		return 1;
>  > >  > +	}
>  > > 
>  > > Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
>  > > dropped into various laptops.
>  > 
>  > Plenty of desktop machines have S3 
> 
> Indeed, that too. So the above assertion seems bogus.

Well, previous version reboots during S3 resume once kernel is > (some
size). I guess that PSE needs fixing but this needed fixing first.

								Pavel
-- 
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]     ` <20021120153833.GA4344-l3A5Bk7waGM@public.gmane.org>
  2002-11-20 16:17       ` Alan Cox
@ 2002-11-21 12:45       ` Pavel Machek
       [not found]         ` <20021121124506.GC1133-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/@public.gmane.org>
  2002-11-24 19:40       ` Pavel Machek
  2 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2002-11-21 12:45 UTC (permalink / raw)
  To: Dave Jones, Pavel Machek, kernel list, ACPI mailing list,
	Andrew Grover

Hi!

>  > -	acpi_create_identity_pmd();
>  > +	if (!cpu_has_pse) {
>  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
>  > +		return 1;
>  > +	}
> 
> Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
> dropped into various laptops.

So S3 will refuse to suspend on those machines. Right now it will
suspend and not wakeup if moon is bad phase.
							Pavel
-- 
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]         ` <20021121124506.GC1133-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/@public.gmane.org>
@ 2002-11-21 13:15           ` Ducrot Bruno
  0 siblings, 0 replies; 8+ messages in thread
From: Ducrot Bruno @ 2002-11-21 13:15 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Dave Jones, kernel list, ACPI mailing list, Andrew Grover

On Thu, Nov 21, 2002 at 01:45:06PM +0100, Pavel Machek wrote:
> Hi!
> 
> >  > -	acpi_create_identity_pmd();
> >  > +	if (!cpu_has_pse) {
> >  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
> >  > +		return 1;
> >  > +	}
> > 
> > Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
> > dropped into various laptops.
> 
> So S3 will refuse to suspend on those machines. Right now it will
> suspend and not wakeup if moon is bad phase.
> 							Pavel

FYI, current swsusp for 2.4 require that cpu has pse _or_ pse36.

-- 
Ducrot Bruno
http://www.poupinou.org        Page profaissionelle
http://toto.tu-me-saoules.com  Haume page

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Fix S3 resume when kernel is big
       [not found]     ` <20021120153833.GA4344-l3A5Bk7waGM@public.gmane.org>
  2002-11-20 16:17       ` Alan Cox
  2002-11-21 12:45       ` Pavel Machek
@ 2002-11-24 19:40       ` Pavel Machek
  2 siblings, 0 replies; 8+ messages in thread
From: Pavel Machek @ 2002-11-24 19:40 UTC (permalink / raw)
  To: Dave Jones, Pavel Machek, kernel list, ACPI mailing list,
	Andrew Grover

Hi!

>  > -	acpi_create_identity_pmd();
>  > +	if (!cpu_has_pse) {
>  > +		printk(KERN_ERR "You have S3 capable machine without pse? Wow!");
>  > +		return 1;
>  > +	}
> 
> Mobile K6 family never had PSE iirc, and also VIA Cyrix 3's are being
> dropped into various laptops.

Okay, here is patch that should be ableto handle machines without
pse... I'd still like to see machine where ACPI S3 work and it does
not have pse, through.

								Pavel

--- clean/arch/i386/kernel/acpi.c	2002-09-22 23:46:52.000000000 +0200
+++ linux-swsusp/arch/i386/kernel/acpi.c	2002-11-24 20:29:33.000000000 +0100
@@ -446,72 +446,19 @@
 
 #ifdef CONFIG_ACPI_SLEEP
 
-#define DEBUG
-
-#ifdef DEBUG
-#include <linux/serial.h>
-#endif
-
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
 
-/* new page directory that we will be using */
-static pmd_t *pmd;
-
-/* saved page directory */
-static pmd_t saved_pmd;
-
-/* page which we'll use for the new page directory */
-static pte_t *ptep;
-
 extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
 
-/*
- * acpi_create_identity_pmd
- *
- * Create a new, identity mapped pmd.
- *
- * Do this by creating new page directory, and marking all the pages as R/W
- * Then set it as the new Page Middle Directory.
- * And, of course, flush the TLB so it takes effect.
- *
- * We save the address of the old one, for later restoration.
- */
-static void acpi_create_identity_pmd (void)
+static void init_low_mapping(pgd_t *pgd, int pgd_ofs, int pgd_limit)
 {
-	pgd_t *pgd;
-	int i;
-
-	ptep = (pte_t*)__get_free_page(GFP_KERNEL);
+	int pgd_ofs = 0;
 
-	/* fill page with low mapping */
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(ptep + i, pfn_pte(i, PAGE_SHARED));
-
-	pgd = pgd_offset(current->active_mm, 0);
-	pmd = pmd_alloc(current->mm,pgd, 0);
-
-	/* save the old pmd */
-	saved_pmd = *pmd;
-
-	/* set the new one */
-	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep)));
-
-	/* flush the TLB */
-	local_flush_tlb();
-}
-
-/*
- * acpi_restore_pmd
- *
- * Restore the old pmd saved by acpi_create_identity_pmd and
- * free the page that said function alloc'd
- */
-static void acpi_restore_pmd (void)
-{
-	set_pmd(pmd, saved_pmd);
-	local_flush_tlb();
-	free_page((unsigned long)ptep);
+	while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
+		set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
+		pgd_ofs++, pgd++;
+	}
 }
 
 /**
@@ -522,7 +469,11 @@
  */
 int acpi_save_state_mem (void)
 {
-	acpi_create_identity_pmd();
+#if CONFIG_X86_PAE
+	panic("S3 and PAE do not like each other for now.");
+	return 1;
+#endif
+	init_low_mapping(swapper_pg_dir, 0, USER_PTRS_PER_PGD);
 	acpi_copy_wakeup_routine(acpi_wakeup_address);
 
 	return 0;
@@ -542,7 +493,7 @@
  */
 void acpi_restore_state_mem (void)
 {
-	acpi_restore_pmd();
+	zap_low_mappings();
 }
 
 /**
@@ -555,7 +506,10 @@
  */
 void __init acpi_reserve_bootmem(void)
 {
+	extern char wakeup_start, wakeup_end;
 	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
+		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
 	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
 }
 
--- clean/arch/i386/kernel/acpi_wakeup.S	2002-11-19 16:45:58.000000000 +0100
+++ linux-swsusp/arch/i386/kernel/acpi_wakeup.S	2002-11-23 20:44:44.000000000 +0100
@@ -1,12 +1,17 @@
-
 .text
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
-# Do we need to deal with A20?
+#
+# wakeup_code runs in real mode, and at unknown address (determined at run-time).
+# Therefore it must only use relative jumps/calls. 
+#
+# Do we need to deal with A20? It seems okay
 
 ALIGN
-wakeup_start:
+	.align	4096
+ENTRY(wakeup_start)
 wakeup_code:
 	wakeup_code_start = .
 	.code16
@@ -14,49 +19,71 @@
  	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'L', %fs:(0x10)
+	
 	cli
 	cld
-	  
-	# setup data segment
-	movw	%cs, %ax
 
-	addw	$(wakeup_data - wakeup_code) >> 4, %ax
-	movw	%ax, %ds
-	movw	%ax, %ss
-	mov	$(wakeup_stack - wakeup_data), %sp		# Private stack is needed for ASUS board
+# We are now probably running at something like 0x0000 : 0x1000
+	call here
+here:
+	pop	 %bx
+	subw	$(here-wakeup_start), %bx
+	shrw	$4, %bx
+	
+        # setup data segment
+        movw    %cs, %ax
+	addw    %bx, %ax
+	movw    %ax, %ds					# Make ds:0 point to wakeup_start
+	movw    %ax, %ss
+	mov	$(wakeup_stack-wakeup_code), %sp		# Private stack is needed for ASUS board
 	movw	$0x0e00 + 'S', %fs:(0x12)	
 
-	movl	real_magic - wakeup_data, %eax
+	pushl	$0						# Kill any dangerous flags
+	popfl
+	cli
+	cld
+	
+	movl	real_magic-wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
-	mov	video_mode - wakeup_data, %ax
+	mov	video_mode-wakeup_code, %ax
 	call	mode_set
 
 	# set up page table
-	movl	(real_save_cr3 - wakeup_data), %eax
+	movl	$swapper_pg_dir-__PAGE_OFFSET,%eax
 	movl	%eax, %cr3
 
 	# make sure %cr4 is set correctly (features, etc)
-	movl	(real_save_cr4 - wakeup_data), %eax
+	movl	real_save_cr4-wakeup_code, %eax
 	movl	%eax, %cr4
 	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'i', %fs:(0x12)
-
+	
 	# need a gdt
-	lgdt	real_save_gdt - wakeup_data
+	lgdt	real_save_gdt-wakeup_code
 
-	movl	(real_save_cr0 - wakeup_data), %eax
+	movl	real_save_cr0-wakeup_code, %eax
 	movl	%eax, %cr0
+	jmp 1f
+1:
 	movw	$0x0e00 + 'n', %fs:(0x14)
 
-	movl	real_magic - wakeup_data, %eax
+	movl	real_magic-wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
 	ljmpl	$__KERNEL_CS,$wakeup_pmode_return
 
+real_save_gdt:	.word 0
+		.long 0
+real_save_cr0:	.long 0
+real_save_cr3:	.long 0
+real_save_cr4:	.long 0
+real_magic:	.long 0
+video_mode:	.long 0
+
 bogus_real_magic:
 	movw	$0x0e00 + 'B', %fs:(0x12)
 	jmp bogus_real_magic
@@ -129,20 +156,12 @@
 	.code32
 	ALIGN
 
-.org	0x300
-wakeup_data:
-		.word 0
-real_save_gdt:	.word 0
-		.long 0
-real_save_cr0:	.long 0
-real_save_cr3:	.long 0
-real_save_cr4:	.long 0
-real_magic:	.long 0
-video_mode:	.long 0
 
-.org	0x500
+.org	0x2000
 wakeup_stack:
-wakeup_end:
+.org	0x3000
+ENTRY(wakeup_end)
+.org	0x4000
 
 wakeup_pmode_return:
 	movl	$__KERNEL_DS, %eax
@@ -205,6 +224,9 @@
 	movw	$0x0e00 + '2', %ds:(0xb8018)
 	jmp bogus_magic2
 		
+.org 0x123456
+eat_some_memory:	
+		.long 0
 
 ##
 # acpi_copy_wakeup_routine
@@ -228,7 +250,7 @@
 
 	movl	%eax, %edi
 	leal	wakeup_start, %esi
-	movl	$(wakeup_end - wakeup_start) >> 2, %ecx
+	movl	$(wakeup_end - wakeup_start + 3) >> 2, %ecx
 
 	rep ;  movsl
 
@@ -290,8 +312,8 @@
 	ret
 	.p2align 4,,7
 .L1432:
-	movl $104,%eax
-	movw %eax, %ds
+	movl $__KERNEL_DS,%eax
+	movw %ax, %ds
 	movl saved_context_esp, %esp
 	movl saved_context_ebp, %ebp
 	movl saved_context_eax, %eax
@@ -310,5 +332,4 @@
 saved_idt:	.long	0,0
 saved_ldt:	.long	0
 saved_tss:	.long	0
-saved_cr0:	.long	0
 
--- clean/arch/i386/mm/init.c	2002-11-19 16:45:26.000000000 +0100
+++ linux-swsusp/arch/i386/mm/init.c	2002-11-24 20:18:22.000000000 +0100
@@ -299,7 +299,7 @@
 #endif
 }
 
-void __init zap_low_mappings (void)
+void zap_low_mappings (void)
 {
 	int i;
 	/*


-- 
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2002-11-24 19:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-20 15:11 Fix S3 resume when kernel is big Pavel Machek
     [not found] ` <20021120151136.GA862-I/5MKhXcvmPrBKCeMvbIDA@public.gmane.org>
2002-11-20 15:38   ` Dave Jones
     [not found]     ` <20021120153833.GA4344-l3A5Bk7waGM@public.gmane.org>
2002-11-20 16:17       ` Alan Cox
     [not found]         ` <1037809055.3702.43.camel-MMxVpc8zpTQVh3rx8e9g/fyykp6/JSeS3vcXtXqGYxw@public.gmane.org>
2002-11-20 15:52           ` Dave Jones
     [not found]             ` <20021120155223.GA5678-l3A5Bk7waGM@public.gmane.org>
2002-11-21 12:44               ` Pavel Machek
2002-11-21 12:45       ` Pavel Machek
     [not found]         ` <20021121124506.GC1133-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/@public.gmane.org>
2002-11-21 13:15           ` Ducrot Bruno
2002-11-24 19:40       ` Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox