Subject: Re: Problems with VIA tech EDEN ESP CPU core.
To: John Clark <>
From: Dan LaBell <>
List: port-i386
Date: 03/30/2005 03:53:06
On Mar 28, 2005, at 11:54 AM, John Clark wrote:

> Joern Clausen wrote:
>> On Fri, Mar 25, 2005 at 06:44:51PM -0800, John Clark wrote:
>>> I've looked a little bit at the difference between the 1.6.2 boot 
>>> code and what is a 'recent' cvs downloaded
>>> version of 2.0.
>> Have you tried the advice from
>> I have not, and I have seen no comments on the list, so maybe you 
>> should
>> start there.
> I'm looking at that. In my brief review of the differences between 1.6 
> and 2.0 boot code, there seems to
> be some significant differences in the first few lines of the code 
> that is in the first boot sector. Since I tuned
> out of the x86 world about 15 years ago, I'll have to excavate in my 
> brain how Intel things work... but
> I'm pretty sure there are some areas that need to be looked at in 
> regard to clearing of registers.
> In the above mentioned message there is a reference to an andl:
> I wonder if just adding:
> 	andl	$0xffff,%esp
> at the start of real_to_prot (in stand/lib/realprot.S)
> is what is needed?
> Which is suggestive of what could be a problem if the ESP has 
> 'garbage' left over
> from the BIOS, ie garbage bits above bit 20. And of course that could 
> be the case
> since my BIOS is perhaps different than others, and would suggest why 
> there may
> be a variety of symptoms.
> This of course at the moment is all hypothetical.
> John

There's no realprot.S in 1.6 that I can find.  It looks like its been 
Seems like it's in stand/lib/crt/bootsect/start_bootsect.S.
I'll include the 2 routines below for comparision purposes.

Anyway If I added, the recommend line , how would I build it?  And to 
get the necessary file for installboot?

from realprot.S (2.0):
  * real_to_prot()
  * Switch CPU to 32bit protected mode to execute C.
  * NB: Call with the 32bit calll instruction so that a 32 bit
  *     return address is pushed.
  * All registers are preserved, %ss:%esp will point to the same
  * place as %ss:%sp did, although the actual value of %esp might
  * be changed.
  * Interrupts are disabled while we are in 32bit mode to save us
  * having to setup a different IDT.  This code is only used during
  * the boot process and it doesn't use any interrupts.
	pushl	%eax

	lgdt	%cs:gdtarg		/* Global descriptor table */

	movl	%cr0, %eax
	or	$CR0_PE, %ax
	movl	%eax, %cr0 		/* Enter 'protected mode' */

	ljmp	$bootcodeseg, $1f	/* Jump into a 32bit segment */

	/*  Set all the segment registers to map the same area as the code */
	mov	$bootdataseg, %eax
	mov	%ax, %ds
	mov	%ax, %es
	mov	%ax, %ss
	addl	stkdif, %esp		/* Allow for real %ss != %ds */

	popl	%eax
from start_bootsect.S (1.6)
CR0_PE		=	0x1

  * real_to_prot()
  * 	transfer from real mode to protected mode.
	# guarantee that interrupt is disabled when in prot mode

	# load the gdtr
	lgdt	gdtarg

	# set the PE bit of CR0
	movl	%cr0, %eax

	orl	$CR0_PE, %eax
	movl	%eax, %cr0

	# make intrasegment jump to flush the processor pipeline and
	# reload CS register
	ljmp	$bootcodeseg, $xprot

	# we are in USE32 mode now
	# set up the protected mode segment registers : DS, SS, ES
	movl	$bootdataseg, %eax
	movl	%ax, %ds
	movl	%ax, %ss
	movl	%ax, %es


I notice that the new version claims to preserve all registers, the old 
version doesn't. And while searching for the definition in 1.6, I found 
some calls with lines like "movb %ah, %bh   # save error code" 
preceding it, but in 2.0 there is still some -- seems weird if its 
actually preserving all registers.