Begin framebuffer abstraction, add BGA driver

This commit is contained in:
Zachary D. Rowitsch 2023-01-15 01:26:19 -05:00
parent b363386005
commit 16065b19d9
9 changed files with 173 additions and 24 deletions

@ -59,6 +59,10 @@ build/fs/fat/fat16.o: src/fs/fat/fat16.c
mkdir -p build/fs/fat
$(CC) $(INCLUDES) $(FLAGS) -Isrc/fs -Isrc/fs/fat -c $< -o $@
build/video/bga/bga.o: src/video/bga/bga.c
mkdir -p build/video/bga
$(CC) $(INCLUDES) $(FLAGS) -Isrc/video -Isrc/video/bga -c $< -o $@
clean: user_programs_clean
rm -rf bin
rm -rf build

@ -19,6 +19,7 @@
#define MAX_FILESYSTEMS 12
#define MAX_FILE_DESCRIPTORS 512
#define MAX_FRAMEBUFFERS 9
#define TOTAL_GDT_SEGMENTS 6

@ -24,11 +24,13 @@ static struct filesystem **fs_get_free_filesystem() {
void fs_insert_filesystem(struct filesystem *filesystem) {
struct filesystem **fs;
if (filesystem == 0) {
//TODO panic
if (!filesystem) {
panic("Null pointer passed to %s:%i\n", __FILE__, __LINE__);
}
fs = fs_get_free_filesystem();
assertf(fs, "Problem inserting filesystem");
if (!fs) {
panic("Failed to insert filesystem %s:%i", __FILE__, __LINE__);
}
*fs = filesystem;
}

@ -35,15 +35,10 @@ struct file_stat {
struct disk;
typedef void *(*FS_OPEN_FUNCTION)(struct disk *disk, struct path_part *, FILE_MODE mode);
typedef int(*FS_RESOLVE_FUNCTION)(struct disk *disk);
typedef int(*FS_READ_FUNCTION)(struct disk *disk, void *private, uint32_t size, uint32_t nmemb, char *out);
typedef int(*FS_SEEK_FUNCTION)(void *private, uint32_t offset, FILE_SEEK_MODE seek_mode);
typedef int(*FS_STAT_FUNCTION)(struct disk *disk, void *private, struct file_stat *stat);
typedef int(*FS_CLOSE_FUNCTION)(void *private);
struct filesystem {

@ -22,8 +22,8 @@
#include "keyboard/keyboard.h"
#include "assert.h"
#include "terminal/terminal.h"
#include "video/bga/bga.h"
#include "io/pci/pci.h"
#include "video/framebuffer.h"
static struct paging_4gb_chunk *kernel_chunk = 0;
@ -76,23 +76,19 @@ void kernel_main() {
// Initialize keyboard(s)
keyboard_init();
if (bga_is_hw_present())
fb_init();
// uint8_t *framebuffer = (uint8_t*) fb_initialize();
if (fb_is_mode_supported(640, 480, 24))
{
printf("bga hw found\n");
printf("bga mode is supported\n");
}
else
{
printf("bga no hw found\n");
printf("bga mode is not supported\n");
}
pci_check_all_buses();
struct pci_address bga_addr;
if (pci_find_device(0x1234, 0x1111, &bga_addr)) {
printf("Found bga adapter at %x:%x.0\n", bga_addr.bus, bga_addr.slot);
}
printf("bar0: %x\n", pci_get_bar0(bga_addr.bus, bga_addr.slot, bga_addr.func));
/*
if (bga_set_mode(640, 480, 24))
/*
if (fb_set_mode(640, 480, 24))
{
printf("bga mode set\n");
}
@ -100,11 +96,12 @@ void kernel_main() {
{
printf("bga mode not set\n");
}
uint8_t *framebuffer = (uint8_t*) pci_get_bar0(bga_addr.bus, bga_addr.slot, bga_addr.func);
for (int i = 10 ; i<30000; i++) {
framebuffer[i] = 0xAF;
}
*/
*/
struct process *process = 0;
int res = process_load_switch("0:/shell.elf", &process);
if (res != ALL_OK) {

@ -1,5 +1,10 @@
#include "bga.h"
#include "io/io.h"
#include "io/pci/pci.h"
#include "string.h"
#include "framebuffer.h"
#include <stdint.h>
#include <stdbool.h>
@ -41,6 +46,9 @@ static const uint16_t supported_bga_versions[] = {
#define VBE_DISPI_BPP_24 (0x18)
#define VBE_DISPI_BPP_32 (0x20)
#define BGA_VENDOR_ID (0x1234)
#define BGA_DEVICE_ID (0x1111)
static void write_register(uint16_t index, uint16_t value)
{
outw(VBE_DISPI_IOPORT_INDEX, index);
@ -61,10 +69,22 @@ bool bga_is_hw_present()
{
uint16_t bga_version = read_register(VBE_DISPI_INDEX_ID);
const uint16_t *version = supported_bga_versions;
struct pci_address address;
for ( ; *version && *version != bga_version; version++)
{
}
return (*version != 0x0000);
return (*version != 0x0000 && pci_find_device(BGA_VENDOR_ID, BGA_DEVICE_ID, &address));
}
void* bga_initialize()
{
void* buffer = NULL;
struct pci_address address;
if (pci_find_device(BGA_VENDOR_ID, BGA_DEVICE_ID, &address)) {
buffer = (void*) pci_get_bar0(address.bus, address.slot, address.func);
}
return buffer;
}
bool bga_is_mode_supported(uint32_t x, uint32_t y, uint32_t bpp)
@ -98,3 +118,33 @@ bool bga_set_mode(uint32_t x, uint32_t y, uint32_t bpp)
out:
return worked;
}
/*
typedef bool (*FRAMEBUFFER_IS_PRESENT)();
typedef void *(*FRAMEBUFFER_INIT)();
typedef bool (*FRAMEBUFFER_IS_MODE_SUPPORTED)(uint32_t x, uint32_t y, uint32_t bpp);
typedef bool (*FRAMEBUFFER_SET_MODE)(uint32_t x, uint32_t y, uint32_t bpp);
typedef void (*FRAMEBUFFER_PAGE_SWAP)();
struct framebuffer {
char name[20];
FRAMEBUFFER_INIT init;
FRAMEBUFFER_IS_PRESENT is_present;
FRAMEBUFFER_IS_MODE_SUPPORTED is_mode_supported;
FRAMEBUFFER_SET_MODE set_mode;
FRAMEBUFFER_PAGE_SWAP page_swap;
bool present;
void *buffer;
};
*/
struct framebuffer bga_framebuffer = {
.init = bga_initialize,
.is_present = bga_is_hw_present,
.is_mode_supported = bga_is_mode_supported,
.set_mode = bga_set_mode,
};
struct framebuffer* bga_driver_initialize() {
strcpy(bga_framebuffer.name, "BGA");
return &bga_framebuffer;
}

@ -1,11 +1,16 @@
#ifndef OPERATING_SYSTEM_BGA_H
#define OPERATING_SYSTEM_BGA_H
#include <stdint.h>
#include <stdbool.h>
struct framebuffer;
bool bga_is_hw_present();
void *bga_initialize();
bool bga_is_mode_supported(uint32_t x, uint32_t y, uint32_t bpp);
bool bga_set_mode(uint32_t x, uint32_t y, uint32_t bpp);
struct framebuffer* bga_driver_initialize();
#endif //OPERATING_SYSTEM_BGA_H

67
src/video/framebuffer.c Normal file

@ -0,0 +1,67 @@
#include "framebuffer.h"
#include "config.h"
#include "memory/memory.h"
#include "assert.h"
#include "bga/bga.h"
struct framebuffer *framebuffers[MAX_FRAMEBUFFERS];
static struct framebuffer **fb_get_free_framebuffer() {
int i = 0;
for (i = 0; i < MAX_FRAMEBUFFERS; i++) {
if (framebuffers[i] == 0) {
return &framebuffers[i];
}
}
return 0;
}
void fb_insert_framebuffer(struct framebuffer *framebuffer) {
struct framebuffer **fb;
if (!framebuffer) {
panic("Null pointer passed to %s:%i\n", __FILE__, __LINE__);
}
fb = fb_get_free_framebuffer();
if (!fb) {
panic("Failed to insert framebuffer %s:%i", __FILE__, __LINE__);
}
*fb = framebuffer;
}
static void fb_static_init() {
fb_insert_framebuffer(bga_driver_initialize());
}
void fb_init() {
memset(framebuffers, 0, sizeof(framebuffers));
fb_static_init();
for (int i = 0; i < MAX_FRAMEBUFFERS; i++) {
if (framebuffers[i]) {
framebuffers[i]->present = framebuffers[i]->is_present();
}
}
}
static struct framebuffer *fb_find_first_present() {
struct framebuffer *fb = NULL;
for (int i = 0; i < MAX_FRAMEBUFFERS; i++) {
if (framebuffers[i]->present) {
fb = framebuffers[i];
break;
}
}
return fb;
}
void *fb_initialize() {
return fb_find_first_present()->init();
}
bool fb_is_mode_supported(uint32_t x, uint32_t y, uint32_t bpp) {
return fb_find_first_present()->is_mode_supported(x, y, bpp);
}
bool fb_set_mode(uint32_t x, uint32_t y, uint32_t bpp) {
return fb_find_first_present()->set_mode(x, y, bpp);
}

28
src/video/framebuffer.h Normal file

@ -0,0 +1,28 @@
#ifndef OPERATING_SYSTEM_FRAMEBUFFER_H
#define OPERATING_SYSTEM_FRAMEBUFFER_H
#include <stdint.h>
#include <stdbool.h>
typedef bool (*FRAMEBUFFER_IS_PRESENT)();
typedef void *(*FRAMEBUFFER_INIT)();
typedef bool (*FRAMEBUFFER_IS_MODE_SUPPORTED)(uint32_t x, uint32_t y, uint32_t bpp);
typedef bool (*FRAMEBUFFER_SET_MODE)(uint32_t x, uint32_t y, uint32_t bpp);
typedef void (*FRAMEBUFFER_PAGE_SWAP)();
struct framebuffer {
char name[20];
FRAMEBUFFER_INIT init;
FRAMEBUFFER_IS_PRESENT is_present;
FRAMEBUFFER_IS_MODE_SUPPORTED is_mode_supported;
FRAMEBUFFER_SET_MODE set_mode;
FRAMEBUFFER_PAGE_SWAP page_swap;
bool present;
};
void fb_init();
void *fb_initialize();
bool fb_is_mode_supported(uint32_t x, uint32_t y, uint32_t bpp);
bool fb_set_mode(uint32_t x, uint32_t y, uint32_t bpp);
#endif //OPERATING_SYSTEM_FRAMEBUFFER_H