From ec3f2b014e64c5f4f2e01bfdc8a87721f8279396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85strand?= Date: Wed, 9 Jun 2021 10:43:38 +0200 Subject: Add weak linkage attributes for stubbing Add weak linkage attribute to underlying kernel module and filedescriptors to be able to replace with stub methods together with an example stub implementation. Change-Id: I766c51fceede7df16c599bd9f1874e31c264776d --- driver_library/src/ethosu.cpp | 52 +++++++++++++++++------- driver_library/src/ethosu_stub.cpp | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 driver_library/src/ethosu_stub.cpp diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp index 997e12a..0262429 100644 --- a/driver_library/src/ethosu.cpp +++ b/driver_library/src/ethosu.cpp @@ -33,8 +33,8 @@ using namespace std; -namespace { -int eioctl(int fd, unsigned long cmd, void *data = nullptr) { +namespace EthosU { +__attribute__((weak)) int eioctl(int fd, unsigned long cmd, void *data = nullptr) { int ret = ::ioctl(fd, cmd, data); if (ret < 0) { throw EthosU::Exception("IOCTL failed"); @@ -43,10 +43,37 @@ int eioctl(int fd, unsigned long cmd, void *data = nullptr) { return ret; } +__attribute__((weak)) int eopen(const char *pathname, int flags) { + int fd = ::open(pathname, flags); + + if (fd < 0) { + throw Exception("Failed to open device"); + } + + return fd; +} + +__attribute__((weak)) int epoll(struct pollfd *fds, nfds_t nfds, int timeout) { + return ::poll(fds, nfds, timeout); +} + +__attribute__((weak)) int eclose(int fd) { + return ::close(fd); +} +__attribute((weak)) void *emmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { + return ::mmap(addr, length, prot, flags, fd, offset); +} + +__attribute__((weak)) int emunmap(void *addr, size_t length) { + return ::munmap(addr, length); +} + +} // namespace EthosU + /**************************************************************************** * TFL micro helpers ****************************************************************************/ - +namespace { size_t getShapeSize(const flatbuffers::Vector *shape) { size_t size = 1; @@ -151,16 +178,12 @@ ostream &operator<<(ostream &out, const SemanticVersion &v) { /**************************************************************************** * Device ****************************************************************************/ - Device::Device(const char *device) { - fd = open(device, O_RDWR | O_NONBLOCK); - if (fd < 0) { - throw Exception("Failed to open device"); - } + fd = eopen(device, O_RDWR | O_NONBLOCK); } Device::~Device() { - close(fd); + eclose(fd); } int Device::ioctl(unsigned long cmd, void *data) { @@ -189,7 +212,7 @@ Buffer::Buffer(Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr) ethosu_uapi_buffer_create uapi = {static_cast(dataCapacity)}; fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast(&uapi)); - void *d = ::mmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + void *d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (d == MAP_FAILED) { throw Exception("MMap failed"); } @@ -198,7 +221,8 @@ Buffer::Buffer(Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr) } Buffer::~Buffer() { - close(fd); + emunmap(dataPtr, dataCapacity); + eclose(fd); } size_t Buffer::capacity() const { @@ -263,7 +287,7 @@ Network::Network(Device &device, shared_ptr &buffer) : fd(-1), buffer(bu } Network::~Network() { - close(fd); + eclose(fd); } int Network::ioctl(unsigned long cmd, void *data) { @@ -307,7 +331,7 @@ size_t Network::getOfmSize() const { ****************************************************************************/ Inference::~Inference() { - close(fd); + eclose(fd); } void Inference::create(std::vector &counterConfigs, bool cycleCounterEnable = false) { @@ -359,7 +383,7 @@ int Inference::wait(int timeoutSec) { pfd.events = POLLIN | POLLERR; pfd.revents = 0; - int ret = ::poll(&pfd, 1, timeoutSec * 1000); + int ret = epoll(&pfd, 1, timeoutSec * 1000); cout << "Poll. ret=" << ret << ", revents=" << pfd.revents << endl; diff --git a/driver_library/src/ethosu_stub.cpp b/driver_library/src/ethosu_stub.cpp new file mode 100644 index 0000000..9dfc029 --- /dev/null +++ b/driver_library/src/ethosu_stub.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace EthosU { +int eopen(const char *p, int) { + std::cout << "Opened filedescriptor for " << p; + return 1; +} + +int eclose(int) { + return 0; +} + +void *emmap(void *, size_t length, int, int, int, off_t) { + void *d = malloc(length); + return d; +} + +int emunmap(void *addr, size_t) { + free(addr); + return 0; +} + +int eioctl(int, unsigned long cmd, void *) { + int result = 0; + using namespace EthosU; + + switch (cmd) { + case ETHOSU_IOCTL_PING: + return result; + case ETHOSU_IOCTL_VERSION_REQ: + return result; + case ETHOSU_IOCTL_CAPABILITIES_REQ: + return result; + case ETHOSU_IOCTL_BUFFER_CREATE: + return result; + case ETHOSU_IOCTL_BUFFER_SET: + return result; + case ETHOSU_IOCTL_BUFFER_GET: + return result; + case ETHOSU_IOCTL_NETWORK_CREATE: + return result; + case ETHOSU_IOCTL_INFERENCE_CREATE: + return result; + case ETHOSU_IOCTL_INFERENCE_STATUS: + return result; + default: + throw EthosU::Exception("Unknown IOCTL"); + } +} + +int epoll(struct pollfd *, nfds_t, int timeout) { + sleep(timeout / 2); + return 1; +} +} // namespace EthosU -- cgit v1.2.1