Enable psf font for framebuffer display

This commit is contained in:
Loic Guegan 2021-04-26 12:37:34 +02:00
parent 7db6db5ae6
commit 9dc527b3be
19 changed files with 386 additions and 111 deletions

View file

@ -1,33 +1,40 @@
#include "acpi.hpp"
#include "core/paging.hpp"
#include "drivers/framebuffer.hpp"
#include "libs/stdio.hpp"
#include "libs/string.hpp"
// TODO: ALL!
RSDP rsdp;
RSDT rsdt;
IOAPIC ioapic;
char acpi_init(void* rsdp_p){
printk("Init ACPI... ");
char acpi_load_madt(void* rsdp_p){
// Load RSDP
RSDP rsdp;
memcpy(rsdp_p, &rsdp, sizeof(rsdp));
if(rsdp.signature!=ACPI_RSDP_SIGNATURE){
printk("Invalid RSDP signature\n");
return 1;
}
if(acpi_checksum(rsdp_p, 20)){
printk("Wrong RSDP Signature\n\n");
printk("Wrong RSDP Signature\n");
return 1;
}
printk("ACPI Revision %d detected!\n",rsdp.revision);
printk("ACPI Revision %d detected. ",rsdp.revision);
// Load RSDT
RSDT rsdt;
// Load sub tables
if(acpi_load_rsdt())
return 1;
if(acpi_load_madt())
return 1;
print("\n");
return 0;
}
paging_allocate_addr(kpml4,(u64)rsdp.rsdt_addr,(u64)rsdp.rsdt_addr,PAGING_OPT_P|PAGING_OPT_RW);
char acpi_load_rsdt(){
PAGING_MAP(rsdp.rsdt_addr); // Ensure page is accessible
memcpy((void*)rsdp.rsdt_addr, &rsdt, sizeof(rsdt));
rsdt.first_entry_addr_ptr=rsdp.rsdt_addr+36;
if(rsdt.header.signature !=ACPI_RSDT_SIGNATURE){
printk("Invalid RSDT signature\n");
return 1;
@ -36,22 +43,38 @@ char acpi_load_madt(void* rsdp_p){
printk("Wrong RSDT Signature\n");
return 1;
}
printk("RSDT loaded. ");
return 0;
}
char acpi_load_madt(){
int n_entry=(rsdt.header.length-36)/4;
// Locate MADT
for(int i=0;i<10;i++){
for(int i=0;i<n_entry;i++){
u32 *addr=(u32*)(rsdt.first_entry_addr_ptr+i*4);
u64 header_p_i=*addr;
// Load header
ACPI_TABLE_HEADER header;
paging_allocate_addr(kpml4,header_p_i,header_p_i,PAGING_OPT_P|PAGING_OPT_RW);
memcpy((void*)header_p_i, &header, sizeof(header));
PAGING_MAP(*addr);
memcpy((void*)*addr, &header, sizeof(header));
// Check if it is MADT
if(header.signature==ACPI_MADT_SIGNATURE){
printk("MADT found!");
printk("MADT found. ");
int int_ctrl_location=0;
while(int_ctrl_location<(header.length-44)){
u32 cur_addr=(*addr)+44+int_ctrl_location;
INT_CTRL_HEADER int_header;
memcpy((void*)cur_addr, &int_header, sizeof(int_header));
if(int_header.type==1){
printk("APIC Detected.");
memcpy((void*)cur_addr, &ioapic, sizeof(ioapic));
return 0;
}
int_ctrl_location+=int_header.length;
}
}
}
return 0;
return 1;
}
char acpi_checksum(void* p, char size){

View file

@ -37,7 +37,21 @@ typedef struct INT_CTRL_HEADER {
u8 length;
} __attribute__((packed)) INT_CTRL_HEADER;
typedef struct IOAPIC {
INT_CTRL_HEADER header;
u8 ioapic_id;
u8 reserved;
u32 ioapic_addr;
u32 global_system_interrupt_base;
} __attribute__((packed)) IOAPIC;
extern RSDP rsdp;
extern RSDT rsdt;
extern IOAPIC ioapic;
char acpi_load_madt(void* rsdp_p);
char acpi_checksum(void* p, char size);
char acpi_load_rsdt();
char acpi_load_madt();
char acpi_init(void* rsdp_p);

View file

@ -1,58 +1,30 @@
#include "framebuffer.hpp"
#include "core/paging.hpp"
#include "libs/string.hpp"
#define MAX_COL 80
#define MAX_LINE 25
FB_CFG fb_cfg;
VIDEO_STATE VS={
(u8 *)0xB8000,
0,
0,
BLACK,
GRAY,
};
void putchar(char c){
// Handle newline here
if(c=='\n'){
VS.col=0;
VS.line+=1;
if(VS.line>=MAX_LINE){
VS.line=MAX_LINE-1;
scrollup();
}
return;
}
// Print char
VS.mem[VS.col*2+MAX_COL*VS.line*2]=c;
VS.mem[VS.col*2+MAX_COL*VS.line*2+1]=VS.fg|VS.bg<<4;
// Refresh location
VS.col+=1;
if(VS.col>= MAX_COL){
VS.col=0;
VS.line+=1;
if(VS.line>=MAX_LINE){
VS.line=MAX_LINE-1;
scrollup();
}
}
void framebuffer_init(FB_CFG config){
fb_cfg=config;
}
void clear(){
for(u8 i=0;i<MAX_LINE;i++){
scrollup();
}
void framebuffer_draw(FB_PIXEL p){
u8 *pixel=(u8*)(fb_cfg.location+p.x*(fb_cfg.depth/8)+p.y*fb_cfg.pitch);
PAGING_MAP(pixel);
pixel[0]=p.r;
pixel[1]=p.g;
pixel[2]=p.b;
if(fb_cfg.depth==32)
pixel[3]=p.a;
}
void scrollup(){
// Move VS.line up
for(u8 i=1;i<=MAX_LINE;i++){
for(u8 j=0;j<=MAX_COL;j++)
VS.mem[j*2+MAX_COL*(i-1)*2]=VS.mem[j*2+MAX_COL*i*2];
}
// Clear last VS.line
for(u8 i=0;i<=MAX_COL;i++){
VS.mem[i*2+MAX_COL*(MAX_LINE-1)*2]='\0';
}
void framebuffer_scrollup(u32 npixel){
u64 start=fb_cfg.location+npixel*fb_cfg.pitch;
u64 amount=fb_cfg.pitch*(fb_cfg.height-npixel);
memcpy((void*)start,(void*)fb_cfg.location,amount);
}
void framebuffer_clear(){
memset((void*)fb_cfg.location, 0, fb_cfg.pitch*fb_cfg.height);
}

View file

@ -1,33 +1,26 @@
#pragma once
#include "core/types.hpp"
#include "include/boucane.hpp"
typedef enum VIDEO_COLORS {
BLACK=0, BLUE=1, GREEN=2,CYAN=3, RED=4,PURPLE=5,BROWN=6,GRAY=7,
DARK_GRAY=8,LIGHT_BLUE=9,LIGHT_GREEN=10,LIGHT_CYAN=11,LIGHT_RED=12,LIGHT_PURPLE=13,YELLOW=14,WHITE=15
} VIDEO_COLORS;
typedef struct {
u32 pitch;
u32 depth;
u64 location;
u32 width;
u32 height;
} __attribute__((packed)) FB_CFG;
typedef struct VIDEO_STATE {
u8 *mem;
u8 col;
u8 line;
u8 bg;
u8 fg;
} VIDEO_STATE;
typedef struct {
u32 x,y;
u8 r,g,b,a;
} __attribute__((packed)) FB_PIXEL;
/**
* Print char
*/
void putchar(char);
extern FB_CFG fb_cfg;
/**
* Scroll the framebuffer from one line
*/
void scrollup();
void framebuffer_init(FB_CFG config);
/**
* Clear all char from the framebuffer
*/
void clear();
void framebuffer_draw(FB_PIXEL p);
void framebuffer_scrollup(u32 npixel);
void framebuffer_clear();

67
src/drivers/psf.cc Normal file
View file

@ -0,0 +1,67 @@
#include "psf.hpp"
#include "core/paging.hpp"
#include "libs/string.hpp"
#include "drivers/framebuffer.hpp"
PSF_STATUS psf_status;
void psf_init(void* psf_addr){
printk("Loading PSF font... ");
memcpy(psf_addr, &psf_status.header, sizeof(PSF_HEADER));
if(psf_status.header.magic!=PSF_MAGIC){
printk("Invalid PSF magic number. Abort.\n");
return;
}
printk("Flags %d Version %d Glyphs number %d Size %dx%d",
psf_status.header.flags, psf_status.header.version,
psf_status.header.glyph_count, psf_status.header.glyph_width, psf_status.header.glyph_height);
psf_status.x=0;
psf_status.y=0;
psf_status.psf_addr=(u8*)psf_addr;
psf_status.nline=fb_cfg.height/psf_status.header.glyph_height;
psf_status.nchar=fb_cfg.width/psf_status.header.glyph_width;
psf_status.bg=0;
psf_status.fg=200;
print("\n");
}
void psf_putchar(char c){
if(c=='\n'){
psf_status.y++;
psf_status.x=0;
if(psf_status.y>psf_status.nline)
framebuffer_scrollup(psf_status.header.glyph_height);
return;
}
u8* glyph=(psf_status.psf_addr+psf_status.header.header_length+c*psf_status.header.glyph_size);
FB_PIXEL pixel;
for(int i=0;i<psf_status.header.glyph_height;i++){
PAGING_MAP(glyph);
for(int k=0;k<(psf_status.header.glyph_width/8);k++){
u8 mask=1<<7;
u8 row=*(glyph+k);
for(int j=0;j<8;j++){
u16 status=row&mask;
u8 color=status ? psf_status.fg:psf_status.bg;
pixel.x=j+k*8+psf_status.x*psf_status.header.glyph_width;
pixel.y=i+psf_status.y*psf_status.header.glyph_height;
pixel.r=color;
pixel.g=color;
pixel.b=color;
pixel.a=color;
framebuffer_draw(pixel);
mask>>=1;
}
}
glyph+=psf_status.header.glyph_width/8;
}
psf_status.x++;
if(psf_status.x>psf_status.nchar){
psf_status.y++;
psf_status.x=0;
if(psf_status.y>psf_status.nline)
framebuffer_scrollup(psf_status.header.glyph_height);
}
}

31
src/drivers/psf.hpp Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include "include/boucane.hpp"
#define PSF_MAGIC 0x864ab572
typedef struct PSF_HEADER {
u32 magic;
u32 version;
u32 header_length;
u32 flags;
u32 glyph_count;
u32 glyph_size;
u32 glyph_height;
u32 glyph_width;
} __attribute__((packed)) PSF_HEADER;
typedef struct PSF_STATUS {
PSF_HEADER header;
u32 x,y;
u32 nline;
u32 nchar;
u8 bg,fg;
u8* psf_addr;
} __attribute__((packed)) PSF_STATUS;
extern PSF_HEADER psf_header;
void psf_init(void* psf_addr);
void psf_putchar(char c);

58
src/drivers/vga_t.cc Normal file
View file

@ -0,0 +1,58 @@
#include "vga_t.hpp"
#define MAX_COL 80
#define MAX_LINE 25
VIDEO_STATE VS={
(u8 *)0xB8000,
0,
0,
BLACK,
GRAY,
};
void vga_t_putchar(char c){
// Handle newline here
if(c=='\n'){
VS.col=0;
VS.line+=1;
if(VS.line>=MAX_LINE){
VS.line=MAX_LINE-1;
vga_t_scrollup();
}
return;
}
// Print char
VS.mem[VS.col*2+MAX_COL*VS.line*2]=c;
VS.mem[VS.col*2+MAX_COL*VS.line*2+1]=VS.fg|VS.bg<<4;
// Refresh location
VS.col+=1;
if(VS.col>= MAX_COL){
VS.col=0;
VS.line+=1;
if(VS.line>=MAX_LINE){
VS.line=MAX_LINE-1;
vga_t_scrollup();
}
}
}
void clear(){
for(u8 i=0;i<MAX_LINE;i++){
vga_t_scrollup();
}
}
void vga_t_scrollup(){
// Move VS.line up
for(u8 i=1;i<=MAX_LINE;i++){
for(u8 j=0;j<=MAX_COL;j++)
VS.mem[j*2+MAX_COL*(i-1)*2]=VS.mem[j*2+MAX_COL*i*2];
}
// Clear last VS.line
for(u8 i=0;i<=MAX_COL;i++){
VS.mem[i*2+MAX_COL*(MAX_LINE-1)*2]='\0';
}
}

33
src/drivers/vga_t.hpp Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include "core/types.hpp"
typedef enum VIDEO_COLORS {
BLACK=0, BLUE=1, GREEN=2,CYAN=3, RED=4,PURPLE=5,BROWN=6,GRAY=7,
DARK_GRAY=8,LIGHT_BLUE=9,LIGHT_GREEN=10,LIGHT_CYAN=11,LIGHT_RED=12,LIGHT_PURPLE=13,YELLOW=14,WHITE=15
} VIDEO_COLORS;
typedef struct VIDEO_STATE {
u8 *mem;
u8 col;
u8 line;
u8 bg;
u8 fg;
} VIDEO_STATE;
/**
* Print char
*/
void vga_t_putchar(char);
/**
* Scroll the framebuffer from one line
*/
void vga_t_scrollup();
/**
* Clear all char from the framebuffer
*/
void vga_t_clear();