mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:47:45 +00:00
Kernel/NVMe: Add initial NVMe driver support
Add a basic NVMe driver support to serenity based on NVMe spec 1.4. The driver can support multiple NVMe drives (subsystems). But in a NVMe drive, the driver can support one controller with multiple namespaces. Each core will get a separate NVMe Queue. As the system lacks MSI support, PIN based interrupts are used for IO. Tested the NVMe support by replacing IDE driver with the NVMe driver :^)
This commit is contained in:
parent
602b35aa62
commit
e99fafb683
13 changed files with 946 additions and 0 deletions
47
Kernel/Storage/NVMe/NVMeNameSpace.cpp
Normal file
47
Kernel/Storage/NVMe/NVMeNameSpace.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Pankaj R <pankydev8@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "NVMeNameSpace.h"
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <Kernel/Devices/DeviceManagement.h>
|
||||
#include <Kernel/Storage/NVMe/NVMeNameSpace.h>
|
||||
#include <Kernel/Storage/StorageManagement.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
ErrorOr<NonnullRefPtr<NVMeNameSpace>> NVMeNameSpace::try_create(NonnullRefPtrVector<NVMeQueue> queues, u8 controller_id, u16 nsid, size_t storage_size, size_t lba_size)
|
||||
{
|
||||
auto minor_number = StorageManagement::generate_storage_minor_number();
|
||||
auto major_number = StorageManagement::storage_type_major_number();
|
||||
auto device_name = String::formatted("nvme{:d}n{:d}", controller_id, nsid);
|
||||
auto device_name_kstring = KString::must_create(device_name.view());
|
||||
auto device = TRY(DeviceManagement::try_create_device<NVMeNameSpace>(queues, storage_size, lba_size, major_number.value(), minor_number.value(), nsid, move(device_name_kstring)));
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
NVMeNameSpace::NVMeNameSpace(NonnullRefPtrVector<NVMeQueue> queues, size_t max_addresable_block, size_t lba_size, size_t major_number, size_t minor_number, u16 nsid, NonnullOwnPtr<KString> dev_name)
|
||||
: StorageDevice(major_number, minor_number, lba_size, max_addresable_block, move(dev_name))
|
||||
, m_nsid(nsid)
|
||||
, m_queues(queues)
|
||||
{
|
||||
}
|
||||
|
||||
void NVMeNameSpace::start_request(AsyncBlockDeviceRequest& request)
|
||||
{
|
||||
auto index = Processor::current_id();
|
||||
auto& queue = m_queues.at(index);
|
||||
// TODO: For now we support only IO transfers of size PAGE_SIZE (Going along with the current constraint in the block layer)
|
||||
// Eventually remove this constraint by using the PRP2 field in the submission struct and remove block layer constraint for NVMe driver.
|
||||
VERIFY(request.block_count() <= (PAGE_SIZE / block_size()));
|
||||
|
||||
if (request.request_type() == AsyncBlockDeviceRequest::Read) {
|
||||
queue.read(request, m_nsid, request.block_index(), request.block_count());
|
||||
} else {
|
||||
queue.write(request, m_nsid, request.block_index(), request.block_count());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue