summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Ruppert <info@vruppert.de>2009-01-24 10:02:14 +0000
committerGerd Hoffmann <kraxel@redhat.com>2010-06-18 12:07:26 +0200
commit462b542124d50104d8914f6176f4f1e35604473d (patch)
tree51902f96535eb4e28ca27ededfc8adb47c366d2c
parent6e62666cfc19e7fd45dd0d7c3ad62fd8d0b5f67a (diff)
- use VBE LFB address from PCI base address if present (rewrite of the cirrus specific function in main vgabios code) - removed unnecessary spaces
-rw-r--r--clext.c51
-rw-r--r--vbe.c59
-rw-r--r--vgabios.c58
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