rendered paste body/* * Autor: Leonardo M. (gnomo86 at gmail.com) * http://projeto-sombra.org */#include <system.h>#include <kernel.h>#include <x86/page.h>#include PCI_H#include <bga.h>//http://tldp.org/LDP/tlk/dd/pci.html//http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.0.html//http://www.pcisig.com/reflector/msg03001.html//http://www.pcisig.com/reflector/msg03002.htmlunsigned fb_seg, banked, banks, line_size, bank_offset[36];//, bank_max_y[36];static unsigned char* vga_mem;unsigned depth_max, width_max, height_max, curr_BPP, curr_Width, curr_Height;void SetVideoMode(unsigned short width, unsigned short height, unsigned short depth, unsigned char LFB);void ExitVideoMode();void BgaWriteCommand(unsigned short index, unsigned short value);unsigned short BgaReadData(unsigned short index);void BgaPutPixel_dummy(unsigned x, unsigned y, unsigned color) {};void BgaPutPixel8_banked(unsigned x, unsigned y, unsigned color);void BgaPutPixel16_banked(unsigned x, unsigned y, unsigned color);void BgaPutPixel24_banked(unsigned x, unsigned y, unsigned color);void BgaPutPixel32_banked(unsigned x, unsigned y, unsigned color);void BgaPutPixel8_lfb(unsigned x, unsigned y, unsigned color);void BgaPutPixel16_lfb(unsigned x, unsigned y, unsigned color);void BgaPutPixel24_lfb(unsigned x, unsigned y, unsigned color);void BgaPutPixel32_lfb(unsigned x, unsigned y, unsigned color);void BgaConfigure(unsigned force_banked){ unsigned i, version, tmp; pci_device_t* pci; printf("BGA Video Driver v0.1b:"); BgaPutPixel = BgaPutPixel_dummy; fb_seg = 0; banked = 1; version = BgaReadData(VBE_DISPI_INDEX_ID); if(version == 0xFFFF) { printf(" nao presente.\n"); return; } printf("\n\tVersao BGA: 0x%X\n", version); switch(version) { case 0xB0C0: // apenas 8bpp e Banked Memory. :( case 0xB0C1: fb_seg = 0xA0000; depth_max = 8; width_max = 1024; height_max = 768; banked = 1; printf("\tMemoria de Video @ 0x%08X (64KB banked)\n", fb_seg); break; case 0xB0C5: case 0xB0C4: // 8 MB de memoria de video // TODO case 0xB0C3: // 8-bit DAC // TODO case 0xB0C2: // 15bpp, 16bpp, 24bpp and 32bpp VBE Suportados + LFB depth_max = 32; width_max = 1024; height_max = 768; banked = 0; // procura por dispositivo de video PCI. pci = (pci_device_t*)malloc(sizeof(pci_device_t)); for( i=0; i < pci_getmax(); i++) { if(pci_setdevice(pci,i)) { panic("Estrutura PCI inconsistente! :(\n"); return; // Aborte!! (se puder mhuahahaha) } if( (pci->vend == 0x1234) && (pci->dev == 0x1111) ) // identifica dispositivo BGA { printf("\tVBE Bochs @ PCI[%i:%i.%i]\n", pci->bus, pci->unit, pci->func); //fb_seg = pci_read(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x10)); // endereço da memória de video //fb_seg &= 0xFFFFFFF0; // quantidade de memoria necessaria para alocar. pci_write(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x10), 0xFFFFFFFF); tmp = pci_read(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x10)); tmp &= 0xFFFFFFF0; tmp = ~tmp; tmp++; // indica memoria de video no endereço fisico 0x1000000 pci_write(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x10), 0x1000000 | 2); //printf("0x%08X\n", pci_read(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x10))); fb_seg = 0x1000000; // ativa acesso à memoria de video pci_write(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x4), pci_read(PCI_ADDRESS_REG(pci->bus, pci->unit, pci->func, 0x4)) | 2 ); if(!fb_seg) { fb_seg = 0xE0000000; printf("ATENCAO: PCI BAR possue valor nulo, assumindo valor padrao de endereco de memoria!\n"); } //page_map((void*)fb_seg, (void*)fb_seg+tmp);//(depth_max/8)*width_max*height_max); /* mapeamento das páginas */ int pagesneed = tmp / 4096, map; for (map = 0; map < pagesneed; map++) page_map_phys((unsigned*)(fb_seg + (map * 4096))); printf("\tMemoria de Video @ 0x%08X (%iKB)\n", fb_seg, tmp >> 10); break; } } free(pci); break; default: printf("Versao BGA estranha. (nova versao?)\n"); return; } if(!fb_seg) { printf("\tVBE Bochs @ ISA Bus\n"); fb_seg = 0xE0000000; page_map((void*)fb_seg, (void*)fb_seg+(depth_max/8)*width_max*height_max); printf("\tMemoria de Video @ 0x%08X\n", fb_seg); } if(force_banked) { fb_seg = VBE_DISPI_BANK_ADDRESS; banked = 1; } vga_mem = (unsigned char*)fb_seg;}unsigned BgaGetFB(){ return fb_seg;}unsigned BgaDisplayBPP(){ return curr_BPP;}unsigned BgaDisplayWidth(){ return curr_Width;}unsigned BgaDisplayHeight(){ return curr_Height;}char BgaSetMode(unsigned short width, unsigned short height, unsigned short depth){ void BgaModeNotSuported() { printf("[BGA Driver]: resolucao de video nao suportada! (%ix%ix%ibpp)\n", width, height, depth); } unsigned i; if( (width>width_max) || (height>height_max) || (depth>depth_max) ) { BgaModeNotSuported(); return 0; // nada acontece! } switch(width) { case 1024: case 800: case 640: case 400: case 320: break; default: BgaModeNotSuported(); return 0; // nada acontece. } switch(height) { case 768: case 600: case 480: case 300: case 240: break; default: BgaModeNotSuported(); return 0; // nada acontece. } switch(depth) { case 32: // printf("Usando funcao: %s()\n", (banked) ? "BgaPutPixel32_banked" : "BgaPutPixel32_lfb"); BgaPutPixel = (banked) ? BgaPutPixel32_banked : BgaPutPixel32_lfb; break; case 24: // printf("Usando funcao: %s()\n", (banked) ? "BgaPutPixel24_banked" : "BgaPutPixel24_lfb"); BgaPutPixel = (banked) ? BgaPutPixel24_banked : BgaPutPixel24_lfb; break; case 16: BgaPutPixel = (banked) ? BgaPutPixel16_banked : BgaPutPixel16_lfb; break; case 8: BgaPutPixel = (banked) ? BgaPutPixel8_banked : BgaPutPixel8_lfb; break; default: BgaModeNotSuported(); return 0; // nada acontece. } line_size = width*(depth>>3); curr_BPP = depth; curr_Width = width; curr_Height = height; if(banked) { banks = (width*height*(depth>>3)) / (VBE_DISPI_BANK_SIZE_KB*1024); if( (width*height*(depth>>3)) % (VBE_DISPI_BANK_SIZE) ) banks++; for( i=0; i<banks; i++) { bank_offset[i] = i*VBE_DISPI_BANK_SIZE;//((i*VBE_DISPI_BANK_SIZE)%line_size)/(depth>>3); // bank_max_y[i] = (i*VBE_DISPI_BANK_SIZE)/line_size; } } SetVideoMode(width,height,depth,banked); return 1;}void BgaExit(){ curr_BPP = curr_Width = curr_Height = 0; BgaPutPixel = BgaPutPixel_dummy; ExitVideoMode();}void SetVideoMode(unsigned short width, unsigned short height, unsigned short depth, unsigned char banked){ BgaWriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED); BgaWriteCommand(VBE_DISPI_INDEX_XRES, width); BgaWriteCommand(VBE_DISPI_INDEX_YRES, height); BgaWriteCommand(VBE_DISPI_INDEX_BPP, depth); BgaWriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | ((banked == 0) ? VBE_DISPI_LFB_ENABLED : 0));// | VBE_DISPI_NOCLEARMEM); outportb(0x3C0, 0x20);}void ExitVideoMode(){ BgaWriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED); }unsigned short BgaReadData(unsigned short index){ outportw(VBE_DISPI_IOPORT_INDEX, index); return inportw(VBE_DISPI_IOPORT_DATA);}void BgaWriteCommand(unsigned short index, unsigned short value){ outportw(VBE_DISPI_IOPORT_INDEX, index); outportw(VBE_DISPI_IOPORT_DATA, value);} void BgaFill(unsigned color){ unsigned i,j; for(i=0; i<curr_Height; i++) for(j=0; j<curr_Width; j++) BgaPutPixel(j,i,color);}void BgaPutPixel8_banked(unsigned x, unsigned y, unsigned color){ unsigned bank, tmp; tmp = (y*line_size+x); bank = (unsigned)(tmp >> 16/*/VBE_DISPI_BANK_SIZE*/); BgaWriteCommand(VBE_DISPI_INDEX_BANK, bank & 0xFF); ((unsigned char*)fb_seg)[tmp-bank_offset[bank]] = color;}void BgaPutPixel16_banked(unsigned x, unsigned y, unsigned color){ unsigned bank, tmp; tmp = (y*line_size+x*2); bank = (unsigned)(tmp >> 16); BgaWriteCommand(VBE_DISPI_INDEX_BANK, bank & 0xFF); ((unsigned short*)fb_seg)[(tmp-bank_offset[bank])>>1] = (unsigned short)(color & 0xFFFF);}void BgaPutPixel24_banked(unsigned x, unsigned y, unsigned color){ unsigned bank, tmp; tmp = (y*line_size+x*3); bank = (unsigned)(tmp >> 16); BgaWriteCommand(VBE_DISPI_INDEX_BANK, bank & 0xFF); ((unsigned char*)fb_seg)[tmp-bank_offset[bank]] = color; ((unsigned char*)fb_seg)[tmp-bank_offset[bank]+1] = (color>>8); ((unsigned char*)fb_seg)[tmp-bank_offset[bank]+2] = (color>>16);}void BgaPutPixel32_banked(unsigned x, unsigned y, unsigned color){ unsigned bank, tmp; tmp = (y*line_size+x*4); bank = (unsigned)(tmp >> 16); BgaWriteCommand(VBE_DISPI_INDEX_BANK, bank & 0xFF); ((unsigned*)fb_seg)[(tmp-bank_offset[bank])>>2] = color;}void BgaPutPixel8_lfb(unsigned x, unsigned y, unsigned color){ vga_mem[y*curr_Width+x] = color & 0xFF;}void BgaPutPixel16_lfb(unsigned x, unsigned y, unsigned color){ ((unsigned short*)fb_seg)[y*curr_Width+x] = color & 0xFFFF;}void BgaPutPixel24_lfb(unsigned x, unsigned y, unsigned color){ ((unsigned char*)fb_seg)[y*line_size+x*3] = color & 0xFF; ((unsigned char*)fb_seg)[y*line_size+x*3+1] = (color>>8) & 0xFF; ((unsigned char*)fb_seg)[y*line_size+x*3+2] = (color>>16) & 0xFF;}void BgaPutPixel32_lfb(unsigned x, unsigned y, unsigned color){ ((unsigned*)fb_seg)[y*curr_Width+x] = color;}void BgaConfigurePages(){ if(banked) return;}