Compare commits

..

No commits in common. "4b917390acce021ffd7f015661a447bf61ceb381" and "bdcf058e52deb949511e35f094215b6621001682" have entirely different histories.

8 changed files with 93 additions and 56 deletions

View File

@ -8,9 +8,8 @@
"${workspaceFolder}/userspace/libraries/*/include" "${workspaceFolder}/userspace/libraries/*/include"
], ],
"defines": [ "defines": [
"__arch=x86_64", "__arch=x86_64"
"__enable_sse=1" ],
],
"compilerPath": "${workspaceFolder}/toolchain/local/bin/x86_64-banan_os-gcc", "compilerPath": "${workspaceFolder}/toolchain/local/bin/x86_64-banan_os-gcc",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "gnu++20", "cppStandard": "gnu++20",
@ -24,10 +23,9 @@
"${workspaceFolder}/userspace/libraries/*/include" "${workspaceFolder}/userspace/libraries/*/include"
], ],
"defines": [ "defines": [
"__arch=x86_64", "__arch=x86_64",
"__is_kernel", "__is_kernel"
"__enable_sse=1" ],
],
"compilerPath": "${workspaceFolder}/toolchain/local/bin/x86_64-banan_os-gcc", "compilerPath": "${workspaceFolder}/toolchain/local/bin/x86_64-banan_os-gcc",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "gnu++20", "cppStandard": "gnu++20",
@ -35,4 +33,4 @@
} }
], ],
"version": 4 "version": 4
} }

View File

@ -82,6 +82,7 @@ namespace Kernel
#if __enable_sse #if __enable_sse
void save_sse(); void save_sse();
void load_sse(); void load_sse();
static Thread* sse_thread();
#endif #endif
void add_mutex() { m_mutex_count++; } void add_mutex() { m_mutex_count++; }

View File

@ -75,12 +75,12 @@ namespace Kernel
}; };
public: public:
static BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> create(USBDevice&, const USBDevice::InterfaceDescriptor&); static BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> create(USBDevice&, const USBDevice::InterfaceDescriptor&, uint8_t interface_index);
void handle_input_data(BAN::ConstByteSpan, uint8_t endpoint_id) override; void handle_input_data(BAN::ConstByteSpan, uint8_t endpoint_id) override;
private: private:
USBHIDDriver(USBDevice&, const USBDevice::InterfaceDescriptor&); USBHIDDriver(USBDevice&, const USBDevice::InterfaceDescriptor&, uint8_t interface_index);
~USBHIDDriver(); ~USBHIDDriver();
BAN::ErrorOr<void> initialize(); BAN::ErrorOr<void> initialize();
@ -90,6 +90,7 @@ namespace Kernel
private: private:
USBDevice& m_device; USBDevice& m_device;
USBDevice::InterfaceDescriptor m_interface; USBDevice::InterfaceDescriptor m_interface;
const uint8_t m_interface_index;
bool m_uses_report_id { false }; bool m_uses_report_id { false };
BAN::Vector<DeviceReport> m_device_inputs; BAN::Vector<DeviceReport> m_device_inputs;

View File

@ -173,10 +173,6 @@ namespace Kernel
if (tid) if (tid)
{ {
#if __enable_sse
Thread::current().save_sse();
#endif
if (isr == ISR::PageFault) if (isr == ISR::PageFault)
{ {
// Check if stack is OOB // Check if stack is OOB
@ -222,6 +218,31 @@ namespace Kernel
} }
} }
} }
#if __enable_sse
else if (isr == ISR::DeviceNotAvailable)
{
#if ARCH(x86_64)
asm volatile(
"movq %cr0, %rax;"
"andq $~(1 << 3), %rax;"
"movq %rax, %cr0;"
);
#elif ARCH(i686)
asm volatile(
"movl %cr0, %eax;"
"andl $~(1 << 3), %eax;"
"movl %eax, %cr0;"
);
#endif
if (auto* current = &Thread::current(); current != Thread::sse_thread())
{
if (auto* sse = Thread::sse_thread())
sse->save_sse();
current->load_sse();
}
goto done;
}
#endif
} }
Debug::s_debug_lock.lock(); Debug::s_debug_lock.lock();
@ -313,11 +334,7 @@ namespace Kernel
ASSERT(Thread::current().state() != Thread::State::Terminated); ASSERT(Thread::current().state() != Thread::State::Terminated);
done: done:
#if __enable_sse
Thread::current().load_sse();
#else
return; return;
#endif
} }
extern "C" void cpp_yield_handler(InterruptStack* interrupt_stack, InterruptRegisters* interrupt_registers) extern "C" void cpp_yield_handler(InterruptStack* interrupt_stack, InterruptRegisters* interrupt_registers)
@ -340,10 +357,6 @@ done:
asm volatile("cli; 1: hlt; jmp 1b"); asm volatile("cli; 1: hlt; jmp 1b");
} }
#if __enable_sse
Thread::current().save_sse();
#endif
if (!InterruptController::get().is_in_service(irq)) if (!InterruptController::get().is_in_service(irq))
dprintln("spurious irq 0x{2H}", irq); dprintln("spurious irq 0x{2H}", irq);
else else
@ -364,10 +377,6 @@ done:
Scheduler::get().reschedule_if_idling(); Scheduler::get().reschedule_if_idling();
ASSERT(Thread::current().state() != Thread::State::Terminated); ASSERT(Thread::current().state() != Thread::State::Terminated);
#if __enable_sse
Thread::current().load_sse();
#endif
} }
void IDT::register_interrupt_handler(uint8_t index, void (*handler)()) void IDT::register_interrupt_handler(uint8_t index, void (*handler)())

View File

@ -364,10 +364,6 @@ namespace Kernel
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
bool old_show_cursor = m_show_cursor;
m_show_cursor = false;
set_cursor_position(m_column, m_row);
switch (codepoint) switch (codepoint)
{ {
case BEL: // TODO case BEL: // TODO
@ -414,6 +410,10 @@ namespace Kernel
for (uint32_t x = 0; x < m_width; x++) for (uint32_t x = 0; x < m_width; x++)
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' }; m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
// hide cursor during scrolling
bool old_show_cursor = m_show_cursor;
m_show_cursor = false;
set_cursor_position(0, 0);
if (!m_terminal_driver->scroll(m_background)) if (!m_terminal_driver->scroll(m_background))
{ {
// No fast scrolling, render the whole buffer to the screen // No fast scrolling, render the whole buffer to the screen
@ -421,12 +421,12 @@ namespace Kernel
for (uint32_t x = 0; x < m_width; x++) for (uint32_t x = 0; x < m_width; x++)
render_from_buffer(x, y); render_from_buffer(x, y);
} }
m_show_cursor = old_show_cursor;
m_column = 0; m_column = 0;
m_row--; m_row--;
} }
m_show_cursor = old_show_cursor;
set_cursor_position(m_column, m_row); set_cursor_position(m_column, m_row);
} }

View File

