Compare commits
3 Commits
bdcf058e52
...
4b917390ac
Author | SHA1 | Date |
---|---|---|
Bananymous | 4b917390ac | |
Bananymous | 7a0fb9a57f | |
Bananymous | 58fcd2b2fe |
|
@ -8,7 +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",
|
||||||
|
@ -24,7 +25,8 @@
|
||||||
],
|
],
|
||||||
"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",
|
||||||
|
|
|
@ -82,7 +82,6 @@ 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++; }
|
||||||
|
|
|
@ -75,12 +75,12 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> create(USBDevice&, const USBDevice::InterfaceDescriptor&, uint8_t interface_index);
|
static BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> create(USBDevice&, const USBDevice::InterfaceDescriptor&);
|
||||||
|
|
||||||
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&, uint8_t interface_index);
|
USBHIDDriver(USBDevice&, const USBDevice::InterfaceDescriptor&);
|
||||||
~USBHIDDriver();
|
~USBHIDDriver();
|
||||||
|
|
||||||
BAN::ErrorOr<void> initialize();
|
BAN::ErrorOr<void> initialize();
|
||||||
|
@ -90,7 +90,6 @@ 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;
|
||||||
|
|
|
@ -173,6 +173,10 @@ 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
|
||||||
|
@ -218,31 +222,6 @@ 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();
|
||||||
|
@ -334,7 +313,11 @@ 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)
|
||||||
|
@ -357,6 +340,10 @@ 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
|
||||||
|
@ -377,6 +364,10 @@ 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)())
|
||||||
|
|
|
@ -364,6 +364,10 @@ 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
|
||||||
|
@ -410,10 +414,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,33 +113,8 @@ namespace Kernel
|
||||||
: m_tid(tid), m_process(process)
|
: m_tid(tid), m_process(process)
|
||||||
{
|
{
|
||||||
#if __enable_sse
|
#if __enable_sse
|
||||||
#if ARCH(x86_64)
|
// initializes sse storage to valid state
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +457,6 @@ 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));
|
||||||
|
@ -492,12 +465,6 @@ 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
|
||||||
|
|
||||||
|
|
|
@ -140,10 +140,8 @@ namespace Kernel
|
||||||
TRY(send_request(request, 0));
|
TRY(send_request(request, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t j = 0; j < configuration.interfaces.size(); j++)
|
for (const auto& interface : configuration.interfaces)
|
||||||
{
|
{
|
||||||
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:
|
||||||
|
@ -153,7 +151,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, j); !result.is_error())
|
if (auto result = USBHIDDriver::create(*this, interface); !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:
|
||||||
|
@ -217,14 +215,17 @@ 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 interface");
|
dprintln("Successfully initialized USB device with {}/{} interfaces",
|
||||||
|
m_class_drivers.size(),
|
||||||
|
configuration.interfaces.size()
|
||||||
|
);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
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,
|
||||||
|
@ -64,17 +69,16 @@ 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, uint8_t interface_index)
|
BAN::ErrorOr<BAN::UniqPtr<USBHIDDriver>> USBHIDDriver::create(USBDevice& device, const USBDevice::InterfaceDescriptor& interface)
|
||||||
{
|
{
|
||||||
auto result = TRY(BAN::UniqPtr<USBHIDDriver>::create(device, interface, interface_index));
|
auto result = TRY(BAN::UniqPtr<USBHIDDriver>::create(device, interface));
|
||||||
TRY(result->initialize());
|
TRY(result->initialize());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
USBHIDDriver::USBHIDDriver(USBDevice& device, const USBDevice::InterfaceDescriptor& interface, uint8_t interface_index)
|
USBHIDDriver::USBHIDDriver(USBDevice& device, const USBDevice::InterfaceDescriptor& interface)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_interface(interface)
|
, m_interface(interface)
|
||||||
, m_interface_index(interface_index)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
USBHIDDriver::~USBHIDDriver()
|
USBHIDDriver::~USBHIDDriver()
|
||||||
|
@ -119,18 +123,17 @@ 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.endpoints.front().descriptor.bDescriptorType & 0x80)
|
if (m_interface.descriptor.bInterfaceSubClass == 0x01)
|
||||||
{
|
{
|
||||||
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 = USB::Request::SET_INTERFACE;
|
request.bRequest = HIDRequest::SET_PROTOCOL;
|
||||||
request.wValue = 1; // report protocol
|
request.wValue = 1; // report protocol
|
||||||
request.wIndex = m_interface_index;
|
request.wIndex = m_interface.descriptor.bInterfaceNumber;
|
||||||
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);
|
||||||
|
@ -139,6 +142,7 @@ 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++)
|
||||||
{
|
{
|
||||||
|
@ -160,8 +164,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;
|
request.wValue = (static_cast<uint16_t>(HIDDescriptorType::Report) << 8) | report_descriptor_index++;
|
||||||
request.wIndex = m_interface_index;
|
request.wIndex = m_interface.descriptor.bInterfaceNumber;
|
||||||
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()));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue