ee9b179a10428a4f6ecb1321ce04282f5fb0c94d
[platform/upstream/hailort.git] /
1 /**
2  * Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
3  * Distributed under the MIT license (https://opensource.org/licenses/MIT)
4 **/
5 /**
6  * @file ddr_action_list_buffer_builder.cpp
7  * @brief Class used to build the action list sent to the firmware through DDR.
8  **/
9
10 #include "ddr_action_list_buffer_builder.hpp"
11
12 namespace hailort
13 {
14
15 // TODO: HRT-12512 : Can remove these variables when / if continuous buffer comes from designated region
16 // In hailo15 - the DDR memory range of 0x80000000 - 0x90000000 is mapped to the M4 using a LUT (look up table) to addresses
17 // 0x50000000 - 0x60000000, Currently this is the range the CMA allocation should come from seeing as this is one of the first CMA allocations
18 // and the linux cma memory pool according to the hailo15 dtsi is - "alloc-ranges = <0 0x80000000 0 0x40000000>"
19 // (meaning starts from 0x80000000 and goes for 992 MB) - so anything allocated from 0x90000000 and on ward will be outside the mapped area
20 // The solution to this issue is to create a specific range for this allocation inide the mapped area - seeing as this affects other components
21 // Like the dsp etc...need to check with them before doing so. For now - this should almost always retirn in the mapped area and we will verify
22 // to double check
23
24 DDRActionListBufferBuilder::DDRActionListBufferBuilder(vdma::ContinuousBuffer &&buffer) :
25     ActionListBufferBuilder(ActionListBufferBuilder::Type::DDR),
26     m_action_list_buffer(std::move(buffer)),
27     m_write_offset(0),
28     m_current_context_info{}
29 {}
30
31 bool DDRActionListBufferBuilder::verify_dma_addr(vdma::ContinuousBuffer &buffer)
32 {
33     // verify that buffer starts and ends inside mapped range
34     if (buffer.dma_address() < CONTEXT_SWITCH_DEFS__START_M4_MAPPED_DDR_ADDRESS ||
35         (buffer.dma_address() + buffer.size() >= CONTEXT_SWITCH_DEFS__END_M4_MAPPED_DDR_ADDRESS)) {
36         return false;
37     }
38     return true;
39 }
40
41 Expected<std::shared_ptr<DDRActionListBufferBuilder>> DDRActionListBufferBuilder::create(size_t num_contexts,
42     HailoRTDriver &driver)
43 {
44     // Try to allocate continous buffer for action list in DDR
45     auto continous_alloc = vdma::ContinuousBuffer::create(num_contexts * 
46         sizeof(CONTROL_PROTOCOL__context_switch_context_info_chunk_t), driver);
47
48     // TODO HRT-12512 - Add fallback to Control if continous buffer allocation fails
49     CHECK_EXPECTED(continous_alloc);
50     // Verify that continous buffer is in allocated region
51     CHECK_AS_EXPECTED(verify_dma_addr(continous_alloc.value()), HAILO_INTERNAL_FAILURE,
52         "Failed to allocate continous buffer in M4 mapped memory region");
53     return make_shared_nothrow<DDRActionListBufferBuilder>(continous_alloc.release());
54 }
55
56 hailo_status DDRActionListBufferBuilder::write_action(MemoryView action,
57     CONTROL_PROTOCOL__context_switch_context_type_t context_type, bool is_new_context, bool is_last_action_in_context)
58 {
59     assert(action.size() < std::numeric_limits<uint32_t>::max());
60     const uint32_t action_size = static_cast<uint32_t>(action.size());
61
62     if (is_new_context) {
63         m_current_context_info.is_first_chunk_per_context = true;
64         m_current_context_info.is_last_chunk_per_context = true;
65         m_current_context_info.context_type = static_cast<uint8_t>(context_type);
66         m_current_context_info.context_network_data_length = 0;
67     }
68
69     CHECK(m_current_context_info.context_network_data_length + action_size <=
70         ARRAY_ENTRIES(m_current_context_info.context_network_data), HAILO_INVALID_ARGUMENT,
71         "Context exceeds maximum context size {}", ARRAY_ENTRIES(m_current_context_info.context_network_data));
72
73     // TODO HRT-12788 - make more efficient by writing directly to DDR without using the local context_info_single_control_t
74     memcpy(&(m_current_context_info.context_network_data[m_current_context_info.context_network_data_length]),
75         action.data(), action_size);
76     m_current_context_info.context_network_data_length += action_size;
77
78     if (is_last_action_in_context) {
79         const auto write_size = sizeof(CONTROL_PROTOCOL__context_switch_context_info_chunk_t);
80         auto status = m_action_list_buffer.write(&m_current_context_info, write_size, m_write_offset);
81         CHECK_SUCCESS(status);
82         m_write_offset += write_size;
83     }
84
85     return HAILO_SUCCESS;
86 }
87
88 uint64_t DDRActionListBufferBuilder::get_mapped_buffer_dma_address() const
89 {
90     return m_action_list_buffer.dma_address();
91 }
92
93 } /* namespace hailort */