tapasco_memory.c 6.43 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//
// Copyright (C) 2017 Jens Korinth, TU Darmstadt
//
// This file is part of Tapasco (TAPASCO).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco.  If not, see <http://www.gnu.org/licenses/>.
//
/**
 *  @file	tapasco_memory.c
 *  @brief	Default implementation of memory functions: Pass-through to
 *  		Platform implementation.
 *  @author	J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
 **/
#ifdef __cplusplus
	#include <cstdint>
	#include <cstring>
28
	#include <cstdarg>
29
30
31
#else
	#include <stdint.h>
	#include <string.h>
32
	#include <stdarg.h>
33
34
35
36
37
#endif
#include <platform.h>
#include <tapasco_memory.h>
#include <tapasco_logging.h>
#include <tapasco_errors.h>
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <tapasco_device.h>
#include <tapasco_status.h>
#include <tapasco_local_mem.h>
#include <platform.h>

static
tapasco_res_t tapasco_device_alloc_local(tapasco_dev_ctx_t *dev_ctx,
		tapasco_handle_t *h, size_t const len,
		tapasco_device_alloc_flag_t const flags,
		tapasco_func_slot_id_t slot_id)
{
	LOG(LALL_MEM, "allocating %zd bytes of pe-local memory for function #%lu",
			len, (unsigned long)slot_id);
	return tapasco_local_mem_alloc(tapasco_device_local_mem(dev_ctx),
			slot_id, len, h);
}

static
tapasco_res_t tapasco_device_free_local(tapasco_dev_ctx_t *dev_ctx,
		tapasco_handle_t h, size_t const len,
		tapasco_device_alloc_flag_t const flags,
		tapasco_func_slot_id_t slot_id)
{
	LOG(LALL_MEM, "freeing %zd bytes of pe-local memory for function #%lu",
			len, (unsigned long)slot_id);
	tapasco_local_mem_dealloc(tapasco_device_local_mem(dev_ctx), slot_id,
			len, h);
	return TAPASCO_SUCCESS;
}
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
static
tapasco_res_t tapasco_device_copy_to_local(tapasco_dev_ctx_t *dev_ctx,
		void const *src, tapasco_handle_t dst, size_t len,
		tapasco_device_copy_flag_t const flags,
		tapasco_func_slot_id_t slot_id)
{
	platform_ctl_addr_t a = platform_address_get_slot_base(slot_id, 0);
	addr_t lbase = tapasco_local_mem_get_base(tapasco_device_local_mem(dev_ctx), slot_id);
	LOG(LALL_MEM, "copying locally to 0x%08lx of slot_id #%lu, bus address: 0x%08lx",
			(unsigned long)dst, (unsigned long)slot_id, (unsigned long)a + (dst - lbase));
	a += (dst - lbase);
	uint32_t *lmem = (uint32_t *)src;
	tapasco_res_t res = TAPASCO_SUCCESS;
	for (size_t i = 0; res == TAPASCO_SUCCESS && i < len; i += sizeof(*lmem), a += sizeof(*lmem)) {
		res = platform_write_ctl(a, sizeof(*lmem), &lmem[i], flags);
	}
	return res;
}

static
tapasco_res_t tapasco_device_copy_from_local(tapasco_dev_ctx_t *dev_ctx,
		tapasco_handle_t src, void *dst, size_t len,
		tapasco_device_copy_flag_t const flags,
		tapasco_func_slot_id_t slot_id)
{
	platform_ctl_addr_t a = platform_address_get_slot_base(slot_id, 0);
	addr_t lbase = tapasco_local_mem_get_base(tapasco_device_local_mem(dev_ctx), slot_id);
	LOG(LALL_MEM, "copying locally from 0x%08lx of slot_id #%lu, bus address: 0x%08lx",
			(unsigned long)src, (unsigned long)slot_id, (unsigned long)a + (src - lbase));
	a += (src - lbase);
	uint32_t *lmem = (uint32_t *)dst;
	tapasco_res_t res = TAPASCO_SUCCESS;
	for (size_t i = 0; res == TAPASCO_SUCCESS && i < len; i += sizeof(*lmem), a += sizeof(*lmem)) {
		res = platform_read_ctl(a, sizeof(*lmem), &lmem[i], flags);
	}
	return res;
}

tapasco_res_t tapasco_device_alloc(tapasco_dev_ctx_t *dev_ctx,
		tapasco_handle_t *h, size_t const len,
		tapasco_device_alloc_flag_t const flags,
		...)
