Reading the EDID block for x86 machines

32 messages, 4 authors, 2003-03-19 · open the first message on its own page

Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 12:52:59

Hi,

I was wondering how to get the EDID block, and my first thought was to
implement DDC.  But it is tricky to implement, so why not just get the
EDID using an int 0x10 BIOS call?

The EDID block can be read before the kernel goes into protected mode
(just a short assembly code in arch/i386/boot/video.S) and this can be
saved later on as struct edid_info during the kernel's setup routine.  

One catch though is that that the "empty_zero_page" is becoming too
tight, so it will just use the same offset used by the EDD (BIOS
Enhanced Disk Drive).  So EDID reading will be disabled if EDD is
enabled under the "Processor Type and Features"  option.

Then, we can also make EDID parsing more powerful.  I've added some code
in fbmon.c to parse the EDID block in more detail.  It should be able to
parse almost everything (except the color point).  Currently, it just
prints all the information it can find.  However, I haven't tested if
parsing the Detailed Monitor information is correct since the EDID block
of the monitor I'm using is incomplete.

One of the goals is to build a video data structure that also includes a
database of video mode in fb_videomode format.  This can be dynamically
created per device using the supported VESA modes, manufacturer's mode
and detailed timings mode information in the EDID block. The EDID block
also contain information on GTF capability.  With these types of
displays, a video mode mode database may not be needed since all
possible supported modelines can be calculated.

The advantage of the above is that the driver can switch to different
modes without relying on user input (of course, user-entered modelines
are still preferred).

Anyway, I need help in testing the code (especially the Detailed
Information part).  Just apply the attached patch, disable Enhanced Disk
Driver support (under Processor Type and Features), and enable EDID
support (under Graphics option).  Finally, add the following line to the
fbdev driver that you use (anywhere, but a good place is the init code):

show_edid(get_EDID(pci_dev))

If using an x86 machine

show_edid(get_EDID(NULL)) 

should also work.

Reboot, check dmesg, and kindly post the ouput.  Thanks.

Tony

PS:  The patch is against linux-2.5.64 + fbdev.diff.gz

Re: Reading the EDID block for x86 machines

From: James Simmons <hidden>
Date: 2003-03-11 15:50:34

I was wondering how to get the EDID block, and my first thought was to
implement DDC.  But it is tricky to implement, so why not just get the
EDID using an int 0x10 BIOS call?
DDC is tricky but the nice thing is it is very portable. We can do the 
BIOS call but that limits it support to intel family of processors.
I still like to do the BIOS call still because it allows us quick supprot 
of EDID on intel platforms. 
The EDID block can be read before the kernel goes into protected mode
(just a short assembly code in arch/i386/boot/video.S) and this can be
saved later on as struct edid_info during the kernel's setup routine.  

One catch though is that that the "empty_zero_page" is becoming too
tight, so it will just use the same offset used by the EDD (BIOS
Enhanced Disk Drive).  So EDID reading will be disabled if EDD is
enabled under the "Processor Type and Features"  option.
I believe it is possible to read the block after we are in protect mode.
Look at vesafb and also the aty128 driver allows you to probe the BIOS 
after we are in protect mode. I suggest we add a feild to struct 
screeninfo to store the address to the edid pointer. 
 
One of the goals is to build a video data structure that also includes a
database of video mode in fb_videomode format.  This can be dynamically
created per device using the supported VESA modes, manufacturer's mode
and detailed timings mode information in the EDID block. The EDID block
also contain information on GTF capability.  With these types of
displays, a video mode mode database may not be needed since all
possible supported modelines can be calculated.

