* [Qemu-devel] [PATCH 1/5] - use VBE LFB address from PCI base address if present (rewrite of the cirrus specific function in main vgabios code) - removed unnecessary spaces
2010-06-18 10:37 [Qemu-devel] [PATCH 0/5] update vgabios to v0.6c Gerd Hoffmann
@ 2010-06-18 10:37 ` Gerd Hoffmann
2010-06-18 10:37 ` [Qemu-devel] [PATCH 2/5] - added support for a lot more non-standard VBE modes (e.g. widescreen modes) - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size in 64k pages stored in VBE register) - check if VBE mode is supported with current VRAM size Gerd Hoffmann
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2010-06-18 10:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Volker Ruppert
From: Volker Ruppert <info@vruppert.de>
---
clext.c | 51 ++-------------------------------------------------
vbe.c | 59 ++++++++++++++++++++++++++++++++---------------------------
vgabios.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 92 insertions(+), 76 deletions(-)
diff --git a/clext.c b/clext.c
index c7a2ad0..b0b6834 100644
--- a/clext.c
+++ b/clext.c
@@ -948,7 +948,8 @@ cirrus_vesa_01h_3:
;; 32-bit LFB address
xor ax, ax
stosw
- call cirrus_get_lfb_addr
+ mov ax, #0x1013 ;; vendor Cirrus
+ call _pci_get_lfb_addr
stosw
or ax, ax
jz cirrus_vesa_01h_4
@@ -1293,54 +1294,6 @@ cgm_2:
cgm_3:
ret
- ; get LFB address
- ; out - ax:LFB address (high 16 bit)
- ;; NOTE - may be called in protected mode
-cirrus_get_lfb_addr:
- push cx
- push dx
- push eax
- xor cx, cx
- mov dl, #0x00
- call cirrus_pci_read
- cmp ax, #0xffff
- jz cirrus_get_lfb_addr_5
- cirrus_get_lfb_addr_3:
- mov dl, #0x00
- call cirrus_pci_read
- cmp ax, #0x1013 ;; cirrus
- jz cirrus_get_lfb_addr_4
- add cx, #0x8
- cmp cx, #0x200 ;; search bus #0 and #1
- jb cirrus_get_lfb_addr_3
- cirrus_get_lfb_addr_5:
- xor dx, dx ;; no LFB
- jmp cirrus_get_lfb_addr_6
- cirrus_get_lfb_addr_4:
- mov dl, #0x10 ;; I/O space #0
- call cirrus_pci_read
- test ax, #0xfff1
- jnz cirrus_get_lfb_addr_5
- shr eax, #16
- mov dx, ax ;; LFB address
- cirrus_get_lfb_addr_6:
- pop eax
- mov ax, dx
- pop dx
- pop cx
- ret
-
-cirrus_pci_read:
- mov eax, #0x00800000
- mov ax, cx
- shl eax, #8
- mov al, dl
- mov dx, #0xcf8
- out dx, eax
- add dl, #4
- in eax, dx
- ret
-
;; out - al:bytes per pixel
cirrus_get_bpp_bytes:
push dx
diff --git a/vbe.c b/vbe.c
index 6173ca0..92e3d0d 100644
--- a/vbe.c
+++ b/vbe.c
@@ -766,9 +766,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
Bit16u cur_mode=0;
Bit16u cur_ptr=34;
ModeInfoListItem *cur_info=&mode_info_list;
-
+
status = read_word(ss, AX);
-
+
#ifdef DEBUG
printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status);
#endif
@@ -784,7 +784,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
(vbe_info_block.VbeSignature[1] == 'B') &&
(vbe_info_block.VbeSignature[2] == 'E') &&
(vbe_info_block.VbeSignature[3] == '2')) ||
-
+
((vbe_info_block.VbeSignature[0] == 'V') &&
(vbe_info_block.VbeSignature[1] == 'E') &&
(vbe_info_block.VbeSignature[2] == 'S') &&
@@ -796,20 +796,20 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
#endif
}
#endif
-
+
// VBE Signature
vbe_info_block.VbeSignature[0] = 'V';
vbe_info_block.VbeSignature[1] = 'E';
vbe_info_block.VbeSignature[2] = 'S';
vbe_info_block.VbeSignature[3] = 'A';
-
+
// VBE Version supported
vbe_info_block.VbeVersion = 0x0200;
-
+
// OEM String
vbe_info_block.OemStringPtr_Seg = 0xc000;
vbe_info_block.OemStringPtr_Off = &vbebios_copyright;
-
+
// Capabilities
vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC;
vbe_info_block.Capabilities[1] = 0;
@@ -824,7 +824,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K;
if (vbe2_info)
- {
+ {
// OEM Stuff
vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV;
vbe_info_block.OemVendorNamePtr_Seg = 0xc000;
@@ -837,12 +837,12 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
// copy updates in vbe_info_block back
memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block));
}
- else
- {
+ else
+ {
// copy updates in vbe_info_block back (VBE 1.x compatibility)
memcpyb(ES, DI, ss, &vbe_info_block, 256);
- }
-
+ }
+
do
{
if ((cur_info->info.XResolution <= dispi_get_max_xres()) &&
@@ -860,7 +860,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
}
cur_info++;
} while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST);
-
+
// Add vesa mode list terminator
write_word(ES, DI + cur_ptr, cur_info->mode);
@@ -888,32 +888,37 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
ModeInfoBlock info;
ModeInfoListItem *cur_info;
Boolean using_lfb;
+ Bit16u lfb_addr;
#ifdef DEBUG
printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX);
#endif
using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
-
+
CX = (CX & 0x1ff);
-
+
cur_info = mode_info_find_mode(CX, using_lfb, &cur_info);
if (cur_info != 0)
{
#ifdef DEBUG
printf("VBE found mode %x\n",CX);
-#endif
+#endif
memsetb(ss, &info, 0, sizeof(ModeInfoBlock));
memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact));
if (using_lfb) {
info.NumberOfBanks = 1;
}
+ lfb_addr = pci_get_lfb_addr(0x1234); // experimental vendor
+ if (lfb_addr > 0) {
+ info.PhysBasePtr = ((Bit32u)lfb_addr << 16);
+ }
if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) {
info.WinFuncPtr = 0xC0000000UL;
*(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall);
}
-
+
result = 0x4f;
}
else
@@ -923,7 +928,7 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
#endif
result = 0x100;
}
-
+
if (result == 0x4f)
{
// copy updates in mode_info_block back
@@ -960,21 +965,21 @@ Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
BX = (BX & 0x1ff);
//result=read_word(ss,AX);
-
+
// check for non vesa mode
if (BX<VBE_MODE_VESA_DEFINED)
{
Bit8u mode;
-
+
dispi_set_enable(VBE_DISPI_DISABLED);
// call the vgabios in order to set the video mode
// this allows for going back to textmode with a VBE call (some applications expect that to work)
-
+
mode=(BX & 0xff);
biosfn_set_video_mode(mode);
result = 0x4f;
}
-
+
cur_info = mode_info_find_mode(BX, using_lfb, &cur_info);
if (cur_info != 0)
@@ -986,7 +991,7 @@ Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
cur_info->info.YResolution,
cur_info->info.BitsPerPixel);
#endif
-
+
// first disable current mode (when switching between vesa modi)
dispi_set_enable(VBE_DISPI_DISABLED);
@@ -1005,15 +1010,15 @@ Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX);
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear));
- result = 0x4f;
+ result = 0x4f;
}
else
{
#ifdef DEBUG
printf("VBE *NOT* found mode %x\n" , BX);
-#endif
+#endif
result = 0x100;
-
+
// FIXME: redirect non VBE modi to normal VGA bios operation
// (switch back to VGA mode
if (BX == 3)
@@ -1089,7 +1094,7 @@ void vbe_biosfn_restore_video_state(ES, BX)
enable = read_word(ES, BX);
BX += 2;
-
+
if (!(enable & VBE_DISPI_ENABLED)) {
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
outw(VBE_DISPI_IOPORT_DATA, enable);
diff --git a/vgabios.c b/vgabios.c
index e6fe2a0..fbc3588 100644
--- a/vgabios.c
+++ b/vgabios.c
@@ -3830,6 +3830,64 @@ void printf(s)
}
#endif
+ASM_START
+ ; get LFB address from PCI
+ ; in - ax: PCI device vendor
+ ; out - ax: LFB address (high 16 bit)
+ ;; NOTE - may be called in protected mode
+_pci_get_lfb_addr:
+ push bx
+ push cx
+ push dx
+ push eax
+ mov bx, ax
+ xor cx, cx
+ mov dl, #0x00
+ call pci_read_reg
+ cmp ax, #0xffff
+ jz pci_get_lfb_addr_5
+ pci_get_lfb_addr_3:
+ mov dl, #0x00
+ call pci_read_reg
+ cmp ax, bx ;; check vendor
+ jz pci_get_lfb_addr_4
+ add cx, #0x8
+ cmp cx, #0x200 ;; search bus #0 and #1
+ jb pci_get_lfb_addr_3
+ pci_get_lfb_addr_5:
+ xor dx, dx ;; no LFB
+ jmp pci_get_lfb_addr_6
+ pci_get_lfb_addr_4:
+ mov dl, #0x10 ;; I/O space #0
+ call pci_read_reg
+ test ax, #0xfff1
+ jnz pci_get_lfb_addr_5
+ shr eax, #16
+ mov dx, ax ;; LFB address
+ pci_get_lfb_addr_6:
+ pop eax
+ mov ax, dx
+ pop dx
+ pop cx
+ pop bx
+ ret
+
+ ; read PCI register
+ ; in - cx: device/function
+ ; in - dl: register
+ ; out - eax: value
+pci_read_reg:
+ mov eax, #0x00800000
+ mov ax, cx
+ shl eax, #8
+ mov al, dl
+ mov dx, #0xcf8
+ out dx, eax
+ add dl, #4
+ in eax, dx
+ ret
+ASM_END
+
#ifdef VBE
#include "vbe.c"
#endif
--
1.6.5.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 2/5] - added support for a lot more non-standard VBE modes (e.g. widescreen modes) - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size in 64k pages stored in VBE register) - check if VBE mode is supported with current VRAM size
2010-06-18 10:37 [Qemu-devel] [PATCH 0/5] update vgabios to v0.6c Gerd Hoffmann
2010-06-18 10:37 ` [Qemu-devel] [PATCH 1/5] - use VBE LFB address from PCI base address if present (rewrite of the cirrus specific function in main vgabios code) - removed unnecessary spaces Gerd Hoffmann
@ 2010-06-18 10:37 ` Gerd Hoffmann
2010-06-18 10:37 ` [Qemu-devel] [PATCH 3/5] - preparing for release 0.6c Gerd Hoffmann
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2010-06-18 10:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Volker Ruppert
From: Volker Ruppert <info@vruppert.de>
---
vbe.c | 31 ++++++++++++++++++------
vbe.h | 70 ++++++++++++++++++++++++++++--------------------------
vbetables-gen.c | 43 +++++++++++++++++++++++++--------
3 files changed, 91 insertions(+), 53 deletions(-)
diff --git a/vbe.c b/vbe.c
index 92e3d0d..ecff90d 100644
--- a/vbe.c
+++ b/vbe.c
@@ -38,8 +38,6 @@
#include "vbe.h"
#include "vbetables.h"
-#define VBE_TOTAL_VIDEO_MEMORY_DIV_64K (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB*1024/64)
-
// The current OEM Software Revision of this VBE Bios
#define VBE_OEM_SOFTWARE_REV 0x0002;
@@ -715,7 +713,7 @@ vbe_init:
mov [bx], al
pop bx
pop ds
- mov ax, # VBE_DISPI_ID4
+ mov ax, # VBE_DISPI_ID5
call dispi_set_id
no_vbe_interface:
#if defined(USE_BX_INFO) || defined(DEBUG)
@@ -742,7 +740,19 @@ no_vbe_flag:
mov ds, ax
mov si, #_no_vbebios_info_string
jmp _display_string
-ASM_END
+
+; helper function for memory size calculation
+
+lmulul:
+ and eax, #0x0000FFFF
+ shl ebx, #16
+ or eax, ebx
+ SEG SS
+ mul eax, dword ptr [di]
+ mov ebx, eax
+ shr ebx, #16
+ ret
+ASM_END
/** Function 00h - Return VBE Controller Information
*
@@ -765,6 +775,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
Bit16u vbe2_info;
Bit16u cur_mode=0;
Bit16u cur_ptr=34;
+ Bit16u size_64k;
ModeInfoListItem *cur_info=&mode_info_list;
status = read_word(ss, AX);
@@ -820,8 +831,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
vbe_info_block.VideoModePtr_Seg= ES ;
vbe_info_block.VideoModePtr_Off= DI + 34;
- // VBE Total Memory (in 64b blocks)
- vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K;
+ // VBE Total Memory (in 64k blocks)
+ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
+ vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA);
if (vbe2_info)
{
@@ -845,8 +857,11 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
do
{
+ size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19;
+
if ((cur_info->info.XResolution <= dispi_get_max_xres()) &&
- (cur_info->info.BitsPerPixel <= dispi_get_max_bpp())) {
+ (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) &&
+ (size_64k <= vbe_info_block.TotalMemory)) {
#ifdef DEBUG
printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode);
#endif
@@ -855,7 +870,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
cur_ptr+=2;
} else {
#ifdef DEBUG
- printf("VBE mode %x (xres=%x / bpp=%02x) not supported by display\n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel);
+ printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel);
#endif
}
cur_info++;
diff --git a/vbe.h b/vbe.h
index 60434ac..72cb045 100644
--- a/vbe.h
+++ b/vbe.h
@@ -275,39 +275,41 @@ typedef struct ModeInfoListItem
// like 0xE0000000
- #define VBE_DISPI_BANK_ADDRESS 0xA0000
- #define VBE_DISPI_BANK_SIZE_KB 64
-
- #define VBE_DISPI_MAX_XRES 1024
- #define VBE_DISPI_MAX_YRES 768
-
- #define VBE_DISPI_IOPORT_INDEX 0x01CE
- #define VBE_DISPI_IOPORT_DATA 0x01CF
-
- #define VBE_DISPI_INDEX_ID 0x0
- #define VBE_DISPI_INDEX_XRES 0x1
- #define VBE_DISPI_INDEX_YRES 0x2
- #define VBE_DISPI_INDEX_BPP 0x3
- #define VBE_DISPI_INDEX_ENABLE 0x4
- #define VBE_DISPI_INDEX_BANK 0x5
- #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
- #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
- #define VBE_DISPI_INDEX_X_OFFSET 0x8
- #define VBE_DISPI_INDEX_Y_OFFSET 0x9
-
- #define VBE_DISPI_ID0 0xB0C0
- #define VBE_DISPI_ID1 0xB0C1
- #define VBE_DISPI_ID2 0xB0C2
- #define VBE_DISPI_ID3 0xB0C3
- #define VBE_DISPI_ID4 0xB0C4
-
- #define VBE_DISPI_DISABLED 0x00
- #define VBE_DISPI_ENABLED 0x01
- #define VBE_DISPI_GETCAPS 0x02
- #define VBE_DISPI_8BIT_DAC 0x20
- #define VBE_DISPI_LFB_ENABLED 0x40
- #define VBE_DISPI_NOCLEARMEM 0x80
-
- #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
+ #define VBE_DISPI_BANK_ADDRESS 0xA0000
+ #define VBE_DISPI_BANK_SIZE_KB 64
+
+ #define VBE_DISPI_MAX_XRES 2560
+ #define VBE_DISPI_MAX_YRES 1600
+
+ #define VBE_DISPI_IOPORT_INDEX 0x01CE
+ #define VBE_DISPI_IOPORT_DATA 0x01CF
+
+ #define VBE_DISPI_INDEX_ID 0x0
+ #define VBE_DISPI_INDEX_XRES 0x1
+ #define VBE_DISPI_INDEX_YRES 0x2
+ #define VBE_DISPI_INDEX_BPP 0x3
+ #define VBE_DISPI_INDEX_ENABLE 0x4
+ #define VBE_DISPI_INDEX_BANK 0x5
+ #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+ #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+ #define VBE_DISPI_INDEX_X_OFFSET 0x8
+ #define VBE_DISPI_INDEX_Y_OFFSET 0x9
+ #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
+
+ #define VBE_DISPI_ID0 0xB0C0
+ #define VBE_DISPI_ID1 0xB0C1
+ #define VBE_DISPI_ID2 0xB0C2
+ #define VBE_DISPI_ID3 0xB0C3
+ #define VBE_DISPI_ID4 0xB0C4
+ #define VBE_DISPI_ID5 0xB0C5
+
+ #define VBE_DISPI_DISABLED 0x00
+ #define VBE_DISPI_ENABLED 0x01
+ #define VBE_DISPI_GETCAPS 0x02
+ #define VBE_DISPI_8BIT_DAC 0x20
+ #define VBE_DISPI_LFB_ENABLED 0x40
+ #define VBE_DISPI_NOCLEARMEM 0x80
+
+ #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
#endif
diff --git a/vbetables-gen.c b/vbetables-gen.c
index 7014a16..550935a 100644
--- a/vbetables-gen.c
+++ b/vbetables-gen.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <stdio.h>
-#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8
+#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16
typedef struct {
int width;
@@ -41,20 +41,41 @@ ModeInfo modes[] = {
{ 1600, 1200, 16 , 0x11E},
{ 1600, 1200, 24 , 0x11F},
- /* BOCHS/PLE, 86 'own' mode numbers */
-{ 320, 200, 32 , 0x140},
-{ 640, 400, 32 , 0x141},
-{ 640, 480, 32 , 0x142},
-{ 800, 600, 32 , 0x143},
-{ 1024, 768, 32 , 0x144},
-{ 1280, 1024, 32 , 0x145},
-{ 320, 200, 8 , 0x146},
-{ 1600, 1200, 32 , 0x147},
-{ 1152, 864, 8 , 0x148},
+ /* BOCHS/PLEX86 'own' mode numbers */
+{ 320, 200, 32 , 0x140},
+{ 640, 400, 32 , 0x141},
+{ 640, 480, 32 , 0x142},
+{ 800, 600, 32 , 0x143},
+{ 1024, 768, 32 , 0x144},
+{ 1280, 1024, 32 , 0x145},
+{ 320, 200, 8 , 0x146},
+{ 1600, 1200, 32 , 0x147},
+{ 1152, 864, 8 , 0x148},
{ 1152, 864, 15 , 0x149},
{ 1152, 864, 16 , 0x14a},
{ 1152, 864, 24 , 0x14b},
{ 1152, 864, 32 , 0x14c},
+{ 1280, 800, 16 , 0x178},
+{ 1280, 800, 24 , 0x179},
+{ 1280, 800, 32 , 0x17a},
+{ 1280, 960, 16 , 0x17b},
+{ 1280, 960, 24 , 0x17c},
+{ 1280, 960, 32 , 0x17d},
+{ 1440, 900, 16 , 0x17e},
+{ 1440, 900, 24 , 0x17f},
+{ 1440, 900, 32 , 0x180},
+{ 1400, 1050, 16 , 0x181},
+{ 1400, 1050, 24 , 0x182},
+{ 1400, 1050, 32 , 0x183},
+{ 1680, 1050, 16 , 0x184},
+{ 1680, 1050, 24 , 0x185},
+{ 1680, 1050, 32 , 0x186},
+{ 1920, 1200, 16 , 0x187},
+{ 1920, 1200, 24 , 0x188},
+{ 1920, 1200, 32 , 0x189},
+{ 2560, 1600, 16 , 0x18a},
+{ 2560, 1600, 24 , 0x18b},
+{ 2560, 1600, 32 , 0x18c},
{ 0, },
};
--
1.6.5.2
^ permalink raw reply related [flat|nested] 6+ messages in thread