Compare commits

..

12 Commits

Author SHA1 Message Date
Bananymous 066e8e1cc2 Kernel: Remove unnecessary debug logging from VFS initialization 2024-08-18 20:51:10 +03:00
Bananymous 5cd7b40165 Kernel: Make BananBootloader info struct header compatible with C 2024-08-18 20:51:10 +03:00
Bananymous c7b134ba4b Kernel: Fix NVMe controller namespace numbering
namespace numbers were incrementing globally instead of per controller.
This led to two single namespace controllers creating nvme0n1 and
nvme1n2
2024-08-18 20:51:10 +03:00
Bananymous ff62c262fe Kernel: Fix PS/2 scancode set 2 keycodes for the bottom row keys 2024-08-18 20:51:10 +03:00
Bananymous 42e2c15e0c Kernel: Add ps2=<scancode set> command line argument
This allows forcing specific scancode set on broken PS/2 emulations
2024-08-18 20:51:10 +03:00
Bananymous 40c6989374 Kernel: Implement AML ObjectTypeOp 2024-08-18 20:51:10 +03:00
Bananymous 71dc373610 Kernel: "Fix" AML _OSI string to return true for windows strings
This is the way its supposed to be done as other code paths are
untested...
2024-08-18 20:51:10 +03:00
Bananymous 0fa16cf982 Kernel: Fix and add some AML to_underlying functions 2024-08-18 20:44:51 +03:00
Bananymous 8902032b42 BuildSystem: Cleanup kernel cmake file 2024-08-18 20:44:12 +03:00
Bananymous 368f5e9799 Kernel: Add command lineoption `nousb` that will disable usb controller 2024-08-16 22:09:24 +03:00
Bananymous 46b34817d2 snake: Remove random goto statements when regenerating apple's position 2024-08-16 17:36:37 +03:00
Bananymous b1fe24bb57 Kernel: Hack AML integers to work better
Something is trying to store into a constant integers. Just by copying
not returning any integers as constants fixes it xD
2024-08-16 13:04:52 +03:00
22 changed files with 286 additions and 82 deletions

View File

@ -175,35 +175,42 @@ set(KERNEL_SOURCES
add_executable(kernel ${KERNEL_SOURCES}) add_executable(kernel ${KERNEL_SOURCES})
target_compile_definitions(kernel PUBLIC __is_kernel) target_compile_definitions(kernel PRIVATE __is_kernel)
target_compile_definitions(kernel PRIVATE __arch=${BANAN_ARCH}) target_compile_definitions(kernel PRIVATE __arch=${BANAN_ARCH})
target_compile_definitions(kernel PRIVATE __enable_sse=${BANAN_ENABLE_SSE}) target_compile_definitions(kernel PRIVATE __enable_sse=${BANAN_ENABLE_SSE})
if (NOT BANAN_ENABLE_SSE)
target_compile_options(kernel PRIVATE -mno-sse -mno-sse2)
endif ()
target_compile_options(kernel PUBLIC -O2 -g) target_compile_options(kernel PRIVATE
target_compile_options(kernel PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suffix -fno-rtti -fno-exceptions>) -O2 -g
target_compile_options(kernel PUBLIC -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.) -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.
target_compile_options(kernel PUBLIC -fstack-protector -ffreestanding -fno-omit-frame-pointer -fstrict-volatile-bitfields -mgeneral-regs-only) -fstack-protector
target_compile_options(kernel PUBLIC -Wall -Wextra -Werror -Wstack-usage=1024) -ffreestanding
-fno-omit-frame-pointer
-fstrict-volatile-bitfields
-mgeneral-regs-only
-Wall -Wextra -Werror -Wstack-usage=1024
)
# This might not work with other toolchains # This might not work with other toolchains
target_compile_options(kernel PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>) target_compile_options(kernel PRIVATE $<$<COMPILE_LANGUAGE:CXX>:
-Wno-literal-suffix
-Wno-invalid-offsetof
-fno-rtti
-fno-exceptions>
)
if(ENABLE_KERNEL_UBSAN) if(ENABLE_KERNEL_UBSAN)
target_compile_options(kernel PUBLIC -fsanitize=undefined) target_compile_options(kernel PRIVATE -fsanitize=undefined)
endif() endif()
if("${BANAN_ARCH}" STREQUAL "x86_64") if("${BANAN_ARCH}" STREQUAL "x86_64")
target_compile_options(kernel PUBLIC -mcmodel=kernel -mno-red-zone) target_compile_options(kernel PRIVATE -mcmodel=kernel -mno-red-zone)
target_link_options(kernel PUBLIC LINKER:-z,max-page-size=4096) target_link_options(kernel PRIVATE LINKER:-z,max-page-size=4096)
target_link_options(kernel PUBLIC LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/x86_64/linker.ld) target_link_options(kernel PRIVATE LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/x86_64/linker.ld)
elseif("${BANAN_ARCH}" STREQUAL "i686") elseif("${BANAN_ARCH}" STREQUAL "i686")
target_link_options(kernel PUBLIC LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/i686/linker.ld) target_link_options(kernel PRIVATE LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/i686/linker.ld)
endif() endif()
target_link_options(kernel PUBLIC -ffreestanding -nostdlib) target_link_options(kernel PRIVATE -ffreestanding -nostdlib)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND OUTPUT_STRIP_TRAILING_WHITESPACE)

View File

@ -67,7 +67,7 @@ namespace Kernel::ACPI::AML
return ParseResult::Failure; return ParseResult::Failure;
} }
auto package_element = package->elements[index]; auto package_element = package->elements[index];
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element)); result = MUST(BAN::RefPtr<AML::Reference>::create(package_element->to_underlying()));
break; break;
} }
case AML::Node::Type::String: case AML::Node::Type::String:

View File

@ -0,0 +1,108 @@
#pragma once
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Reference.h>
namespace Kernel::ACPI::AML
{
struct ObjectType
{
static ParseResult parse(ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::ObjectTypeOp);
context.aml_data = context.aml_data.slice(1);
auto object_result = AML::parse_object(context);
if (!object_result.success())
return ParseResult::Failure;
auto object = object_result.node()
? object_result.node()->to_underlying()
: BAN::RefPtr<AML::Node>();
if (object && object->type == AML::Node::Type::Reference)
object = static_cast<AML::Reference*>(object.ptr())->node->to_underlying();
uint64_t value = 0;
if (object)
{
switch (object->type)
{
case AML::Node::Type::None:
case AML::Node::Type::Alias:
case AML::Node::Type::Name:
case AML::Node::Type::PackageElement:
case AML::Node::Type::Reference:
case AML::Node::Type::Register:
ASSERT_NOT_REACHED();
case AML::Node::Type::Namespace:
value = 0;
break;
case AML::Node::Type::Integer:
value = 1;
break;
case AML::Node::Type::String:
value = 2;
break;
case AML::Node::Type::Buffer:
value = 3;
break;
case AML::Node::Type::Package:
value = 4;
break;
case AML::Node::Type::FieldElement:
case AML::Node::Type::BankFieldElement:
case AML::Node::Type::IndexFieldElement:
value = 5;
break;
case AML::Node::Type::Device:
value = 6;
break;
case AML::Node::Type::Event:
value = 7;
break;
case AML::Node::Type::Method:
value = 8;
break;
case AML::Node::Type::Mutex:
value = 9;
break;
case AML::Node::Type::OpRegion:
value = 10;
break;
case AML::Node::Type::PowerResource:
value = 11;
break;
case AML::Node::Type::Processor:
value = 12;
break;
case AML::Node::Type::ThermalZone:
value = 13;
break;
case AML::Node::Type::BufferField:
value = 14;
break;
case AML::Node::Type::Debug:
value = 16;
break;
}
}
#if AML_DEBUG_LEVEL >= 2
if (!object)
AML_DEBUG_PRINTLN("ObjectType { null }");
else
{
AML_DEBUG_PRINTLN("ObjectType {");
object->debug_print(1);
AML_DEBUG_PRINTLN("");
}
#endif
return ParseResult(MUST(BAN::RefPtr<AML::Integer>::create(value)));
}
};
}

View File

