From 06644f770e644c4ebe05afd6735294094d81fcb9 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 20 Feb 2016 09:57:44 +0000 Subject: [PATCH] kernel: framebuffers code git-svn-id: svn://kolibrios.org@6263 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/const.inc | 2 +- kernel/trunk/core/exports.inc | 1 + kernel/trunk/core/memory.inc | 89 ----------- kernel/trunk/core/taskman.inc | 53 +++---- kernel/trunk/data32.inc | 2 +- kernel/trunk/kernel.asm | 108 ++----------- kernel/trunk/kernel32.inc | 3 +- kernel/trunk/video/framebuffer.inc | 245 +++++++++++++++++++++++++++++ 8 files changed, 288 insertions(+), 215 deletions(-) create mode 100644 kernel/trunk/video/framebuffer.inc diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 6d48a623cc..5d03cb7864 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -685,7 +685,7 @@ struct display_t height dd ? bits_per_pixel dd ? vrefresh dd ? - lfb dd ? + current_lfb dd ? lfb_pitch dd ? win_map_lock RWSEM diff --git a/kernel/trunk/core/exports.inc b/kernel/trunk/core/exports.inc index 3108eeaf11..c348556298 100644 --- a/kernel/trunk/core/exports.inc +++ b/kernel/trunk/core/exports.inc @@ -56,6 +56,7 @@ __exports: \ get_display, 'GetDisplay', \ set_screen, 'SetScreen', \ + set_framebuffer, 'SetFramebuffer', \ ; gcc fastcall window._.get_rect, 'GetWindowRect', \ ; gcc fastcall pci_api_drv, 'PciApi', \ pci_read8, 'PciRead8', \ ; stdcall diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 758cb14908..994ee1f0ba 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -404,95 +404,6 @@ proc create_trampoline_pgmap ret endp -align 4 -proc init_LFB - locals - pg_count dd ? - endl - - cmp dword [LFBAddress], -1 - jne @f - mov [BOOT_VARS+BOOT_MTRR], byte 2 -; max VGA=640*480*4=1228800 bytes -; + 32*640*4=81920 bytes for mouse pointer - stdcall alloc_pages, ((1228800+81920)/4096) - - push eax - call alloc_page - stdcall map_page_table, LFB_BASE, eax - pop eax - or eax, PG_UWR - mov ebx, LFB_BASE -; max VGA=640*480*4=1228800 bytes -; + 32*640*4=81920 bytes for mouse pointer - mov ecx, (1228800+81920)/4096 - call commit_pages - mov [LFBAddress], dword LFB_BASE - ret -@@: - test [SCR_MODE], word 0100000000000000b - jnz @f - mov [BOOT_VARS+BOOT_MTRR], byte 2 - ret -@@: - call init_mtrr - - mov edx, LFB_BASE - mov esi, [LFBAddress] - mov edi, 0x00C00000 - mov dword [exp_lfb+4], edx - - shr edi, 12 - mov [pg_count], edi - shr edi, 10 - - bt [cpu_caps], CAPS_PSE - jnc .map_page_tables - or esi, PDE_LARGE+PG_UWR - mov edx, sys_proc+PROC.pdt_0+(LFB_BASE shr 20) -@@: - mov [edx], esi - add edx, 4 - add esi, 0x00400000 - dec edi - jnz @B - - bt [cpu_caps], CAPS_PGE - jnc @F - or dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL -@@: - mov dword [LFBAddress], LFB_BASE - mov eax, cr3 ;flush TLB - mov cr3, eax - ret - -.map_page_tables: - -@@: - call alloc_page - stdcall map_page_table, edx, eax - add edx, 0x00400000 - dec edi - jnz @B - - mov eax, [LFBAddress] - mov edi, page_tabs + (LFB_BASE shr 10) - or eax, PG_GLOBAL+PG_UWR - and eax, [pte_valid_mask] - mov ecx, [pg_count] - cld -@@: - stosd - add eax, 0x1000 - loop @B - - mov dword [LFBAddress], LFB_BASE - mov eax, cr3 ;flush TLB - mov cr3, eax - - ret -endp - align 4 proc new_mem_resize stdcall, new_size:dword diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc index ee9e17c563..2078955a9e 100644 --- a/kernel/trunk/core/taskman.inc +++ b/kernel/trunk/core/taskman.inc @@ -75,7 +75,7 @@ proc fs_execute slot_base dd ? file_base dd ? file_size dd ? - handle dd ? ;temp. for default cursor handle for curr. thread +; handle dd ? ;temp. for default cursor handle for curr. thread ;app header data hdr_cmdline dd ? ;0x00 hdr_path dd ? ;0x04 @@ -87,15 +87,15 @@ proc fs_execute pushad - cmp [SCR_MODE], word 0x13 - jbe @f - pushad - stdcall set_cursor, [def_cursor_clock] - mov [handle], eax - mov [redrawmouse_unconditional], 1 - call wakeup_osloop - popad -@@: +; cmp [SCR_MODE], word 0x13 +; jbe @f +; pushad +; stdcall set_cursor, [def_cursor_clock] +; mov [handle], eax +; mov [redrawmouse_unconditional], 1 +; call wakeup_osloop +; popad +;@@: mov [flags], edx ; [ebp] pointer to filename @@ -256,6 +256,9 @@ proc fs_execute test eax, eax jz .failed + mov ebx, [sys_proc+LHEAD.prev] + __list_add eax, ebx, sys_proc + mov ebx, [hdr_mem] mov [eax+PROC.mem_used], ebx @@ -274,8 +277,6 @@ proc fs_execute @@: mov [ebx+APPDATA.tls_base], edx -if GREEDY_KERNEL -else mov ecx, [hdr_mem] mov edi, [file_size] add edi, 4095 @@ -287,7 +288,6 @@ else cld rep stosb @@: -end if ; release only virtual space, not phisical memory @@ -315,14 +315,14 @@ end if call unlock_application_table mov eax, esi .final: - cmp [SCR_MODE], word 0x13 - jbe @f - pushad - stdcall set_cursor, [handle] - mov [redrawmouse_unconditional], 1 - call wakeup_osloop - popad -@@: +; cmp [SCR_MODE], word 0x13 +; jbe @f +; pushad +; stdcall set_cursor, [handle] +; mov [redrawmouse_unconditional], 1 +; call wakeup_osloop +; popad +;@@: ret endp @@ -632,11 +632,11 @@ align 4 .internal: push ecx - mov esi, [ecx+PROC.dlls_list_ptr] - call destroy_all_hdlls + mov esi, ecx + list_del esi -; mov ecx, pg_data.mutex -; call mutex_lock + mov esi, [esi+PROC.dlls_list_ptr] + call destroy_all_hdlls mov esi, [esp] add esi, PROC.pdt_0 @@ -657,9 +657,6 @@ align 4 call kernel_free ;ecx still in stack stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP - ; mov ecx, pg_data.mutex - ; call mutex_unlock - .exit: ret diff --git a/kernel/trunk/data32.inc b/kernel/trunk/data32.inc index dfbdeb4b04..b2db65858c 100644 --- a/kernel/trunk/data32.inc +++ b/kernel/trunk/data32.inc @@ -358,7 +358,6 @@ free_blocks rd 1 mem_block_mask rd 2 next_memblock rd 1 - mst MEM_STATE pte_valid_mask rd 1 @@ -374,6 +373,7 @@ srv.bk rd 1 align 16 _display display_t +bios_fb FRB LFBAddress dd ? diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index a367a5b491..7898ef04bc 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -440,44 +440,12 @@ high_code: ; ----------------------------------------- mov al, [BOOT_VARS+BOOT_DMA] ; DMA access mov [allow_dma_access], al - movzx eax, byte [BOOT_VARS+BOOT_BPP] ; bpp - mov [_display.bits_per_pixel], eax - mov [_display.vrefresh], 60 + mov al, [BOOT_VARS+BOOT_DEBUG_PRINT] ; If nonzero, duplicates debug output to the screen mov [debug_direct_print], al + mov al, [BOOT_VARS+BOOT_LAUNCHER_START] ; Start the first app (LAUNCHER) after kernel is loaded? mov [launcher_start], al - movzx eax, word [BOOT_VARS+BOOT_X_RES]; X max - mov [_display.width], eax - mov [display_width_standard], eax - dec eax - mov [screen_workarea.right], eax - movzx eax, word [BOOT_VARS+BOOT_Y_RES]; Y max - mov [_display.height], eax - mov [display_height_standard], eax - dec eax - mov [screen_workarea.bottom], eax - movzx eax, word [BOOT_VARS+BOOT_VESA_MODE] ; screen mode - mov dword [SCR_MODE], eax -; mov eax, [BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add -; mov [BANK_SWITCH], eax - mov eax, 640 *4 ; Bytes PerScanLine - cmp [SCR_MODE], word 0x13 ; 320x200 - je @f - cmp [SCR_MODE], word 0x12 ; VGA 640x480 - je @f - movzx eax, word[BOOT_VARS+BOOT_PITCH] ; for other modes -@@: - mov [_display.lfb_pitch], eax - mov eax, [_display.width] - mul [_display.height] - mov [_display.win_map_size], eax - - call calculate_fast_getting_offset_for_WinMapAddress -; for Qemu or non standart video cards -; Unfortunately [BytesPerScanLine] does not always -; equal to [_display.width] * [ScreenBPP] / 8 - call calculate_fast_getting_offset_for_LFB mov esi, BOOT_VARS+0x9080 movzx ecx, byte [esi-1] @@ -485,59 +453,6 @@ high_code: mov edi, BiosDisksData rep movsd -setvideomode: - - mov eax, [BOOT_VARS+BOOT_LFB] - mov [LFBAddress], eax - - cmp word [SCR_MODE], 0x0012 ; VGA (640x480 16 colors) - je .vga - cmp word [SCR_MODE], 0x0013 ; MCGA (320*200 256 colors) - je .32bpp - cmp byte [_display.bits_per_pixel], 32 - je .32bpp - cmp byte [_display.bits_per_pixel], 24 - je .24bpp - cmp byte [_display.bits_per_pixel], 16 - je .16bpp -; cmp byte [_display.bits_per_pixel], 15 -; je .15bpp - - .vga: - mov [PUTPIXEL], VGA_putpixel - mov [GETPIXEL], Vesa20_getpixel32 ; Conversion buffer is 32 bpp - mov [_display.bytes_per_pixel], 4 ; Conversion buffer is 32 bpp - jmp .finish - -; .15bpp: -; mov [PUTPIXEL], Vesa20_putpixel15 -; mov [GETPIXEL], Vesa20_getpixel15 -; mov [_display.bytes_per_pixel], 2 -; jmp .finish - - .16bpp: - mov [PUTPIXEL], Vesa20_putpixel16 - mov [GETPIXEL], Vesa20_getpixel16 - mov [_display.bytes_per_pixel], 2 - jmp .finish - - .24bpp: - mov [PUTPIXEL], Vesa20_putpixel24 - mov [GETPIXEL], Vesa20_getpixel24 - mov [_display.bytes_per_pixel], 3 - jmp .finish - - .32bpp: - mov [PUTPIXEL], Vesa20_putpixel32 - mov [GETPIXEL], Vesa20_getpixel32 - mov [_display.bytes_per_pixel], 4 -; jmp .finish - - .finish: - mov [MOUSE_PICTURE], mousepointer - mov [_display.check_mouse], check_mouse_area_for_putpixel - mov [_display.check_m_pixel], check_mouse_area_for_getpixel - ; -------- Fast System Call init ---------- ; Intel SYSENTER/SYSEXIT (AMD CPU support it too) bt [cpu_caps], CAPS_SEP @@ -619,8 +534,16 @@ setvideomode: mov ax, tss0 ltr ax - mov [LFBSize], 0xC00000 - call init_LFB + mov eax, sys_proc + list_init eax + add eax, PROC.thr_list + list_init eax + + call init_video + call init_mtrr + mov [LFBAddress], LFB_BASE + mov ecx, bios_fb + call set_framebuffer call init_fpu call init_malloc @@ -707,14 +630,9 @@ setvideomode: mov esi, boot_setostask call boot_log - mov eax, sys_proc - lea edi, [eax+PROC.heap_lock] + mov edi, sys_proc+PROC.heap_lock mov ecx, (PROC.ht_free-PROC.heap_lock)/4 - list_init eax - add eax, PROC.thr_list - list_init eax - xor eax, eax cld rep stosd diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index e2237403b3..bbf421ec57 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -64,9 +64,10 @@ include "sound/playnote.inc" ; player Note for Speaker PC ;include "video/vesa12.inc" ; Vesa 1.2 functions include "video/vesa20.inc" ; Vesa 2.0 functions -include "video/blitter.inc" ; +include "video/blitter.inc" include "video/vga.inc" ; VGA 16 color functions include "video/cursors.inc" ; cursors functions +include "video/framebuffer.inc" ; framebuffer functions ; Network Interface & TCPIP Stack diff --git a/kernel/trunk/video/framebuffer.inc b/kernel/trunk/video/framebuffer.inc new file mode 100644 index 0000000000..018a40f170 --- /dev/null +++ b/kernel/trunk/video/framebuffer.inc @@ -0,0 +1,245 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Synhronization for MenuetOS. ;; +;; Author: Halyavin Andrey, halyavin@land.ru ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision: 6240 $ + +struct FRB + list LHEAD + magic rd 1 + handle rd 1 + destroy rd 1 + + width rd 1 + height rd 1 + pitch rd 1 + format rd 1 + private rd 1 + pde rd 8 +ends + +align 4 +create_framebuffer: + mov ecx, sizeof.FRB + call create_object + test eax, eax + jz .fail + + mov [eax+FRB.magic], 'FRMB' + mov [eax+FRB.destroy], 0 +.fail: + ret + + +align 4 +init_video: + mov ebp, bios_fb + + movzx eax, byte [BOOT_VARS+BOOT_BPP] ; bpp + mov [_display.bits_per_pixel], eax + mov [_display.vrefresh], 60 + + movzx eax, word [BOOT_VARS+BOOT_X_RES]; X max + mov [_display.width], eax + mov [ebp+FRB.width], eax + mov [display_width_standard], eax + dec eax + mov [screen_workarea.right], eax + + movzx eax, word [BOOT_VARS+BOOT_Y_RES]; Y max + mov [_display.height], eax + mov [ebp+FRB.height], eax + mov [display_height_standard], eax + dec eax + mov [screen_workarea.bottom], eax + + movzx eax, word [BOOT_VARS+BOOT_VESA_MODE] ; screen mode + mov dword [SCR_MODE], eax + mov eax, 640 *4 ; Bytes PerScanLine + cmp [SCR_MODE], word 0x13 ; 320x200 + je @f + cmp [SCR_MODE], word 0x12 ; VGA 640x480 + je @f + movzx eax, word[BOOT_VARS+BOOT_PITCH] ; for other modes +@@: + mov [_display.lfb_pitch], eax + mov [ebp+FRB.pitch], eax + + mov eax, [BOOT_VARS+BOOT_LFB] + mov [LFBAddress], eax + + mov eax, [_display.width] + mul [_display.height] + mov [_display.win_map_size], eax + + cmp word [SCR_MODE], 0x0012 ; VGA (640x480 16 colors) + je .vga + cmp word [SCR_MODE], 0x0013 ; MCGA (320*200 256 colors) + je .32bpp + cmp byte [_display.bits_per_pixel], 32 + je .32bpp + cmp byte [_display.bits_per_pixel], 24 + je .24bpp + cmp byte [_display.bits_per_pixel], 16 + je .16bpp + +.vga: + mov [PUTPIXEL], VGA_putpixel + mov [GETPIXEL], Vesa20_getpixel32 ; Conversion buffer is 32 bpp + mov [_display.bytes_per_pixel], 4 ; Conversion buffer is 32 bpp + jmp .finish + +.16bpp: + mov [PUTPIXEL], Vesa20_putpixel16 + mov [GETPIXEL], Vesa20_getpixel16 + mov [_display.bytes_per_pixel], 2 + jmp .finish + +.24bpp: + mov [PUTPIXEL], Vesa20_putpixel24 + mov [GETPIXEL], Vesa20_getpixel24 + mov [_display.bytes_per_pixel], 3 + jmp .finish + +.32bpp: + mov [PUTPIXEL], Vesa20_putpixel32 + mov [GETPIXEL], Vesa20_getpixel32 + mov [_display.bytes_per_pixel], 4 + +.finish: + mov [MOUSE_PICTURE], mousepointer + mov [_display.check_mouse], check_mouse_area_for_putpixel + mov [_display.check_m_pixel], check_mouse_area_for_getpixel + + mov ax, word [SCR_MODE] + cmp ax, 0x0012 + je .fake + cmp ax, 0x0013 + je .fake + + mov esi, [LFBAddress] + bt [cpu_caps], CAPS_PSE + jnc .create_page_tables + + mov edx, 0x00400000 + or esi, PG_GLOBAL+PDE_LARGE+PAT_WC+PG_UWR + and esi, [pte_valid_mask] + mov [ebp+FRB.pde], esi + add esi, edx + mov [ebp+FRB.pde+4], esi + add esi, edx + mov [ebp+FRB.pde+8], esi + add esi, edx + mov [ebp+FRB.pde+12], esi + add esi, edx +.ok: + call calculate_fast_getting_offset_for_WinMapAddress +; for Qemu or non standart video cards +; Unfortunately [BytesPerScanLine] does not always +; equal to [_display.width] * [ScreenBPP] / 8 + call calculate_fast_getting_offset_for_LFB + ret + +.create_page_tables: + + add ebp, FRB.pde + or esi, PG_GLOBAL+PAT_WC+PG_UWR + and esi, [pte_valid_mask] + + stdcall alloc_kernel_space, 0x1000 + mov edi, eax + mov ebx, 4 + +.new_pd: + call alloc_page + lea edx, [eax+PG_UWR] + mov [ebp], edx + + stdcall map_page, edi, eax, PG_SWR + + mov eax, esi + mov ecx, 1024 +@@: + stosd + add eax, 0x1000 + loop @B + + add esi, 0x400000 + add ebp, 4 + sub edi, 4096 + dec ebx + jnz .new_pd + stdcall free_kernel_space, edi + jmp .ok + +.fake: + mov [BOOT_VARS+BOOT_MTRR], byte 2 + + stdcall alloc_kernel_space, 0x1000 + push eax ;store in stack for subsequent + mov edi, eax ;free_kernel_space call + + call alloc_page + lea edx, [eax+PG_UWR] + mov [ebp+FRB.pde], edx + + stdcall map_page, edi, eax, PG_SWR + +; max VGA=640*480*4=1228800 bytes +; + 32*640*4=81920 bytes for mouse pointer + stdcall alloc_pages, ((1228800+81920)/4096) + or eax, PG_GLOBAL+PG_UWR + and eax, [pte_valid_mask] + mov ecx, (1228800+81920)/4096 +@@: + stosd + add eax, 0x1000 + loop @B + + call free_kernel_space + jmp .ok + +align 4 +set_framebuffer: + push esi + push edi + lea esi, [ecx+FRB.pde] + mov eax, sys_proc + + cld + pushfd + cli + mov [_display.current_lfb], ecx +.patch_pde: + lea edi, [eax+PROC.pdt_0+4096-32] ;last 8 pd entries up to 32Mb framebuffer + mov ecx, 4 + rep movsd ;patch pde + sub esi, 16 + mov eax, [eax+PROC.list.next] ;next process/address space + cmp eax, sys_proc + jne .patch_pde + + bt [cpu_caps], CAPS_PGE + jnc .cr3_flush + + mov eax, cr4 + btr eax, 7 ;clear cr4.PGE + mov cr4, eax ;flush TLB + bts eax, 7 + mov cr4, eax ;flush TLB +.exit: + popfd + pop edi + pop esi + ret + +.cr3_flush: + mov eax, cr3 + mov cr3, eax ;flush TLB + jmp .exit +