[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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user