@ -92,6 +92,18 @@ namespace Kernel::ACPI::AML
return element->convert(mask); return element->convert(mask);
} }
BAN::RefPtr<AML::Node> to_underlying() override
{
if (!initialized)
{
AML_ERROR("Trying to store into uninitialized PackageElement");
return {};
}
if (!resolved && !resolve())
return {};
return element;
}
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
{ {
if (!initialized) if (!initialized)

View File

@ -12,7 +12,7 @@ namespace Kernel::ACPI::AML
Register(); Register();
Register(BAN::RefPtr<AML::Node> node); Register(BAN::RefPtr<AML::Node> node);
BAN::RefPtr<AML::Node> to_underlying() override { return value; } BAN::RefPtr<AML::Node> to_underlying() override { return value->to_underlying(); }
BAN::RefPtr<AML::Node> convert(uint8_t mask) override; BAN::RefPtr<AML::Node> convert(uint8_t mask) override;
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> source) override; BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> source) override;

View File

@ -7,12 +7,12 @@
struct BananBootFramebufferInfo struct BananBootFramebufferInfo
{ {
uint32_t address; uint32_t address;
uint32_t pitch; uint32_t pitch;
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
uint8_t bpp; uint8_t bpp;
uint8_t type; uint8_t type;
}; };
struct BananBootloaderMemoryMapEntry struct BananBootloaderMemoryMapEntry
@ -24,8 +24,8 @@ struct BananBootloaderMemoryMapEntry
struct BananBootloaderMemoryMapInfo struct BananBootloaderMemoryMapInfo
{ {
uint32_t entry_count; uint32_t entry_count;
BananBootloaderMemoryMapEntry entries[]; struct BananBootloaderMemoryMapEntry entries[];
} __attribute__((packed)); } __attribute__((packed));
struct BananBootloaderInfo struct BananBootloaderInfo

View File

@ -15,7 +15,7 @@ namespace Kernel::Input
class PS2Controller class PS2Controller
{ {
public: public:
static BAN::ErrorOr<void> initialize(); static BAN::ErrorOr<void> initialize(uint8_t scancode_set);
static PS2Controller& get(); static PS2Controller& get();
bool append_command_queue(PS2Device*, uint8_t command, uint8_t response_size); bool append_command_queue(PS2Device*, uint8_t command, uint8_t response_size);
@ -26,8 +26,8 @@ namespace Kernel::Input
private: private:
PS2Controller() = default; PS2Controller() = default;
BAN::ErrorOr<void> initialize_impl(); BAN::ErrorOr<void> initialize_impl(uint8_t scancode_set);
BAN::ErrorOr<void> initialize_device(uint8_t); BAN::ErrorOr<void> initialize_device(uint8_t, uint8_t scancode_set);
BAN::ErrorOr<uint8_t> read_byte(); BAN::ErrorOr<uint8_t> read_byte();
BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte); BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte);

View File

@ -17,7 +17,7 @@ namespace Kernel::Input
}; };
public: public:
static BAN::ErrorOr<BAN::RefPtr<PS2Keyboard>> create(PS2Controller&); static BAN::ErrorOr<BAN::RefPtr<PS2Keyboard>> create(PS2Controller&, uint8_t scancode_set);
virtual void send_initialize() override; virtual void send_initialize() override;
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override; virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override;
@ -27,13 +27,14 @@ namespace Kernel::Input
virtual void update() final override { m_controller.update_command_queue(); } virtual void update() final override { m_controller.update_command_queue(); }
private: private:
PS2Keyboard(PS2Controller& controller); PS2Keyboard(PS2Controller& controller, bool basic);
void update_leds(); void update_leds();
private: private:
BAN::Array<uint8_t, 3> m_byte_buffer; BAN::Array<uint8_t, 3> m_byte_buffer;
uint8_t m_byte_index { 0 }; uint8_t m_byte_index { 0 };
bool m_basic { false };
uint8_t m_scancode_set { 0xFF }; uint8_t m_scancode_set { 0xFF };
uint16_t m_modifiers { 0 }; uint16_t m_modifiers { 0 };

View File

