Compare commits
5 Commits
37e6cd6500
...
957df08932
Author | SHA1 | Date |
---|---|---|
Bananymous | 957df08932 | |
Bananymous | fd018b32d0 | |
Bananymous | e000c7d818 | |
Bananymous | bb40069773 | |
Bananymous | 37d5b60f5c |
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <BAN/Optional.h>
|
#include <BAN/Optional.h>
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/String.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -19,6 +19,54 @@ namespace BAN
|
||||||
{
|
{
|
||||||
return memcmp(this, &other, sizeof(GUID)) == 0;
|
return memcmp(this, &other, sizeof(GUID)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<BAN::String> to_string() const
|
||||||
|
{
|
||||||
|
char buffer[37];
|
||||||
|
char* ptr = buffer;
|
||||||
|
|
||||||
|
const auto append_hex_nibble =
|
||||||
|
[&ptr](uint8_t nibble)
|
||||||
|
{
|
||||||
|
if (nibble < 10)
|
||||||
|
*ptr++ = '0' + nibble;
|
||||||
|
else
|
||||||
|
*ptr++ = 'A' + nibble - 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto append_hex_byte =
|
||||||
|
[&append_hex_nibble](uint8_t byte)
|
||||||
|
{
|
||||||
|
append_hex_nibble(byte >> 4);
|
||||||
|
append_hex_nibble(byte & 0xF);
|
||||||
|
};
|
||||||
|
|
||||||
|
append_hex_byte((component1 >> 24) & 0xFF);
|
||||||
|
append_hex_byte((component1 >> 16) & 0xFF);
|
||||||
|
append_hex_byte((component1 >> 8) & 0xFF);
|
||||||
|
append_hex_byte((component1 >> 0) & 0xFF);
|
||||||
|
*ptr++ = '-';
|
||||||
|
append_hex_byte((component2 >> 8) & 0xFF);
|
||||||
|
append_hex_byte((component2 >> 0) & 0xFF);
|
||||||
|
*ptr++ = '-';
|
||||||
|
append_hex_byte((component3 >> 8) & 0xFF);
|
||||||
|
append_hex_byte((component3 >> 0) & 0xFF);
|
||||||
|
*ptr++ = '-';
|
||||||
|
append_hex_byte(component45[0]);
|
||||||
|
append_hex_byte(component45[1]);
|
||||||
|
*ptr++ = '-';
|
||||||
|
append_hex_byte(component45[2]);
|
||||||
|
append_hex_byte(component45[3]);
|
||||||
|
append_hex_byte(component45[4]);
|
||||||
|
append_hex_byte(component45[5]);
|
||||||
|
append_hex_byte(component45[6]);
|
||||||
|
append_hex_byte(component45[7]);
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
BAN::String guid;
|
||||||
|
TRY(guid.append(buffer));
|
||||||
|
return BAN::move(guid);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(GUID) == 16);
|
static_assert(sizeof(GUID) == 16);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace BAN
|
||||||
uint32_t old = m_ref_count.fetch_sub(1);
|
uint32_t old = m_ref_count.fetch_sub(1);
|
||||||
ASSERT(old > 0);
|
ASSERT(old > 0);
|
||||||
if (old == 1)
|
if (old == 1)
|
||||||
delete (const T*)this;
|
delete static_cast<const T*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
|
#include <kernel/ACPI/AML/NamedObject.h>
|
||||||
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ThreadBlocker.h>
|
||||||
|
#include <kernel/Timer/Timer.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Event : public AML::NamedObject
|
||||||
|
{
|
||||||
|
BAN::Atomic<uint32_t> signal_count { 0 };
|
||||||
|
ThreadBlocker thread_blocker;
|
||||||
|
|
||||||
|
Event(NameSeg name)
|
||||||
|
: NamedObject(Node::Type::Event, name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
|
||||||
|
const auto ext_op = static_cast<AML::ExtOp>(context.aml_data[1]);
|
||||||
|
switch (ext_op)
|
||||||
|
{
|
||||||
|
case AML::ExtOp::EventOp:
|
||||||
|
return parse_event(context);
|
||||||
|
case AML::ExtOp::ResetOp:
|
||||||
|
case AML::ExtOp::SignalOp:
|
||||||
|
case AML::ExtOp::WaitOp:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto event_result = parse_object(context);
|
||||||
|
if (!event_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
auto general_node = event_result.node() ? event_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
|
if (!general_node || general_node->type != Node::Type::Event)
|
||||||
|
{
|
||||||
|
AML_ERROR("Release, Wait or Signal does not name an event");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* event_node = static_cast<AML::Event*>(general_node.ptr());
|
||||||
|
|
||||||
|
if (ext_op == AML::ExtOp::WaitOp)
|
||||||
|
{
|
||||||
|
auto timeout_result = parse_object(context);
|
||||||
|
if (!timeout_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
auto timeout = timeout_result.node() ? timeout_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
|
if (!timeout)
|
||||||
|
{
|
||||||
|
AML_ERROR("Wait timeout does not evaluate to integer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t start_ms = SystemTimer::get().ms_since_boot();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto expected = event_node->signal_count.load();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (expected == 0)
|
||||||
|
break;
|
||||||
|
if (event_node->signal_count.compare_exchange(expected, expected - 1))
|
||||||
|
return ParseResult(Integer::Constants::Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout->value >= 0xFFFF)
|
||||||
|
event_node->thread_blocker.block_indefinite();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||||
|
if (current_ms >= start_ms + timeout->value)
|
||||||
|
return ParseResult(Integer::Constants::Ones);
|
||||||
|
event_node->thread_blocker.block_with_timeout_ms(start_ms + timeout->value - current_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ext_op)
|
||||||
|
{
|
||||||
|
case AML::ExtOp::ResetOp:
|
||||||
|
event_node->signal_count = 0;
|
||||||
|
break;
|
||||||
|
case AML::ExtOp::SignalOp:
|
||||||
|
event_node->signal_count++;
|
||||||
|
event_node->thread_blocker.unblock();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("Event ");
|
||||||
|
name.debug_print();
|
||||||
|
AML_DEBUG_PRINT(" (Signals: {})", signal_count.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ParseResult parse_event(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::EventOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto name_string = NameString::parse(context.aml_data);
|
||||||
|
if (!name_string.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
auto event = MUST(BAN::RefPtr<Event>::create(name_string->path.back()));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), event))
|
||||||
|
return ParseResult::Success;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
event->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ namespace Kernel::ACPI::AML
|
||||||
BufferField,
|
BufferField,
|
||||||
Debug,
|
Debug,
|
||||||
Device,
|
Device,
|
||||||
|
Event,
|
||||||
FieldElement,
|
FieldElement,
|
||||||
IndexFieldElement,
|
IndexFieldElement,
|
||||||
Integer,
|
Integer,
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace Kernel
|
||||||
|
|
||||||
virtual BAN::StringView name() const override { return m_name; }
|
virtual BAN::StringView name() const override { return m_name; }
|
||||||
|
|
||||||
|
BAN::StringView uuid() const { return m_guid_string; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Partition(BAN::RefPtr<BlockDevice>, const BAN::GUID&, const BAN::GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t, BAN::StringView);
|
Partition(BAN::RefPtr<BlockDevice>, const BAN::GUID&, const BAN::GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t, BAN::StringView);
|
||||||
|
|
||||||
|
@ -32,6 +34,7 @@ namespace Kernel
|
||||||
BAN::RefPtr<BlockDevice> m_device;
|
BAN::RefPtr<BlockDevice> m_device;
|
||||||
const BAN::GUID m_type;
|
const BAN::GUID m_type;
|
||||||
const BAN::GUID m_guid;
|
const BAN::GUID m_guid;
|
||||||
|
const BAN::String m_guid_string;
|
||||||
const uint64_t m_first_block;
|
const uint64_t m_first_block;
|
||||||
const uint64_t m_last_block;
|
const uint64_t m_last_block;
|
||||||
const uint64_t m_attributes;
|
const uint64_t m_attributes;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
#include <kernel/ACPI/AML/Device.h>
|
||||||
#include <kernel/ACPI/AML/Expression.h>
|
#include <kernel/ACPI/AML/Expression.h>
|
||||||
|
#include <kernel/ACPI/AML/Event.h>
|
||||||
#include <kernel/ACPI/AML/Field.h>
|
#include <kernel/ACPI/AML/Field.h>
|
||||||
#include <kernel/ACPI/AML/IfElse.h>
|
#include <kernel/ACPI/AML/IfElse.h>
|
||||||
#include <kernel/ACPI/AML/Index.h>
|
#include <kernel/ACPI/AML/Index.h>
|
||||||
|
@ -76,6 +77,11 @@ namespace Kernel::ACPI
|
||||||
return AML::OpRegion::parse(context);
|
return AML::OpRegion::parse(context);
|
||||||
case AML::ExtOp::DeviceOp:
|
case AML::ExtOp::DeviceOp:
|
||||||
return AML::Device::parse(context);
|
return AML::Device::parse(context);
|
||||||
|
case AML::ExtOp::EventOp:
|
||||||
|
case AML::ExtOp::ResetOp:
|
||||||
|
case AML::ExtOp::SignalOp:
|
||||||
|
case AML::ExtOp::WaitOp:
|
||||||
|
return AML::Event::parse(context);
|
||||||
case AML::ExtOp::MutexOp:
|
case AML::ExtOp::MutexOp:
|
||||||
case AML::ExtOp::AcquireOp:
|
case AML::ExtOp::AcquireOp:
|
||||||
case AML::ExtOp::ReleaseOp:
|
case AML::ExtOp::ReleaseOp:
|
||||||
|
|
|
@ -113,6 +113,8 @@ namespace Kernel
|
||||||
ASSERT(!device->name().contains('/'));
|
ASSERT(!device->name().contains('/'));
|
||||||
MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*device, device->name()));
|
MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*device, device->name()));
|
||||||
MUST(m_devices.push_back(device));
|
MUST(m_devices.push_back(device));
|
||||||
|
|
||||||
|
dprintln("Added device /dev/{}", device->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevFileSystem::remove_device(BAN::RefPtr<Device> device)
|
void DevFileSystem::remove_device(BAN::RefPtr<Device> device)
|
||||||
|
@ -128,6 +130,8 @@ namespace Kernel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintln("Removed device /dev/{}", device->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevFileSystem::add_inode(BAN::StringView path, BAN::RefPtr<TmpInode> inode)
|
void DevFileSystem::add_inode(BAN::StringView path, BAN::RefPtr<TmpInode> inode)
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <kernel/FS/TmpFS/FileSystem.h>
|
#include <kernel/FS/TmpFS/FileSystem.h>
|
||||||
#include <kernel/FS/VirtualFileSystem.h>
|
#include <kernel/FS/VirtualFileSystem.h>
|
||||||
#include <kernel/Lock/LockGuard.h>
|
#include <kernel/Lock/LockGuard.h>
|
||||||
|
#include <kernel/Storage/Partition.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
@ -17,13 +19,57 @@ namespace Kernel
|
||||||
ASSERT(!s_instance);
|
ASSERT(!s_instance);
|
||||||
s_instance = MUST(BAN::RefPtr<VirtualFileSystem>::create());
|
s_instance = MUST(BAN::RefPtr<VirtualFileSystem>::create());
|
||||||
|
|
||||||
ASSERT(root_path.size() >= 5 && root_path.substring(0, 5) == "/dev/"_sv);;
|
BAN::RefPtr<BlockDevice> root_device;
|
||||||
root_path = root_path.substring(5);
|
if (root_path.size() >= 5 && root_path.substring(0, 5) == "UUID="_sv)
|
||||||
|
{
|
||||||
|
auto uuid = root_path.substring(5);
|
||||||
|
if (uuid.size() != 36)
|
||||||
|
panic("Invalid UUID specified for root '{}'", uuid);
|
||||||
|
|
||||||
auto root_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root_path));
|
BAN::RefPtr<Partition> root_partition;
|
||||||
if (!root_inode->mode().ifblk())
|
DevFileSystem::get().for_each_inode(
|
||||||
Kernel::panic("Specified root '/dev/{}' does not name a block device", root_path);
|
[&root_partition, uuid](BAN::RefPtr<Inode> inode) -> BAN::Iteration
|
||||||
s_instance->m_root_fs = MUST(FileSystem::from_block_device(static_cast<BlockDevice*>(root_inode.ptr())));
|
{
|
||||||
|
if (!inode->is_device())
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
if (!static_cast<Device*>(inode.ptr())->is_partition())
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
auto* partition = static_cast<Partition*>(inode.ptr());
|
||||||
|
dprintln("compare '{}' vs '{}'", partition->uuid(), uuid);
|
||||||
|
if (partition->uuid() != uuid)
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
dprintln("FOUND");
|
||||||
|
root_partition = partition;
|
||||||
|
return BAN::Iteration::Break;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!root_partition)
|
||||||
|
panic("Could not find partition with UUID '{}'", uuid);
|
||||||
|
root_device = root_partition;
|
||||||
|
}
|
||||||
|
else if (root_path.size() >= 5 && root_path.substring(0, 5) == "/dev/"_sv)
|
||||||
|
{
|
||||||
|
auto device_name = root_path.substring(5);
|
||||||
|
|
||||||
|
auto device_result = DevFileSystem::get().root_inode()->find_inode(device_name);
|
||||||
|
if (device_result.is_error())
|
||||||
|
panic("Could not open root device '{}': {}", root_path, device_result.error());
|
||||||
|
|
||||||
|
auto device_inode = device_result.release_value();
|
||||||
|
if (!device_inode->mode().ifblk())
|
||||||
|
panic("Root inode '{}' is not an block device", root_path);
|
||||||
|
|
||||||
|
root_device = static_cast<BlockDevice*>(device_inode.ptr());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panic("Unknown root path format '{}' specified", root_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto filesystem_result = FileSystem::from_block_device(root_device);
|
||||||
|
if (filesystem_result.is_error())
|
||||||
|
panic("Could not create filesystem from '{}': {}", root_path, filesystem_result.error());
|
||||||
|
s_instance->m_root_fs = filesystem_result.release_value();
|
||||||
|
|
||||||
Credentials root_creds { 0, 0, 0, 0 };
|
Credentials root_creds { 0, 0, 0, 0 };
|
||||||
MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"_sv));
|
MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"_sv));
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Kernel
|
||||||
, m_device(device)
|
, m_device(device)
|
||||||
, m_type(type)
|
, m_type(type)
|
||||||
, m_guid(guid)
|
, m_guid(guid)
|
||||||
|
, m_guid_string(MUST(guid.to_string()))
|
||||||
, m_first_block(first_block)
|
, m_first_block(first_block)
|
||||||
, m_last_block(last_block)
|
, m_last_block(last_block)
|
||||||
, m_attributes(attr)
|
, m_attributes(attr)
|
||||||
|
|
Loading…
Reference in New Issue