0.0.2d: Added BGA support, graphics!
This commit is contained in:
@ -11,7 +11,7 @@
|
||||
#define ALIGN_UP(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
|
||||
|
||||
|
||||
elf_executable_t* load_elf32(void* elf_data)
|
||||
int load_elf32(void* elf_data, elf_executable_t** ptr)
|
||||
{
|
||||
Elf32_Ehdr* ehdr = (Elf32_Ehdr*)elf_data;
|
||||
|
||||
@ -19,13 +19,13 @@ elf_executable_t* load_elf32(void* elf_data)
|
||||
if (memcmp(ehdr->e_ident, (uint8_t*)("\x7F""ELF"), 4) != 0)
|
||||
{
|
||||
printf("Invalid ELF file\n");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ehdr->e_machine != 3 || ehdr->e_type != 2)
|
||||
{
|
||||
printf("Unsupported ELF type or architecture\n");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Elf32_Phdr* phdrs = (Elf32_Phdr*)((uint8_t*)elf_data + ehdr->e_phoff);
|
||||
@ -60,10 +60,17 @@ elf_executable_t* load_elf32(void* elf_data)
|
||||
#endif
|
||||
}
|
||||
|
||||
elf_executable_t* result = malloc(sizeof(elf_executable_t));
|
||||
result->entry_point = (elf_entry_t)(uintptr_t)ehdr->e_entry;
|
||||
return result;
|
||||
*ptr = malloc(sizeof(elf_executable_t));
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
(*ptr)->entry_point = (elf_entry_t)(uintptr_t) ehdr->e_entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
/*
|
||||
elf_executable_t* result = malloc(sizeof(elf_executable_t));
|
||||
result->entry_point = (elf_entry_t)(uintptr_t)ehdr->e_entry;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include <drivers/ide.h>
|
||||
|
||||
#include <fs/ekfs.h>
|
||||
|
||||
/* work on this later */
|
||||
#if 0
|
||||
|
||||
/* note: __l being 0 is allowed, because that way read() can be used to tell if a file exists (with return value 0) */
|
||||
int ekfs_read(struct ekfs_file* __f, void* __b, size_t __l)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (!__f || !__b || (!__f->f_inode))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we assume drive 0 is already mounted */
|
||||
|
||||
char buffer[512];
|
||||
memset(buffer, 0, 512);
|
||||
|
||||
int num_sectors = __f->f_inode->i_len / 512;
|
||||
|
||||
if ((__l / 512) > num_sectors)
|
||||
{
|
||||
return EKFS_E_FILETOOSMALL;
|
||||
}
|
||||
|
||||
int read_sectors = num_sectors;
|
||||
|
||||
for (int i = 0; i < read_sectors; i++);
|
||||
{
|
||||
rv = read_sector(__f->f_inode->i_start, buffer);
|
||||
|
||||
if (rv != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -20,6 +20,8 @@ int fat16_mount(uint8_t drive)
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void) drive;
|
||||
|
||||
fs.bytes_per_sector = boot_sector[11] | (boot_sector[12] << 8);
|
||||
fs.sectors_per_cluster = boot_sector[13];
|
||||
fs.reserved_sector_count = boot_sector[14] | (boot_sector[15] << 8);
|
||||
@ -53,7 +55,7 @@ static int read_fat_entry(uint16_t cluster, uint16_t* out_value)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (idx == fs.bytes_per_sector - 1)
|
||||
if (idx == (uint32_t)(fs.bytes_per_sector - 1))
|
||||
{
|
||||
/* entry spans boundary -> read next sector */
|
||||
uint8_t next_sector[SECTOR_SIZE];
|
||||
|
||||
@ -7,25 +7,7 @@
|
||||
|
||||
/* we use something similar to the Linux kernel in terms of a VFS system */
|
||||
|
||||
#define MAX_FDS 64
|
||||
|
||||
struct inode {
|
||||
size_t size;
|
||||
int permissions;
|
||||
void *fs_data; /* FS-specific */
|
||||
};
|
||||
|
||||
struct file_ops {
|
||||
int (*read)(struct file*, char*, size_t);
|
||||
int (*write)(struct file*, const char*, size_t);
|
||||
};
|
||||
|
||||
struct file {
|
||||
struct inode* f_inode;
|
||||
size_t f_offset;
|
||||
size_t f_refcount;
|
||||
const struct file_ops f_ops;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -35,17 +17,9 @@ struct fdtable {
|
||||
|
||||
|
||||
|
||||
int vfs_handle_stdout(struct file* __f, const char* __s, size_t __l)
|
||||
{
|
||||
(void) __f;
|
||||
terminal_write(__s, __l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct fdtable* vfs_init_kernel_fdtable(void)
|
||||
{
|
||||
#if 0
|
||||
struct fdtable* ft = malloc(sizeof(struct fdtable));
|
||||
struct file* _stdout = malloc(sizeof(struct file));
|
||||
struct file* _stdin = malloc(sizeof(struct file));
|
||||
@ -59,9 +33,9 @@ struct fdtable* vfs_init_kernel_fdtable(void)
|
||||
_stdout->f_offset = 0;
|
||||
_stdout->f_refcount = 1;
|
||||
_stdout->f_ops = { .read = NULL, .write = vfs_handle_stdout };
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int init_vfs(int argc, char** argv)
|
||||
{
|
||||
|
||||
173
drivers/graphics/vga.c
Normal file
173
drivers/graphics/vga.c
Normal file
@ -0,0 +1,173 @@
|
||||
#include <types.h>
|
||||
#include <mm/paging.h>
|
||||
#include <stdio.h>
|
||||
#include <port_io.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <drivers/graphics/vga.h>
|
||||
|
||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
||||
|
||||
#define VBE_DISPI_INDEX_ID 0x0
|
||||
#define VBE_DISPI_INDEX_XRES 0x1
|
||||
#define VBE_DISPI_INDEX_YRES 0x2
|
||||
#define VBE_DISPI_INDEX_BPP 0x3
|
||||
#define VBE_DISPI_INDEX_ENABLE 0x4
|
||||
#define VBE_DISPI_INDEX_BANK 0x5
|
||||
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
|
||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
|
||||
#define VBE_DISPI_INDEX_X_OFFSET 0x8
|
||||
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
|
||||
|
||||
#define VBE_DISPI_DISABLED 0x00
|
||||
#define VBE_DISPI_ENABLED 0x01
|
||||
#define VBE_DISPI_LFB_ENABLED 0x40
|
||||
|
||||
static bool bga_init = false;
|
||||
static bool bga_error = false;
|
||||
|
||||
uint32_t current_bpp = 0;
|
||||
uint32_t current_xres = 0;
|
||||
uint32_t current_yres = 0;
|
||||
|
||||
static struct bga_framebuffer bga_fb;
|
||||
|
||||
void init_bga_framebuffer(uint32_t* _p)
|
||||
{
|
||||
uint32_t width = 1024;
|
||||
uint32_t height = 768;
|
||||
uint32_t bpp = 32;
|
||||
|
||||
uint32_t pitch = width * (bpp / 8);
|
||||
|
||||
uint32_t fb_size = pitch * height;
|
||||
|
||||
fb_size = (fb_size + 0xFFF) & ~0xFFF;
|
||||
|
||||
uint8_t* bp = (uint8_t*) _p;
|
||||
|
||||
for (uint32_t off = 0; off < fb_size; off += 0x1000)
|
||||
{
|
||||
map_page(bp + off, bp + off);
|
||||
}
|
||||
|
||||
|
||||
bga_fb.addr = _p;
|
||||
bga_fb.bpp = bpp;
|
||||
bga_fb.height = height;
|
||||
bga_fb.width = width;
|
||||
bga_fb.pitch = pitch;
|
||||
|
||||
bga_init = true;
|
||||
}
|
||||
|
||||
uint8_t* bga_get_framebuffer(void)
|
||||
{
|
||||
return bga_fb.addr;
|
||||
}
|
||||
|
||||
void bga_write_register(uint16_t index, uint16_t data)
|
||||
{
|
||||
outw(VBE_DISPI_IOPORT_INDEX, index);
|
||||
outw(VBE_DISPI_IOPORT_DATA, data);
|
||||
}
|
||||
|
||||
uint16_t bga_read_register(uint16_t index)
|
||||
{
|
||||
outw(VBE_DISPI_IOPORT_INDEX, index);
|
||||
return inw(VBE_DISPI_IOPORT_DATA);
|
||||
}
|
||||
|
||||
void bga_set_video_mode(uint32_t width, uint32_t height, uint32_t bit_depth)
|
||||
{
|
||||
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
bga_write_register(VBE_DISPI_INDEX_XRES, width);
|
||||
bga_write_register(VBE_DISPI_INDEX_YRES, height);
|
||||
bga_write_register(VBE_DISPI_INDEX_BPP, bit_depth);
|
||||
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
|
||||
|
||||
/* now we check to see if any info we gave was rejected, in which case everything would be the way it was before we wrote the configuration info. */
|
||||
uint16_t bpp = bga_read_register(VBE_DISPI_INDEX_BPP);
|
||||
if (bpp != bit_depth)
|
||||
{
|
||||
bga_error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_bpp = bit_depth;
|
||||
current_xres = width;
|
||||
current_yres = height;
|
||||
}
|
||||
}
|
||||
|
||||
void bga_defaults(void)
|
||||
{
|
||||
// Disable device while changing settings
|
||||
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
|
||||
// Set resolution
|
||||
bga_write_register(VBE_DISPI_INDEX_XRES, 1024);
|
||||
bga_write_register(VBE_DISPI_INDEX_YRES, 768);
|
||||
bga_write_register(VBE_DISPI_INDEX_BPP, 32);
|
||||
|
||||
// Enable graphics + linear framebuffer
|
||||
bga_write_register(
|
||||
VBE_DISPI_INDEX_ENABLE,
|
||||
VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
/*void bga_putpixel(uint32_t x, uint32_t y, uint32_t color)
|
||||
{
|
||||
if (current_bpp == 16)
|
||||
{
|
||||
uint16_t* fb = (uint16_t*) bga_framebuffer;
|
||||
uint32_t idx = (y * current_xres + x) * 2;
|
||||
|
||||
*(fb + idx) = (uint16_t) color;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
void bga_putpixel(uint32_t x, uint32_t y, uint32_t color)
|
||||
{
|
||||
uint32_t bytes_per_pixel = bga_fb.bpp / 8;
|
||||
|
||||
uint8_t* pixel = (uint8_t*)bga_fb.addr + (y * bga_fb.pitch) + (x * bytes_per_pixel);
|
||||
|
||||
*(volatile uint32_t*)pixel = color;
|
||||
}
|
||||
|
||||
void bga_drawline(int x0, int y0, int x1, int y1, uint32_t color)
|
||||
{
|
||||
int dx = abs(x1 - x0);
|
||||
int dy = abs(y1 - y0);
|
||||
|
||||
int sx = (x0 < x1) ? 1 : -1;
|
||||
int sy = (y0 < y1) ? 1 : -1;
|
||||
|
||||
int err = dx - dy;
|
||||
|
||||
while (1)
|
||||
{
|
||||
bga_putpixel(x0, y0, color);
|
||||
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
|
||||
int e2 = err * 2;
|
||||
|
||||
if (e2 > -dy)
|
||||
{
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
|
||||
if (e2 < dx)
|
||||
{
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,12 @@ static int32_t ide_wait_ready(uint16_t io)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_sector_size(uint8_t drive)
|
||||
{
|
||||
(void) drive;
|
||||
return SECTOR_SIZE;
|
||||
}
|
||||
|
||||
int32_t ide_identify(uint8_t drive, uint16_t* buffer)
|
||||
{
|
||||
uint16_t io = ATA_PRIMARY_IO;
|
||||
|
||||
@ -61,7 +61,6 @@ int init_keyboard(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
registers_t* keyboard_handler(registers_t* regs)
|
||||
{
|
||||
if (!(inb(PS2_STATUS_PORT) & 1))
|
||||
@ -70,14 +69,78 @@ registers_t* keyboard_handler(registers_t* regs)
|
||||
}
|
||||
|
||||
uint8_t scancode = inb(PS2_DATA_PORT);
|
||||
|
||||
if (scancode & 0x80)
|
||||
|
||||
if (scancode == 0xE0)
|
||||
{
|
||||
extended = true;
|
||||
return regs;
|
||||
}
|
||||
|
||||
bool is_release = scancode & 0x80;
|
||||
uint8_t key = scancode & 0x7F;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
if (is_release)
|
||||
{
|
||||
if (key == 0x1D)
|
||||
{
|
||||
mods &= ~MODIFIER_RCTRL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key == 0x1D)
|
||||
{
|
||||
mods |= MODIFIER_RCTRL;
|
||||
}
|
||||
}
|
||||
|
||||
/* delete key, should add this functionality */
|
||||
/*if (key == 0x53)*/
|
||||
|
||||
extended = false;
|
||||
return regs;
|
||||
}
|
||||
|
||||
if (is_release)
|
||||
{
|
||||
if (key == 0x2A || key == 0x36)
|
||||
{
|
||||
mods &= ~MODIFIER_SHIFT;
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key == 0x2A || key == 0x36)
|
||||
{
|
||||
mods |= MODIFIER_SHIFT;
|
||||
return regs;
|
||||
}
|
||||
else if (key == 0x3A)
|
||||
{
|
||||
mods ^= MODIFIER_CAPS;
|
||||
return regs;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t c = (uint16_t) scancode_map[scancode];
|
||||
|
||||
if (c)
|
||||
{
|
||||
//tty_receive_char(c, mods);
|
||||
char ch = tty_translate_char(c, mods);
|
||||
tty_input_char(tty_get_active(), ch);
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
|
||||
/* Handle shift press/release */
|
||||
if (scancode == 0x2A || scancode == 0x36)
|
||||
/*if (scancode == 0x2A || scancode == 0x36)
|
||||
{
|
||||
mods |= MODIFIER_SHIFT;
|
||||
return regs;
|
||||
@ -89,9 +152,11 @@ registers_t* keyboard_handler(registers_t* regs)
|
||||
}
|
||||
else if (scancode == 0x3A)
|
||||
{
|
||||
TOGGLE_BIT(mods, 0); /* TOGGLE_BIT defined in types.h, should move elsewhere. */
|
||||
TOGGLE_BIT(mods, 0);
|
||||
return regs;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*else if (scancode == 0xE0)
|
||||
{
|
||||
extended = true;
|
||||
@ -127,22 +192,10 @@ registers_t* keyboard_handler(registers_t* regs)
|
||||
return;
|
||||
}*/
|
||||
|
||||
bool release = scancode & 0x80;
|
||||
/*bool release = scancode & 0x80;
|
||||
scancode &= 0x7F;
|
||||
|
||||
if (release)
|
||||
{
|
||||
return regs;
|
||||
}
|
||||
|
||||
uint16_t c = (uint16_t) scancode_map[scancode];
|
||||
|
||||
if (c)
|
||||
{
|
||||
//tty_receive_char(c, mods);
|
||||
char ch = tty_translate_char(c, mods);
|
||||
tty_input_char(tty_get_active(), ch);
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
}*/
|
||||
|
||||
@ -33,11 +33,27 @@ static inline bool is_canonical(tty_t* tty)
|
||||
return (tty->flags & TTY_CANONICAL) != 0;
|
||||
}
|
||||
|
||||
static void raw_put(tty_t* tty, char c)
|
||||
{
|
||||
size_t next = (tty->raw_head + 1) % TTY_RAW_BUFFER_SIZE;
|
||||
|
||||
if (next != tty->raw_tail) // avoid overflow
|
||||
{
|
||||
tty->raw_buf[tty->raw_head] = c;
|
||||
tty->raw_head = next;
|
||||
}
|
||||
}
|
||||
|
||||
tty_t* tty_get_active(void)
|
||||
{
|
||||
return active_tty;
|
||||
}
|
||||
|
||||
int tty_fread(struct file* f, char* b, size_t s)
|
||||
{
|
||||
return (int) tty_read_active(b, s);
|
||||
}
|
||||
|
||||
void tty_backspace(tty_t* tty)
|
||||
{
|
||||
if (tty->head == tty->tail)
|
||||
@ -48,50 +64,88 @@ void tty_backspace(tty_t* tty)
|
||||
tty->head = (tty->head + TTY_BUFFER_SIZE - 1) / TTY_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
void tty_and_flags(tty_t* tty, uint32_t flags)
|
||||
{
|
||||
tty->flags &= flags;
|
||||
}
|
||||
|
||||
uint32_t tty_get_flags(tty_t* tty)
|
||||
{
|
||||
return tty->flags;
|
||||
}
|
||||
|
||||
ssize_t tty_read_active(char* buf, size_t count)
|
||||
{
|
||||
return tty_read(active_tty, buf, count);
|
||||
}
|
||||
|
||||
/*ssize_t tty_read(tty_t* tty, char* buf, size_t count)
|
||||
/*
|
||||
this is special, because when this is called the char returned by this function
|
||||
is NOT added to the TTY buffer.
|
||||
This can be changed however by setting flag TTY_ADDCHAR_ALWAYS.
|
||||
*/
|
||||
/*char tty_get_char(void)
|
||||
{
|
||||
size_t bytes_read = 0;
|
||||
tty_t* tty = get_active_tty();
|
||||
if (!tty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (bytes_read < count)
|
||||
while (1)
|
||||
{
|
||||
IRQ_DISABLE();
|
||||
spin_lock(&tty->lock);
|
||||
|
||||
if (!tty_empty(tty))
|
||||
if (tty->char_available)
|
||||
{
|
||||
char c = tty->input_buffer[tty->tail];
|
||||
tty->tail = (tty->tail + 1) % TTY_BUFFER_SIZE;
|
||||
tty->tail = next_index(tty->tail);
|
||||
char c = tty->last_char;
|
||||
tty->char_available = false;
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE(); /* change? *//*
|
||||
|
||||
buf[bytes_read++] = c;
|
||||
|
||||
if (is_canonical(tty) && c == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
return c;
|
||||
}
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
}
|
||||
}*/
|
||||
|
||||
char tty_get_char(void)
|
||||
{
|
||||
tty_t* tty = get_active_tty();
|
||||
if (!tty)
|
||||
return 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
IRQ_DISABLE();
|
||||
spin_lock(&tty->lock);
|
||||
|
||||
if (tty->raw_head != tty->raw_tail)
|
||||
{
|
||||
char c = tty->raw_buf[tty->raw_tail];
|
||||
tty->raw_tail = (tty->raw_tail + 1) % TTY_RAW_BUFFER_SIZE;
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t tty_read(tty_t* tty, char* buf, size_t count)
|
||||
{
|
||||
if (!tty || !buf)
|
||||
return -1;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t bytes = 0;
|
||||
|
||||
@ -169,6 +223,9 @@ int init_tty(void)
|
||||
active_tty = t;
|
||||
num_ttys = 1;
|
||||
|
||||
t->f_ops.read = tty_fread;
|
||||
t->line_ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -238,15 +295,18 @@ void tty_receive_char(char c, uint32_t kbd_mod)
|
||||
}
|
||||
}
|
||||
|
||||
void tty_input_char(tty_t* tty, char c)
|
||||
/*void tty_input_char(tty_t* tty, char c)
|
||||
{
|
||||
if (!tty || c == 0)
|
||||
return;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IRQ_DISABLE();
|
||||
spin_lock(&tty->lock);
|
||||
|
||||
/* backspace */
|
||||
raw_put(tty, c);
|
||||
|
||||
if (c == '\b')
|
||||
{
|
||||
if (tty->head != tty->tail)
|
||||
@ -255,9 +315,7 @@ void tty_input_char(tty_t* tty, char c)
|
||||
|
||||
if (tty->flags & TTY_ECHO)
|
||||
{
|
||||
putc('\b');/*
|
||||
putc(' ');
|
||||
putc('\b');*/
|
||||
putc('\b');
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,6 +340,65 @@ void tty_input_char(tty_t* tty, char c)
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
|
||||
if (tty->flags & TTY_ECHO)
|
||||
{
|
||||
putc(c);
|
||||
}
|
||||
}*/
|
||||
|
||||
void tty_input_char(tty_t* tty, char c)
|
||||
{
|
||||
if (!tty || c == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IRQ_DISABLE();
|
||||
spin_lock(&tty->lock);
|
||||
|
||||
/* RAW queue always gets input */
|
||||
raw_put(tty, c);
|
||||
|
||||
if (!(tty->flags & TTY_RAW))
|
||||
{
|
||||
/* canonical behavior */
|
||||
|
||||
if (c == '\b')
|
||||
{
|
||||
if (tty->head != tty->tail)
|
||||
{
|
||||
tty->head = (tty->head + TTY_BUFFER_SIZE - 1) % TTY_BUFFER_SIZE;
|
||||
|
||||
putc('\b');
|
||||
putc(' ');
|
||||
putc('\b');
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t next = next_index(tty->head);
|
||||
|
||||
if (next != tty->tail)
|
||||
{
|
||||
tty->input_buffer[tty->head] = c;
|
||||
tty->head = next;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
tty->line_ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&tty->lock);
|
||||
IRQ_ENABLE();
|
||||
|
||||
if (tty->flags & TTY_ECHO)
|
||||
{
|
||||
putc(c);
|
||||
|
||||
132
drivers/pci.c
132
drivers/pci.c
@ -17,96 +17,104 @@
|
||||
|
||||
uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
|
||||
{
|
||||
uint32_t address = 0;
|
||||
address |= (bus << 16); /* Bus number (bits 23-16) */
|
||||
address |= (device << 11); /* Device number (bits 15-11) */
|
||||
address |= (function << 8); /* Function number (bits 10-8) */
|
||||
address |= (offset & 0xFC); /* Register offset (bits 7-0) */
|
||||
address |= (1 << 31); /* Enable configuration access */
|
||||
uint32_t address = 0;
|
||||
address |= (bus << 16); /* Bus number (bits 23-16) */
|
||||
address |= (device << 11); /* Device number (bits 15-11) */
|
||||
address |= (function << 8); /* Function number (bits 10-8) */
|
||||
address |= (offset & 0xFC); /* Register offset (bits 7-0) */
|
||||
address |= (1 << 31); /* Enable configuration access */
|
||||
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Write address to PCI config space */
|
||||
return inl(PCI_CONFIG_DATA); /* Read data from PCI config space */
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Write address to PCI config space */
|
||||
return inl(PCI_CONFIG_DATA); /* Read data from PCI config space */
|
||||
}
|
||||
|
||||
void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value)
|
||||
{
|
||||
uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Send the address to PCI config space */
|
||||
outl(PCI_CONFIG_DATA, value); /* Write data to PCI config space */
|
||||
uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Send the address to PCI config space */
|
||||
outl(PCI_CONFIG_DATA, value); /* Write data to PCI config space */
|
||||
}
|
||||
|
||||
void pci_config_read_block(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, void* buffer, size_t size)
|
||||
{
|
||||
uint8_t* buf = (uint8_t*)buffer;
|
||||
uint8_t* buf = (uint8_t*)buffer;
|
||||
|
||||
for (size_t i = 0; i < size; i += 4)
|
||||
{
|
||||
uint32_t value = pci_config_read(bus, device, function, offset + i);
|
||||
for (size_t i = 0; i < size; i += 4)
|
||||
{
|
||||
uint32_t value = pci_config_read(bus, device, function, offset + i);
|
||||
|
||||
size_t remaining = size - i;
|
||||
if (remaining >= 4)
|
||||
{
|
||||
*(uint32_t*)(buf + i) = value;
|
||||
size_t remaining = size - i;
|
||||
if (remaining >= 4)
|
||||
{
|
||||
*(uint32_t*)(buf + i) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t j = 0; j < remaining; ++j)
|
||||
{
|
||||
buf[i + j] = (value >> (8 * j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t j = 0; j < remaining; ++j)
|
||||
{
|
||||
buf[i + j] = (value >> (8 * j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pci_init(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
printf("[ PCI ] Initializing PCI...\n");
|
||||
printf("[ PCI ] Initializing PCI...\n");
|
||||
#endif
|
||||
|
||||
pci_enumerate();
|
||||
|
||||
pci_enumerate();
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("[ PCI ] PCI initialized\n");
|
||||
printf("[ PCI ] PCI initialized\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void pci_enumerate(void)
|
||||
{
|
||||
for (uint16_t bus = 0; bus < 256; bus++) /* Maximum 256 buses */
|
||||
{
|
||||
for (uint8_t device = 0; device < 32; device++) /* Maximum 32 devices per bus */
|
||||
for (uint16_t bus = 0; bus < 256; bus++) /* Maximum 256 buses */
|
||||
{
|
||||
for (uint8_t function = 0; function < 8; function++) /* Maximum 8 functions per device */
|
||||
{
|
||||
struct pci_header pre_header;
|
||||
pci_config_read_block(bus, device, function, 0x00, &pre_header, sizeof(pre_header));
|
||||
for (uint8_t device = 0; device < 32; device++) /* Maximum 32 devices per bus */
|
||||
{
|
||||
for (uint8_t function = 0; function < 8; function++) /* Maximum 8 functions per device */
|
||||
{
|
||||
struct pci_header pre_header;
|
||||
pci_config_read_block(bus, device, function, 0x00, &pre_header, sizeof(pre_header));
|
||||
|
||||
if (pre_header.vendor_id == 0xFFFF)
|
||||
{
|
||||
continue; /* No device present */
|
||||
}
|
||||
|
||||
if (pre_header.class_code == 0xB)
|
||||
{
|
||||
printf("Processor found on PCI bus, what?!?!\n"); /* For some stupid reason, processors can be on the PCI bus? */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pre_header.header_type == 0x00)
|
||||
{
|
||||
struct pci_header_type_0 hdr;
|
||||
pci_config_read_block(bus, device, function, 0x00, &hdr, sizeof(hdr));
|
||||
if (pre_header.vendor_id == 0xFFFF)
|
||||
{
|
||||
continue; /* No device present */
|
||||
}
|
||||
|
||||
if (hdr.class_code == 0x1 && hdr.subclass == 0x6 && hdr.prog_if == 0x1)
|
||||
{
|
||||
/*configure_ahci_controller(hdr);*/
|
||||
}
|
||||
|
||||
|
||||
/*printf("PCI device: cc: %x sc: %x pi: %x b: %x d: %x f: %x int: %x\n", hdr.class_code, hdr.subclass, hdr.prog_if, bus, device, function, (uint32_t) hdr.interrupt_line);*/
|
||||
if (pre_header.class_code == 0xB)
|
||||
{
|
||||
printf("Processor found on PCI bus, what?!?!\n"); /* For some stupid reason, processors can be on the PCI bus? */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pre_header.header_type == 0x00)
|
||||
{
|
||||
struct pci_header_type_0 hdr;
|
||||
pci_config_read_block(bus, device, function, 0x00, &hdr, sizeof(hdr));
|
||||
|
||||
if (hdr.class_code == 0x1 && hdr.subclass == 0x6 && hdr.prog_if == 0x1)
|
||||
{
|
||||
/*configure_ahci_controller(hdr);*/
|
||||
}
|
||||
|
||||
if (hdr.class_code == 0x03)
|
||||
{
|
||||
uint32_t bar0 = hdr.bar0;
|
||||
extern void init_bga_framebuffer(uint32_t* _p);
|
||||
init_bga_framebuffer((uint32_t*) bar0);
|
||||
printf("Found framebffer addr 0x%x on device %x \n", bar0, hdr.device_id);
|
||||
}
|
||||
|
||||
|
||||
/*printf("PCI device: cc: %x sc: %x pi: %x b: %x d: %x f: %x int: %x\n", hdr.class_code, hdr.subclass, hdr.prog_if, bus, device, function, (uint32_t) hdr.interrupt_line);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include <vga/vga.h>
|
||||
#include <stdio.h>
|
||||
#include <port_io.h>
|
||||
#include <new_tty.h>
|
||||
#include <fs/vfs.h>
|
||||
|
||||
#include <tty.h>
|
||||
|
||||
@ -18,6 +20,19 @@ void terminal_initialize(void)
|
||||
terminal_update_cursor();
|
||||
}
|
||||
|
||||
ssize_t tty_write(struct file* f, const char* buf, size_t size)
|
||||
{
|
||||
/*struct tty* tty = (struct tty*)f->private_data;*/
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
/*tty_putchar(tty, buf[i]);*/ /* do this when we have multiple TTY outputs & stuff */
|
||||
terminal_putchar(buf[i]);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void terminal_get_cursor(int* row, int* column)
|
||||
{
|
||||
*row = (int) terminal_row;
|
||||
@ -106,7 +121,7 @@ void terminal_putchar(const char c)
|
||||
|
||||
return;
|
||||
}
|
||||
else if (uc == '\b')
|
||||
/*else if (uc == '\b')
|
||||
{
|
||||
if (terminal_column == 0)
|
||||
{
|
||||
@ -117,7 +132,7 @@ void terminal_putchar(const char c)
|
||||
}
|
||||
else
|
||||
{
|
||||
terminal_update_cursor(); /* For good measure */
|
||||
terminal_update_cursor();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -131,6 +146,31 @@ void terminal_putchar(const char c)
|
||||
|
||||
terminal_update_cursor();
|
||||
|
||||
return;
|
||||
}*/
|
||||
else if (uc == '\b')
|
||||
{
|
||||
if (terminal_column == 0)
|
||||
{
|
||||
if (terminal_row > 0)
|
||||
{
|
||||
terminal_row--;
|
||||
terminal_column = VGA_WIDTH - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
terminal_update_cursor();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terminal_column--;
|
||||
}
|
||||
|
||||
terminal_update_cursor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user