@ -139,7 +139,7 @@ namespace Kernel::PCI
static void initialize(); static void initialize();
static PCIManager& get(); static PCIManager& get();
void initialize_devices(); void initialize_devices(bool disable_usb);
template<typename F> template<typename F>
void for_each_device(F callback) void for_each_device(F callback)

View File

@ -11,7 +11,7 @@ namespace Kernel
class NVMeNamespace : public StorageDevice class NVMeNamespace : public StorageDevice
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<NVMeNamespace>> create(NVMeController&, uint32_t nsid, uint64_t block_count, uint32_t block_size); static BAN::ErrorOr<BAN::RefPtr<NVMeNamespace>> create(NVMeController&, uint32_t ns_index, uint32_t nsid, uint64_t block_count, uint32_t block_size);
virtual uint32_t sector_size() const override { return m_block_size; } virtual uint32_t sector_size() const override { return m_block_size; }
virtual uint64_t total_size() const override { return m_block_size * m_block_count; } virtual uint64_t total_size() const override { return m_block_size * m_block_count; }
@ -20,7 +20,7 @@ namespace Kernel
virtual BAN::StringView name() const { return m_name; } virtual BAN::StringView name() const { return m_name; }
private: private:
NVMeNamespace(NVMeController&, uint32_t nsid, uint64_t block_count, uint32_t block_size); NVMeNamespace(NVMeController&, uint32_t ns_index, uint32_t nsid, uint64_t block_count, uint32_t block_size);
BAN::ErrorOr<void> initialize(); BAN::ErrorOr<void> initialize();
virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) override; virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) override;

View File

@ -100,13 +100,16 @@ namespace Kernel::ACPI
{ {
case AML::Byte::ZeroOp: case AML::Byte::ZeroOp:
aml_data = aml_data.slice(1); aml_data = aml_data.slice(1);
return ParseResult(Constants::Zero); // FIXME: no copy
return ParseResult(Constants::Zero->copy());
case AML::Byte::OneOp: case AML::Byte::OneOp:
aml_data = aml_data.slice(1); aml_data = aml_data.slice(1);
return ParseResult(Constants::One); // FIXME: no copy
return ParseResult(Constants::One->copy());
case AML::Byte::OnesOp: case AML::Byte::OnesOp:
aml_data = aml_data.slice(1); aml_data = aml_data.slice(1);
return ParseResult(Constants::Ones); // FIXME: no copy
return ParseResult(Constants::Ones->copy());
case AML::Byte::BytePrefix: case AML::Byte::BytePrefix:
{ {
if (aml_data.size() < 2) if (aml_data.size() < 2)

View File

@ -247,8 +247,37 @@ namespace Kernel::ACPI
AML_ERROR("Invalid _OSI argument"); AML_ERROR("Invalid _OSI argument");
return {}; return {};
} }
auto string = static_cast<AML::String*>(arg.ptr());
return string->string_view() == "Linux"_sv ? AML::Integer::Constants::Ones : AML::Integer::Constants::Zero; constexpr BAN::StringView valid_strings[] {
"Windows 2000"_sv,
"Windows 2001"_sv,
"Windows 2001 SP1"_sv,
"Windows 2001.1"_sv,
"Windows 2001 SP2"_sv,
"Windows 2001.1 SP1"_sv,
"Windows 2006.1"_sv,
"Windows 2006 SP1"_sv,
"Windows 2006 SP2"_sv,
"Windows 2009"_sv,
"Windows 2012"_sv,
"Windows 2013"_sv,
"Windows 2015"_sv,
"Windows 2016"_sv,
"Windows 2017"_sv,
"Windows 2017.2"_sv,
"Windows 2018"_sv,
"Windows 2018.2"_sv,
"Windows 2019"_sv,
"Extended Address Space Descriptor"_sv,
// just to pass osi test from uACPI :D
"AnotherTestString"_sv,
};
auto string = static_cast<AML::String*>(arg.ptr())->string_view();
for (auto valid_string : valid_strings)
if (string == valid_string)
return AML::Integer::Constants::Ones;
return AML::Integer::Constants::Zero;
}; };
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi)); ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi));

View File

@ -15,6 +15,7 @@
#include <kernel/ACPI/AML/Names.h> #include <kernel/ACPI/AML/Names.h>
#include <kernel/ACPI/AML/Node.h> #include <kernel/ACPI/AML/Node.h>
#include <kernel/ACPI/AML/Notify.h> #include <kernel/ACPI/AML/Notify.h>
#include <kernel/ACPI/AML/ObjectType.h>
#include <kernel/ACPI/AML/Package.h> #include <kernel/ACPI/AML/Package.h>
#include <kernel/ACPI/AML/ParseContext.h> #include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/PowerResource.h> #include <kernel/ACPI/AML/PowerResource.h>
@ -191,6 +192,8 @@ namespace Kernel::ACPI
return AML::Notify::parse(context); return AML::Notify::parse(context);
case AML::Byte::SizeOfOp: case AML::Byte::SizeOfOp:
return AML::SizeOf::parse(context); return AML::SizeOf::parse(context);
case AML::Byte::ObjectTypeOp:
return AML::ObjectType::parse(context);
case AML::Byte::BreakPointOp: // TODO: support breakpoints? case AML::Byte::BreakPointOp: // TODO: support breakpoints?
case AML::Byte::NoopOp: case AML::Byte::NoopOp:
context.aml_data = context.aml_data.slice(1); context.aml_data = context.aml_data.slice(1);

View File

@ -35,10 +35,8 @@ namespace Kernel
if (!static_cast<Device*>(inode.ptr())->is_partition()) if (!static_cast<Device*>(inode.ptr())->is_partition())
return BAN::Iteration::Continue; return BAN::Iteration::Continue;
auto* partition = static_cast<Partition*>(inode.ptr()); auto* partition = static_cast<Partition*>(inode.ptr());
dprintln("compare '{}' vs '{}'", partition->uuid(), uuid);
if (partition->uuid() != uuid) if (partition->uuid() != uuid)
return BAN::Iteration::Continue; return BAN::Iteration::Continue;
dprintln("FOUND");
root_partition = partition; root_partition = partition;
return BAN::Iteration::Break; return BAN::Iteration::Break;
} }

View File

@ -221,14 +221,14 @@ namespace Kernel::Input
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
BAN::ErrorOr<void> PS2Controller::initialize() BAN::ErrorOr<void> PS2Controller::initialize(uint8_t scancode_set)
{ {
ASSERT(s_instance == nullptr); ASSERT(s_instance == nullptr);
s_instance = new PS2Controller; s_instance = new PS2Controller;
if (s_instance == nullptr) if (s_instance == nullptr)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
BAN::ScopeGuard guard([] { delete s_instance; }); BAN::ScopeGuard guard([] { delete s_instance; });
TRY(s_instance->initialize_impl()); TRY(s_instance->initialize_impl(scancode_set));
guard.disable(); guard.disable();
return {}; return {};
} }
@ -239,7 +239,7 @@ namespace Kernel::Input
return *s_instance; return *s_instance;
} }
BAN::ErrorOr<void> PS2Controller::initialize_impl() BAN::ErrorOr<void> PS2Controller::initialize_impl(uint8_t scancode_set)
{ {
// Determine if the PS/2 Controller Exists // Determine if the PS/2 Controller Exists
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::ACPI::get().get_header("FACP"_sv, 0)); auto* fadt = static_cast<const ACPI::FADT*>(ACPI::ACPI::get().get_header("FACP"_sv, 0));
@ -317,7 +317,7 @@ namespace Kernel::Input
dwarnln_if(DEBUG_PS2, "PS/2 device enable failed: {}", ret.error()); dwarnln_if(DEBUG_PS2, "PS/2 device enable failed: {}", ret.error());
continue; continue;
} }
if (auto res = initialize_device(device); res.is_error()) if (auto res = initialize_device(device, scancode_set); res.is_error())
{ {
dwarnln_if(DEBUG_PS2, "PS/2 device initialization failed: {}", res.error()); dwarnln_if(DEBUG_PS2, "PS/2 device initialization failed: {}", res.error());
(void)send_command(device == 0 ? PS2::Command::DISABLE_FIRST_PORT : PS2::Command::DISABLE_SECOND_PORT); (void)send_command(device == 0 ? PS2::Command::DISABLE_FIRST_PORT : PS2::Command::DISABLE_SECOND_PORT);
@ -368,7 +368,7 @@ namespace Kernel::Input
return {}; return {};
} }
BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device) BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device, uint8_t scancode_set)
{ {
// Reset device // Reset device
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::RESET)); TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::RESET));
@ -411,7 +411,7 @@ namespace Kernel::Input
if (index == 2 && (bytes[0] == 0xAB && (bytes[1] == 0x83 || bytes[1] == 0x41))) if (index == 2 && (bytes[0] == 0xAB && (bytes[1] == 0x83 || bytes[1] == 0x41)))
{ {
dprintln_if(DEBUG_PS2, "PS/2 found keyboard"); dprintln_if(DEBUG_PS2, "PS/2 found keyboard");
m_devices[device] = TRY(PS2Keyboard::create(*this)); m_devices[device] = TRY(PS2Keyboard::create(*this, scancode_set));
return {}; return {};
} }