The advantage of the above is that the driver can switch to different
modes without relying on user input (of course, user-entered modelines
are still preferred).
Wow. I'm glad we both think alike. I was thinking the same thing except my 
hands are tied with working on the upper layer stuff. 
Anyway, I need help in testing the code (especially the Detailed
Information part).  Just apply the attached patch, disable Enhanced Disk
Driver support (under Processor Type and Features), and enable EDID
support (under Graphics option).  Finally, add the following line to the
fbdev driver that you use (anywhere, but a good place is the init code):
Diable Enhanced Disk support :-( I have a few suggestions. One we add a 
pointer to struct screen_info that points to the edid information. We can 
use phys_to_virt to translate that address into virtual memory. I can 
create a patch today and store it in the BK tree. 



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 20:11:05

On Tue, 2003-03-11 at 23:49, James Simmons wrote:
quoted
I was wondering how to get the EDID block, and my first thought was to
implement DDC.  But it is tricky to implement, so why not just get the
EDID using an int 0x10 BIOS call?
DDC is tricky but the nice thing is it is very portable. We can do the 
BIOS call but that limits it support to intel family of processors.
I still like to do the BIOS call still because it allows us quick supprot 
of EDID on intel platforms. 
That's true.  The downside of course is that each driver/hardware has to
have it's own i2c support.  So this may not be very lightweight on first
glance.

Also, the int10 method is simple enough to implement and should
theoretically support all x86 graphics card with a reasonably unbroken
BIOS.  If ppc can get the EDID via OpenFirmware, the x86 can get it via
VBE int10.  Theoretically, other archs that follow some kind of video
standard will have this kind of support also.

The downside of this method is it can only get the EDID block of the
video controller/s initialized at boot time. 
  
quoted
The EDID block can be read before the kernel goes into protected mode
(just a short assembly code in arch/i386/boot/video.S) and this can be
saved later on as struct edid_info during the kernel's setup routine.  

One catch though is that that the "empty_zero_page" is becoming too
tight, so it will just use the same offset used by the EDD (BIOS
Enhanced Disk Drive).  So EDID reading will be disabled if EDD is
enabled under the "Processor Type and Features"  option.
I believe it is possible to read the block after we are in protect mode.
Look at vesafb and also the aty128 driver allows you to probe the BIOS 
after we are in protect mode. I suggest we add a feild to struct 
screeninfo to store the address to the edid pointer. 
 
Not in this case.  I believe there are very few int10 functions that
have a protected mode interface counterpart.  One of the reasons vesafb
cannot switch modes is because of this.
 
Also the int10 function is a request for the VBE to do DDC, and place
the results to a buffer provided by the caller.  It's possible, of
course, that the VBE has it's own copy of the EDID block, but I don't
know how to search for that. 
quoted
One of the goals is to build a video data structure that also includes a
database of video mode in fb_videomode format.  This can be dynamically
created per device using the supported VESA modes, manufacturer's mode
and detailed timings mode information in the EDID block. The EDID block
also contain information on GTF capability.  With these types of
displays, a video mode mode database may not be needed since all
possible supported modelines can be calculated.

The advantage of the above is that the driver can switch to different
modes without relying on user input (of course, user-entered modelines
are still preferred).
Wow. I'm glad we both think alike. I was thinking the same thing except my 
hands are tied with working on the upper layer stuff. 
quoted
Anyway, I need help in testing the code (especially the Detailed
Information part).  Just apply the attached patch, disable Enhanced Disk
Driver support (under Processor Type and Features), and enable EDID
support (under Graphics option).  Finally, add the following line to the
fbdev driver that you use (anywhere, but a good place is the init code):
Diable Enhanced Disk support :-( I have a few suggestions. One we add a 
pointer to struct screen_info that points to the edid information. We can 
use phys_to_virt to translate that address into virtual memory. I can 
create a patch today and store it in the BK tree. 
You can't.  The EDID block was placed in the "empty_zero_page", the same
page shared by screen_info (and the EDD, apm, etc) at boottime .  This
page will get overwritten later on so an explicit save of the contents
must be done.  And because it's only a page (4086 bytes), there may not
be enough room to squeeze in 128 bytes.  The EDD already requires a
buffer at offset 0x600, and I'm not sure how large is the block.  Of
course, if someone tells me where to squeeze in 128 bytes without
overlapping the others, that is infinitely much better.

Tony



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 21:36:10

On Tue, 2003-03-11 at 23:49, James Simmons wrote:
quoted
Anyway, I need help in testing the code (especially the Detailed
Information part).  Just apply the attached patch, disable Enhanced Disk
Driver support (under Processor Type and Features), and enable EDID
support (under Graphics option).  Finally, add the following line to the
fbdev driver that you use (anywhere, but a good place is the init code):
Diable Enhanced Disk support :-( I have a few suggestions. One we add a 
pointer to struct screen_info that points to the edid information. We can 
use phys_to_virt to translate that address into virtual memory. I can 
create a patch today and store it in the BK tree. 
I think I found a chunk of around 500 bytes between INITRD and EDD, so
we can squeeze in EDID in there :-)  Although I'm confident on this,
I'll feel better if someone who boots with initrd can test it.

Tony



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 21:51:22

On Wed, 2003-03-12 at 05:33, Antonino Daplas wrote:
I think I found a chunk of around 500 bytes between INITRD and EDD, so
we can squeeze in EDID in there :-)  Although I'm confident on this,
I'll feel better if someone who boots with initrd can test it.
Forgot the patch :-)

Tony

diff -Naur linux-2.5.64-fbdev/arch/i386/boot/compressed/misc.c linux-2.5.64/arch/i386/boot/compressed/misc.c
--- linux-2.5.64-fbdev/arch/i386/boot/compressed/misc.c	2003-03-11 21:19:34.000000000 +0000
+++ linux-2.5.64/arch/i386/boot/compressed/misc.c	2003-03-11 21:07:24.000000000 +0000
@@ -91,7 +91,7 @@
 #define ALT_MEM_K   (*(unsigned long *)(real_mode + 0x1e0))
 #endif
 #define SCREEN_INFO (*(struct screen_info *)(real_mode+0))
-#define EDID_INFO   (*(struct edid_info   *)(real_mode+0x600))
+#define EDID_INFO   (*(struct edid_info   *)(real_mode+0x440))
 
 extern char input_data[];
 extern int input_len;
diff -Naur linux-2.5.64-fbdev/arch/i386/boot/video.S linux-2.5.64/arch/i386/boot/video.S
--- linux-2.5.64-fbdev/arch/i386/boot/video.S	2003-03-11 21:19:34.000000000 +0000
+++ linux-2.5.64/arch/i386/boot/video.S	2003-03-11 21:07:24.000000000 +0000
@@ -1888,7 +1888,6 @@
 	popw	%ax
 	ret
 
-#if defined(CONFIG_EDID)
 	store_edid:
 	pushw	%es				# just save all affected 
 	pushw	%ax				# affected registers
@@ -1914,21 +1913,22 @@
 store_edid_magic:	
 	movb	$0x13, %al 
 	movw    $128, %cx
-	movw	$0x600, %di
+	movw	$0x440, %di
 	cld
 	rep 
 	stosb  
 	ret
+#if defined(CONFIG_EDID)
 read_edid:	
 	movw	$0x4f15, %ax
 	movw	$0x01, %bx
 	movw	$0x00, %cx
 	movw    $0x01, %dx
-	movw	$0x600, %di
+	movw	$0x440, %di
 	int	$0x10	
 	ret
 #else
-store_edid:
+read_edid:
 	ret
 #endif
 
diff -Naur linux-2.5.64-fbdev/arch/i386/kernel/setup.c linux-2.5.64/arch/i386/kernel/setup.c
--- linux-2.5.64-fbdev/arch/i386/kernel/setup.c	2003-03-11 21:19:34.000000000 +0000
+++ linux-2.5.64/arch/i386/kernel/setup.c	2003-03-11 21:07:24.000000000 +0000
@@ -496,23 +496,6 @@
 #define copy_edd() do {} while (0)
 #endif
 
