[fb] Create fb driver

Create a new framebuffer driver. Also hackily passing frame buffer size
in the list of init handles to all processes and mapping the framebuffer
into all processes. Changed bootloader passing frame buffer as a module
to its own struct.
This commit is contained in:
2020-12-27 18:49:38 -08:00
committed by Justin C. Miller
parent e70eb5a926
commit 19cbf1ca67
15 changed files with 170 additions and 71 deletions

View File

@@ -17,6 +17,7 @@
#include "log.h"
#include "objects/channel.h"
#include "objects/event.h"
#include "objects/thread.h"
#include "scheduler.h"
#include "serial.h"
#include "symbol_table.h"
@@ -44,6 +45,10 @@ run_constructors()
extern void __kernel_assert(const char *, unsigned, const char *);
/// TODO: not this. this is awful.
uintptr_t fb_loc = 0;
size_t fb_size = 0;
/// Bootstrap the memory managers.
void memory_initialize_pre_ctors(kernel::args::header *kargs);
void memory_initialize_post_ctors(kernel::args::header *kargs);
@@ -131,6 +136,11 @@ kernel_main(args::header *header)
}
}
if (header->video.size > 0) {
fb_size = header->video.size;
fb_loc = header->video.phys_addr;
}
log::debug(logs::boot, " jsix header is at: %016lx", header);
log::debug(logs::boot, " Memory map is at: %016lx", header->mem_map);
log::debug(logs::boot, "ACPI root table is at: %016lx", header->acpi_table);
@@ -176,7 +186,10 @@ kernel_main(args::header *header)
// Skip program 0, which is the kernel itself
for (size_t i = 1; i < header->num_programs; ++i) {
args::program &prog = header->programs[i];
sched->load_process(prog.phys_addr, prog.virt_addr, prog.size, prog.entrypoint);
thread *th = sched->load_process(prog.phys_addr, prog.virt_addr, prog.size, prog.entrypoint);
if (i == 2) {
th->set_state(thread::state::constant);
}
}
sched->create_kernel_task(logger_task, scheduler::max_priority-1, true);

View File

@@ -28,6 +28,8 @@ enum class vm_flags : uint32_t
large_pages = 0x00000100,
huge_pages = 0x00000200,
mmio = 0x00010000,
user_mask = 0x0000ffff ///< flags allowed via syscall
};

View File

@@ -22,6 +22,9 @@
scheduler *scheduler::s_instance = nullptr;
extern uintptr_t fb_loc;
extern size_t fb_size;
const uint64_t rflags_noint = 0x002;
const uint64_t rflags_int = 0x202;
@@ -87,6 +90,12 @@ load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb)
init->handles[1] = j6_handle_invalid;
init->handles[2] = j6_handle_invalid;
// Crazypants framebuffer part
init->handles[1] = reinterpret_cast<j6_handle_t>(fb_size);
vma = new vm_area_open(fb_size, space, vm_flags::write|vm_flags::mmio);
space.add(0x100000000, vma);
vma->commit(fb_loc, 0, memory::page_count(fb_size));
thread::current().clear_state(thread::state::loading);
return tcb->rsp3;
}
@@ -107,7 +116,7 @@ scheduler::create_process(bool user)
return th;
}
void
thread *
scheduler::load_process(uintptr_t phys, uintptr_t virt, size_t size, uintptr_t entry)
{
@@ -145,6 +154,8 @@ scheduler::load_process(uintptr_t phys, uintptr_t virt, size_t size, uintptr_t e
log::debug(logs::task, " RSP %016lx", tcb->rsp);
log::debug(logs::task, " RSP0 %016lx", tcb->rsp0);
log::debug(logs::task, " PML4 %016lx", tcb->pml4);
return th;
}
void

View File

@@ -45,7 +45,8 @@ public:
/// \arg virt Virtual address of the loaded program image
/// \arg size Size of the program image, in bytes
/// \arg entry Virtual address of the program entrypoint
void load_process(uintptr_t phys, uintptr_t virt, size_t size, uintptr_t entry);
/// \returns The main thread of the loaded process
thread * load_process(uintptr_t phys, uintptr_t virt, size_t size, uintptr_t entry);
/// Create a new kernel task
/// \arg proc Function to run as a kernel task

View File

@@ -30,6 +30,14 @@ vm_mapper_single::unmap(uintptr_t offset, size_t count)
m_space.clear(m_area, offset, count, true);
}
void
vm_mapper_single::remove(vm_space *space)
{
size_t count = memory::page_count(m_area.size());
bool keep = m_area.flags() && vm_flags::mmio;
m_space.clear(m_area, 0, count, !keep);
}
vm_mapper_multi::vm_mapper_multi(vm_area &area) :
@@ -88,11 +96,13 @@ void
vm_mapper_multi::remove(vm_space *space)
{
size_t count = memory::page_count(m_area.size());
bool keep = m_area.flags() && vm_flags::mmio;
for (int i = 0; i < m_spaces.count(); ++i) {
if (m_spaces[i] == space) {
m_spaces.remove_swap_at(i);
space->clear(m_area, 0, count, m_spaces.count() == 0);
keep &= m_spaces.count() > 0;
space->clear(m_area, 0, count, !keep);
}
}
}

View File

@@ -54,6 +54,8 @@ public:
vm_space & space() { return m_space; }
virtual void remove(vm_space *space) override;
private:
vm_area &m_area;
vm_space &m_space;

View File

@@ -175,8 +175,10 @@ vm_space::page_in(const vm_area &vma, uintptr_t offset, uintptr_t phys, size_t c
page_table::iterator it {virt, m_pml4};
for (size_t i = 0; i < count; ++i) {
it.entry(page_table::level::pt) =
(phys + i * frame_size) | flags;
uint64_t &entry = it.entry(page_table::level::pt);
entry = (phys + i * frame_size) | flags;
log::debug(logs::paging, "Setting entry for %016llx: %016llx [%04llx]",
it.vaddress(), (phys + i * frame_size), flags);
++it;
}
}