View File

@ -9,21 +9,41 @@
namespace Kernel::Input namespace Kernel::Input
{ {
BAN::ErrorOr<BAN::RefPtr<PS2Keyboard>> PS2Keyboard::create(PS2Controller& controller) BAN::ErrorOr<BAN::RefPtr<PS2Keyboard>> PS2Keyboard::create(PS2Controller& controller, uint8_t scancode_set)
{ {
return TRY(BAN::RefPtr<PS2Keyboard>::create(controller)); auto keyboard = TRY(BAN::RefPtr<PS2Keyboard>::create(controller, scancode_set != 0));
if (scancode_set)
{
if (scancode_set > 3)
{
dwarnln("Invalid scancode set {}, using scan code set 2 instead", scancode_set);
scancode_set = 2;
}
keyboard->m_scancode_set = scancode_set;
keyboard->m_keymap.initialize(scancode_set);
dprintln("Skipping scancode detection, using scan code set {}", scancode_set);
}
return keyboard;
} }
PS2Keyboard::PS2Keyboard(PS2Controller& controller) PS2Keyboard::PS2Keyboard(PS2Controller& controller, bool basic)
: PS2Device(controller, InputDevice::Type::Keyboard) : PS2Device(controller, InputDevice::Type::Keyboard)
, m_basic(basic)
{ } { }
void PS2Keyboard::send_initialize() void PS2Keyboard::send_initialize()
{ {
constexpr uint8_t wanted_scancode_set = 3; constexpr uint8_t wanted_scancode_set = 3;
append_command_queue(Command::SET_LEDS, 0x00, 0); update_leds();
append_command_queue(Command::CONFIG_SCANCODE_SET, wanted_scancode_set, 0); if (m_scancode_set == 0xFF)
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1); {
append_command_queue(Command::CONFIG_SCANCODE_SET, wanted_scancode_set, 0);
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
}
else
{
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
}
} }
void PS2Keyboard::command_timedout(uint8_t* command_data, uint8_t command_size) void PS2Keyboard::command_timedout(uint8_t* command_data, uint8_t command_size)
@ -33,8 +53,8 @@ namespace Kernel::Input
if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE) if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE)
{ {
dwarnln("Could not detect scancode set, assuming 1"); dwarnln("Could not detect scancode set, assuming 2");
m_scancode_set = 1; m_scancode_set = 2;
m_keymap.initialize(m_scancode_set); m_keymap.initialize(m_scancode_set);
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
} }
@ -169,6 +189,9 @@ namespace Kernel::Input
{ {
using KeyModifier = LibInput::KeyEvent::Modifier; using KeyModifier = LibInput::KeyEvent::Modifier;
if (m_basic)
return;
uint8_t new_leds = 0; uint8_t new_leds = 0;
if (m_modifiers & +KeyModifier::ScrollLock) if (m_modifiers & +KeyModifier::ScrollLock)
new_leds |= PS2::KBLeds::SCROLL_LOCK; new_leds |= PS2::KBLeds::SCROLL_LOCK;

View File

@ -200,12 +200,12 @@ namespace Kernel::Input
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10); m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11); m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12); m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x14] = keycode_normal(4, 1); m_scancode_to_keycode_normal[0x14] = keycode_normal(4, 0);
m_scancode_to_keycode_extended[0x1F] = keycode_normal(4, 2); m_scancode_to_keycode_extended[0x1F] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 3); m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 4); m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 3);
m_scancode_to_keycode_extended[0x11] = keycode_normal(4, 5); m_scancode_to_keycode_extended[0x11] = keycode_normal(4, 4);
m_scancode_to_keycode_extended[0x14] = keycode_normal(4, 6); m_scancode_to_keycode_extended[0x14] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x77] = keycode_numpad(0, 0); m_scancode_to_keycode_normal[0x77] = keycode_numpad(0, 0);
m_scancode_to_keycode_extended[0x4A] = keycode_numpad(0, 1); m_scancode_to_keycode_extended[0x4A] = keycode_numpad(0, 1);

