diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/acpi.cc | 61 | ||||
| -rw-r--r-- | src/drivers/acpi.hpp | 16 | ||||
| -rw-r--r-- | src/drivers/framebuffer.cc | 70 | ||||
| -rw-r--r-- | src/drivers/framebuffer.hpp | 53 | ||||
| -rw-r--r-- | src/drivers/psf.cc | 67 | ||||
| -rw-r--r-- | src/drivers/psf.hpp | 31 | ||||
| -rw-r--r-- | src/drivers/vga_t.cc | 58 | ||||
| -rw-r--r-- | src/drivers/vga_t.hpp | 33 |
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(); + |
