From 392ed763445f0f036dbb1cb37e0ba6c2d24ade47 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Mon, 9 Oct 2023 16:09:45 +0200 Subject: [PATCH] nvme_drv: arch-specific Dma_buffer allocation Different cacheability properties should be applied dependent on the target architecture. genodelabs/genode#5000 --- repos/os/src/drivers/nvme/dma_buffer.h | 42 +++++++++++++++++++ repos/os/src/drivers/nvme/main.cc | 29 +++++++------ .../drivers/nvme/spec/arm_64/dma_buffer.cc | 19 +++++++++ .../os/src/drivers/nvme/spec/arm_64/target.mk | 4 ++ .../src/drivers/nvme/spec/x86/dma_buffer.cc | 19 +++++++++ repos/os/src/drivers/nvme/spec/x86/target.mk | 4 ++ repos/os/src/drivers/nvme/target.inc | 6 +++ repos/os/src/drivers/nvme/target.mk | 4 -- 8 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 repos/os/src/drivers/nvme/dma_buffer.h create mode 100644 repos/os/src/drivers/nvme/spec/arm_64/dma_buffer.cc create mode 100644 repos/os/src/drivers/nvme/spec/arm_64/target.mk create mode 100644 repos/os/src/drivers/nvme/spec/x86/dma_buffer.cc create mode 100644 repos/os/src/drivers/nvme/spec/x86/target.mk create mode 100644 repos/os/src/drivers/nvme/target.inc delete mode 100644 repos/os/src/drivers/nvme/target.mk diff --git a/repos/os/src/drivers/nvme/dma_buffer.h b/repos/os/src/drivers/nvme/dma_buffer.h new file mode 100644 index 0000000000..20a197ad4c --- /dev/null +++ b/repos/os/src/drivers/nvme/dma_buffer.h @@ -0,0 +1,42 @@ +/* + * \brief DMA buffer utility + * \author Johannes Schlatow + * \date 2023-10-09 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _NVME_DMA_BUFFER_H_ +#define _NVME_DMA_BUFFER_H_ + +/* Genode includes */ +#include + +namespace Util { + + using namespace Genode; + + /** + * We use an arch-specific Dma_buffer implementation to care about + * whether to use CACHED or UNCACHED memory. + */ + class Dma_buffer : public Platform::Dma_buffer + { + public: + + Dma_buffer(Platform::Connection &platform, size_t size); + + /** + * If needed, we can add a method for cache clean/invalidate operations + * that arch-specifically. Currently, the driver is used on x86 with + * strong coherency and arm with uncached memory. + */ + }; +} + +#endif /* _NVME_DMA_BUFFER_H_ */ diff --git a/repos/os/src/drivers/nvme/main.cc b/repos/os/src/drivers/nvme/main.cc index 6d00e4c04c..282ff6f609 100644 --- a/repos/os/src/drivers/nvme/main.cc +++ b/repos/os/src/drivers/nvme/main.cc @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ /* local includes */ #include +#include namespace { @@ -514,7 +514,7 @@ struct Nvme::Sqe_io : Nvme::Sqe /* * Queue base structure */ -struct Nvme::Queue : Platform::Dma_buffer +struct Nvme::Queue : Util::Dma_buffer { size_t len; uint32_t max_entries; @@ -523,7 +523,7 @@ struct Nvme::Queue : Platform::Dma_buffer uint32_t max_entries, size_t len) : - Dma_buffer(platform, len * max_entries, UNCACHED), + Dma_buffer(platform, len * max_entries), len(len), max_entries(max_entries) {}; }; @@ -812,11 +812,11 @@ class Nvme::Controller : Platform::Device, Constructible &_admin_cq = _cq[0]; Constructible &_admin_sq = _sq[0]; - Platform::Dma_buffer _nvme_identify { _platform, IDENTIFY_LEN, UNCACHED }; + Util::Dma_buffer _nvme_identify { _platform, IDENTIFY_LEN }; Genode::Constructible _identify_data { }; - Platform::Dma_buffer _nvme_nslist { _platform, IDENTIFY_LEN, UNCACHED }; + Util::Dma_buffer _nvme_nslist { _platform, IDENTIFY_LEN }; uint32_t _nvme_nslist_count { 0 }; size_t _mdts_bytes { 0 }; @@ -841,19 +841,19 @@ class Nvme::Controller : Platform::Device, SET_HMB_CID, }; - Constructible _nvme_query_ns[MAX_NS] { }; + Constructible _nvme_query_ns[MAX_NS] { }; struct Hmb_chunk { Registry::Element _elem; - Platform::Dma_buffer dma_buffer; + Util::Dma_buffer dma_buffer; Hmb_chunk(Registry ®istry, Platform::Connection &platform, size_t size) : _elem { registry, *this }, - dma_buffer { platform, size, UNCACHED } + dma_buffer { platform, size } { } virtual ~Hmb_chunk() { } @@ -875,7 +875,7 @@ class Nvme::Controller : Platform::Device, Heap _hmb_alloc { _env.ram(), _env.rm() }; Constructible _hmb_chunk_registry { }; - Constructible _hmb_descr_list_buffer { }; + Constructible _hmb_descr_list_buffer { }; Info _info { }; @@ -1103,7 +1103,7 @@ class Nvme::Controller : Platform::Device, uint16_t const id = 0; if (!_nvme_query_ns[id].constructed()) - _nvme_query_ns[id].construct(_platform, IDENTIFY_LEN, UNCACHED); + _nvme_query_ns[id].construct(_platform, IDENTIFY_LEN); Sqe_identify b(_admin_command(Opcode::IDENTIFY, ns[id], QUERYNS_CID)); b.write(_nvme_query_ns[id]->dma_addr()); @@ -1222,7 +1222,7 @@ class Nvme::Controller : Platform::Device, uint32_t const num_entries = bytes / HMB_CHUNK_SIZE; try { - _hmb_descr_list_buffer.construct(_platform, HMB_LIST_SIZE, UNCACHED); + _hmb_descr_list_buffer.construct(_platform, HMB_LIST_SIZE); } catch (... /* intentional catch-all */) { warning("could not allocate HMB descriptor list page"); return; @@ -1771,14 +1771,13 @@ class Nvme::Driver : Genode::Noncopyable ** DMA ** *********/ - Constructible _dma_buffer { }; + Constructible _dma_buffer { }; /* * The PRP (Physical Region Pages) page is used to setup * large requests. */ - Platform::Dma_buffer _prp_list_helper { _platform, Nvme::PRP_DS_SIZE, - UNCACHED }; + Util::Dma_buffer _prp_list_helper { _platform, Nvme::PRP_DS_SIZE }; /*********** ** Block ** @@ -2162,7 +2161,7 @@ class Nvme::Driver : Genode::Noncopyable Dataspace_capability dma_buffer_construct(size_t size) { - _dma_buffer.construct(_platform, size, UNCACHED); + _dma_buffer.construct(_platform, size); return _dma_buffer->cap(); } diff --git a/repos/os/src/drivers/nvme/spec/arm_64/dma_buffer.cc b/repos/os/src/drivers/nvme/spec/arm_64/dma_buffer.cc new file mode 100644 index 0000000000..c85418c513 --- /dev/null +++ b/repos/os/src/drivers/nvme/spec/arm_64/dma_buffer.cc @@ -0,0 +1,19 @@ +/* + * \brief ARM 64bit DMA buffer + * \author Johannes Schlatow + * \date 2023-10-09 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +Util::Dma_buffer::Dma_buffer(Platform::Connection &platform, Genode::size_t size) +: Platform::Dma_buffer(platform, size, Genode::UNCACHED) +{ } diff --git a/repos/os/src/drivers/nvme/spec/arm_64/target.mk b/repos/os/src/drivers/nvme/spec/arm_64/target.mk new file mode 100644 index 0000000000..a2731f0253 --- /dev/null +++ b/repos/os/src/drivers/nvme/spec/arm_64/target.mk @@ -0,0 +1,4 @@ +include $(PRG_DIR)/../../target.inc + +REQUIRES += arm_64 +SRC_CC += spec/arm_64/dma_buffer.cc diff --git a/repos/os/src/drivers/nvme/spec/x86/dma_buffer.cc b/repos/os/src/drivers/nvme/spec/x86/dma_buffer.cc new file mode 100644 index 0000000000..db18b59098 --- /dev/null +++ b/repos/os/src/drivers/nvme/spec/x86/dma_buffer.cc @@ -0,0 +1,19 @@ +/* + * \brief x86 DMA buffer + * \author Johannes Schlatow + * \date 2023-10-09 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +Util::Dma_buffer::Dma_buffer(Platform::Connection &platform, Genode::size_t size) +: Platform::Dma_buffer(platform, size, UNCACHED) +{ } diff --git a/repos/os/src/drivers/nvme/spec/x86/target.mk b/repos/os/src/drivers/nvme/spec/x86/target.mk new file mode 100644 index 0000000000..fa15657fef --- /dev/null +++ b/repos/os/src/drivers/nvme/spec/x86/target.mk @@ -0,0 +1,4 @@ +include $(PRG_DIR)/../../target.inc + +REQUIRES += x86 +SRC_CC += spec/x86/dma_buffer.cc diff --git a/repos/os/src/drivers/nvme/target.inc b/repos/os/src/drivers/nvme/target.inc new file mode 100644 index 0000000000..c3ff468886 --- /dev/null +++ b/repos/os/src/drivers/nvme/target.inc @@ -0,0 +1,6 @@ +TARGET = nvme_drv +SRC_CC = main.cc +INC_DIR += $(PRG_DIR)/../.. $(PRG_DIR) +LIBS += base + +vpath %.cc $(PRG_DIR)/../.. diff --git a/repos/os/src/drivers/nvme/target.mk b/repos/os/src/drivers/nvme/target.mk deleted file mode 100644 index 4dfeb6250f..0000000000 --- a/repos/os/src/drivers/nvme/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = nvme_drv -SRC_CC = main.cc -INC_DIR += $(PRG_DIR) -LIBS += base