View File

@ -177,7 +177,7 @@ namespace Kernel::PCI
} }
} }
void PCIManager::initialize_devices() void PCIManager::initialize_devices(bool disable_usb)
{ {
for_each_device( for_each_device(
[&](PCI::Device& pci_device) [&](PCI::Device& pci_device)
@ -215,7 +215,9 @@ namespace Kernel::PCI
switch (pci_device.subclass()) switch (pci_device.subclass())
{ {
case 0x03: case 0x03:
if (auto res = USBManager::get().add_controller(pci_device); res.is_error()) if (disable_usb)
dprintln("USB support disabled, will not initialize {2H}.{2H}.{2H}", pci_device.class_code(), pci_device.subclass(), pci_device.prog_if());
else if (auto res = USBManager::get().add_controller(pci_device); res.is_error())
dprintln("{}", res.error()); dprintln("{}", res.error());
break; break;
default: default:

View File

@ -213,7 +213,7 @@ namespace Kernel
dprintln(" block size {} B", block_size); dprintln(" block size {} B", block_size);
dprintln(" total {} MiB", block_count * block_size / (1 << 20)); dprintln(" total {} MiB", block_count * block_size / (1 << 20));
auto ns = TRY(NVMeNamespace::create(*this, nsid, block_count, block_size)); auto ns = TRY(NVMeNamespace::create(*this, m_namespaces.size(), nsid, block_count, block_size));
TRY(m_namespaces.push_back(BAN::move(ns))); TRY(m_namespaces.push_back(BAN::move(ns)));
} }

View File

@ -14,9 +14,9 @@ namespace Kernel
return minor++; return minor++;
} }
BAN::ErrorOr<BAN::RefPtr<NVMeNamespace>> NVMeNamespace::create(NVMeController& controller, uint32_t nsid, uint64_t block_count, uint32_t block_size) BAN::ErrorOr<BAN::RefPtr<NVMeNamespace>> NVMeNamespace::create(NVMeController& controller, uint32_t ns_index, uint32_t nsid, uint64_t block_count, uint32_t block_size)
{ {
auto* namespace_ptr = new NVMeNamespace(controller, nsid, block_count, block_size); auto* namespace_ptr = new NVMeNamespace(controller, ns_index, nsid, block_count, block_size);
if (namespace_ptr == nullptr) if (namespace_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
auto ns = BAN::RefPtr<NVMeNamespace>::adopt(namespace_ptr); auto ns = BAN::RefPtr<NVMeNamespace>::adopt(namespace_ptr);
@ -24,7 +24,7 @@ namespace Kernel
return ns; return ns;
} }
NVMeNamespace::NVMeNamespace(NVMeController& controller, uint32_t nsid, uint64_t block_count, uint32_t block_size) NVMeNamespace::NVMeNamespace(NVMeController& controller, uint32_t ns_index, uint32_t nsid, uint64_t block_count, uint32_t block_size)
: m_controller(controller) : m_controller(controller)
, m_nsid(nsid) , m_nsid(nsid)
, m_block_size(block_size) , m_block_size(block_size)
@ -35,7 +35,7 @@ namespace Kernel
ASSERT(m_controller.name().size() + 2 < sizeof(m_name)); ASSERT(m_controller.name().size() + 2 < sizeof(m_name));
memcpy(m_name, m_controller.name().data(), m_controller.name().size()); memcpy(m_name, m_controller.name().data(), m_controller.name().size());
m_name[m_controller.name().size() + 0] = 'n'; m_name[m_controller.name().size() + 0] = 'n';
m_name[m_controller.name().size() + 1] = '1' + minor(m_rdev); m_name[m_controller.name().size() + 1] = '1' + ns_index;
m_name[m_controller.name().size() + 2] = '\0'; m_name[m_controller.name().size() + 2] = '\0';
} }

View File

@ -32,11 +32,15 @@
#include <LibInput/KeyboardLayout.h> #include <LibInput/KeyboardLayout.h>
#include <ctype.h>
struct ParsedCommandLine struct ParsedCommandLine
{ {
bool force_pic = false; bool force_pic = false;
bool disable_serial = false; bool disable_serial = false;
bool disable_smp = false; bool disable_smp = false;
bool disable_usb = false;
uint8_t ps2_override = 0;
BAN::StringView console = "tty0"_sv; BAN::StringView console = "tty0"_sv;
BAN::StringView root; BAN::StringView root;
}; };
@ -75,6 +79,14 @@ static void parse_command_line()
cmdline.disable_serial = true; cmdline.disable_serial = true;
else if (argument == "nosmp") else if (argument == "nosmp")
cmdline.disable_smp = true; cmdline.disable_smp = true;
else if (argument == "nousb")
cmdline.disable_usb = true;
else if (argument.starts_with("ps2="))
{
if (argument.size() != 5 || !isdigit(argument[4]))
dprintln("Invalid ps2= command line argument format '{}'", argument);
cmdline.ps2_override = argument[4] - '0';
}
else if (argument.size() > 5 && argument.substring(0, 5) == "root=") else if (argument.size() > 5 && argument.substring(0, 5) == "root=")
cmdline.root = argument.substring(5); cmdline.root = argument.substring(5);
else if (argument.size() > 8 && argument.substring(0, 8) == "console=") else if (argument.size() > 8 && argument.substring(0, 8) == "console=")
@ -199,8 +211,11 @@ static void init2(void*)
PCI::PCIManager::initialize(); PCI::PCIManager::initialize();
dprintln("PCI initialized"); dprintln("PCI initialized");
MUST(USBManager::initialize()); if (!cmdline.disable_usb)
dprintln("USBManager initialized"); {
MUST(USBManager::initialize());
dprintln("USBManager initialized");
}
if (ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error()) if (ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error())
dprintln("Failed to enter ACPI mode"); dprintln("Failed to enter ACPI mode");
@ -215,14 +230,14 @@ static void init2(void*)
// Initialize empty keymap // Initialize empty keymap
MUST(LibInput::KeyboardLayout::initialize()); MUST(LibInput::KeyboardLayout::initialize());
if (auto res = PS2Controller::initialize(); res.is_error()) if (auto res = PS2Controller::initialize(cmdline.ps2_override); res.is_error())
dprintln("{}", res.error()); dprintln("{}", res.error());
MUST(NetworkManager::initialize()); MUST(NetworkManager::initialize());
// NOTE: PCI devices are the last ones to be initialized // NOTE: PCI devices are the last ones to be initialized
// so other devices can reserve predefined interrupts // so other devices can reserve predefined interrupts
PCI::PCIManager::get().initialize_devices(); PCI::PCIManager::get().initialize_devices(cmdline.disable_usb);
dprintln("PCI devices initialized"); dprintln("PCI devices initialized");
VirtualFileSystem::initialize(cmdline.root); VirtualFileSystem::initialize(cmdline.root);

View File

@ -65,13 +65,16 @@ Point get_random_point()
void update_apple() void update_apple()
{ {
regenerate: for (;;)
g_apple = get_random_point(); {
if (g_head == g_apple) g_apple = get_random_point();
goto regenerate; if (g_head == g_apple)
for (auto point : g_tail) continue;
if (point == g_apple) for (auto point : g_tail)
goto regenerate; if (point == g_apple)
continue;
break;
}
set_grid_tile(g_apple, "\e[31mO"); set_grid_tile(g_apple, "\e[31mO");
} }