Compare commits
13 Commits
b8622f2b4b
...
39802b56c1
Author | SHA1 | Date |
---|---|---|
Bananymous | 39802b56c1 | |
Bananymous | ebb87ccdde | |
Bananymous | f0e55938c1 | |
Bananymous | 348d04f7f5 | |
Bananymous | 1b0086217c | |
Bananymous | d395cf38b7 | |
Bananymous | 57aec2a733 | |
Bananymous | ae89237453 | |
Bananymous | 60d5257678 | |
Bananymous | d59463d11b | |
Bananymous | 1280528e4e | |
Bananymous | 23d6205659 | |
Bananymous | bc0acc6f44 |
|
@ -47,6 +47,27 @@
|
|||
|
||||
#define BOCHS_BREAK() asm volatile("xchgw %bx, %bx")
|
||||
|
||||
|
||||
#define DEBUG_PCI 0
|
||||
#define DEBUG_SCHEDULER 0
|
||||
#define DEBUG_PS2 1
|
||||
|
||||
#define DEBUG_ARP 0
|
||||
#define DEBUG_IPV4 0
|
||||
#define DEBUG_ETHERTYPE 0
|
||||
#define DEBUG_TCP 0
|
||||
#define DEBUG_E1000 0
|
||||
|
||||
#define DEBUG_DISK_SYNC 0
|
||||
#define DEBUG_NVMe 0
|
||||
|
||||
#define DEBUG_XHCI 0
|
||||
#define DEBUG_USB 0
|
||||
#define DEBUG_USB_HID 0
|
||||
#define DEBUG_USB_KEYBOARD 0
|
||||
#define DEBUG_USB_MOUSE 0
|
||||
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
void dump_stack_trace();
|
||||
|
|
|
@ -160,6 +160,7 @@ namespace Kernel
|
|||
BAN::WeakPtr<SharedFileData> m_shared_region;
|
||||
friend class FileBackedRegion;
|
||||
friend class SharedFileData;
|
||||
friend class TTY;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -171,6 +171,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<long> sys_tty_ctrl(int fildes, int command, int flags);
|
||||
|
||||
static BAN::ErrorOr<void> kill(pid_t pid, int signal);
|
||||
BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
|
||||
BAN::ErrorOr<long> sys_sigaction(int signal, const struct sigaction* act, struct sigaction* oact);
|
||||
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
|
||||
|
|
|
@ -82,6 +82,8 @@ namespace Kernel
|
|||
|
||||
void timer_interrupt();
|
||||
|
||||
static BAN::ErrorOr<void> bind_thread_to_processor(Thread*, ProcessorID);
|
||||
// if thread is already bound, this will never fail
|
||||
BAN::ErrorOr<void> add_thread(Thread*);
|
||||
|
||||
void block_current_thread(ThreadBlocker* thread_blocker, uint64_t wake_time_ns);
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace Kernel
|
|||
static BAN::RefPtr<TTY> current();
|
||||
void set_as_current();
|
||||
|
||||
static void keyboard_task(void*);
|
||||
static void initialize_devices();
|
||||
void on_key_event(LibInput::KeyEvent);
|
||||
void handle_input_byte(uint8_t);
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Kernel
|
|||
|
||||
public:
|
||||
static BAN::ErrorOr<Thread*> create_kernel(entry_t, void*, Process*);
|
||||
static BAN::ErrorOr<Thread*> create_userspace(Process*);
|
||||
static BAN::ErrorOr<Thread*> create_userspace(Process*, PageTable&);
|
||||
~Thread();
|
||||
|
||||
BAN::ErrorOr<Thread*> clone(Process*, uintptr_t sp, uintptr_t ip);
|
||||
|
@ -49,11 +49,11 @@ namespace Kernel
|
|||
bool add_signal(int signal);
|
||||
|
||||
// blocks current thread and returns either on unblock, eintr, spuriously or after timeout
|
||||
BAN::ErrorOr<void> sleep_or_eintr_ms(uint64_t ms) { return sleep_or_eintr_ns(ms * 1'000'000); }
|
||||
BAN::ErrorOr<void> sleep_or_eintr_ms(uint64_t ms) { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(ms, 1'000'000)); return sleep_or_eintr_ns(ms * 1'000'000); }
|
||||
BAN::ErrorOr<void> sleep_or_eintr_ns(uint64_t ns);
|
||||
BAN::ErrorOr<void> block_or_eintr_indefinite(ThreadBlocker& thread_blocker);
|
||||
BAN::ErrorOr<void> block_or_eintr_or_timeout_ms(ThreadBlocker& thread_blocker, uint64_t timeout_ms, bool etimedout) { return block_or_eintr_or_timeout_ns(thread_blocker, timeout_ms * 1'000'000, etimedout); }
|
||||
BAN::ErrorOr<void> block_or_eintr_or_waketime_ms(ThreadBlocker& thread_blocker, uint64_t wake_time_ms, bool etimedout) { return block_or_eintr_or_waketime_ns(thread_blocker, wake_time_ms * 1'000'000, etimedout); }
|
||||
BAN::ErrorOr<void> block_or_eintr_or_timeout_ms(ThreadBlocker& thread_blocker, uint64_t timeout_ms, bool etimedout) { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000)); return block_or_eintr_or_timeout_ns(thread_blocker, timeout_ms * 1'000'000, etimedout); }
|
||||
BAN::ErrorOr<void> block_or_eintr_or_waketime_ms(ThreadBlocker& thread_blocker, uint64_t wake_time_ms, bool etimedout) { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(wake_time_ms, 1'000'000)); return block_or_eintr_or_waketime_ns(thread_blocker, wake_time_ms * 1'000'000, etimedout); }
|
||||
BAN::ErrorOr<void> block_or_eintr_or_timeout_ns(ThreadBlocker& thread_blocker, uint64_t timeout_ns, bool etimedout);
|
||||
BAN::ErrorOr<void> block_or_eintr_or_waketime_ns(ThreadBlocker& thread_blocker, uint64_t wake_time_ns, bool etimedout);
|
||||
|
||||
|
@ -72,6 +72,8 @@ namespace Kernel
|
|||
static Thread& current();
|
||||
static pid_t current_tid();
|
||||
|
||||
void give_keep_alive_page_table(BAN::UniqPtr<PageTable>&& page_table) { m_keep_alive_page_table = BAN::move(page_table); }
|
||||
|
||||
Process& process();
|
||||
const Process& process() const;
|
||||
bool has_process() const { return m_process; }
|
||||
|
@ -99,6 +101,10 @@ namespace Kernel
|
|||
void on_exit();
|
||||
|
||||
private:
|
||||
// NOTE: this is the first member to force it being last destructed
|
||||
// {kernel,userspace}_stack has to be destroyed before page table
|
||||
BAN::UniqPtr<PageTable> m_keep_alive_page_table;
|
||||
|
||||
static constexpr size_t m_kernel_stack_size { PAGE_SIZE * 64 };
|
||||
static constexpr size_t m_userspace_stack_size { PAGE_SIZE * 64 };
|
||||
BAN::UniqPtr<VirtualRange> m_kernel_stack;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/Math.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
#include <kernel/Scheduler.h>
|
||||
|
||||
|
@ -10,8 +11,8 @@ namespace Kernel
|
|||
{
|
||||
public:
|
||||
void block_indefinite();
|
||||
void block_with_timeout_ms(uint64_t timeout_ms) { return block_with_timeout_ns(timeout_ms * 1'000'000); }
|
||||
void block_with_wake_time_ms(uint64_t wake_time_ms) { return block_with_wake_time_ns(wake_time_ms * 1'000'000); }
|
||||
void block_with_timeout_ms(uint64_t timeout_ms) { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000)); return block_with_timeout_ns(timeout_ms * 1'000'000); }
|
||||
void block_with_wake_time_ms(uint64_t wake_time_ms) { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(wake_time_ms, 1'000'000)); return block_with_wake_time_ns(wake_time_ms * 1'000'000); }
|
||||
void block_with_timeout_ns(uint64_t timeout_ns);
|
||||
void block_with_wake_time_ns(uint64_t wake_time_ns);
|
||||
void unblock();
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Kernel
|
|||
virtual bool pre_scheduler_sleep_needs_lock() const override;
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) override;
|
||||
|
||||
void sleep_ms(uint64_t ms) const { return sleep_ns(ms * 1'000'000); }
|
||||
void sleep_ms(uint64_t ms) const { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(ms, 1'000'000)); return sleep_ns(ms * 1'000'000); }
|
||||
void sleep_ns(uint64_t ns) const;
|
||||
|
||||
timespec real_time() const;
|
||||
|
|
|
@ -41,6 +41,12 @@ namespace Debug
|
|||
BAN::Formatter::print(Debug::putchar, "\e[36mStack trace:\r\n");
|
||||
while (frame)
|
||||
{
|
||||
if (!PageTable::is_valid_pointer((vaddr_t)frame))
|
||||
{
|
||||
derrorln("invalid pointer {H}", (vaddr_t)frame);
|
||||
break;
|
||||
}
|
||||
|
||||
if (PageTable::current().is_page_free((vaddr_t)frame & PAGE_ADDR_MASK))
|
||||
{
|
||||
derrorln(" {} not mapped", frame);
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include <kernel/IO.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#define DEBUG_PS2 1
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
|
|
|
@ -167,13 +167,18 @@ namespace Kernel
|
|||
|
||||
void ARPTable::add_arp_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
||||
{
|
||||
if (buffer.size() < sizeof(ARPPacket))
|
||||
{
|
||||
dwarnln_if(DEBUG_ARP, "ARP packet too small");
|
||||
return;
|
||||
}
|
||||
auto& arp_packet = buffer.as<const ARPPacket>();
|
||||
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
|
||||
if (m_pending_packets.full())
|
||||
{
|
||||
dprintln("arp packet queue full");
|
||||
dwarnln_if(DEBUG_ARP, "ARP packet queue full");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#include <kernel/Networking/E1000/E1000.h>
|
||||
#include <kernel/Networking/NetworkManager.h>
|
||||
|
||||
#define DEBUG_E1000 1
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -68,10 +66,8 @@ namespace Kernel
|
|||
|
||||
detect_eeprom();
|
||||
TRY(read_mac_address());
|
||||
#if DEBUG_E1000
|
||||
dprintln("E1000 at PCI {}:{}.{}", m_pci_device.bus(), m_pci_device.dev(), m_pci_device.func());
|
||||
dprintln(" MAC: {}", m_mac_address);
|
||||
#endif
|
||||
|
||||
TRY(initialize_rx());
|
||||
TRY(initialize_tx());
|
||||
|
@ -81,14 +77,12 @@ namespace Kernel
|
|||
|
||||
m_link_up = !!(read32(REG_STATUS) & STATUS_LU);
|
||||
|
||||
#if DEBUG_E1000
|
||||
dprintln(" link up: {}", link_up());
|
||||
if (link_up())
|
||||
{
|
||||
int speed = link_speed();
|
||||
dprintln(" link speed: {} Mbps", speed);
|
||||
}
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -285,6 +279,8 @@ namespace Kernel
|
|||
while (descriptor.status == 0)
|
||||
continue;
|
||||
|
||||
dprintln_if(DEBUG_E1000, "sent {} bytes", sizeof(EthernetHeader) + buffer.size());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -303,6 +299,8 @@ namespace Kernel
|
|||
break;
|
||||
ASSERT(descriptor.length <= E1000_RX_BUFFER_SIZE);
|
||||
|
||||
dprintln_if(DEBUG_E1000, "got {} bytes", (uint16_t)descriptor.length);
|
||||
|
||||
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
||||
reinterpret_cast<const uint8_t*>(m_rx_buffer_region->vaddr() + rx_current * E1000_RX_BUFFER_SIZE),
|
||||
descriptor.length
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define DEBUG_IPV4 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -118,7 +116,9 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EAFNOSUPPORT);
|
||||
|
||||
auto& sockaddr_in = *reinterpret_cast<const struct sockaddr_in*>(address);
|
||||
uint16_t port = BAN::host_to_network_endian(sockaddr_in.sin_port);
|
||||
const uint16_t port = BAN::host_to_network_endian(sockaddr_in.sin_port);
|
||||
if (port == NetworkSocket::PORT_NONE)
|
||||
return bind_socket_to_unused(socket, address, address_len);
|
||||
|
||||
SpinLockGuard _(m_bound_socket_lock);
|
||||
|
||||
|
@ -201,6 +201,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> IPv4Layer::handle_ipv4_packet(NetworkInterface& interface, BAN::ByteSpan packet)
|
||||
{
|
||||
ASSERT(packet.size() >= sizeof(IPv4Header));
|
||||
auto& ipv4_header = packet.as<const IPv4Header>();
|
||||
auto ipv4_data = packet.slice(sizeof(IPv4Header));
|
||||
|
||||
|
@ -213,6 +214,11 @@ namespace Kernel
|
|||
{
|
||||
case NetworkProtocol::ICMP:
|
||||
{
|
||||
if (ipv4_data.size() < sizeof(ICMPHeader))
|
||||
{
|
||||
dwarnln("IPv4 packet too small for ICMP");
|
||||
return {};
|
||||
}
|
||||
auto& icmp_header = ipv4_data.as<const ICMPHeader>();
|
||||
switch (icmp_header.type)
|
||||
{
|
||||
|
@ -245,6 +251,11 @@ namespace Kernel
|
|||
}
|
||||
case NetworkProtocol::UDP:
|
||||
{
|
||||
if (ipv4_data.size() < sizeof(UDPHeader))
|
||||
{
|
||||
dwarnln("IPv4 packet too small for UDP");
|
||||
return {};
|
||||
}
|
||||
auto& udp_header = ipv4_data.as<const UDPHeader>();
|
||||
dst_port = udp_header.dst_port;
|
||||
src_port = udp_header.src_port;
|
||||
|
@ -252,6 +263,11 @@ namespace Kernel
|
|||
}
|
||||
case NetworkProtocol::TCP:
|
||||
{
|
||||
if (ipv4_data.size() < sizeof(TCPHeader))
|
||||
{
|
||||
dwarnln("IPv4 packet too small for TCP");
|
||||
return {};
|
||||
}
|
||||
auto& tcp_header = ipv4_data.as<const TCPHeader>();
|
||||
dst_port = tcp_header.dst_port;
|
||||
src_port = tcp_header.src_port;
|
||||
|
@ -322,7 +338,7 @@ namespace Kernel
|
|||
const size_t ipv4_packet_size = reinterpret_cast<const IPv4Header*>(buffer_start)->total_length;
|
||||
|
||||
if (auto ret = handle_ipv4_packet(pending.interface, BAN::ByteSpan(buffer_start, ipv4_packet_size)); ret.is_error())
|
||||
dwarnln("{}", ret.error());
|
||||
dwarnln_if(DEBUG_IPV4, "{}", ret.error());
|
||||
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
m_pending_total_size -= ipv4_packet_size;
|
||||
|
@ -333,32 +349,38 @@ namespace Kernel
|
|||
|
||||
void IPv4Layer::add_ipv4_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
||||
{
|
||||
if (buffer.size() < sizeof(IPv4Header))
|
||||
{
|
||||
dwarnln_if(DEBUG_IPV4, "IPv4 packet too small");
|
||||
return;
|
||||
}
|
||||
|
||||
SpinLockGuard _(m_pending_lock);
|
||||
|
||||
if (m_pending_packets.full())
|
||||
{
|
||||
dwarnln("IPv4 packet queue full");
|
||||
dwarnln_if(DEBUG_IPV4, "IPv4 packet queue full");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pending_total_size + buffer.size() > m_pending_packet_buffer->size())
|
||||
{
|
||||
dwarnln("IPv4 packet queue full");
|
||||
dwarnln_if(DEBUG_IPV4, "IPv4 packet queue full");
|
||||
return;
|
||||
}
|
||||
|
||||
auto& ipv4_header = buffer.as<const IPv4Header>();
|
||||
if (calculate_internet_checksum(BAN::ConstByteSpan::from(ipv4_header), {}) != 0)
|
||||
{
|
||||
dwarnln("Invalid IPv4 packet");
|
||||
dwarnln_if(DEBUG_IPV4, "Invalid IPv4 packet");
|
||||
return;
|
||||
}
|
||||
if (ipv4_header.total_length > buffer.size() || ipv4_header.total_length > interface.payload_mtu())
|
||||
{
|
||||
if (ipv4_header.flags_frament & IPv4Flags::DF)
|
||||
dwarnln("Invalid IPv4 packet");
|
||||
dwarnln_if(DEBUG_IPV4, "Invalid IPv4 packet");
|
||||
else
|
||||
dwarnln("IPv4 fragmentation not supported");
|
||||
dwarnln_if(DEBUG_IPV4, "IPv4 fragmentation not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <kernel/Networking/UDPSocket.h>
|
||||
#include <kernel/Networking/UNIX/Socket.h>
|
||||
|
||||
#define DEBUG_ETHERTYPE 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define DEBUG_TCP 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#define PCI_CMD_BUS_MASTER (1 << 2)
|
||||
#define PCI_CMD_INTERRUPT_DISABLE (1 << 10)
|
||||
|
||||
#define DEBUG_PCI 0
|
||||
|
||||
namespace Kernel::PCI
|
||||
{
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ namespace Kernel
|
|||
process->m_userspace_info.argv = argv;
|
||||
process->m_userspace_info.envp = nullptr;
|
||||
|
||||
auto* thread = MUST(Thread::create_userspace(process));
|
||||
auto* thread = MUST(Thread::create_userspace(process, process->page_table()));
|
||||
process->add_thread(thread);
|
||||
process->register_to_scheduler();
|
||||
return process;
|
||||
|
@ -477,10 +477,13 @@ namespace Kernel
|
|||
{
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
auto new_page_table = BAN::UniqPtr<PageTable>::adopt(TRY(PageTable::create_userspace()));
|
||||
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
auto executable_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_EXEC)).inode;
|
||||
auto executable_file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_EXEC));
|
||||
auto executable_inode = executable_file.inode;
|
||||
|
||||
BAN::Vector<BAN::String> str_argv;
|
||||
for (int i = 0; argv && argv[i]; i++)
|
||||
|
@ -498,35 +501,18 @@ namespace Kernel
|
|||
TRY(str_envp.emplace_back(envp[i]));
|
||||
}
|
||||
|
||||
m_open_file_descriptors.close_cloexec();
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, *new_page_table));
|
||||
auto new_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
m_mapped_regions.clear();
|
||||
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, page_table()));
|
||||
m_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
|
||||
m_credentials.set_euid(executable_inode->uid());
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISGID)
|
||||
m_credentials.set_egid(executable_inode->gid());
|
||||
|
||||
m_userspace_info.entry = executable.entry_point;
|
||||
int file_fd = -1;
|
||||
if (executable.has_interpreter)
|
||||
{
|
||||
VirtualFileSystem::File file;
|
||||
TRY(file.canonical_path.append("<self>"));
|
||||
file.canonical_path = BAN::move(executable_file.canonical_path);
|
||||
file.inode = executable_inode;
|
||||
m_userspace_info.file_fd = TRY(m_open_file_descriptors.open(BAN::move(file), O_RDONLY));
|
||||
file_fd = TRY(m_open_file_descriptors.open(BAN::move(file), O_RDONLY));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(m_signal_handlers) / sizeof(*m_signal_handlers); i++)
|
||||
{
|
||||
m_signal_handlers[i].sa_handler = SIG_DFL;
|
||||
m_signal_handlers[i].sa_flags = 0;
|
||||
}
|
||||
|
||||
ASSERT(m_threads.size() == 1);
|
||||
ASSERT(&Process::current() == this);
|
||||
BAN::ScopeGuard file_closer([&] { if (file_fd != -1) MUST(m_open_file_descriptors.close(file_fd)); });
|
||||
|
||||
// allocate memory on the new process for arguments and environment
|
||||
auto create_region =
|
||||
|
@ -540,9 +526,9 @@ namespace Kernel
|
|||
bytes += PAGE_SIZE - rem;
|
||||
|
||||
auto region = TRY(MemoryBackedRegion::create(
|
||||
page_table(),
|
||||
*new_page_table,
|
||||
bytes,
|
||||
{ .start = m_userspace_info.entry, .end = KERNEL_OFFSET },
|
||||
{ .start = executable.entry_point, .end = KERNEL_OFFSET },
|
||||
MemoryRegion::Type::PRIVATE,
|
||||
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present
|
||||
));
|
||||
|
@ -562,20 +548,62 @@ namespace Kernel
|
|||
return BAN::UniqPtr<MemoryRegion>(BAN::move(region));
|
||||
};
|
||||
|
||||
auto argv_region = MUST(create_region(str_argv.span()));
|
||||
m_userspace_info.argv = (char**)argv_region->vaddr();
|
||||
MUST(m_mapped_regions.push_back(BAN::move(argv_region)));
|
||||
TRY(new_mapped_regions.reserve(new_mapped_regions.size() + 2));
|
||||
MUST(new_mapped_regions.push_back(TRY(create_region(str_argv.span()))));
|
||||
MUST(new_mapped_regions.push_back(TRY(create_region(str_envp.span()))));
|
||||
|
||||
auto envp_region = MUST(create_region(str_envp.span()));
|
||||
m_userspace_info.envp = (char**)envp_region->vaddr();
|
||||
MUST(m_mapped_regions.push_back(BAN::move(envp_region)));
|
||||
auto* new_thread = TRY(Thread::create_userspace(this, *new_page_table));
|
||||
|
||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Enabled);
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
// NOTE: bind new thread to this processor so it wont be rescheduled before end of this function
|
||||
if (auto ret = Scheduler::bind_thread_to_processor(new_thread, Processor::current_id()); ret.is_error())
|
||||
{
|
||||
Processor::set_interrupt_state(InterruptState::Enabled);
|
||||
return ret.release_error();
|
||||
}
|
||||
|
||||
// after this point, everything is initialized and nothing can fail!
|
||||
|
||||
ASSERT(m_threads.size() == 1);
|
||||
ASSERT(&Thread::current() == m_threads.front());
|
||||
|
||||
// Make current thread standalone and terminated
|
||||
// We need to give it the current page table to keep it alive
|
||||
// while its kernel stack is in use
|
||||
m_threads.front()->m_state = Thread::State::Terminated;
|
||||
m_threads.front()->m_process = nullptr;
|
||||
m_threads.front()->give_keep_alive_page_table(BAN::move(m_page_table));
|
||||
|
||||
m_threads.front() = new_thread;
|
||||
MUST(Processor::scheduler().add_thread(m_threads.front()));
|
||||
|
||||
for (size_t i = 0; i < sizeof(m_signal_handlers) / sizeof(*m_signal_handlers); i++)
|
||||
{
|
||||
m_signal_handlers[i].sa_handler = SIG_DFL;
|
||||
m_signal_handlers[i].sa_flags = 0;
|
||||
}
|
||||
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
|
||||
m_credentials.set_euid(executable_inode->uid());
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISGID)
|
||||
m_credentials.set_egid(executable_inode->gid());
|
||||
|
||||
m_open_file_descriptors.close_cloexec();
|
||||
m_mapped_regions = BAN::move(new_mapped_regions);
|
||||
m_page_table = BAN::move(new_page_table);
|
||||
|
||||
file_closer.disable();
|
||||
|
||||
m_userspace_info.argc = str_argv.size();
|
||||
m_userspace_info.argv = reinterpret_cast<char**>(m_mapped_regions[m_mapped_regions.size() - 2]->vaddr());
|
||||
m_userspace_info.envp = reinterpret_cast<char**>(m_mapped_regions[m_mapped_regions.size() - 1]->vaddr());
|
||||
m_userspace_info.entry = executable.entry_point;
|
||||
m_userspace_info.file_fd = file_fd;
|
||||
|
||||
m_cmdline = BAN::move(str_argv);
|
||||
m_environ = BAN::move(str_envp);
|
||||
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
}
|
||||
|
||||
m_has_called_exec = true;
|
||||
|
@ -1847,20 +1875,13 @@ namespace Kernel
|
|||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_kill(pid_t pid, int signal)
|
||||
BAN::ErrorOr<void> Process::kill(pid_t pid, int signal)
|
||||
{
|
||||
if (pid == 0 || pid == -1)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
if (pid == m_pid)
|
||||
{
|
||||
if (signal)
|
||||
add_pending_signal(signal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for_each_process(
|
||||
[&](Process& process)
|
||||
|
@ -1880,10 +1901,28 @@ namespace Kernel
|
|||
);
|
||||
|
||||
if (found)
|
||||
return 0;
|
||||
return {};
|
||||
return BAN::Error::from_errno(ESRCH);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_kill(pid_t pid, int signal)
|
||||
{
|
||||
if (pid == 0 || pid == -1)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
if (pid == m_pid)
|
||||
{
|
||||
if (signal)
|
||||
add_pending_signal(signal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRY(kill(pid, signal));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_sigaction(int signal, const struct sigaction* act, struct sigaction* oact)
|
||||
{
|
||||
if (signal < _SIGMIN || signal > _SIGMAX)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <kernel/Thread.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#define DEBUG_SCHEDULER 0
|
||||
#define SCHEDULER_ASSERT 1
|
||||
#define SCHEDULER_LOAD_BALANCE 0
|
||||
|
||||
|
@ -568,25 +567,37 @@ namespace Kernel
|
|||
}
|
||||
#endif
|
||||
|
||||
BAN::ErrorOr<void> Scheduler::add_thread(Thread* thread)
|
||||
BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
|
||||
{
|
||||
ASSERT(thread->m_scheduler_node == nullptr);
|
||||
auto* new_node = new SchedulerQueue::Node(thread);
|
||||
if (new_node == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
const size_t processor_index = s_next_processor_index++ % Processor::count();
|
||||
const auto processor_id = Processor::id_from_index(processor_index);
|
||||
|
||||
ASSERT(processor_id != PROCESSOR_NONE);
|
||||
new_node->processor_id = processor_id;
|
||||
thread->m_scheduler_node = new_node;
|
||||
|
||||
if (processor_id == Processor::current_id())
|
||||
add_thread(new_node);
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Scheduler::add_thread(Thread* thread)
|
||||
{
|
||||
if (thread->m_scheduler_node == nullptr)
|
||||
{
|
||||
const size_t processor_index = s_next_processor_index++ % Processor::count();
|
||||
const auto processor_id = Processor::id_from_index(processor_index);
|
||||
TRY(bind_thread_to_processor(thread, processor_id));
|
||||
}
|
||||
|
||||
auto* node = thread->m_scheduler_node;
|
||||
if (node->processor_id == Processor::current_id())
|
||||
add_thread(node);
|
||||
else
|
||||
{
|
||||
Processor::send_smp_message(processor_id, {
|
||||
Processor::send_smp_message(node->processor_id, {
|
||||
.type = Processor::SMPMessage::Type::NewThread,
|
||||
.new_thread = new_node
|
||||
.new_thread = node
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <kernel/Storage/DiskCache.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
|
||||
#define DEBUG_SYNC 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -127,7 +125,7 @@ namespace Kernel
|
|||
sector_start++;
|
||||
else
|
||||
{
|
||||
dprintln_if(DEBUG_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
|
||||
dprintln_if(DEBUG_DISK_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
|
||||
auto data_slice = m_sync_cache.span().slice(sector_start * m_sector_size, sector_count * m_sector_size);
|
||||
TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, data_slice));
|
||||
sector_start += sector_count + 1;
|
||||
|
@ -137,7 +135,7 @@ namespace Kernel
|
|||
|
||||
if (sector_count > 0)
|
||||
{
|
||||
dprintln_if(DEBUG_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
|
||||
dprintln_if(DEBUG_DISK_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
|
||||
auto data_slice = m_sync_cache.span().slice(sector_start * m_sector_size, sector_count * m_sector_size);
|
||||
TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, data_slice));
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#define DEBUG_NVMe 1
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -65,8 +63,8 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
dprintln_if(DEBUG_NVMe, "NVMe controller");
|
||||
dprintln_if(DEBUG_NVMe, " version: {}.{}", (uint16_t)vs.major, (uint8_t)vs.minor);
|
||||
dprintln("NVMe controller");
|
||||
dprintln(" version: {}.{}", (uint16_t)vs.major, (uint8_t)vs.minor);
|
||||
|
||||
auto& cap = m_controller_registers->cap;
|
||||
if (!(cap.css & NVMe::CAP_CSS_NVME))
|
||||
|
@ -160,7 +158,7 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
|
||||
dprintln_if(DEBUG_NVMe, " model: '{}'", BAN::StringView { (char*)dma_page->vaddr() + 24, 20 });
|
||||
dprintln(" model: '{}'", BAN::StringView { (char*)dma_page->vaddr() + 24, 20 });
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -59,7 +59,10 @@ namespace Kernel
|
|||
else if (syscall == SYS_FORK)
|
||||
ret = sys_fork_trampoline();
|
||||
else
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
|
||||
ret = (Process::current().*s_syscall_handlers[syscall])(arg1, arg2, arg3, arg4, arg5);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
asm volatile("cli");
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <kernel/Lock/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
@ -95,35 +96,47 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
void TTY::keyboard_task(void*)
|
||||
{
|
||||
BAN::RefPtr<Inode> keyboard_inode;
|
||||
if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error())
|
||||
keyboard_inode = ret.value().inode;
|
||||
else
|
||||
{
|
||||
dprintln("could not open keyboard device: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (!TTY::current()->m_tty_ctrl.receive_input)
|
||||
TTY::current()->m_tty_ctrl.thread_blocker.block_indefinite();
|
||||
|
||||
while (TTY::current()->m_tty_ctrl.receive_input)
|
||||
{
|
||||
LockGuard _(keyboard_inode->m_mutex);
|
||||
if (!keyboard_inode->can_read())
|
||||
{
|
||||
SystemTimer::get().sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
LibInput::RawKeyEvent event;
|
||||
[[maybe_unused]] const size_t read = MUST(keyboard_inode->read(0, BAN::ByteSpan::from(event)));
|
||||
ASSERT(read == sizeof(event));
|
||||
|
||||
TTY::current()->on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTY::initialize_devices()
|
||||
{
|
||||
static bool initialized = false;
|
||||
ASSERT(!initialized);
|
||||
|
||||
Process::create_kernel(
|
||||
[](void*)
|
||||
{
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY);
|
||||
if (file_or_error.is_error())
|
||||
{
|
||||
dprintln("no keyboard found");
|
||||
return;
|
||||
}
|
||||
|
||||
auto inode = file_or_error.value().inode;
|
||||
while (true)
|
||||
{
|
||||
while (!TTY::current()->m_tty_ctrl.receive_input)
|
||||
TTY::current()->m_tty_ctrl.thread_blocker.block_indefinite();
|
||||
|
||||
LibInput::RawKeyEvent event;
|
||||
size_t read = MUST(inode->read(0, BAN::ByteSpan::from(event)));
|
||||
ASSERT(read == sizeof(event));
|
||||
|
||||
TTY::current()->on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
|
||||
}
|
||||
}, nullptr
|
||||
);
|
||||
auto* thread = MUST(Thread::create_kernel(&TTY::keyboard_task, nullptr, nullptr));
|
||||
MUST(Processor::scheduler().add_thread(thread));
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
@ -260,7 +273,7 @@ namespace Kernel
|
|||
// ^C
|
||||
if (ch == '\x03')
|
||||
{
|
||||
if (auto ret = Process::current().sys_kill(-m_foreground_pgrp, SIGINT); ret.is_error())
|
||||
if (auto ret = Process::kill(-m_foreground_pgrp, SIGINT); ret.is_error())
|
||||
dwarnln("TTY: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Kernel
|
|||
return thread;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<Thread*> Thread::create_userspace(Process* process)
|
||||
BAN::ErrorOr<Thread*> Thread::create_userspace(Process* process, PageTable& page_table)
|
||||
{
|
||||
ASSERT(process);
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace Kernel
|
|||
thread->m_is_userspace = true;
|
||||
|
||||
thread->m_kernel_stack = TRY(VirtualRange::create_to_vaddr_range(
|
||||
process->page_table(),
|
||||
page_table,
|
||||
0x300000, KERNEL_OFFSET,
|
||||
m_kernel_stack_size,
|
||||
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||
|
@ -95,7 +95,7 @@ namespace Kernel
|
|||
));
|
||||
|
||||
thread->m_userspace_stack = TRY(VirtualRange::create_to_vaddr_range(
|
||||
process->page_table(),
|
||||
page_table,
|
||||
0x300000, KERNEL_OFFSET,
|
||||
m_userspace_stack_size,
|
||||
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <kernel/USB/Device.h>
|
||||
#include <kernel/USB/HID/HIDDriver.h>
|
||||
|
||||
#define DEBUG_USB 0
|
||||
#define USB_DUMP_DESCRIPTORS 0
|
||||
|
||||
namespace Kernel
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <kernel/USB/HID/Keyboard.h>
|
||||
#include <kernel/USB/HID/Mouse.h>
|
||||
|
||||
#define DEBUG_HID 0
|
||||
#define DUMP_HID_REPORT 0
|
||||
|
||||
namespace Kernel
|
||||
|
@ -135,12 +134,12 @@ namespace Kernel
|
|||
}
|
||||
|
||||
const auto& hid_descriptor = *reinterpret_cast<const HIDDescriptor*>(m_interface.misc_descriptors[hid_descriptor_index].data());
|
||||
dprintln_if(DEBUG_HID, "HID descriptor ({} bytes)", m_interface.misc_descriptors[hid_descriptor_index].size());
|
||||
dprintln_if(DEBUG_HID, " bLength: {}", hid_descriptor.bLength);
|
||||
dprintln_if(DEBUG_HID, " bDescriptorType: {}", hid_descriptor.bDescriptorType);
|
||||
dprintln_if(DEBUG_HID, " bcdHID: {H}.{2H}", hid_descriptor.bcdHID >> 8, hid_descriptor.bcdHID & 0xFF);
|
||||
dprintln_if(DEBUG_HID, " bCountryCode: {}", hid_descriptor.bCountryCode);
|
||||
dprintln_if(DEBUG_HID, " bNumDescriptors: {}", hid_descriptor.bNumDescriptors);
|
||||
dprintln_if(DEBUG_USB_HID, "HID descriptor ({} bytes)", m_interface.misc_descriptors[hid_descriptor_index].size());
|
||||
dprintln_if(DEBUG_USB_HID, " bLength: {}", hid_descriptor.bLength);
|
||||
dprintln_if(DEBUG_USB_HID, " bDescriptorType: {}", hid_descriptor.bDescriptorType);
|
||||
dprintln_if(DEBUG_USB_HID, " bcdHID: {H}.{2H}", hid_descriptor.bcdHID >> 8, hid_descriptor.bcdHID & 0xFF);
|
||||
dprintln_if(DEBUG_USB_HID, " bCountryCode: {}", hid_descriptor.bCountryCode);
|
||||
dprintln_if(DEBUG_USB_HID, " bNumDescriptors: {}", hid_descriptor.bNumDescriptors);
|
||||
|
||||
uint32_t report_descriptor_index = 0;
|
||||
BAN::Vector<Collection> collections;
|
||||
|
@ -150,7 +149,7 @@ namespace Kernel
|
|||
|
||||
if (static_cast<HIDDescriptorType>(descriptor.bDescriptorType) != HIDDescriptorType::Report)
|
||||
{
|
||||
dprintln_if(DEBUG_HID, "Skipping HID descriptor type 0x{2H}", descriptor.bDescriptorType);
|
||||
dprintln_if(DEBUG_USB_HID, "Skipping HID descriptor type 0x{2H}", descriptor.bDescriptorType);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -176,7 +175,7 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
dprintln_if(DEBUG_HID, "Parsing {} byte report descriptor", +descriptor.wItemLength);
|
||||
dprintln_if(DEBUG_USB_HID, "Parsing {} byte report descriptor", +descriptor.wItemLength);
|
||||
|
||||
auto report_data = BAN::ConstByteSpan(reinterpret_cast<uint8_t*>(dma_buffer->vaddr()), descriptor.wItemLength);
|
||||
auto new_collections = TRY(parse_report_descriptor(report_data, m_uses_report_id));
|
||||
|
@ -275,7 +274,7 @@ namespace Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if constexpr(DEBUG_HID)
|
||||
if constexpr(DEBUG_USB_HID)
|
||||
{
|
||||
const auto nibble_to_hex = [](uint8_t x) -> char { return x + (x < 10 ? '0' : 'A' - 10); };
|
||||
|
||||
|
@ -289,7 +288,7 @@ namespace Kernel
|
|||
}
|
||||
*ptr = '\0';
|
||||
|
||||
dprintln_if(DEBUG_HID, "Received {} bytes from endpoint {}: {}", data.size(), endpoint_id, buffer);
|
||||
dprintln_if(DEBUG_USB_HID, "Received {} bytes from endpoint {}: {}", data.size(), endpoint_id, buffer);
|
||||
}
|
||||
|
||||
const auto extract_bits =
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include <kernel/USB/HID/Keyboard.h>
|
||||
#include <LibInput/KeyEvent.h>
|
||||
|
||||
#define DEBUG_KEYBOARD 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -66,7 +64,7 @@ namespace Kernel
|
|||
|
||||
const bool pressed = m_keyboard_state_temp[i];
|
||||
if (pressed)
|
||||
dprintln_if(DEBUG_KEYBOARD, "Pressed {2H}", i);
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Pressed {2H}", i);
|
||||
|
||||
auto opt_keycode = s_scancode_to_keycode[i];
|
||||
if (opt_keycode.has_value())
|
||||
|
@ -102,7 +100,7 @@ namespace Kernel
|
|||
|
||||
if (usage_page != 0x07)
|
||||
{
|
||||
dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
return;
|
||||
}
|
||||
if (!state)
|
||||
|
@ -117,7 +115,7 @@ namespace Kernel
|
|||
|
||||
if (usage_page != 0x07)
|
||||
{
|
||||
dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
return;
|
||||
}
|
||||
if (usage >= 4 && usage < m_keyboard_state_temp.size())
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#include <kernel/USB/HID/Mouse.h>
|
||||
#include <LibInput/MouseEvent.h>
|
||||
|
||||
#define DEBUG_MOUSE 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -16,7 +14,7 @@ namespace Kernel
|
|||
{
|
||||
if (m_pointer_x || m_pointer_y)
|
||||
{
|
||||
dprintln_if(DEBUG_MOUSE, "Mouse move event {}, {}", m_pointer_x, m_pointer_y);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse move event {}, {}", m_pointer_x, m_pointer_y);
|
||||
|
||||
LibInput::MouseEvent event;
|
||||
event.type = LibInput::MouseEventType::MouseMoveEvent;
|
||||
|
@ -30,7 +28,7 @@ namespace Kernel
|
|||
|
||||
if (m_wheel)
|
||||
{
|
||||
dprintln_if(DEBUG_MOUSE, "Mouse scroll event {}", m_wheel);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse scroll event {}", m_wheel);
|
||||
|
||||
LibInput::MouseEvent event;
|
||||
event.type = LibInput::MouseEventType::MouseScrollEvent;
|
||||
|
@ -47,7 +45,7 @@ namespace Kernel
|
|||
|
||||
const bool pressed = m_button_state_temp[i];
|
||||
|
||||
dprintln_if(DEBUG_MOUSE, "Mouse button event {}: {}", i, pressed);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse button event {}: {}", i, pressed);
|
||||
|
||||
LibInput::MouseEvent event;
|
||||
event.type = LibInput::MouseEventType::MouseButtonEvent;
|
||||
|
@ -76,7 +74,7 @@ namespace Kernel
|
|||
m_wheel = state;
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_MOUSE, "Unsupported mouse usage {2H} on page {2H}", usage, usage_page);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage {2H} on page {2H}", usage, usage_page);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -86,14 +84,14 @@ namespace Kernel
|
|||
m_button_state_temp[usage - 1] = state;
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_MOUSE, "Unsupported mouse usage page {2H}", usage_page);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage page {2H}", usage_page);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void USBMouse::handle_array(uint16_t usage_page, uint16_t usage)
|
||||
{
|
||||
dprintln_if(DEBUG_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include <kernel/USB/XHCI/Controller.h>
|
||||
#include <kernel/USB/XHCI/Device.h>
|
||||
|
||||
#define DEBUG_XHCI 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#include <kernel/Timer/Timer.h>
|
||||
#include <kernel/USB/XHCI/Device.h>
|
||||
|
||||
#define DEBUG_XHCI 0
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
|
|
@ -75,6 +75,11 @@ extern "C"
|
|||
builtin_check_kind kind;
|
||||
};
|
||||
|
||||
struct unreachable_data
|
||||
{
|
||||
struct source_location location;
|
||||
};
|
||||
|
||||
using value_handle = uintptr_t;
|
||||
|
||||
static const char* type_check_kinds[] = {
|
||||
|
@ -114,6 +119,8 @@ extern "C"
|
|||
|
||||
HANDLER(__ubsan_handle_invalid_builtin, false, invalid_builtin_data* data);
|
||||
|
||||
HANDLER(__ubsan_handle_builtin_unreachable, true, unreachable_data* data);
|
||||
|
||||
void __ubsan_handle_type_mismatch_v1(type_mismatch_data* data, value_handle pointer)
|
||||
{
|
||||
print_location(data->location);
|
||||
|
|
|
@ -19,6 +19,8 @@ foreach(library ${USERSPACE_LIBRARIES})
|
|||
add_dependencies(libraries ${library_lower})
|
||||
# This is to allow cmake to link when libc updates
|
||||
target_link_options(${library_lower} PRIVATE -nolibc)
|
||||
# Default compile options
|
||||
target_compile_options(${library_lower} PRIVATE -g -O2)
|
||||
|
||||
target_compile_definitions(${library_lower} PRIVATE __enable_sse=${BANAN_ENABLE_SSE})
|
||||
if (NOT BANAN_ENABLE_SSE)
|
||||
|
|
|
@ -5,7 +5,6 @@ set(LIBIMAGE_SOURCES
|
|||
)
|
||||
|
||||
add_library(libimage ${LIBIMAGE_SOURCES})
|
||||
target_compile_options(libimage PRIVATE -O3)
|
||||
banan_link_library(libimage libc)
|
||||
banan_link_library(libimage ban)
|
||||
|
||||
|
|
|
@ -518,8 +518,14 @@ Rectangle Terminal::putchar(uint8_t ch)
|
|||
m_cursor.y++;
|
||||
}
|
||||
|
||||
// scrolling is already handled in `read_shell()`
|
||||
ASSERT(m_cursor.y < rows());
|
||||
if (m_cursor.y >= rows())
|
||||
{
|
||||
const uint32_t scroll = m_cursor.y - rows() + 1;
|
||||
m_cursor.y -= scroll;
|
||||
m_window->shift_vertical(-scroll * (int32_t)m_font.height());
|
||||
m_window->fill_rect(0, m_window->height() - scroll * m_font.height(), m_window->width(), scroll * m_font.height(), m_bg_color);
|
||||
should_invalidate = { 0, 0, m_window->width(), m_window->height() };
|
||||
}
|
||||
|
||||
return should_invalidate;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue