X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FDisplay%2FBochsGA%2Fbochsvbe.c;h=58a024f96f9dae93b91ecc44078d8ea2a73c1e19;hb=de37bdfbcd4814c20babda4a7198736bf0effd3e;hp=4b76c22309a92eb1391a6885ddadcd77cdea5344;hpb=156885e938b60fee9d061d989ae7711c9aeea493;p=tpg%2Facess2.git diff --git a/Modules/Display/BochsGA/bochsvbe.c b/Modules/Display/BochsGA/bochsvbe.c index 4b76c223..58a024f9 100644 --- a/Modules/Display/BochsGA/bochsvbe.c +++ b/Modules/Display/BochsGA/bochsvbe.c @@ -1,33 +1,30 @@ /** - * \file drv_bochsvbe.c - * \brief BGA (Bochs Graphic Adapter) Driver - * \note for Acess2 - * \warning This driver does NOT support the Bochs PCI VGA driver -*/ + * Acess2 Bochs graphics adapter Driver + * - By John Hodge (thePowersGang) + * + * bochsvbe.c + * - Driver core + */ #define DEBUG 0 +#define VERSION VER2(0,10) + #include #include #include #include #include #include -#include - -#define INT +#include -// === TYPEDEFS === -typedef struct { +// === TYPES === +typedef struct sBGA_Mode { Uint16 width; Uint16 height; Uint16 bpp; - Uint16 flags; Uint32 fbSize; -} t_bga_mode; +} tBGA_Mode; // === CONSTANTS === -enum eMode_Flags { - MODEFLAG_TEXT = 1 -}; #define BGA_LFB_MAXSIZE (1024*768*4) #define VBE_DISPI_BANK_ADDRESS 0xA0000 #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 @@ -50,6 +47,7 @@ enum { VBE_DISPI_INDEX_Y_OFFSET }; +extern void MM_DumpTables(tVAddr Start, tVAddr End); // === PROTOTYPES === // Driver @@ -65,34 +63,31 @@ void BGA_int_SetMode(Uint16 width, Uint16 height); int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info); int BGA_int_MapFB(void *Dest); // Filesystem -Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer); -Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer); - int BGA_Ioctl(tVFS_Node *node, int id, void *data); +Uint64 BGA_Read(tVFS_Node *Node, Uint64 off, Uint64 len, void *buffer); +Uint64 BGA_Write(tVFS_Node *Node, Uint64 off, Uint64 len, void *buffer); + int BGA_IOCtl(tVFS_Node *Node, int ID, void *Data); // === GLOBALS === -MODULE_DEFINE(0, 0x0032, BochsGA, BGA_Install, NULL, NULL); +MODULE_DEFINE(0, VERSION, BochsGA, BGA_Install, NULL, "PCI", NULL); tDevFS_Driver gBGA_DriverStruct = { NULL, "BochsGA", { .Read = BGA_Read, .Write = BGA_Write, - .IOCtl = BGA_Ioctl + .IOCtl = BGA_IOCtl } }; int giBGA_CurrentMode = -1; tVideo_IOCtl_Pos gBGA_CursorPos = {-1,-1}; - int giBGA_DriverId = -1; Uint *gBGA_Framebuffer; -t_bga_mode gBGA_Modes[] = { - {}, - { 80,25, 12, MODEFLAG_TEXT, 80*25*8}, // 640 x 480 - {100,37, 12, MODEFLAG_TEXT, 100*37*8}, // 800 x 600 - {640,480,8, 0, 640*480}, - {640,480,32, 0, 640*480*4}, - {800,600,8, 0, 800*600}, - {800,600,32, 0, 800*600*4}, +const tBGA_Mode *gpBGA_CurrentMode; +const tBGA_Mode gBGA_Modes[] = { + {640,480,32, 640*480*4}, + {800,600,32, 800*600*4}, + {1024,768,32, 1024*768*4} }; #define BGA_MODE_COUNT (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0])) +tDrvUtil_Video_BufInfo gBGA_DrvUtil_BufInfo; // === CODE === /** @@ -100,36 +95,48 @@ t_bga_mode gBGA_Modes[] = { */ int BGA_Install(char **Arguments) { - int bga_version = 0; + int version = 0; + tPAddr base; + tPCIDev dev; // Check BGA Version - bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID); - // NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable - if(bga_version < 0xB0C4 || bga_version > 0xB0C5) { - Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version); + version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID); + LOG("version = 0x%x", version); + + // NOTE: This driver was written for BGA versions >= 0xBOC2 + // NOTE: However, Qemu is braindead and doesn't return the actual version + if( version != 0xB0C0 && ((version & 0xFFF0) != 0xB0C0 || version < 0xB0C2) ) { + Log_Warning("BGA", "Bochs Adapter Version is not compatible (need >= 0xB0C2), instead 0x%x", version); return MODULE_ERR_NOTNEEDED; } - + + // Get framebuffer base + dev = PCI_GetDevice(0x1234, 0x1111, 0); + if(dev == -1) + base = VBE_DISPI_LFB_PHYSICAL_ADDRESS; + else + base = PCI_GetBAR(dev, 0); + + // Map Framebuffer to hardware address + gBGA_Framebuffer = (void *) MM_MapHWPages(base, 768); // 768 pages (3Mb) + // Install Device - giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct ); - if(giBGA_DriverId == -1) { - Warning("[BGA ] Unable to register with DevFS, maybe already loaded?"); + if( DevFS_AddDevice( &gBGA_DriverStruct ) == -1 ) + { + Log_Warning("BGA", "Unable to register with DevFS, maybe already loaded?"); return MODULE_ERR_MISC; } - - // Map Framebuffer to hardware address - gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768); // 768 pages (3Mb) - + return MODULE_ERR_OK; } /** - * \fn void BGA_Uninstall() + * \brief Clean up driver resources before destruction */ -void BGA_Uninstall() +void BGA_Uninstall(void) { - //DevFS_DelDevice( giBGA_DriverId ); - MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 ); + DevFS_DelDevice( &gBGA_DriverStruct ); + MM_UnmapHWPages( (tVAddr)gBGA_Framebuffer, 768 ); } /** @@ -142,7 +149,7 @@ Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer) if(giBGA_CurrentMode == -1) return -1; // Check Offset and Length against Framebuffer Size - if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize) + if(off+len > gpBGA_CurrentMode->fbSize) return -1; // Copy from Framebuffer @@ -151,109 +158,30 @@ Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer) } /** - * \fn Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer) * \brief Write to the framebuffer */ -Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *Buffer) -{ - ENTER("xoff xlen", off, len); - - // Check Mode - if(giBGA_CurrentMode == -1) { - LEAVE('i', -1); - return -1; - } - - // Check Input against Frambuffer Size - if(off + len > gBGA_Modes[giBGA_CurrentMode].fbSize) { - LEAVE('i', -1); - return -1; - } - - // Text Mode - if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT ) - { - tVT_Char *chars = Buffer; - int pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth; - int x, y; - Uint32 *dest; - - off /= sizeof(tVT_Char); - dest = (void*)gBGA_Framebuffer; - x = (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth; - y = (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight; - dest += y * pitch; - dest += x * giVT_CharWidth; - len /= sizeof(tVT_Char); - while(len--) - { - VT_Font_Render( - chars->Ch, - dest, pitch, - VT_Colour12to24(chars->BGCol), - VT_Colour12to24(chars->FGCol) - ); - - dest += giVT_CharWidth; - - chars ++; - x += giVT_CharWidth; - if( x >= pitch ) { - x = 0; - y += giVT_CharHeight; - dest += pitch*(giVT_CharHeight-1); - } - } - } - else - { - Uint8 *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off); - - Log("buffer = %p", Buffer); - Log("Updating Framebuffer (%p to %p)", - destBuf, destBuf + (Uint)len); - - - // Copy to Frambuffer - memcpy(destBuf, Buffer, len); - - Log("BGA Framebuffer updated"); - } - - LEAVE('i', len); - return len; +Uint64 BGA_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + if( giBGA_CurrentMode == -1 ) BGA_int_UpdateMode(0); + return DrvUtil_Video_WriteLFB(&gBGA_DrvUtil_BufInfo, Offset, Length, Buffer); } +const char *csaBGA_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL}; /** - * \fn INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data) * \brief Handle messages to the device */ -INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data) +int BGA_IOCtl(tVFS_Node *Node, int ID, void *Data) { int ret = -2; - ENTER("pNode iId pData", node, ID, Data); + ENTER("pNode iId pData", Node, ID, Data); switch(ID) { - case DRV_IOCTL_TYPE: - ret = DRV_TYPE_VIDEO; - break; - case DRV_IOCTL_IDENT: - memcpy(Data, "BGA1", 4); - ret = 1; - break; - case DRV_IOCTL_VERSION: - ret = 0x100; - break; - case DRV_IOCTL_LOOKUP: // TODO: Implement - ret = 0; - break; - + BASE_IOCTLS(DRV_TYPE_VIDEO, "BochsGA", VERSION, csaBGA_IOCtls); + case VIDEO_IOCTL_GETSETMODE: - if( Data ) - ret = BGA_int_UpdateMode(*(int*)(Data)); - else - ret = giBGA_CurrentMode; + if( Data ) BGA_int_UpdateMode(*(int*)(Data)); + ret = giBGA_CurrentMode; break; case VIDEO_IOCTL_FINDMODE: @@ -264,14 +192,30 @@ INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data) ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)Data); break; - // Request Access to LFB - case VIDEO_IOCTL_REQLFB: - ret = BGA_int_MapFB( *(void**)Data ); + case VIDEO_IOCTL_SETBUFFORMAT: + DrvUtil_Video_RemoveCursor( &gBGA_DrvUtil_BufInfo ); + ret = gBGA_DrvUtil_BufInfo.BufferFormat; + if(Data) + gBGA_DrvUtil_BufInfo.BufferFormat = *(int*)Data; + if(gBGA_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT) + DrvUtil_Video_SetCursor( &gBGA_DrvUtil_BufInfo, &gDrvUtil_TextModeCursor ); break; case VIDEO_IOCTL_SETCURSOR: + DrvUtil_Video_RemoveCursor( &gBGA_DrvUtil_BufInfo ); gBGA_CursorPos.x = ((tVideo_IOCtl_Pos*)Data)->x; gBGA_CursorPos.y = ((tVideo_IOCtl_Pos*)Data)->y; + if(gBGA_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT) + DrvUtil_Video_DrawCursor( + &gBGA_DrvUtil_BufInfo, + gBGA_CursorPos.x*giVT_CharWidth, + gBGA_CursorPos.y*giVT_CharHeight + ); + else + DrvUtil_Video_DrawCursor( + &gBGA_DrvUtil_BufInfo, + gBGA_CursorPos.x, gBGA_CursorPos.y + ); break; default: @@ -285,7 +229,6 @@ INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data) //== Internal Functions == /** - * \fn void BGA_int_WriteRegister(Uint16 reg, Uint16 value) * \brief Writes to a BGA register */ void BGA_int_WriteRegister(Uint16 reg, Uint16 value) @@ -294,32 +237,23 @@ void BGA_int_WriteRegister(Uint16 reg, Uint16 value) outw(VBE_DISPI_IOPORT_DATA, value); } -INT Uint16 BGA_int_ReadRegister(Uint16 reg) +Uint16 BGA_int_ReadRegister(Uint16 reg) { outw(VBE_DISPI_IOPORT_INDEX, reg); return inw(VBE_DISPI_IOPORT_DATA); } -#if 0 -INT void BGA_int_SetBank(Uint16 bank) -{ - BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank); -} -#endif - /** - * \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp) - * \brief Sets the video mode from the dimensions and bpp given + * \brief Sets the video mode (32bpp only) */ -void BGA_int_SetMode(Uint16 width, Uint16 height) +void BGA_int_SetMode(Uint16 Width, Uint16 Height) { - ENTER("iwidth iheight ibpp", width, height, bpp); + ENTER("iWidth iHeight", Width, Height); BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED); - BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES, width); - BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES, height); - BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32); - BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED); - //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM); + BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES, Width); + BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES, Height); + BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32); + BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED); LEAVE('-'); } @@ -332,17 +266,18 @@ int BGA_int_UpdateMode(int id) // Sanity Check if(id < 0 || id >= BGA_MODE_COUNT) return -1; - // Check if it is a text mode - if( gBGA_Modes[id].flags & MODEFLAG_TEXT ) - BGA_int_SetMode( - gBGA_Modes[id].width*giVT_CharWidth, - gBGA_Modes[id].height*giVT_CharHeight); - else // Graphics? - BGA_int_SetMode( - gBGA_Modes[id].width, - gBGA_Modes[id].height); + BGA_int_SetMode( + gBGA_Modes[id].width, + gBGA_Modes[id].height); + gBGA_DrvUtil_BufInfo.Framebuffer = gBGA_Framebuffer; + gBGA_DrvUtil_BufInfo.Pitch = gBGA_Modes[id].width * 4; + gBGA_DrvUtil_BufInfo.Width = gBGA_Modes[id].width; + gBGA_DrvUtil_BufInfo.Height = gBGA_Modes[id].height; + gBGA_DrvUtil_BufInfo.Depth = gBGA_Modes[id].bpp; + giBGA_CurrentMode = id; + gpBGA_CurrentMode = &gBGA_Modes[id]; return id; } @@ -354,8 +289,8 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info) { int i; int best = 0, bestFactor = 1000; - int factor, tmp; - int rqdProduct = info->width * info->height * info->bpp; + int tmp; + int rqdProduct = info->width * info->height; ENTER("pinfo", info); LOG("info = {width:%i,height:%i,bpp:%i})\n", info->width, info->height, info->bpp); @@ -363,38 +298,34 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info) for(i = 0; i < BGA_MODE_COUNT; i++) { #if DEBUG >= 2 - LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp); + LOG("Mode %i (%ix%i,%ibpp), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp); #endif - - // Check if this mode is the same type as what we want - if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) ) - continue; + + if( gBGA_Modes[i].bpp != info->bpp ) + continue ; // Ooh! A perfect match - if(gBGA_Modes[i].width == info->width - && gBGA_Modes[i].height == info->height - && gBGA_Modes[i].bpp == info->bpp) + if(gBGA_Modes[i].width == info->width && gBGA_Modes[i].height == info->height) { #if DEBUG >= 2 - LogF("Perfect!\n"); + LOG("Perfect"); #endif best = i; break; } - + + // If not, how close are we? - tmp = gBGA_Modes[i].width * gBGA_Modes[i].height * gBGA_Modes[i].bpp; - tmp -= rqdProduct; + tmp = gBGA_Modes[i].width * gBGA_Modes[i].height - rqdProduct; tmp = tmp < 0 ? -tmp : tmp; // tmp = ABS(tmp) - factor = tmp * 100 / rqdProduct; #if DEBUG >= 2 - LogF("factor = %i\n", factor); + LOG("tmp = %i", tmp); #endif - if(factor < bestFactor) + if(tmp < bestFactor) { - bestFactor = factor; + bestFactor = tmp; best = i; } } @@ -403,11 +334,8 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info) info->width = gBGA_Modes[best].width; info->height = gBGA_Modes[best].height; info->bpp = gBGA_Modes[best].bpp; - - info->flags = 0; - if(gBGA_Modes[best].flags & MODEFLAG_TEXT) - info->flags |= VIDEO_FLAG_TEXT; - + + LEAVE('i', best); return best; } @@ -428,40 +356,6 @@ int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info) info->height = gBGA_Modes[info->id].height; info->bpp = gBGA_Modes[info->id].bpp; - info->flags = 0; - if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT) - info->flags |= VIDEO_FLAG_TEXT; - return 1; } -/** - * \fn int BGA_int_MapFB(void *Dest) - * \brief Map the framebuffer into a process's space - * \param Dest User address to load to - */ -int BGA_int_MapFB(void *Dest) -{ - Uint i; - Uint pages; - - // Sanity Check - if((Uint)Dest > 0xC0000000) return 0; - if(gBGA_Modes[giBGA_CurrentMode].bpp < 15) return 0; // Only non-pallete modes are supported - - // Count required pages - pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12; - - // Check if there is space - for( i = 0; i < pages; i++ ) - { - if(MM_GetPhysAddr( (Uint)Dest + (i << 12) )) - return 0; - } - - // Map - for( i = 0; i < pages; i++ ) - MM_Map( (Uint)Dest + (i<<12), VBE_DISPI_LFB_PHYSICAL_ADDRESS + (i<<12) ); - - return 1; -}