[metal] Fix video mode filtering & frame buffer ref-counting (#889)

Co-authored-by: tkchia <tkchia-cosmo@gmx.com>
This commit is contained in:
tkchia 2023-09-06 18:41:07 +08:00 committed by GitHub
parent 0d748ad58e
commit b21842ed7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 10 deletions

View file

@ -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));

View file

@ -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

View file

@ -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.