mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 11:37:35 +00:00
[metal] Fix video mode filtering & frame buffer ref-counting (#889)
Co-authored-by: tkchia <tkchia-cosmo@gmx.com>
This commit is contained in:
parent
0d748ad58e
commit
b21842ed7a
3 changed files with 20 additions and 10 deletions
|
@ -159,6 +159,7 @@
|
||||||
#define PAGE_V /* */ 0b000000000001
|
#define PAGE_V /* */ 0b000000000001
|
||||||
#define PAGE_RW /* */ 0b000000000010
|
#define PAGE_RW /* */ 0b000000000010
|
||||||
#define PAGE_U /* */ 0b000000000100
|
#define PAGE_U /* */ 0b000000000100
|
||||||
|
#define PAGE_PCD /* */ 0b000000010000
|
||||||
#define PAGE_PS /* */ 0b000010000000
|
#define PAGE_PS /* */ 0b000010000000
|
||||||
#define PAGE_G /* */ 0b000100000000
|
#define PAGE_G /* */ 0b000100000000
|
||||||
#define PAGE_IGN1 /* */ 0b111000000000
|
#define PAGE_IGN1 /* */ 0b111000000000
|
||||||
|
@ -196,6 +197,20 @@ void __ref_page(struct mman *, uint64_t *, uint64_t);
|
||||||
void __ref_pages(struct mman *, uint64_t *, uint64_t, uint64_t);
|
void __ref_pages(struct mman *, uint64_t *, uint64_t, uint64_t);
|
||||||
void __unref_page(struct mman *, uint64_t *, uint64_t);
|
void __unref_page(struct mman *, uint64_t *, uint64_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identity maps an area of physical memory to its negative address and
|
||||||
|
* marks it as permanently referenced and unreclaimable (so that it will
|
||||||
|
* never be added to the free list). This is useful for special-purpose
|
||||||
|
* physical memory regions, such as video frame buffers and memory-mapped
|
||||||
|
* I/O devices.
|
||||||
|
*/
|
||||||
|
forceinline void __invert_and_perm_ref_memory_area(struct mman *mm,
|
||||||
|
uint64_t *pml4t, uint64_t ps,
|
||||||
|
uint64_t size,
|
||||||
|
uint64_t pte_flags) {
|
||||||
|
__invert_memory_area(mm, pml4t, ps, size, pte_flags | PAGE_REFC);
|
||||||
|
}
|
||||||
|
|
||||||
forceinline unsigned char inb(unsigned short port) {
|
forceinline unsigned char inb(unsigned short port) {
|
||||||
unsigned char al;
|
unsigned char al;
|
||||||
asm volatile("inb\t%1,%0" : "=a"(al) : "dN"(port));
|
asm volatile("inb\t%1,%0" : "=a"(al) : "dN"(port));
|
||||||
|
|
|
@ -46,11 +46,7 @@
|
||||||
.set "mi::sizeof",14
|
.set "mi::sizeof",14
|
||||||
|
|
||||||
// Routine to activate additional VESA functionality if the user holds
|
// Routine to activate additional VESA functionality if the user holds
|
||||||
// down a magic key, when booting from bare metal. Currently this just
|
// down a magic key, when booting from bare metal.
|
||||||
// dumps a list of all usable VESA VBE video modes on the console.
|
|
||||||
//
|
|
||||||
// TODO: allow user to select a video mode and switch to it
|
|
||||||
// TODO: implement character drawing in graphics modes
|
|
||||||
//
|
//
|
||||||
// @return CF = 0 if we decided to set a new video mode, CF = 1 otherwise
|
// @return CF = 0 if we decided to set a new video mode, CF = 1 otherwise
|
||||||
|
|
||||||
|
@ -372,7 +368,7 @@ _rlinit_vesa:
|
||||||
jz .fail3
|
jz .fail3
|
||||||
call .video_type # check if we know about the video
|
call .video_type # check if we know about the video
|
||||||
jc .fail3 # buffer type, & what exact type it is
|
jc .fail3 # buffer type, & what exact type it is
|
||||||
mov (%bp),%bx # if we are already tracking too
|
mov (%bp),%bx # if we are already tracking too many
|
||||||
cmp $MAX_VESA_MODES_TO_TRACK,%bx # VESA modes, also skip
|
cmp $MAX_VESA_MODES_TO_TRACK,%bx # VESA modes, also skip
|
||||||
jnb .fail3
|
jnb .fail3
|
||||||
inc %bx # otherwise start noting down mode
|
inc %bx # otherwise start noting down mode
|
||||||
|
@ -435,7 +431,7 @@ _rlinit_vesa:
|
||||||
mov $PC_VIDEO_TEXT,%al # if text mode, simply say so
|
mov $PC_VIDEO_TEXT,%al # if text mode, simply say so
|
||||||
test $0b00010000,%cl
|
test $0b00010000,%cl
|
||||||
jz .ok4
|
jz .ok4
|
||||||
cmpl $6,%es:0x1b(%di) # if graphics mode, check if direct
|
cmpb $6,%es:0x1b(%di) # if graphics mode, check if direct
|
||||||
jnz .fail4 # color; bail out if not
|
jnz .fail4 # color; bail out if not
|
||||||
mov %es:0x19(%di),%cl # check actual color fields & bits
|
mov %es:0x19(%di),%cl # check actual color fields & bits
|
||||||
mov %es:0x1f(%di),%ax # per pixel, against a list
|
mov %es:0x1f(%di),%ax # per pixel, against a list
|
||||||
|
|
|
@ -53,9 +53,8 @@ void _vga_reinit(struct Tty *tty, unsigned short starty, unsigned short startx,
|
||||||
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
||||||
chr_wid = VGA_ASSUME_CHAR_WIDTH_PX;
|
chr_wid = VGA_ASSUME_CHAR_WIDTH_PX;
|
||||||
/* Make sure the video buffer is mapped into virtual memory. */
|
/* Make sure the video buffer is mapped into virtual memory. */
|
||||||
__invert_memory_area(mm, __get_pml4t(), vid_buf_phy, vid_buf_sz,
|
__invert_and_perm_ref_memory_area(mm, __get_pml4t(), vid_buf_phy, vid_buf_sz,
|
||||||
PAGE_RW | PAGE_XD);
|
PAGE_RW | PAGE_XD);
|
||||||
__ref_pages(mm, __get_pml4t(), vid_buf_phy, vid_buf_sz);
|
|
||||||
/*
|
/*
|
||||||
* Initialize our tty structure from the current screen geometry, screen
|
* Initialize our tty structure from the current screen geometry, screen
|
||||||
* contents, cursor position, & character dimensions.
|
* contents, cursor position, & character dimensions.
|
||||||
|
|
Loading…
Reference in a new issue