Hi, all,
I am trying to implement the ACPI S3 on coreboot. I have some questions:
1. Where is the proper place to check the sleep type in the power register? Now I check it just prior to disabling the cache as RAM, for not ruining the RAM.
2. How to jump into the wakeup_start in x86_64/kernel/acpi/wakeup.S? The code is in real mode, how does coreboot jump from the protected mode to the entry? In my case, the wakeup_start points to the physical address 0x2000, from there some real mode code reside. How to jump to the code. The below is the beginning part of wakeup_start:
.text #include <linux/linkage.h> #include <asm/segment.h> #include <asm/page.h> #include <asm/msr.h> # Copyright 2003 Pavel Machek pavel@suse.cz, distribute under GPLv2 # # 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 is okay: ACPI specs says A20 must be enabled # # If physical address of wakeup_code is 0x12345, BIOS should call us with # cs = 0x1234, eip = 0x05 # ALIGN .align 16 ENTRY(wakeup_start) wakeup_code: wakeup_code_start = . .code16
# Running in *copy* of this code, somewhere in low 1MB.
movb $0xa1, %al ; outb %al, $0x80 cli cld # setup data segment movw %cs, %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
pushl $0 # Kill any dangerous flags popfl =================================================================
Any comments are appreciated.
Best Regards
丰立波 Feng Libo @ AMD Ext: 20906 Mobile Phone: 13683249071 Office Phone: 0086-010-62801406
Feng, Libo napsal(a):
Hi, all,
I am trying to implement the ACPI S3 on coreboot. I have some questions:
Hi, I have posted some experimental version year ago. It is quite tricky to get it working correctly because coreboot overwrittes lot of memory.
Here is the patch: http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html
Worked for K8T890 and K8 DDR revE
Here is described in the steps what needs to be done: http://www.coreboot.org/pipermail/coreboot/2008-September/038539.html
- Where is the proper place to check the sleep type in the power
register? Now I check it just prior to disabling the cache as RAM, for not ruining the RAM.
Problem is that you need to setup again some devices which are not setup by OS. Like memory controller DDR and chipset low level stuff.
ACPI allows to wakeup in state like fresh boot, therefore I just let coreboot run again and then jump not to payload but to previously saved waking vector.
Problem only is not to overwrite the memory. I solved that by instructing the kernel not to use the low memory at all. Except one page for the trampoline code from your mail.
- How to jump into the wakeup_start in x86_64/kernel/acpi/wakeup.S? The
code is in real mode, how does coreboot jump from the protected mode to the entry? In my case, the wakeup_start points to the physical address 0x2000, from there some real mode code reside. How to jump to the code.
There is reset vector in some DSDT table. Check mine original patch.
For which chipset/processor are you planning that?
Rudolf
----- Original Message ----
From: Rudolf Marek r.marek@assembler.cz To: "Feng, Libo" Libo.Feng@amd.com Cc: coreboot@coreboot.org Sent: Wednesday, November 12, 2008 1:38:39 PM Subject: Re: [coreboot] ACPI S3
Feng, Libo napsal(a):
Hi, all,
I am trying to implement the ACPI S3 on coreboot. I have some questions:
Hi, I have posted some experimental version year ago. It is quite tricky to get it working correctly because coreboot overwrittes lot of memory.
Here is the patch: http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html
Worked for K8T890 and K8 DDR revE
Here is described in the steps what needs to be done: http://www.coreboot.org/pipermail/coreboot/2008-September/038539.html
- Where is the proper place to check the sleep type in the power register?
Now I check it just prior to disabling the cache as RAM, for not ruining the RAM.
Problem is that you need to setup again some devices which are not setup by OS. Like memory controller DDR and chipset low level stuff.
ACPI allows to wakeup in state like fresh boot, therefore I just let coreboot run again and then jump not to payload but to previously saved waking vector.
Problem only is not to overwrite the memory. I solved that by instructing the kernel not to use the low memory at all. Except one page for the trampoline code from your mail.
Did you do that with e820 ( via the coreboot table)? I think you could reserve the stack area with E820. That would at least give back some of the memory.
It also looks like we need a s3 aware CAR
- How to jump into the wakeup_start in x86_64/kernel/acpi/wakeup.S? The code
is in real mode, how does coreboot jump from the protected mode to the entry? In my case, the wakeup_start points to the physical address 0x2000, from there some real mode code reside. How to jump to the code.
There is reset vector in some DSDT table. Check mine original patch.
The real vm86 think code in either real_mode_switch_call_* should be a good example.
For which chipset/processor are you planning that?
Libo and Co. are working on the dbm690t platform K8 revf/g and rs690/sb600.
Marc
Did you do that with e820 ( via the coreboot table)? I think you could reserve the stack area with E820. That would at least give back some of the memory.
Well linux cannot do ACPI reclaim. I simply supplied memory map from CMDline check the original patch. I had in plan to enable memory hotplug in ACPI so it would gain back the memory.
It also looks like we need a s3 aware CAR
Yes please check mine second link. There was lengthy discussion. I dont know how is it now but imho when CAR is not flushed back to main memory we have no problem?
Libo and Co. are working on the dbm690t platform K8 revf/g and rs690/sb600.
Thanks,
Rudolf
Marc Jones wrote:
----- Original Message ----
From: Rudolf Marek r.marek@assembler.cz To: "Feng, Libo" Libo.Feng@amd.com Cc: coreboot@coreboot.org Sent: Wednesday, November 12, 2008 1:38:39 PM Subject: Re: [coreboot] ACPI S3
Feng, Libo napsal(a):
Hi, all,
I am trying to implement the ACPI S3 on coreboot. I have some questions:
Hi, I have posted some experimental version year ago. It is quite tricky to get it working correctly because coreboot overwrittes lot of memory.
Here is the patch: http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html
Worked for K8T890 and K8 DDR revE
Here is described in the steps what needs to be done: http://www.coreboot.org/pipermail/coreboot/2008-September/038539.html
- Where is the proper place to check the sleep type in the power register?
Now I check it just prior to disabling the cache as RAM, for not ruining the RAM.
Problem is that you need to setup again some devices which are not setup by OS. Like memory controller DDR and chipset low level stuff.
ACPI allows to wakeup in state like fresh boot, therefore I just let coreboot run again and then jump not to payload but to previously saved waking vector.
Problem only is not to overwrite the memory. I solved that by instructing the kernel not to use the low memory at all. Except one page for the trampoline code from your mail.
Did you do that with e820 ( via the coreboot table)? I think you could reserve the stack area with E820. That would at least give back some of the memory.
That is a good idea. There might also be some ACPI rules about where the stack can be on a resuming BIOS - I'm not sure what traditional BIOSes do for that. The only other x86 firmware I'm aware of is OFW on the OLPC, and he manages to make it through the entire resume with just registers. Hopefully we don't need too much stack - the quicker we can resume (and the fewer functions we have to call) the happier we will be.
- How to jump into the wakeup_start in x86_64/kernel/acpi/wakeup.S? The code
is in real mode, how does coreboot jump from the protected mode to the entry? In my case, the wakeup_start points to the physical address 0x2000, from there some real mode code reside. How to jump to the code.
There is reset vector in some DSDT table. Check mine original patch.
The real vm86 think code in either real_mode_switch_call_* should be a good example.
The jump back to the OS should be as generic as possible, since every platform will eventually need it.
Jordan
That is a good idea. There might also be some ACPI rules about where the stack can be on a resuming BIOS - I'm not sure what traditional BIOSes do for that.
They grab one MB at the end of memory. So maybe we can do the same.
Rudolf
Rudolf Marek wrote:
That is a good idea. There might also be some ACPI rules about where the stack can be on a resuming BIOS - I'm not sure what traditional BIOSes do for that.
They grab one MB at the end of memory. So maybe we can do the same.
We will need to reserve it from the beginning. 1Mb seems to much - how much extra system state did you have to save off in your implementation?
I was hoping more along the lines of using 4 or 8k from the f0000 segment.
Jordan
Well we need somewhere memory where Coreboot can do its heap, processor stacks etc. For v3 I would go to some isolated region above 1MB.
Maybe we can use f0000 and copy original back (seabios might be there already when resuming).
its really difficult to track what v2 is corrupting in low mem.
Rudolf
Hi, all,
Thank you very much. Such a lot of information pours to me. It will take quite a while for me to digest. ;-)
The below are my thought and some experiment results, the platform is: AMD dbm690t mainboard mounted with Turion 64x2, Rs690 and Sb600. OS is Fedora 6 shipping with the 2.6.18 kernel. ACPI spec is 3.0a
1. According to the ACPI spec, prior to transitioning to S3, OS saves a lot of processor and devices' context, flushes and invalids cache. Please reference to 15.1.6. I will check the kernel source to find what are exactly saved.
2. In 15.1.3.1, Only the four items below need to be done by BIOS when waking up: 1. Program the initial boot configuration of the CPU (such as the MSR and MTRR registers). 2. Initialize the cache controller to its initial boot size and configuration. 3. Enable the memory controller to accept memory accesses. 4. Jump to the waking vector.
3. In coreboot, within cache_as_ram_auto.c, the cache is enabled. Not all MTRR but some are set up, precisely, MSR 0269h MTRfix4K_C8000 Register and MSR 02FFh MTRRdefType Register. The memory controller is setup, too. So if we don’t copy the data in cache and the coreboot code into RAM in the function of post_cache_as_ram, the content of RAM keeps intact since the last transition of S3.
4. Then, is RAM accessible in cache_as_ram_auto.c now? I did some experiments. FACS table can be found, the waking vector can be fetched. With HDT( AMD debug tool ), I can also find the waking source code at 0x2000 in RAM, identical with /arch/x86_64/kernel/acpi/wakeup.S. So, I think after initializing the memory controller, RAM has exited the self-refresh state.
5. At this point, Power Management Register is also accessible, strange but true. So I can decide it is normal boot or waking by reading Sleep Type in AcpiPm1CntBlk.
6. Some MSR and MTRR can be stored in CMOS RAM during the previous normal boot, now I can read back them from CMOS RAM.
7. After all these, jumping to the waking vector and handing the control to OS, OS will restore system and wake up.
I am not sure this can work or not yet. So, any comments are appreciated. Thanks again.
Best Regards
丰立波 Feng Libo @ AMD Ext: 20906 Mobile Phone: 13683249071 Office Phone: 0086-010-62801406
-----Original Message----- From: Rudolf Marek [mailto:r.marek@assembler.cz] Sent: Thursday, November 13, 2008 4:39 AM To: Feng, Libo Cc: coreboot@coreboot.org Subject: Re: [coreboot] ACPI S3
Feng, Libo napsal(a):
Hi, all,
I am trying to implement the ACPI S3 on coreboot. I have some questions:
Hi, I have posted some experimental version year ago. It is quite tricky to get it working correctly because coreboot overwrittes lot of memory.
Here is the patch: http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html
Worked for K8T890 and K8 DDR revE
Here is described in the steps what needs to be done: http://www.coreboot.org/pipermail/coreboot/2008-September/038539.html
- Where is the proper place to check the sleep type in the power
register? Now I check it just prior to disabling the cache as RAM, for not ruining the RAM.
Problem is that you need to setup again some devices which are not setup by OS. Like memory controller DDR and chipset low level stuff.
ACPI allows to wakeup in state like fresh boot, therefore I just let coreboot run again and then jump not to payload but to previously saved waking vector.
Problem only is not to overwrite the memory. I solved that by instructing the kernel not to use the low memory at all. Except one page for the trampoline code from your mail.
- How to jump into the wakeup_start in x86_64/kernel/acpi/wakeup.S?
The code is in real mode, how does coreboot jump from the protected mode to the entry? In my case, the wakeup_start points to the physical address 0x2000, from there some real mode code reside. How to jump to the code.
There is reset vector in some DSDT table. Check mine original patch.
For which chipset/processor are you planning that?
Rudolf
Feng, Libo wrote:
I am not sure this can work or not yet. So, any comments are appreciated.
It looks like the right sequence, so I think it should work.
But I am not sure about saving MTRRs in NVRAM for production use. I think it would be less intrusive to save them in a reserved block of RAM.
//Peter
Feng, Libo wrote:
Hi, all,
Thank you very much. Such a lot of information pours to me. It will take quite a while for me to digest. ;-)
The below are my thought and some experiment results, the platform is: AMD dbm690t mainboard mounted with Turion 64x2, Rs690 and Sb600. OS is Fedora 6 shipping with the 2.6.18 kernel. ACPI spec is 3.0a
- According to the ACPI spec, prior to transitioning to S3, OS saves
a lot of processor and devices' context, flushes and invalids cache. Please reference to 15.1.6. I will check the kernel source to find what are exactly saved.
That is mostly correct. The OS is usually only responsible for "leaf" devices - meaning devices that are attached to a bus. In other words, the OS knows how to save the SATA controller, but it won't understand how to restore the southbridge so that it can see the SATA controller. During a suspend, most (but not all) of the chipsets will be powered down. A good rule of thumb is that if you have to configure a device in coreboot during cold boot, then you probably have to configure it during resume. When in doubt, check the kernel to see what it does. In the beginning, it probably wouldn't hurt if you accidentally set up a device twice, but we want to avoid that as much as possible.
- In 15.1.3.1, Only the four items below need to be done by BIOS
when waking up: 1. Program the initial boot configuration of the CPU (such as the MSR and MTRR registers). 2. Initialize the cache controller to its initial boot size and configuration. 3. Enable the memory controller to accept memory accesses. 4. Jump to the waking vector.
As I said above - you will probably have some chipset initialization that needs to happen.
- In coreboot, within cache_as_ram_auto.c, the cache is enabled. Not
all MTRR but some are set up, precisely, MSR 0269h MTRfix4K_C8000 Register and MSR 02FFh MTRRdefType Register. The memory controller is setup, too. So if we don’t copy the data in cache and the coreboot code into RAM in the function of post_cache_as_ram, the content of RAM keeps intact since the last transition of S3.
- Then, is RAM accessible in cache_as_ram_auto.c now? I did some
experiments. FACS table can be found, the waking vector can be fetched. With HDT( AMD debug tool ), I can also find the waking source code at 0x2000 in RAM, identical with /arch/x86_64/kernel/acpi/wakeup.S. So, I think after initializing the memory controller, RAM has exited the self-refresh state.
- At this point, Power Management Register is also accessible,
strange but true. So I can decide it is normal boot or waking by reading Sleep Type in AcpiPm1CntBlk.
Above, I said that not all the chipset is turned off during suspend - this is one of those registers that lives in what we call the standby domain. The standby domain saves the state of the registers through a suspend especially so that you can read it at this point.
- Some MSR and MTRR can be stored in CMOS RAM during the previous
normal boot, now I can read back them from CMOS RAM.
This is not a good idea - you have limited CMOS space, and you will quickly fill it up. It is perfectly valid to save the values of these registers in a reserved bit of system memory. When you resume, bring up the memory with default MSR and MTRR values (like on cold boot), and then restore the active values after you can access RAM. I think that you will find that most of the MSR values are the "default" values set at cold boot time, so you probably don't need to save many of those.
You will need some system RAM to save state and to have a stack - you can reserve that memory at boot time through the coreboot tables, and then use it at will during resume.
- After all these, jumping to the waking vector and handing the
control to OS, OS will restore system and wake up.
Don't forget to put the code into 16 bit mode before jumping to the wake vector.
Jordan
Hi all,
As Jordan noted, some device context must be restored. It won't fit in CMOS. Some chipset have additional NVRAM for this S3 resume process.
You have basically two options:
1) Follow the way I did, re-run coreboot and jump later to OS waking vector. Check the patches and the other threads.
2) Save memory config in CMOS, restore memory config, restore memory, re-init the chipset registers (not the leafs) and jump to OS vector. This means that the rest of device state is saved in reserved RAM. To be sure to save actual context you will need also SMM (system management mode trap) and trap the SLP register write, do the backup of all important registers and then go off.
I think easier is 1) Only problem is about memory overwrites. Check the Jason's thread. He is facing similar issues. Maybe put whole coreboot to TOPMEM-something and put low memory trampolines and stack to some place where it don't hurt. You may also save/restore the region during resume.
Rudolf
Hi, All,
I am still trying to implement the S3 state in dbm690t. Now I can jump into the waking vector code running under the real mode. However, the code contains some 32bit instructions, when these instructions are executed, the system always hangs, for the processor thought they were of 16bit. Please see the code in the below link.
http://lxr.linux.no/linux+v2.6.18/arch/x86_64/kernel/acpi/wakeup.S
In 37 and 38 line, there are two 32bit instructions,
66 6a 00 pushl $0 # Kill any dangerous flags 66 9d popfl
You can see the machine codes starting with 0x66 indicating these 32bit instructions. However, processor always thought these were of 16bit, so, instructions are changed into:
66 6a push byte 00h 00 66 9d add [bp-63h], ah
Then, maybe an exception occurs, system hangs. I am stuck here for a while, How can I make processor running both 16bit and 32bit instructions under the real mode? Thanks in advance.
Best Regards
丰立波 Feng Libo @ AMD Ext: 20906 Mobile Phone: 13683249071 Office Phone: 0086-010-62801406
-----Original Message----- From: Rudolf Marek [mailto:r.marek@assembler.cz] Sent: Saturday, November 15, 2008 7:33 AM To: Feng, Libo Cc: coreboot@coreboot.org; Xie, Michael; Bao, Zheng; Huang, FrankR; Li, Maggie; Wang, Qingpei Subject: Re: [coreboot] ACPI S3
Hi all,
As Jordan noted, some device context must be restored. It won't fit in CMOS. Some chipset have additional NVRAM for this S3 resume process.
You have basically two options:
1) Follow the way I did, re-run coreboot and jump later to OS waking vector. Check the patches and the other threads.
2) Save memory config in CMOS, restore memory config, restore memory, re-init the chipset registers (not the leafs) and jump to OS vector. This means that the rest of device state is saved in reserved RAM. To be sure to save actual context you will need also SMM (system management mode trap) and trap the SLP register write, do the backup of all important registers and then go off.
I think easier is 1) Only problem is about memory overwrites. Check the Jason's thread. He is facing similar issues. Maybe put whole coreboot to TOPMEM-something and put low memory trampolines and stack to some place where it don't hurt. You may also save/restore the region during resume.
Rudolf
On Sun, Nov 23, 2008 at 11:02 PM, Feng, Libo Libo.Feng@amd.com wrote:
Hi, All,
I am still trying to implement the S3 state in dbm690t. Now I can jump into the waking vector code running under the real mode. However, the code contains some 32bit instructions, when these instructions are executed, the system always hangs, for the processor thought they were of 16bit. Please see the code in the below link.
http://lxr.linux.no/linux+v2.6.18/arch/x86_64/kernel/acpi/wakeup.S
In 37 and 38 line, there are two 32bit instructions,
66 6a 00 pushl $0 # Kill any dangerous flags 66 9d popfl
You can see the machine codes starting with 0x66 indicating these 32bit instructions. However, processor always thought these were of 16bit, so, instructions are changed into:
66 6a push byte 00h 00 66 9d add [bp-63h], ah
what could explain this is that you are not in 16-bit mode, you are actually in 32-bit mode for some reason. The 66 will then run these instructions in 16 bit. That is just a guess.
Are you certain you are in 16 bit mode?
ron
Hi,
Yes, the processor is running in the real mode, both HDT(AMD debug tool) and machine code can verify it. The prefix of 0x66 indicates a 32bit instruction to the processor which is running in the real mode, however, the processor still executes the instructions in the 16bit way. I will check how to support 32bit instruction set in the real mode. And the code of wakeup.S is put here by Linux for resuming. When system resumes, the processor must be in the real mode, but you can see there are some 32bit instruction from either the assembly code or the machine code.
Best Regards
??? Feng Libo @ AMD Ext: 20906 Mobile Phone: 13683249071 Office Phone: 0086-010-62801406
-----Original Message----- From: ron minnich [mailto:rminnich@gmail.com] Sent: Tuesday, November 25, 2008 1:10 AM To: Feng, Libo Cc: coreboot@coreboot.org; Huang, FrankR; Li, Maggie; Bao, Zheng; Wang, Qingpei; Xie, Michael Subject: Re: [coreboot] ACPI S3
On Sun, Nov 23, 2008 at 11:02 PM, Feng, Libo Libo.Feng@amd.com wrote:
Hi, All,
I am still trying to implement the S3 state in dbm690t. Now I can jump into the waking vector code running under the real mode. However, the code contains some 32bit instructions, when these instructions are executed, the system always hangs, for the processor thought they were of 16bit. Please see the code in the below link.
http://lxr.linux.no/linux+v2.6.18/arch/x86_64/kernel/acpi/wakeup.S
In 37 and 38 line, there are two 32bit instructions,
66 6a 00 pushl $0 # Kill any dangerous flags 66 9d popfl
You can see the machine codes starting with 0x66 indicating these 32bit instructions. However, processor always thought these were of 16bit, so, instructions are changed into:
66 6a push byte 00h 00 66 9d add [bp-63h], ah
what could explain this is that you are not in 16-bit mode, you are actually in 32-bit mode for some reason. The 66 will then run these instructions in 16 bit. That is just a guess.
Are you certain you are in 16 bit mode?
ron
Feng, Libo wrote:
Yes, the processor is running in the real mode, both HDT(AMD debug tool)
That is good.
and machine code can verify it. The prefix of 0x66 indicates a 32bit instruction to the processor which is running in the real mode,
Actually this is not the complete picture.
There is good information in AMD document 24594: "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions", in particular section 1.2.2 on pages 4-5.
Quoting page 4: "The default operand size for an instruction is determined by a combination of its opcode, the D (default) bit in the current code-segment descriptor, and the current operating mode, as shown in Table 1-2. The operand-size override prefix (66h) selects the non-default operand size."
however, the processor still executes the instructions in the 16bit way.
One issue could be the D bit in the code segment descriptor as mentioned in the quote above. What does the GDT look like that you are using when switching back to real mode after coreboot is done? And I think cs must also be reloaded after lgdt, but I may be mistaken about that.
I will check how to support 32bit instruction set in the real mode.
Using the 0x66 prefix.
And the code of wakeup.S is put here by Linux for resuming. When system resumes, the processor must be in the real mode,
When the CPU starts executing again, coreboot will run. coreboot switches to protected mode as usual. To properly resume an operating system, coreboot must switch the processor back to real mode before jumping to the resume code that is in Linux wakeup.S. Rudolf has implemented this in the code he has contributed and I think you are already using parts of that. (That is good!)
but you can see there are some 32bit instruction from either the assembly code or the machine code.
There are 32-bit instructions also in real mode, so the assembly source code is OK.
//Peter
Hi, all,
Thank you, Mr. Peter Stuge, The D bit is the key point. With other tricks, the system stepped into the 64bit operating mode, however, was lost at the line 224 of wakeup.S, as the below link.
http://lxr.linux.no/linux+v2.6.18/arch/x86_64/kernel/acpi/wakeup.S
222 movw $0x0e00 + '!', %ds:(0xb801a) 223 movq saved_eip, %rax 224 jmp *%rax
I think saved_eip is stored prior to sleeping, so, now, I don't know where the system jumps into, which is totally random, depending on the system state just before sleeping. Now some traces can be sent out via serial port, I can't say it is resuming, for the system seems not fully working. Now I think resuming the system in the function of post_cache_as_ram is not a good idea. Few devices are initialized at this point. Rudolf's method is more practicable. I will try it later. Thank everyone again.
Best Regards
??? Feng Libo @ AMD Ext: 20906 Mobile Phone: 13683249071 Office Phone: 0086-010-62801406
-----Original Message----- From: Peter Stuge [mailto:peter@stuge.se] Sent: Tuesday, November 25, 2008 11:05 AM To: Feng, Libo Cc: ron minnich; Li, Maggie; Bao, Zheng; coreboot@coreboot.org; Xie, Michael; Huang, FrankR; Wang, Qingpei Subject: Re: [coreboot] ACPI S3
Feng, Libo wrote:
Yes, the processor is running in the real mode, both HDT(AMD debug tool)
That is good.
and machine code can verify it. The prefix of 0x66 indicates a 32bit instruction to the processor which is running in the real mode,
Actually this is not the complete picture.
There is good information in AMD document 24594: "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions", in particular section 1.2.2 on pages 4-5.
Quoting page 4: "The default operand size for an instruction is determined by a combination of its opcode, the D (default) bit in the current code-segment descriptor, and the current operating mode, as shown in Table 1-2. The operand-size override prefix (66h) selects the non-default operand size."
however, the processor still executes the instructions in the 16bit way.
One issue could be the D bit in the code segment descriptor as mentioned in the quote above. What does the GDT look like that you are using when switching back to real mode after coreboot is done? And I think cs must also be reloaded after lgdt, but I may be mistaken about that.
I will check how to support 32bit instruction set in the real mode.
Using the 0x66 prefix.
And the code of wakeup.S is put here by Linux for resuming. When system resumes, the processor must be in the real mode,
When the CPU starts executing again, coreboot will run. coreboot switches to protected mode as usual. To properly resume an operating system, coreboot must switch the processor back to real mode before jumping to the resume code that is in Linux wakeup.S. Rudolf has implemented this in the code he has contributed and I think you are already using parts of that. (That is good!)
but you can see there are some 32bit instruction from either the assembly code or the machine code.
There are 32-bit instructions also in real mode, so the assembly source code is OK.
//Peter
Feng, Libo wrote:
Hi, all,
Thank you, Mr. Peter Stuge, The D bit is the key point. With other tricks, the system stepped into the 64bit operating mode, however, was lost at the line 224 of wakeup.S, as the below link.
http://lxr.linux.no/linux+v2.6.18/arch/x86_64/kernel/acpi/wakeup.S
222 movw $0x0e00 + '!', %ds:(0xb801a) 223 movq saved_eip, %rax 224 jmp *%rax
I think saved_eip is stored prior to sleeping, so, now, I don't know where the system jumps into, which is totally random, depending on the system state just before sleeping. Now some traces can be sent out via serial port, I can't say it is resuming, for the system seems not fully working. Now I think resuming the system in the function of post_cache_as_ram is not a good idea. Few devices are initialized at this point. Rudolf's method is more practicable. I will try it later. Thank everyone again.
saved_eip should absolutely not be random - it is saved while the system is going down (in save_registers). You should confirm with HDT that the value in saved_eip is somewhat sane (i.e - pointing to somewhere else in the kernel code space).
What other indications do you have that the system was "lost"? Remember that you won't get back the video state due to silly behavior on the part of the ATI GPU - but you should be seeing kernel activity on your serial port, assuming that you have the kernel console enabled on your serial port.
Also, any reason why you are using kernel version 2.6.18 sources? IIRC, the images you are using had a newer version of the kernel.
I recommend that you step as far as you can with HDT through the resume process until you confirm that the system has re-entered the C functions.
Jordan