110
111
112
{
	platform_mem_addr_t addr;
	platform_res_t r;
113
114
115
116
117
118
	if (flags & TAPASCO_DEVICE_ALLOC_FLAGS_PE_LOCAL) {
		va_list ap; va_start(ap, flags);
		tapasco_func_slot_id_t slot_id = va_arg(ap, tapasco_func_slot_id_t);
		va_end(ap);
		return tapasco_device_alloc_local(dev_ctx, h, len, flags, slot_id);
	}
119
120
121
122
123
124
125
126
127
128
129
	if ((r = platform_alloc(len, &addr, PLATFORM_ALLOC_FLAGS_NONE)) == PLATFORM_SUCCESS) {
		LOG(LALL_MEM, "allocated %zd bytes at 0x%08x", len, addr);
		*h = addr;
		return TAPASCO_SUCCESS;
	}
	WRN("could not allocate %zd bytes of device memory: %s",
			len, platform_strerror(r));
	return TAPASCO_ERR_OUT_OF_MEMORY;
}

void tapasco_device_free(tapasco_dev_ctx_t *dev_ctx, tapasco_handle_t handle,
130
		tapasco_device_alloc_flag_t const flags, ...)
131
132
{
	LOG(LALL_MEM, "freeing handle 0x%08x", (unsigned)handle);
133
134
135
136
137
138
139
	if (flags & TAPASCO_DEVICE_ALLOC_FLAGS_PE_LOCAL) {
		va_list ap; va_start(ap, flags);
		tapasco_func_slot_id_t slot_id = va_arg(ap, tapasco_func_slot_id_t);
		size_t len = va_arg(ap, size_t);
		va_end(ap);
		tapasco_device_free_local(dev_ctx, handle, len, flags, slot_id);
	}
140
141
142
143
144
	platform_dealloc(handle, PLATFORM_ALLOC_FLAGS_NONE);
}

tapasco_res_t tapasco_device_copy_to(tapasco_dev_ctx_t *dev_ctx, void const *src,
		tapasco_handle_t dst, size_t len,
145
		tapasco_device_copy_flag_t const flags, ...)
146
147
148
149
{
	LOG(LALL_MEM, "dst = 0x%08x, len = %zd, flags = %d", (unsigned)dst, len, flags);
	if (flags & TAPASCO_DEVICE_COPY_NONBLOCKING)
		return TAPASCO_ERR_NONBLOCKING_MODE_NOT_SUPPORTED;
150
151
152
153
154
155
156
	if (flags & TAPASCO_DEVICE_COPY_PE_LOCAL) {
		va_list ap;
		va_start(ap, flags);
		tapasco_func_slot_id_t slot_id = va_arg(ap, tapasco_func_slot_id_t);
		va_end(ap);
		return tapasco_device_copy_to_local(dev_ctx, src, dst, len, flags, slot_id);
	}
157
158
159
160
161
162
	if (flags)
		return TAPASCO_ERR_NOT_IMPLEMENTED;
	return platform_write_mem(dst, len, src, PLATFORM_MEM_FLAGS_NONE) == PLATFORM_SUCCESS ?
			TAPASCO_SUCCESS : TAPASCO_FAILURE;
}

163
164
165
166
tapasco_res_t tapasco_device_copy_from(tapasco_dev_ctx_t *dev_ctx,
		tapasco_handle_t src, void *dst, size_t len,
		tapasco_device_copy_flag_t const flags,
		...)
167
168
169
170
{
	LOG(LALL_MEM, "src = 0x%08x, len = %zd, flags = %d", (unsigned)src, len, flags);
	if (flags & TAPASCO_DEVICE_COPY_NONBLOCKING)
		return TAPASCO_ERR_NONBLOCKING_MODE_NOT_SUPPORTED;
171
172
173
174
175
176
177
	if (flags & TAPASCO_DEVICE_COPY_PE_LOCAL) {
		va_list ap;
		va_start(ap, flags);
		tapasco_func_slot_id_t slot_id = va_arg(ap, tapasco_func_slot_id_t);
		va_end(ap);
		return tapasco_device_copy_from_local(dev_ctx, src, dst, len, flags, slot_id);
	}
178
179
180
181
182
	if (flags)
		return TAPASCO_ERR_NOT_IMPLEMENTED;
	return platform_read_mem(src, len, dst, PLATFORM_MEM_FLAGS_NONE) == PLATFORM_SUCCESS ?
			TAPASCO_SUCCESS : TAPASCO_FAILURE;
}