Subject: Re: Problems with VIA tech EDEN ESP CPU core.
To: John Clark <jclark@metricsystems.com>
From: Dan LaBell <dan4l-nospam@verizon.net>
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
>>
>>   http://mail-index.netbsd.org/port-i386/2005/03/10/0002.html
>>
>> 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 
reworked.
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.
  */
ENTRY(real_to_prot)
	.code16
	pushl	%eax
	cli

	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 */
1:

	.code32
	/*  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
	ret
---------------------
from start_bootsect.S (1.6)
-----------------------
CR0_PE		=	0x1

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

	# load the gdtr
	addr32
	data32
	lgdt	gdtarg

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

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

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

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

	ret

--------------
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.