@ -113,8 +113,33 @@ namespace Kernel
: m_tid(tid), m_process(process) : m_tid(tid), m_process(process)
{ {
#if __enable_sse #if __enable_sse
// initializes sse storage to valid state #if ARCH(x86_64)
uintptr_t cr0;
asm volatile(
"movq %%cr0, %%rax;"
"movq %%rax, %[cr0];"
"andq $~(1 << 3), %%rax;"
"movq %%rax, %%cr0;"
: [cr0]"=r"(cr0)
:: "rax"
);
save_sse(); save_sse();
asm volatile("movq %0, %%cr0" :: "r"(cr0));
#elif ARCH(i686)
uintptr_t cr0;
asm volatile(
"movl %%cr0, %%eax;"
"movl %%eax, %[cr0];"
"andl $~(1 << 3), %%eax;"
"movl %%eax, %%cr0;"
: [cr0]"=r"(cr0)
:: "eax"
);
save_sse();
asm volatile("movl %0, %%cr0" :: "r"(cr0));
#else
#error
#endif
#endif #endif
} }
@ -457,6 +482,8 @@ namespace Kernel
} }
#if __enable_sse #if __enable_sse
static Thread* s_sse_thread = nullptr;
void Thread::save_sse() void Thread::save_sse()
{ {
asm volatile("fxsave %0" :: "m"(m_sse_storage)); asm volatile("fxsave %0" :: "m"(m_sse_storage));
@ -465,6 +492,12 @@ namespace Kernel
void Thread::load_sse() void Thread::load_sse()
{ {
asm volatile("fxrstor %0" :: "m"(m_sse_storage)); asm volatile("fxrstor %0" :: "m"(m_sse_storage));
s_sse_thread = this;
}
Thread* Thread::sse_thread()
{
return s_sse_thread;
} }
#endif #endif

View File

@ -140,8 +140,10 @@ namespace Kernel
TRY(send_request(request, 0)); TRY(send_request(request, 0));
} }
for (const auto& interface : configuration.interfaces) for (size_t j = 0; j < configuration.interfaces.size(); j++)
{ {
const auto& interface = configuration.interfaces[j];
switch (static_cast<USB::InterfaceBaseClass>(interface.descriptor.bInterfaceClass)) switch (static_cast<USB::InterfaceBaseClass>(interface.descriptor.bInterfaceClass))
{ {
case USB::InterfaceBaseClass::Audio: case USB::InterfaceBaseClass::Audio:
@ -151,7 +153,7 @@ namespace Kernel
dprintln_if(DEBUG_USB, "Found CommunicationAndCDCControl interface"); dprintln_if(DEBUG_USB, "Found CommunicationAndCDCControl interface");
break; break;
case USB::InterfaceBaseClass::HID: case USB::InterfaceBaseClass::HID:
if (auto result = USBHIDDriver::create(*this, interface); !result.is_error()) if (auto result = USBHIDDriver::create(*this, interface, j); !result.is_error())
TRY(m_class_drivers.push_back(result.release_value())); TRY(m_class_drivers.push_back(result.release_value()));
break; break;
case USB::InterfaceBaseClass::Physical: case USB::InterfaceBaseClass::Physical:
@ -215,15 +217,12 @@ namespace Kernel
dprintln_if(DEBUG_USB, "Invalid interface base class {2H}", interface.descriptor.bInterfaceClass); dprintln_if(DEBUG_USB, "Invalid interface base class {2H}", interface.descriptor.bInterfaceClass);
break; break;
} }
}
if (!m_class_drivers.empty()) if (!m_class_drivers.empty())
{ {
dprintln("Successfully initialized USB device with {}/{} interfaces", dprintln("Successfully initialized USB interface");
m_class_drivers.size(), return {};
configuration.interfaces.size() }
);
return {};
} }
} }

View File

@ -11,11 +11,6 @@
namespace Kernel namespace Kernel
{ {
enum HIDRequest : uint8_t
{
SET_PROTOCOL = 0x0B,
};
enum class HIDDescriptorType : uint8_t enum class HIDDescriptorType : uint8_t
{ {
HID = 0x21, HID = 0x21,
@ -69,16 +64,17 @@ namespace Kernel
static BAN::ErrorOr<BAN::Vector<Collection>> parse_report_descriptor(BAN::ConstByteSpan report_data, bool& out_use_report_id); static BAN::ErrorOr<BAN::Vector<Collection>> parse_report_descriptor(BAN::ConstByteSpan report_data, bool& out_use_report_id);
BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> USBHIDDriver::create(USBDevice& device, const USBDevice::InterfaceDescriptor& interface) BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> USBHIDDriver::create(USBDevice& device, const USBDevice::InterfaceDescriptor& interface, uint8_t interface_index)
{ {
auto result = TRY(BAN::UniqPtr<USBHIDDriver>::create(device, interface)); auto result = TRY(BAN::UniqPtr<USBHIDDriver>::create(device, interface, interface_index));
TRY(result->initialize()); TRY(result->initialize());
return result; return result;
} }
USBHIDDriver::USBHIDDriver(USBDevice& device, const USBDevice::InterfaceDescriptor& interface) USBHIDDriver::USBHIDDriver(USBDevice& device, const USBDevice::InterfaceDescriptor& interface, uint8_t interface_index)
: m_device(device) : m_device(device)
, m_interface(interface) , m_interface(interface)
, m_interface_index(interface_index)
{} {}
USBHIDDriver::~USBHIDDriver() USBHIDDriver::~USBHIDDriver()
@ -123,17 +119,18 @@ namespace Kernel
} }
// If this device supports boot protocol, make sure it is not used // If this device supports boot protocol, make sure it is not used
if (m_interface.descriptor.bInterfaceSubClass == 0x01) if (m_interface.endpoints.front().descriptor.bDescriptorType & 0x80)
{ {
USBDeviceRequest request; USBDeviceRequest request;
request.bmRequestType = USB::RequestType::HostToDevice | USB::RequestType::Class | USB::RequestType::Interface; request.bmRequestType = USB::RequestType::HostToDevice | USB::RequestType::Class | USB::RequestType::Interface;
request.bRequest = HIDRequest::SET_PROTOCOL; request.bRequest = USB::Request::SET_INTERFACE;
request.wValue = 1; // report protocol request.wValue = 1; // report protocol
request.wIndex = m_interface.descriptor.bInterfaceNumber; request.wIndex = m_interface_index;
request.wLength = 0; request.wLength = 0;
TRY(m_device.send_request(request, 0)); TRY(m_device.send_request(request, 0));
} }
const auto& hid_descriptor = *reinterpret_cast<const HIDDescriptor*>(m_interface.misc_descriptors[hid_descriptor_index].data()); 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, "HID descriptor ({} bytes)", m_interface.misc_descriptors[hid_descriptor_index].size());
dprintln_if(DEBUG_HID, " bLength: {}", hid_descriptor.bLength); dprintln_if(DEBUG_HID, " bLength: {}", hid_descriptor.bLength);
@ -142,7 +139,6 @@ namespace Kernel
dprintln_if(DEBUG_HID, " bCountryCode: {}", hid_descriptor.bCountryCode); dprintln_if(DEBUG_HID, " bCountryCode: {}", hid_descriptor.bCountryCode);
dprintln_if(DEBUG_HID, " bNumDescriptors: {}", hid_descriptor.bNumDescriptors); dprintln_if(DEBUG_HID, " bNumDescriptors: {}", hid_descriptor.bNumDescriptors);
uint32_t report_descriptor_index = 0;
BAN::Vector<Collection> collections; BAN::Vector<Collection> collections;
for (size_t i = 0; i < hid_descriptor.bNumDescriptors; i++) for (size_t i = 0; i < hid_descriptor.bNumDescriptors; i++)
{ {
@ -164,8 +160,8 @@ namespace Kernel
USBDeviceRequest request; USBDeviceRequest request;
request.bmRequestType = USB::RequestType::DeviceToHost | USB::RequestType::Standard | USB::RequestType::Interface; request.bmRequestType = USB::RequestType::DeviceToHost | USB::RequestType::Standard | USB::RequestType::Interface;
request.bRequest = USB::Request::GET_DESCRIPTOR; request.bRequest = USB::Request::GET_DESCRIPTOR;
request.wValue = (static_cast<uint16_t>(HIDDescriptorType::Report) << 8) | report_descriptor_index++; request.wValue = static_cast<uint16_t>(HIDDescriptorType::Report) << 8;
request.wIndex = m_interface.descriptor.bInterfaceNumber; request.wIndex = m_interface_index;
request.wLength = descriptor.wItemLength; request.wLength = descriptor.wItemLength;
auto transferred = TRY(m_device.send_request(request, dma_buffer->paddr())); auto transferred = TRY(m_device.send_request(request, dma_buffer->paddr()));