-#if defined(CONFIG_EDID)
-/*
- * Since empty_zero_page has a limited size, we are going to use the
- * same offset as EDD.  Thus, copying of the EDID block will only be
- * enabled if EDD is disabled.  
- */
-static inline void copy_edid(void)
-{
-	edid_info = EDID_INFO;
-}
-#else
-static inline void copy_edid(void)
-{
-	memset(&edid_info, 0x13, 128);
-}
-#endif
-
 /*
  * Do NOT EVER look at the BIOS memory size location.
  * It does not work on many machines.
@@ -880,7 +863,7 @@
  	ROOT_DEV = ORIG_ROOT_DEV;
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
-	copy_edid();
+	edid_info = EDID_INFO;
 	apm_info.bios = APM_BIOS_INFO;
 	saved_videomode = VIDEO_MODE;
 	printk("Video mode to be used for restore is %lx\n", saved_videomode);
diff -Naur linux-2.5.64-fbdev/drivers/video/Kconfig linux-2.5.64/drivers/video/Kconfig
--- linux-2.5.64-fbdev/drivers/video/Kconfig	2003-03-11 21:19:34.000000000 +0000
+++ linux-2.5.64/drivers/video/Kconfig	2003-03-11 21:07:47.000000000 +0000
@@ -6,7 +6,7 @@
 
 config EDID
 	bool "Get EDID block from VBE"
-	depends on X86 && !EDD
+	depends on X86
           
 config FB
 	bool "Support for frame buffer devices"
diff -Naur linux-2.5.64-fbdev/include/asm-i386/setup.h linux-2.5.64/include/asm-i386/setup.h
--- linux-2.5.64-fbdev/include/asm-i386/setup.h	2003-03-11 21:19:34.000000000 +0000
+++ linux-2.5.64/include/asm-i386/setup.h	2003-03-11 21:07:25.000000000 +0000
@@ -37,10 +37,10 @@
 #define KERNEL_START (*(unsigned long *) (PARAM+0x214))
 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
+#define EDID_INFO   (*(struct edid_info *) (PARAM+0x440))
+#define EDID_SIZE   128
 #define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
 #define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
-/* Note: EDID_INFO uses the same offset as EDD_BUF */
-#define EDID_INFO   (*(struct edid_info *) (PARAM+EDDBUF))
 #define COMMAND_LINE ((char *) (PARAM+2048))
 #define COMMAND_LINE_SIZE 256
 



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-11 22:05:40

If your in messing with the early boot sequence, why
don't you make the kernel initialize all of the video
cards in the system instead of only the primary one.

Alsom is it really better to continue messing with
these real mode X86 BIOS calls, or would it just be
better to try and extract the info from the card
vendors on how to do reset or get the DDC info? If we
had the info about the cards we could just ignore the
VBIOS and write this code into the protected mode FB
drivers where it belongs. This problem just keeps
recurring over and over on the non-X86 platforms; it's
stupid having to carry around an X86 emulator just to
run the VBIOS code.

Personally I'd like to be able to insmod a fb driver
for a secondary card. If the card needs it, it would
get initialized, read the DDC data, and come up in a
mode that makes sense.

I have a user space program that can reset secondary
cards using their VBIOS and emulating X86 real mode.
It can probably be easily modified to get the DDC info
and then IOCTL it into the fb driver. I'll post it if
you want.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 22:36:29

On Wed, 2003-03-12 at 06:05, Jon Smirl wrote:
If your in messing with the early boot sequence, why
don't you make the kernel initialize all of the video
cards in the system instead of only the primary one.
Because I don't know how to :)?  It basically just involves a far call
no, if we know where the VBIOS code actually starts?  

Note that this will still be arch-specific.  Separate non-primary card
initialization code for each arch is still necessary.
Alsom is it really better to continue messing with
these real mode X86 BIOS calls, or would it just be
better to try and extract the info from the card
vendors on how to do reset or get the DDC info? If we
Initialization can only be done in real mode.  Once the kernel is in
protected mode, BIOS code cannot be run again (without extreme
difficulty), so resetting is out of the question.

Unfortunately, we don't have info from manufacturers, so we rely on some
standards, such as VESA, to do it transparently for us.  Still VESA code
is mostly 16-bit.
had the info about the cards we could just ignore the
VBIOS and write this code into the protected mode FB
drivers where it belongs. This problem just keeps
recurring over and over on the non-X86 platforms; it's
stupid having to carry around an X86 emulator just to
run the VBIOS code.
Again, most BIOS code cannot run in protected mode, so we need to
emulate a real-mode environment for them.  It's doubtful that Linus
would want that in his kernel.  Our only chance to do this is during
early boot, or in user space.
I have a user space program that can reset secondary
cards using their VBIOS and emulating X86 real mode.
It can probably be easily modified to get the DDC info
and then IOCTL it into the fb driver. I'll post it if
you want.
Yes, let me see what I can do.

Tony




-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-11 22:54:08

--- Antonino Daplas <adaplas@pol.net> wrote:
On Wed, 2003-03-12 at 06:05, Jon Smirl wrote:
quoted
If your in messing with the early boot sequence,
why
quoted
don't you make the kernel initialize all of the
video
quoted
cards in the system instead of only the primary
one.

