aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-04-26 12:37:34 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-04-26 12:37:34 +0200
commit9dc527b3be9d493dcf8cf1baf78477373eb5990d (patch)
tree0b32c28e57fc5a6a3e6210d9a601dfdbfe246cd8 /src/drivers
parent7db6db5ae64e7ab2626bbd898c63f58e053dc1a6 (diff)
Enable psf font for framebuffer display
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/acpi.cc61
-rw-r--r--src/drivers/acpi.hpp16
-rw-r--r--src/drivers/framebuffer.cc70
-rw-r--r--src/drivers/framebuffer.hpp53
-rw-r--r--src/drivers/psf.cc67
-rw-r--r--src/drivers/psf.hpp31
-rw-r--r--src/drivers/vga_t.cc58
-rw-r--r--src/drivers/vga_t.hpp33
8 files changed, 290 insertions, 99 deletions
diff --git a/src/drivers/acpi.cc b/src/drivers/acpi.cc
index bb48ba4..9c25202 100644
--- a/src/drivers/acpi.cc
+++ b/src/drivers/acpi.cc
@@ -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){
diff --git a/src/drivers/acpi.hpp b/src/drivers/acpi.hpp
index 7bbcdb0..15374d8 100644
--- a/src/drivers/acpi.hpp
+++ b/src/drivers/acpi.hpp
@@ -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);
diff --git a/src/drivers/framebuffer.cc b/src/drivers/framebuffer.cc
index 2fbe153..2ac47db 100644
--- a/src/drivers/framebuffer.cc
+++ b/src/drivers/framebuffer.cc
@@ -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);
+} \ No newline at end of file
diff --git a/src/drivers/framebuffer.hpp b/src/drivers/framebuffer.hpp
index fb09d6f..958a44b 100644
--- a/src/drivers/framebuffer.hpp
+++ b/src/drivers/framebuffer.hpp
@@ -1,33 +1,26 @@
#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 putchar(char);
-
-/**
- * Scroll the framebuffer from one line
- */
-void scrollup();
-
-/**
- * Clear all char from the framebuffer
- */
-void clear();
+#include "include/boucane.hpp"
+typedef struct {
+ u32 pitch;
+ u32 depth;
+ u64 location;
+ u32 width;
+ u32 height;
+} __attribute__((packed)) FB_CFG;
+
+typedef struct {
+ u32 x,y;
+ u8 r,g,b,a;
+} __attribute__((packed)) FB_PIXEL;
+
+extern FB_CFG fb_cfg;
+
+void framebuffer_init(FB_CFG config);
+
+void framebuffer_draw(FB_PIXEL p);
+
+void framebuffer_scrollup(u32 npixel);
+
+void framebuffer_clear(); \ No newline at end of file
diff --git a/src/drivers/psf.cc b/src/drivers/psf.cc
new file mode 100644
index 0000000..187d711
--- /dev/null
+++ b/src/drivers/psf.cc
@@ -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);
+ }
+} \ No newline at end of file
diff --git a/src/drivers/psf.hpp b/src/drivers/psf.hpp
new file mode 100644
index 0000000..1163dee
--- /dev/null
+++ b/src/drivers/psf.hpp
@@ -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); \ No newline at end of file
diff --git a/src/drivers/vga_t.cc b/src/drivers/vga_t.cc
new file mode 100644
index 0000000..6e50b40
--- /dev/null
+++ b/src/drivers/vga_t.cc
@@ -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';
+ }
+}
diff --git a/src/drivers/vga_t.hpp b/src/drivers/vga_t.hpp
new file mode 100644
index 0000000..dd947bd
--- /dev/null
+++ b/src/drivers/vga_t.hpp
@@ -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();
+