Because I don't know how to :)?  It basically just
involves a far call
no, if we know where the VBIOS code actually starts?
It is more complicated. You need to call the PCI Bios
to find the video cards by their PCI class. There is
already code in the kernel that calls PCIBios.
arch/i386/pci/*

Then you need to one by one map their ROMs (via PCI
config registers) into C000:0 and call C000:3. But as
you swap out the other adapters you need to disable
their VGA emulation as there can only be on VGA device
per system.  By default the VBIOS code will enable VGA
emulation on all of the adapters and they won't. You
also need to record the INT vectors and make sure they
get set back to the primary ones.
Note that this will still be arch-specific. 
Separate non-primary card
initialization code for each arch is still
necessary.
Having X86 work is better than nothing.
Again, most BIOS code cannot run in protected mode,
so we need to
emulate a real-mode environment for them.  It's
doubtful that Linus
would want that in his kernel.  Our only chance to
do this is during
early boot, or in user space.
The right answer is to get the vendors to give us the
info and then write protected mode versions of
reset/DDC into the fb drivers. Until they do this
everything else is a major hack.

It is not possible to enter VM86 mode from a device
driver. Only two choices are: early boot time or as a
user app.  I have to send you the app directly, it is
too big for SF list.

Early boot time may be a better solution. A complete
implementation would reset all video adapters in the
system and record their DDC info for retrieval by the
FB drivers.
Tony
=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-11 23:05:37

On Wed, 2003-03-12 at 06:54, Jon Smirl wrote:
quoted hunk
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
On Wed, 2003-03-12 at 06:05, Jon Smirl wrote:
quoted
If your in messing with the early boot sequence,
why
quoted
don't you make the kernel initialize all of the
video
quoted
cards in the system instead of only the primary
one.

Because I don't know how to :)?  It basically just
involves a far call
no, if we know where the VBIOS code actually starts?
It is more complicated. You need to call the PCI Bios
to find the video cards by their PCI class. There is
already code in the kernel that calls PCIBios.
arch/i386/pci/*

Then you need to one by one map their ROMs (via PCI
config registers) into C000:0 and call C000:3. But as
you swap out the other adapters you need to disable
their VGA emulation as there can only be on VGA device
per system.  By default the VBIOS code will enable VGA
emulation on all of the adapters and they won't. You
also need to record the INT vectors and make sure they
get set back to the primary ones.
Yikes!  No, it can't be done this way.  During the early boot sequence,
the kernel is not yet decompressed and loaded, so all the services the
kernel provides are still unavailable.  Unless you want to walk, detect,
enable, etc the PCI subsystem in pure 16-bit assembly...

Tony



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-11 23:42:50

--- Antonino Daplas <adaplas@pol.net> wrote:
Yikes!  No, it can't be done this way.  During the
early boot sequence,
the kernel is not yet decompressed and loaded, so
all the services the
kernel provides are still unavailable.  Unless you
want to walk, detect,
enable, etc the PCI subsystem in pure 16-bit
assembly...
You don't Linux to look at the PCI subsys you make
calls into the system BIOS to find the devices.
Tony

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-12 17:41:33

On Wed, 2003-03-12 at 07:42, Jon Smirl wrote:
quoted hunk
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
Yikes!  No, it can't be done this way.  During the
early boot sequence,
the kernel is not yet decompressed and loaded, so
all the services the
kernel provides are still unavailable.  Unless you
want to walk, detect,
enable, etc the PCI subsystem in pure 16-bit
assembly...
You don't Linux to look at the PCI subsys you make
calls into the system BIOS to find the devices.
That's not the only reason.  The problem is in 16-bit mode, the code can
only access an address range up to only 1MB.  PCI resources are located
above 16MB.  So in order to copy the ROM, it might be necessary to
switch to 32-bit mode, copy the ROM, switch back to 16-bit mode, etc.

Unless I missed some imported BIOS calls or other methods to do this or
something similar in real-mode...

Tony



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-12 18:16:59

--- Antonino Daplas <adaplas@pol.net> wrote:
Unless I missed some imported BIOS calls or other
methods to do this or
something similar in real-mode...
You missed something. The address of the VBIOS ROM can
be controlled by writing to the PCI config space. You
can make the ROM appear anywhere you want it to.

This happens even for the boot video device. 
Somewhere very early in the boot the system BIOS
enabled the VBIOS ROM and copied it to C000. This is
the "shadow BIOS" option.



=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-12 22:41:24

On Thu, 2003-03-13 at 02:16, Jon Smirl wrote:
quoted hunk
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
Unless I missed some imported BIOS calls or other
methods to do this or
something similar in real-mode...
You missed something. The address of the VBIOS ROM can
be controlled by writing to the PCI config space. You
can make the ROM appear anywhere you want it to.

This happens even for the boot video device. 
Somewhere very early in the boot the system BIOS
enabled the VBIOS ROM and copied it to C000. This is
the "shadow BIOS" option.
So the steps needed would be:

1.  scan for pci devices looking for the vga controller type

2.  if 1 is found other than the primary, disable the current controller

3.  write to PCI config space of secondary controller the address you
want it to appear (ie C000:0000).  Can I use other addresses?

4. enable the controller

5. far call c000:0003

6. disable the controller

7. repeat

Besides the finer points, did I miss anything obvious?

Tony 



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-12 23:36:34

--- Antonino Daplas <adaplas@pol.net> wrote:
1.  scan for pci devices looking for the vga
controller type
BIOS provide this via INT for find-pci-device-by-class
= 3
2.  if 1 is found other than the primary, disable
the current controller
Must disable VGA ports. ROM should already be
disabled. The reset program I sent you had the code
for doing the disable properly. You need to poke some
output ports.

No need to diable primary ROM it is not enabled. C000
is a copy of it.
3.  write to PCI config space of secondary
controller the address you
want it to appear (ie C000:0000).  Can I use other
addresses?
The ROM will need to appear in an address space hole.
Look in your BIOS for where it is leaving a hole in
the 1MB. Map the VBIOS into the hole and then copy it
to C000. The PC has RAM mapped to C000 so you can't
map the ROM there. 

I believe there is a standard place for this hole
probably E000 or A000 but I would need to reboot to
look.
4. enable the controller

5. far call c000:0003
This will set up INTs to work on secondary controller.

Now call INT to get EDID data and stick it somewhere
FB can find it.
6. disable the controller

7. repeat
8) Move the default one back and copy it's ROM back.

You will also need to fix up the INT 10 vectors to
point to the correct entry points for the primary ROM.
The reset code did this too.
Besides the finer points, did I miss anything
obvious?

Tony 

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-12 23:47:58

The system BIOS may not map the ROM into the first 1MB
to copy it. It probably maps it to a high address and
then plays with the X86 memory management to map a
segment register to it. I am having vague
recollections about doing this long ago when I worked
at MS.

I seem to recall there is a real mode instruction that
will force a register like ES to point to a high mode
address.  This is how an ancient EMM driver (remember
the AboveBoard and Lotus 123?) was implemented on a
386 without special hardware.

So you would map the ROM to a high address, map the
segment register to it, copy to C000, restore segment
register and jump to C000:3.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2003-03-13 06:51:47

On 13 Mar 2003, Antonino Daplas wrote:
On Thu, 2003-03-13 at 02:16, Jon Smirl wrote:
quoted
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
Unless I missed some imported BIOS calls or other
methods to do this or
something similar in real-mode...
You missed something. The address of the VBIOS ROM can
be controlled by writing to the PCI config space. You
can make the ROM appear anywhere you want it to.

This happens even for the boot video device. 
Somewhere very early in the boot the system BIOS
enabled the VBIOS ROM and copied it to C000. This is
the "shadow BIOS" option.
So the steps needed would be:

1.  scan for pci devices looking for the vga controller type

2.  if 1 is found other than the primary, disable the current controller

3.  write to PCI config space of secondary controller the address you
want it to appear (ie C000:0000).  Can I use other addresses?

4. enable the controller

5. far call c000:0003

6. disable the controller

7. repeat

Besides the finer points, did I miss anything obvious?
Write a portable x86 emulator for non-ia32 platforms. Besides, you may even
want to use it on ia32 to make it less dependent on BIOS quirks (or for
machines without a PC BIOS).

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-13 15:42:04

--- Geert Uytterhoeven <geert@linux-m68k.org> wrote:
Write a portable x86 emulator for non-ia32
platforms. Besides, you may even
want to use it on ia32 to make it less dependent on
BIOS quirks (or for
machines without a PC BIOS).
Already have one. It's only 300K of code that needs to
be ported/maintained just to call a hundred lines of
code in a ROM. It also has to run in user space and
can't be run in a device driver.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-16 23:03:49

On Thu, 2003-03-13 at 14:50, Geert Uytterhoeven wrote:
On 13 Mar 2003, Antonino Daplas wrote:
quoted
On Thu, 2003-03-13 at 02:16, Jon Smirl wrote:
quoted
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
Unless I missed some imported BIOS calls or other
methods to do this or
something similar in real-mode...
You missed something. The address of the VBIOS ROM can
be controlled by writing to the PCI config space. You
can make the ROM appear anywhere you want it to.

This happens even for the boot video device. 
Somewhere very early in the boot the system BIOS
enabled the VBIOS ROM and copied it to C000. This is
the "shadow BIOS" option.
So the steps needed would be:

1.  scan for pci devices looking for the vga controller type

2.  if 1 is found other than the primary, disable the current controller

3.  write to PCI config space of secondary controller the address you
want it to appear (ie C000:0000).  Can I use other addresses?
I checked the PCI 2.2 specs, and it doesn't have this capability.  It
will give you the address of the expansion ROM, but you still have to
manually copy the ROM and place it in any of the expansion areas. 
Unfortunately for VGA controllers, it's always C000:0000.  

There's a big problem in real mode:

1.  COOO:0000 will be write protected by the BIOS upon initialization of
the first VGA controller.  This will prevent copying of the succeeding
ROMS into that segment (unless you have a BIOS that supports read-write
shadow ROM's).

2.  Real mode does not support paging (ie copy on write tricks will not
work)

quoted
4. enable the controller

5. far call c000:0003

6. disable the controller

7. repeat

Besides the finer points, did I miss anything obvious?
Write a portable x86 emulator for non-ia32 platforms. Besides, you may even
want to use it on ia32 to make it less dependent on BIOS quirks (or for
machines without a PC BIOS).
I read Kendall's thread, and it seems a userspace vm86/vm86emu daemon
might do the job.

Tony



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-17 04:00:51

--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
quoted
3.  write to PCI config space of secondary
controller the address you
quoted
quoted
want it to appear (ie C000:0000).  Can I use
other addresses?

I checked the PCI 2.2 specs, and it doesn't have
this capability.  It
will give you the address of the expansion ROM, but
you still have to
manually copy the ROM and place it in any of the
expansion areas. 
Unfortunately for VGA controllers, it's always
C000:0000.  
You can very definitely move the ROMs to where ever
you want that isn't occupied by something else. I have
written code that does it. Also, the system BIOS must
be moving the ROMs in order to sort things out so that
they don't all appear on top of each other.

You don't even need to move the ROM. Just enable it
and read it's address form PCI space.  The system BIOS
will have sorted the addresses out so that they don't
overlap. PCI config Region 6 is always the ROM see
include/linux/pci.h
1.  COOO:0000 will be write protected by the BIOS
upon initialization of
the first VGA controller.  This will prevent copying
of the succeeding
ROMS into that segment (unless you have a BIOS that
supports read-write
shadow ROM's).
How is C000 write protected? I'm pretty sure that the
ATI ROM are writing to C000.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-17 07:03:38

On Mon, 2003-03-17 at 12:00, Jon Smirl wrote:
quoted hunk
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
quoted
quoted
3.  write to PCI config space of secondary
controller the address you
quoted
quoted
want it to appear (ie C000:0000).  Can I use
other addresses?

I checked the PCI 2.2 specs, and it doesn't have
this capability.  It
will give you the address of the expansion ROM, but
you still have to
manually copy the ROM and place it in any of the
expansion areas. 
Unfortunately for VGA controllers, it's always
C000:0000.  
You can very definitely move the ROMs to where ever
you want that isn't occupied by something else. I have
written code that does it. Also, the system BIOS must
be moving the ROMs in order to sort things out so that
they don't all appear on top of each other.
You're talking about other device's expansion ROM's.  VGA ROM's,
especially for the x86, are an exception and has to be always mapped at
c000:0000.

You don't even need to move the ROM. Just enable it
and read it's address form PCI space.  The system BIOS
will have sorted the addresses out so that they don't
overlap. PCI config Region 6 is always the ROM see
include/linux/pci.h
quoted
1.  COOO:0000 will be write protected by the BIOS
upon initialization of
the first VGA controller.  This will prevent copying
of the succeeding
ROMS into that segment (unless you have a BIOS that
supports read-write
shadow ROM's).
How is C000 write protected? I'm pretty sure that the
ATI ROM are writing to C000.
It is.  C000 is write enabled by the BIOS before init.  Then it calls
the INIT procedure, which adjusts the initialization size before
returning.  Afterwards, the BIOS write-protects the block equivalent to
the initialization size.  Suceeding ROM's will then be mapped after this
block.

Remember, ROM's are supposed to be read-only, so even if they are
shadowed, the BIOS write protects it.

Tony




-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-17 19:33:38

--- Antonino Daplas <adaplas@pol.net> wrote:
You're talking about other device's expansion ROM's.
 VGA ROM's,
especially for the x86, are an exception and has to
be always mapped at
c000:0000.
Reboot and add pci=rom (case sensitive) to your kernel
parameters. That will show you where the video ROMs
are really located.

My x86 PC's boot video ROM is located at dd000000 not
C00000. C00000 is only a copy of the ROM in RAM.

01:00.0 VGA compatible controller: ATI Technologies
Inc Radeon R250 If [Radeon 9
000] (rev 01) (prog-if 00 [VGA])
        Subsystem: C.P. Technology Co. Ltd: Unknown
device 2039
        Flags: stepping, 66Mhz, medium devsel, IRQ 5
        Memory at d0000000 (32-bit, prefetchable)
[disabled] [size=64M]
        I/O ports at c000 [disabled] [size=256]
        Memory at de000000 (32-bit, non-prefetchable)
[disabled] [size=64K]
        Expansion ROM at dd000000 [size=128K]
        Capabilities: [58] AGP version 2.0
        Capabilities: [50] Power Management version 2

The ROM on my other video card is located here:

00:0b.0 VGA compatible controller: ATI Technologies
Inc Rage 128 PD/PRO TMDS (pr
og-if 00 [VGA])
        Subsystem: ATI Technologies Inc Rage 128 AIW
        Flags: bus master, stepping, medium devsel,
latency 32, IRQ 10
        Memory at d8000000 (32-bit, prefetchable)
[size=64M]
        I/O ports at e400 [size=256]
        Memory at df000000 (32-bit, non-prefetchable)
[size=16K]
        Expansion ROM at 20060000 [size=128K]
        Capabilities: [5c] Power Management version 2
Remember, ROM's are supposed to be read-only, so
even if they are
shadowed, the BIOS write protects it.
How is this write protection being achieved? Is it
done via manipulation of the processor descriptor
tables; if so just undo it.


=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-17 21:42:26

On Tue, 2003-03-18 at 03:33, Jon Smirl wrote:
quoted hunk
--- Antonino Daplas <adaplas@pol.net> wrote:
quoted
You're talking about other device's expansion ROM's.
 VGA ROM's,
especially for the x86, are an exception and has to
be always mapped at
c000:0000.
Reboot and add pci=rom (case sensitive) to your kernel
parameters. That will show you where the video ROMs
are really located.

My x86 PC's boot video ROM is located at dd000000 not
C00000. C00000 is only a copy of the ROM in RAM.
That's not the problem.  I can easily grab a copy of the ROM through
extended memory copy, but it cannot just run anywhere.  The VBIOS code
(as with other BIOS code) must run in real mode (address below 1MB) and
VBIOS can only run when at C000:0000 (C000:0000 is in real-mode
segmented addressing, it is C0000 when translated to a linear address). 
Check the definition of DEFAULT_V_BIOS in the code you sent me.
How is this write protection being achieved? Is it
done via manipulation of the processor descriptor
tables; if so just undo it.
Possibly through some BIOS specific thing.  Usually the BIOS places it
somewhere where it cannot be reached, even by the OS.

Tony




-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-17 22:02:16

The VBIOS should be position independent code and it
will run at any 64K boundary. The PC bus spec simply
says the video BIOS defaults to C000, it is not a
requirement that it be located there. For example if
you look at the aty128fb driver's find ROM routine
your will notice that it is searching a broad address
space for the ROM.

I'm still not convinced that the memory at C000 is
really hardware write protected, I think it is just
RAM with a copy of the ROM in it. For example if I
turn off BIOS shadowing my system will not boot. When
debugging this I spent some time tracing into the ATI
ROM and I was pretty sure that they are dependent on
begin copied into RAM before begin run. 

Do you have a DOS floppy around? Just boot into DOS,
start debug and see if you can change C000:0.

If C000:0 is hardware write protected, there is
nothing stopping the ROM from begin copied into 8000:0
or 9000:0 or whatever where there is guaranteed RAM.
We would just need to temporarily get the kernel out
of the way.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-17 22:33:25

On Tue, 2003-03-18 at 06:02, Jon Smirl wrote:
The VBIOS should be position independent code and it
will run at any 64K boundary. The PC bus spec simply
says the video BIOS defaults to C000, it is not a
requirement that it be located there. For example if
you look at the aty128fb driver's find ROM routine
your will notice that it is searching a broad address
space for the ROM.

I'm still not convinced that the memory at C000 is
really hardware write protected, I think it is just
RAM with a copy of the ROM in it. For example if I
turn off BIOS shadowing my system will not boot. When
debugging this I spent some time tracing into the ATI
ROM and I was pretty sure that they are dependent on
begin copied into RAM before begin run. 
    The PC-compatible specific set of steps for the system POST code
    when handling each expansion ROM are:
    
    1. Map and enable the expansion ROM to an unoccupied area of the
    memory address space.
    2. Find the proper image in the ROM and copy it from ROM into the
    compatibility area of RAM (typically 0C0000h to 0DFFFFhh) using the
    number of bytes specified by Initialization Size.
    3. Disable the Expansion ROM Base Address register.
    4. Leave the RAM area writable and call the INIT function.
    5. Use the byte at offset 02h (which may have been modified) to
    determine how much memory is used at runtime.
    
    Before system boot, the POST code must make the RAM area containing
    expansion ROM code read-only.
    
    POST code must handle VGA devices with expansion ROMs in a special
    way.  The VGA device's expansion BIOS must be copied to 0C0000h. 
    VGA devices can be identified by examining the Class Code field in
    the device's Configuration Space.
    
-- pg. 210 PCI Local Bus Specification Revision 2.2 December 18, 1998

Do you have a DOS floppy around? Just boot into DOS,
start debug and see if you can change C000:0.
Yes, it's unchangeable.

Tony




-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-17 23:41:44

The C000 must be a PCI restriction, it was not there
during ISA days.

Plan A: how is C000:0 protected; does the chipset
hardware do it or is it done via the descriptor
tables? Descriptor tables can be fixed but there is
probably no general solution to chipset protection. 

On the other hand, we may be lucky and the PCI spec
has specified a standard way for enabling write
protect. Could there be a BIOS INT xx function for
this?

Plan B is to copy the ROM to something like 8000 or
9000. But the question there is, are VBIOS ROMs still
written to run position independent give the PCI C000
requirement?

Plan C is go into VM86 mode during early boot and
remap the memory.

Plan D would be to get enough info to write the code
in protected mode.

Are there more ways to do this?

I'll go poke around in google and see what I can come
up with. Let me know if you come up with anything.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2003-03-18 09:08:23

On Mon, 17 Mar 2003, Jon Smirl wrote:
Plan B is to copy the ROM to something like 8000 or
9000. But the question there is, are VBIOS ROMs still
written to run position independent give the PCI C000
requirement?
Probably. Some drivers are even compressed, since they don't fit in the ROM.
So they have to be decompressed elsewhere.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds



-------------------------------------------------------
This SF.net email is sponsored by: Does your code think in ink? 
You could win a Tablet PC. Get a free Tablet PC hat just for playing. 
What are you waiting for?
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-18 10:03:39

On Tue, 2003-03-18 at 07:41, Jon Smirl wrote:
The C000 must be a PCI restriction, it was not there
during ISA days.
It's not.  It's IBM defining that VGA ROM should be at segment C000. 
 
Plan A: how is C000:0 protected; does the chipset
hardware do it or is it done via the descriptor
tables? Descriptor tables can be fixed but there is
probably no general solution to chipset protection. 
This is most probably chipset specific.  
On the other hand, we may be lucky and the PCI spec
has specified a standard way for enabling write
protect. Could there be a BIOS INT xx function for
this?
If writable shadow ROM is to be supported, this has to be a specific
implementation by the BIOS vendor.  The standard (well, at least by
Phoenix), does not define any BIOS service to do this.
Plan B is to copy the ROM to something like 8000 or
9000. But the question there is, are VBIOS ROMs still
written to run position independent give the PCI C000
requirement?
It won't run.  I already tried it.
Plan C is go into VM86 mode during early boot and
remap the memory.
That means go to protected mode first, then vm86, since vm86 can only be
entered in protected mode.  Personally, this is too much work.
Plan D would be to get enough info to write the code
in protected mode.
That's one plan.  Emulate real-mode x86 while in real-mode/protected
mode.  However, x86emu requires a bunch of functions to parse and
execute the opcodes.
Are there more ways to do this?

I've thought of 2 more things.  The first is similar to Unreal Mode or
Voodoo mode. This mode was employed by DOS game developers before the
advent of protected mode DOS.  They initialize the GDT to have a segment
limit of 4G, go to protected mode, then immediately switch back to real
mode.  Upon return to real mode, they now have a segment:offset of 16:32
instead of 16:16.  This is real mode with a 4 Gigabyte address limit. 

The variant of what I'm thinking is to do the same thing, but instead of
adjusting the segment limit, adjust the base address of the GDT by an
offset of 1 MB.  Copy the memory contents from 0 - 1 MB and place them
at 1 - 2 MB. Then, go to protected mode and back to real mode. 
Hopefully, if this works, I can now have an address space that starts at
0x100000  (1MB) but would still appear to everyone as starting at 0
effectively bypassing BIOS protection of expansion segments.  

I'm not sure if the above will work though, but should be easy enough to
experiment on. But if anyone knows that it won't work, let me know.

The other one is proposed by Kendall. Let's just have a userspace daemon
that does all BIOS requests.

The second is easy to implement since we already have the tools.  Also,
you can literally request for BIOS services anytime.  Plus, it can even
run on non-x86 using an emulator.

The first may not work at all, and even if it does, will run only once. 
Also, it has to be coded in assembly and though I've done a lot of
assembly before, it takes too long to code.  But it does have the
advantage of initializing adapters before the kernel loads, so we can
have multiple framebuffers loaded at boot time.

I'm still weighing which I should look first into.  The second seems to
be more useful, the first is much more interesting.  

What do you think?

Tony





-------------------------------------------------------
This SF.net email is sponsored by: Does your code think in ink? 
You could win a Tablet PC. Get a free Tablet PC hat just for playing. 
What are you waiting for?
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-18 17:08:02

Here is a description of how to control the shadow
write protect for a SIS chipset. It is done by writing
to PCI config space. There is a slim chance that this
is a standard procedure.

http://www.missl.cs.umd.edu/Projects/sebos/winint/index1.html

When you copied to 8000 ot 9000, did you copy the ROM
or the image at C000? I compared a dump of C000 to the
ROM and they don't match. ATI may have overlaid some
code during the init procedure.

So I guess we are stuck with a user space daemon.
Athlon-64 and IA64 will require the entire VM86
emulator. Last I checked the scitech emulator (ver8)
han't implemented all of the instructions needed to
run the ATI ROMs so it will need some work.

How do the Transmeta tools work? Could we turn the
ROMs into a C program and compile them again? Or use
something like use an emulator to capture the reset
sequence and then compile it for protected mode. 

I tried a couple of reverse engineering tools on the
ROMs but I didn't get very far. I don't have access to
the ATI Radeon documentation so it is hard for me to
tell what is going on.  

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by: Does your code think in ink? 
You could win a Tablet PC. Get a free Tablet PC hat just for playing. 
What are you waiting for?
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en

Re: Reading the EDID block for x86 machines

From: Antonino Daplas <hidden>
Date: 2003-03-19 05:18:54

On Wed, 2003-03-19 at 01:07, Jon Smirl wrote:
Here is a description of how to control the shadow
write protect for a SIS chipset. It is done by writing
to PCI config space. There is a slim chance that this
is a standard procedure.

http://www.missl.cs.umd.edu/Projects/sebos/winint/index1.html
I tried this part, and it doesn't work with the chipset I'm using. 
Plus, PCI config space register 0x70 is device specific, only the first
64 bytes is defined generically.
When you copied to 8000 ot 9000, did you copy the ROM
or the image at C000? I compared a dump of C000 to the
ROM and they don't match. ATI may have overlaid some
code during the init procedure.
I copied the actual ROM (pointed to by Expansion ROM base address 0x30)
and placed it in 0xc000 and 0x8000.  0xc000 of course is write protected
by the BIOS, and it won't run in 0x8000.

Yes, the final BIOS image can be different from the initial image.  Most
of the time, the initial image is larger, or needs decompression.  Some 
of the newer ROM's may even use the POST Memory Manager Specification
(kinda like a POST-specific malloc and family) during INIT, but this is
available only during POST, and memory allocated by the PMM is
unavailable after POST.
So I guess we are stuck with a user space daemon.
Athlon-64 and IA64 will require the entire VM86
emulator. Last I checked the scitech emulator (ver8)
han't implemented all of the instructions needed to
run the ATI ROMs so it will need some work.

How do the Transmeta tools work? Could we turn the
ROMs into a C program and compile them again? Or use
something like use an emulator to capture the reset
sequence and then compile it for protected mode. 
That's another problem.  Some of the BIOS services used during INIT may
become unavailable after POST, so emulating ROM's can either be caused
by this or by an incomplete emulator.
 
I tried a couple of reverse engineering tools on the
ROMs but I didn't get very far. I don't have access to
the ATI Radeon documentation so it is hard for me to
tell what is going on.  
Our best hope is for graphics manufacturer to drop VGA :-) which should
allow for relocatable ROM's and therefore initialization of multiple
graphics adapters.  Second best hope is for manufacturer's to open up
the source for initializing devices without having to initialize the VGA
BIOS. 

Anyway, attached is the code I'm using.  It basically saves the video
state, disables all VGA controllers, disables VGA routing on PCI-PCI
bridges, searches for valid expansion ROM addresss on VGA class devices,
copies it into a scratch segment, verifies the ROM, copies the verified
ROM to 0xc000 and call 0xc000:0003.  Of course, the "copies the verified
ROM to 0xc000" part will fail, so the "call 0xc000:0003" will just
warmboot your primary display again.

You have to place the file in linux/arch/i386/boot

Then in setup.S

add "include detect.S"

and 

call init_video #preferably before or after 'call video'

I'll probably drop effort on this (for now) and concentrate on adding a
userspace daemon.

Tony

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-19 06:07:13

Thanks for making an extreme effort at trying to get
this work. I wish the video card vendors paid
attention to the list so that they would have an idea
of what lengths their customers will take in order to
use their products. It's times like this that made me
abandon the Microsoft world and become a Linux
convert. 

Does anyone have a good ATI contact? Maybe they'll at
least see the light and provide us with the info
needed to avoid a user mode solution for their
hardware. 

I agree that the user mode solution is the easiest
path from here.  V0.6 of the scitech x86emu works to
reset my radeon with a minor tweak - INT 15 needs to
be implement to simply return 1.

I have had no success in getting V0.8 to work but I
didn't try very hard given that V0.6 is working for
me. The emulator hangs on both versions.

Just to report on what I'm doing to keep busy, I have
a full DRI accelerated Mesa running standalone on most
Radeons100-300. The accelerated Mesa uses both DRM and
FB drivers.  I'm in the process of modifying embedded
QT (which contains a window manager) to run on it as
an OpenGL application. The goal is to see if OpenGL
would make an effective alternative platform to X.
There is a lot of code to write before this all works,
contributions welcome.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by: Does your code think in ink? 
You could win a Tablet PC. Get a free Tablet PC hat just for playing. 
What are you waiting for?
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-18 00:00:53

This describes a BIOS INT for controlling the write
protect on the shadow RAM.

http://216.239.33.100/search?q=cache:ekBz42QrBngC:www.digital-logic.de/support/download/Treiber/misc/pcchip/c%26t/INT1F.TXT+shadow+BIOS+write+protect+int&hl=en&ie=UTF-8

Unsure if this is a standard BIOS feature.

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en

Re: Reading the EDID block for x86 machines

From: Jon Smirl <hidden>
Date: 2003-03-11 23:54:01

Check out:

arch/i386/pci/pcbios.c

http://members.datafast.net.au/dft0802/specs/bios21.pdf

=====
Jon Smirl
jonsmirl@yahoo.com

__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - establish your business online
http://webhosting.yahoo.com


-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help