aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYulia Garbovich <yulia.garbovich@arm.com>2021-11-23 20:00:04 +0200
committerYulia Garbovich <yulia.garbovich@arm.com>2021-12-14 11:43:57 +0200
commite9cdc6374dc730dc61d2a8a81beabe563ad7fe88 (patch)
treee56813c3fb447cf0bb9200157f802971d6f40be8
parent29467e04fbc15f53001c0c95227db34160b776e7 (diff)
downloadethos-u-core-platform-e9cdc6374dc730dc61d2a8a81beabe563ad7fe88.tar.gz
Add mpu driver and remove interface library
from drivers Add mpu driver for upstreaming After removing of interface library,targets and applications will list explicitly which libraries to link Change-Id: Icfa449a2981093161f283e45b4d52ca6199371b8
-rw-r--r--drivers/CMakeLists.txt49
-rw-r--r--drivers/mailbox/CMakeLists.txt21
-rw-r--r--drivers/mailbox/include/mailbox.hpp100
-rw-r--r--drivers/mailbox/src/mailbox.cpp65
-rw-r--r--drivers/mhu_dummy/CMakeLists.txt23
-rw-r--r--drivers/mhu_dummy/include/mhu_dummy.hpp36
-rw-r--r--drivers/mhu_dummy/src/mhu_dummy.cpp33
-rw-r--r--drivers/mhu_juno/CMakeLists.txt23
-rw-r--r--drivers/mhu_juno/include/mhu_juno.hpp66
-rw-r--r--drivers/mhu_juno/src/mhu_juno.cpp76
-rw-r--r--drivers/mhu_v2/CMakeLists.txt23
-rw-r--r--drivers/mhu_v2/include/mhu_v2.hpp169
-rw-r--r--drivers/mhu_v2/src/mhu_v2.cpp209
-rw-r--r--drivers/mpu/CMakeLists.txt25
-rw-r--r--drivers/mpu/include/mpu.hpp (renamed from targets/corstone-300/mpu.hpp)0
-rw-r--r--drivers/mpu/src/mpu.cpp (renamed from targets/corstone-300/mpu.cpp)4
-rw-r--r--drivers/timing_adapter/CMakeLists.txt23
-rw-r--r--drivers/timing_adapter/include/timing_adapter.h133
-rw-r--r--drivers/timing_adapter/src/timing_adapter.c215
-rw-r--r--drivers/uart/CMakeLists.txt41
-rw-r--r--drivers/uart/include/uart_stdout.h (renamed from targets/corstone-300/uart.h)10
-rw-r--r--drivers/uart/src/uart_cmsdk_apb.c (renamed from targets/corstone-300/uart.c)41
-rw-r--r--drivers/uart/src/uart_dummy.c36
-rw-r--r--drivers/uart/src/uart_pl011.c220
-rw-r--r--drivers/uart/uart_config.h.in (renamed from targets/corstone-300/uart_config.h)8
-rw-r--r--targets/common/CMakeLists.txt2
-rw-r--r--targets/corstone-300/CMakeLists.txt10
-rw-r--r--targets/corstone-300/retarget.c8
-rw-r--r--targets/corstone-300/target.cpp4
29 files changed, 1627 insertions, 46 deletions
diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt
new file mode 100644
index 0000000..1f97dc5
--- /dev/null
+++ b/drivers/CMakeLists.txt
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+#############################################################################
+# Mailbox driver
+#############################################################################
+add_subdirectory(mailbox)
+
+#############################################################################
+# MHU drivers
+#############################################################################
+# NOTE: These are all built and linked from a CMake perspective. However the
+# application code can instantiate one or more of the drivers. The
+# one(s) not used will later be removed by the linker.
+add_subdirectory(mhu_v2)
+add_subdirectory(mhu_juno)
+add_subdirectory(mhu_dummy)
+
+#############################################################################
+# UART drivers
+#############################################################################
+# NOTE: All UART drivers are built, however a platform application should
+# link the appropriate driver target (see drivers/uart/CMakeLists.txt).
+add_subdirectory(uart)
+
+#############################################################################
+# Timing adapter driver
+#############################################################################
+add_subdirectory(timing_adapter)
+
+#############################################################################
+# MPU driver
+#############################################################################
+add_subdirectory(mpu)
diff --git a/drivers/mailbox/CMakeLists.txt b/drivers/mailbox/CMakeLists.txt
new file mode 100644
index 0000000..bf8889a
--- /dev/null
+++ b/drivers/mailbox/CMakeLists.txt
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+add_library(ethosu_mailbox STATIC)
+target_include_directories(ethosu_mailbox PUBLIC include)
+target_sources(ethosu_mailbox PRIVATE src/mailbox.cpp)
diff --git a/drivers/mailbox/include/mailbox.hpp b/drivers/mailbox/include/mailbox.hpp
new file mode 100644
index 0000000..f6d9edb
--- /dev/null
+++ b/drivers/mailbox/include/mailbox.hpp
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef MAILBOX_HPP
+#define MAILBOX_HPP
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+
+namespace Mailbox {
+
+/**
+ * The Mailbox parent class
+ *
+ * Intended to be implemented by a driver subclass, see MHU_v2 driver as example.
+ */
+class Mailbox {
+public:
+ /**
+ * Constructor/Destructor
+ */
+ Mailbox();
+ virtual ~Mailbox();
+
+ /**
+ * Intended to trigger an interrupt to an external block
+ * MUST be implemented by subclass.
+ */
+ virtual bool sendMessage() = 0;
+
+ /**
+ * Intended to be called when Cortex M has received an
+ * interrupt/event from mailbox/mhu. If an interrupt needs to be cleared,
+ * this is a good place to do that. MUST call notify().
+ * MUST be implemented by subclass.
+ */
+ virtual void handleMessage() = 0;
+
+ /**
+ * Can be used to verify that hardware versions match expected versions
+ * CAN be implemented by subclass, optional. Default impl returns true.
+ */
+ virtual bool verifyHardware();
+
+ /**
+ * Function signature for callbacks
+ */
+ typedef void (*CallbackFptr)(void *userArg);
+
+ /**
+ * Register a callback to be called when a message is received.
+ */
+ void registerCallback(CallbackFptr callback, void *userArg);
+
+ /**
+ * Remove a specific callback from the callback list.
+ */
+ void deregisterCallback(CallbackFptr callback, void *userArg);
+
+protected:
+ /**
+ * Calls every registered callback when a message has been received.
+ */
+ void notify();
+
+ /**
+ * Helper functions
+ */
+ uint32_t read32(volatile uint32_t *baseAddr, const uint32_t offset);
+ void write32(volatile uint32_t *baseAddr, const uint32_t offset, const uint32_t value);
+
+private:
+ struct Callback {
+ bool operator==(const Callback &b) const;
+ CallbackFptr callback;
+ void *userArg;
+ };
+
+ std::list<Callback> callbacks;
+};
+
+} // namespace Mailbox
+
+#endif
diff --git a/drivers/mailbox/src/mailbox.cpp b/drivers/mailbox/src/mailbox.cpp
new file mode 100644
index 0000000..e5950f0
--- /dev/null
+++ b/drivers/mailbox/src/mailbox.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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 <mailbox.hpp>
+
+#include <cassert>
+#include <cstddef>
+
+namespace Mailbox {
+
+Mailbox::Mailbox() {}
+Mailbox::~Mailbox() {}
+
+bool Mailbox::verifyHardware() {
+ return true;
+}
+
+void Mailbox::registerCallback(CallbackFptr callback, void *userArg) {
+ callbacks.push_back({callback, userArg});
+}
+
+void Mailbox::deregisterCallback(CallbackFptr callback, void *userArg) {
+ callbacks.remove({callback, userArg});
+}
+
+void Mailbox::notify() {
+ for (auto &it : callbacks) {
+ it.callback(it.userArg);
+ }
+}
+
+uint32_t Mailbox::read32(volatile uint32_t *baseAddr, const uint32_t offset) {
+ assert(offset % 4 == 0);
+ volatile uint32_t *addr = baseAddr + (offset / 4);
+
+ return *addr;
+}
+
+void Mailbox::write32(volatile uint32_t *baseAddr, const uint32_t offset, const uint32_t value) {
+ assert(offset % 4 == 0);
+ volatile uint32_t *addr = baseAddr + (offset / 4);
+
+ *addr = value;
+}
+
+bool Mailbox::Callback::operator==(const Callback &b) const {
+ return (callback == b.callback && userArg == b.userArg);
+}
+
+} // namespace Mailbox
diff --git a/drivers/mhu_dummy/CMakeLists.txt b/drivers/mhu_dummy/CMakeLists.txt
new file mode 100644
index 0000000..fca7d5b
--- /dev/null
+++ b/drivers/mhu_dummy/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+add_library(ethosu_mhu_dummy STATIC)
+target_include_directories(ethosu_mhu_dummy PUBLIC include)
+
+target_sources(ethosu_mhu_dummy PRIVATE src/mhu_dummy.cpp)
+target_link_libraries(ethosu_mhu_dummy PRIVATE ethosu_mailbox)
diff --git a/drivers/mhu_dummy/include/mhu_dummy.hpp b/drivers/mhu_dummy/include/mhu_dummy.hpp
new file mode 100644
index 0000000..d04fe1c
--- /dev/null
+++ b/drivers/mhu_dummy/include/mhu_dummy.hpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef MHU_DUMMY_HPP
+#define MHU_DUMMY_HPP
+
+#include <mailbox.hpp>
+
+namespace Mailbox {
+
+class MHUDummy : public Mailbox {
+public:
+ MHUDummy();
+ virtual ~MHUDummy();
+ virtual bool sendMessage() final;
+ virtual void handleMessage() final;
+};
+
+} // namespace Mailbox
+
+#endif /* #ifndef MHU_DUMMY_HPP */
diff --git a/drivers/mhu_dummy/src/mhu_dummy.cpp b/drivers/mhu_dummy/src/mhu_dummy.cpp
new file mode 100644
index 0000000..3ae51e7
--- /dev/null
+++ b/drivers/mhu_dummy/src/mhu_dummy.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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 <mhu_dummy.hpp>
+
+namespace Mailbox {
+
+MHUDummy::MHUDummy() {}
+MHUDummy::~MHUDummy() {}
+
+void MHUDummy::handleMessage() {
+ notify();
+}
+bool MHUDummy::sendMessage() {
+ return true;
+}
+
+} // namespace Mailbox
diff --git a/drivers/mhu_juno/CMakeLists.txt b/drivers/mhu_juno/CMakeLists.txt
new file mode 100644
index 0000000..2116ee7
--- /dev/null
+++ b/drivers/mhu_juno/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+add_library(ethosu_mhu_juno STATIC)
+target_include_directories(ethosu_mhu_juno PUBLIC include)
+
+target_sources(ethosu_mhu_juno PRIVATE src/mhu_juno.cpp)
+target_link_libraries(ethosu_mhu_juno PRIVATE ethosu_mailbox)
diff --git a/drivers/mhu_juno/include/mhu_juno.hpp b/drivers/mhu_juno/include/mhu_juno.hpp
new file mode 100644
index 0000000..6b36512
--- /dev/null
+++ b/drivers/mhu_juno/include/mhu_juno.hpp
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef MHU_JUNO_HPP
+#define MHU_JUNO_HPP
+
+#include <mailbox.hpp>
+
+#include <cstddef>
+#include <cstdint>
+
+namespace Mailbox {
+
+// Doorbell implementation only
+class MHUJuno : public Mailbox {
+public:
+ MHUJuno(const uint32_t baseAddress);
+ virtual ~MHUJuno();
+ virtual bool sendMessage() final;
+ virtual void handleMessage() final;
+ virtual bool verifyHardware() final;
+
+private:
+ /* Offsets */
+ static constexpr uint32_t CPU0_INTR_STAT = 0x00;
+ static constexpr uint32_t CPU0_INTR_SET = 0x04;
+ static constexpr uint32_t CPU0_INTR_CLR = 0x08;
+ static constexpr uint32_t CPU1_INTR_STAT = 0x10;
+ static constexpr uint32_t CPU1_INTR_SET = 0x14;
+ static constexpr uint32_t CPU1_INTR_CLR = 0x18;
+ static constexpr uint32_t OFFSET = 0x10;
+ static constexpr uint32_t PIDR0 = 0xfe0;
+ static constexpr uint32_t PIDR1 = 0xfe4;
+ static constexpr uint32_t PIDR2 = 0xfe8;
+ static constexpr uint32_t PIDR3 = 0xfec;
+ static constexpr uint32_t PIDR4 = 0xfd0;
+ static constexpr uint32_t CIDR0 = 0xff0;
+ static constexpr uint32_t CIDR1 = 0xff4;
+ static constexpr uint32_t CIDR2 = 0xff8;
+ static constexpr uint32_t CIDR3 = 0xffc;
+
+ volatile uint32_t *baseAddr;
+
+ void clearMessage();
+ void write(uint32_t offset, uint32_t val);
+ uint32_t read(uint32_t offset);
+};
+
+} // namespace Mailbox
+
+#endif /* #ifndef MHU_JUNO_HPP */
diff --git a/drivers/mhu_juno/src/mhu_juno.cpp b/drivers/mhu_juno/src/mhu_juno.cpp
new file mode 100644
index 0000000..04b1352
--- /dev/null
+++ b/drivers/mhu_juno/src/mhu_juno.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 <mhu_juno.hpp>
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+
+namespace Mailbox {
+
+MHUJuno::MHUJuno(const uint32_t baseAddress) {
+ baseAddr = reinterpret_cast<volatile uint32_t *>(baseAddress);
+}
+
+void MHUJuno::handleMessage() {
+ clearMessage();
+ notify();
+}
+
+MHUJuno::~MHUJuno() {}
+
+// Doorbell only
+bool MHUJuno::sendMessage() {
+ write(CPU1_INTR_SET, 1);
+ return true;
+}
+// Doorbell only
+void MHUJuno::clearMessage() {
+ write(CPU0_INTR_CLR, 0xF);
+}
+
+bool MHUJuno::verifyHardware() {
+ uint32_t pidr0 = read(PIDR0);
+ uint32_t pidr1 = read(PIDR1);
+ uint32_t pidr2 = read(PIDR2);
+ uint32_t pidr3 = read(PIDR3);
+ uint32_t pidr4 = read(PIDR4);
+ uint32_t cidr0 = read(CIDR0);
+ uint32_t cidr1 = read(CIDR1);
+ uint32_t cidr2 = read(CIDR2);
+ uint32_t cidr3 = read(CIDR3);
+
+ if (pidr0 != 0x56 || pidr1 != 0xb8 || pidr2 != 0x0b || pidr3 != 0x00 || pidr4 != 0x04 || cidr0 != 0x0d ||
+ cidr1 != 0xf0 || cidr2 != 0x05 || cidr3 != 0xb1) {
+ return false;
+ }
+ return true;
+}
+
+void MHUJuno::write(const uint32_t offset, const uint32_t value) {
+ write32(baseAddr, offset, value);
+}
+
+uint32_t MHUJuno::read(const uint32_t offset) {
+ return read32(baseAddr, offset);
+}
+
+} // namespace Mailbox
diff --git a/drivers/mhu_v2/CMakeLists.txt b/drivers/mhu_v2/CMakeLists.txt
new file mode 100644
index 0000000..2505901
--- /dev/null
+++ b/drivers/mhu_v2/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+add_library(ethosu_mhu_v2 STATIC)
+target_include_directories(ethosu_mhu_v2 PUBLIC include)
+
+target_sources(ethosu_mhu_v2 PRIVATE src/mhu_v2.cpp)
+target_link_libraries(ethosu_mhu_v2 PRIVATE ethosu_mailbox ethosu_log)
diff --git a/drivers/mhu_v2/include/mhu_v2.hpp b/drivers/mhu_v2/include/mhu_v2.hpp
new file mode 100644
index 0000000..147bc8a
--- /dev/null
+++ b/drivers/mhu_v2/include/mhu_v2.hpp
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+#ifndef MHU_V2_HPP
+#define MHU_V2_HPP
+
+#include <mailbox.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+
+namespace Mailbox {
+/*
+ * SENDER OVERVIEW
+ * ------------------------------------------------------------------------
+ * Offset Access Type Register Name Short Name
+ * ------------------------------------------------------------------------
+ * 0x000-0xF7C - Sender Channel Window 0-123 -
+ * 0xF80 RO Message Handling Unit Configuration MHU_CFG
+ * 0xF84 RW Response Configuration RESP_CFG
+ * 0xF88 RW Access Request ACCESS_REQUEST
+ * 0xF8C RO Access Ready ACCESS_READY
+ * 0xF90 RO Interrupt Status INT_ST
+ * 0xF94 WO Interrupt Clear INT_CLR
+ * 0xF98 RW Interrupt Enable INT_EN
+ * 0xF9C-0xFC4 RO Reserved -
+ * 0xFC8 RO Implementer Identification Register IIDR
+ * 0xFCC RO Architecture Identification Register AIDR
+ * 0xFD0-0xFFC - IMPL DEF Identification Regs -
+ */
+
+/*
+ * RECEIVER OVERVIEW
+ * ------------------------------------------------------------------------
+ * Offset Access Type Register Name Short Name
+ * ------------------------------------------------------------------------
+ * 0x000-0xF7C - Receiver Channel Window 0-123 -
+ * 0xF80 RO Message Handling Unit Configuration MHU_CFG
+ * 0xF84-0xFC4 RO Reserved -
+ * 0xFC8 RO Implementer Identification Register IIDR
+ * 0xFCC RO Architecture Identification Register AIDR
+ * 0xFD0-0xFFC - IMPL DEF Identification Regs -
+ */
+
+/*
+ * Sender Channel Window
+ * ------------------------------------------------------------------------
+ * Offset Access Type Register Name Short Name
+ * ------------------------------------------------------------------------
+ * 0x00 RO Channel Status CH_ST
+ * 0x04 RO Reserved -
+ * 0x08 RO Reserved -
+ * 0x0C WO Channel Set CH_SET
+ * 0x10 RO Reserved -
+ * 0x14 RO Reserved -
+ * 0x18 RO Reserved -
+ * 0x1C RO Reserved -
+ */
+
+/*
+ * Receiver Channel Window
+ * ------------------------------------------------------------------------
+ * Offset Access Type Register Name Short Name
+ * ------------------------------------------------------------------------
+ * 0x00 RO Channel Status CH_ST
+ * 0x04 RO Channel Status Masked CH_ST_MSK
+ * 0x08 WO Channel Clear CH_CLR
+ * 0x0C RO Reserved -
+ * 0x10 RO Channel Mask Status CH_MSK_ST
+ * 0x14 WO Channel Mask Set CH_MSK_SET
+ * 0x18 WO Channel Mask Clear CH_MSK_CLR
+ * 0x1C RO Reserved -
+ */
+
+// Doorbell implementation only
+// NOTE: MHUv2 is unidirectional. Two MHU's are needed for bidirectional
+// messaging. txBase/rxBase refers to the base address of _two_
+// separate MHU blocks.
+class MHUv2 : public Mailbox {
+public:
+ MHUv2(const uint32_t txBaseAddress, const uint32_t rxBaseAddress);
+ virtual ~MHUv2();
+ virtual bool sendMessage() final;
+ virtual void handleMessage() final;
+ virtual bool verifyHardware() final;
+
+private:
+ /* Offsets */
+ static constexpr uint32_t MHUv2_CH_ST = 0x00;
+ static constexpr uint32_t MHUv2_CH_ST_MSK = 0x04;
+ static constexpr uint32_t MHUv2_CH_CLR = 0x08;
+ static constexpr uint32_t MHUv2_CH_SET = 0x0C;
+ static constexpr uint32_t MHUv2_CH_MSK_ST = 0x10;
+ static constexpr uint32_t MHUv2_CH_MSK_SET = 0x14;
+ static constexpr uint32_t MHUv2_CH_MSK_CLR = 0x18;
+ static constexpr uint32_t MHUv2_CH_INT_CLR = 0x14;
+ static constexpr uint32_t MHUv2_CH_INT_EN = 0x18;
+ static constexpr uint32_t MHUv2_SND_CHAN_WINDOW_SIZE = 0x20;
+ static constexpr uint32_t MHUv2_SND_MHU_CFG_OFFS = 0xF80;
+ static constexpr uint32_t MHUv2_SND_RESP_CFG_OFFS = 0xF84;
+ static constexpr uint32_t MHUv2_SND_ACCESS_REQUEST_OFFS = 0xF88;
+ static constexpr uint32_t MHUv2_SND_ACCESS_READY_OFFS = 0xF8C;
+ static constexpr uint32_t MHUv2_SND_INT_ST_OFFS = 0xF90;
+ static constexpr uint32_t MHUv2_SND_INT_CLR_OFFS = 0xF94;
+ static constexpr uint32_t MHUv2_SND_INT_EN_OFFS = 0xF98;
+ static constexpr uint32_t MHUv2_SND_IIDR_OFFS = 0xFC8;
+ static constexpr uint32_t MHUv2_SND_AIDR_OFFS = 0xFCC;
+ static constexpr uint32_t MHUv2_RCV_CHAN_WINDOW_SIZE = 0x20;
+ static constexpr uint32_t MHUv2_RCV_MHU_CFG_OFFS = 0xF80;
+ static constexpr uint32_t MHUv2_RCV_IIDR_OFFS = 0xFC8;
+ static constexpr uint32_t MHUv2_RCV_AIDR_OFFS = 0xFCC;
+ static constexpr uint32_t MHUv2_RCV_INT_EN_OFFS = 0xF98;
+
+ struct aidr_t {
+ uint32_t ARCH_MINOR_REV : 4;
+ uint32_t ARCH_MAJOR_REV : 4;
+ uint32_t RESERVED : 24;
+ };
+
+ volatile uint32_t *txBaseAddr;
+ volatile uint32_t *rxBaseAddr;
+
+ void clearMessage();
+ void printAIDR(bool tx = true, bool rx = true);
+
+ void txWrite(uint32_t offset, uint32_t value);
+ void rxWrite(uint32_t offset, uint32_t value);
+ uint32_t txRead(uint32_t offset);
+ uint32_t rxRead(uint32_t offset);
+
+ // Sender/tx
+ uint32_t getAccessReady();
+ uint32_t getAccessRequest();
+ uint32_t getInterruptStatus();
+ uint32_t getTxAIDR();
+ uint32_t getTxStatusForChan(uint8_t chan);
+ void enableAccessRequest();
+ void disableAccessRequest();
+ void setCombinedClearInterrupt(bool enable);
+ void setReadyNotReadyInterrupts(bool enable);
+
+ // Receiver/rx
+ uint32_t getRxAIDR();
+ uint32_t getRxStatusForChan(uint8_t chan);
+ void setCombinedRecvInterrupt(bool enable);
+ void enableClearChanInterrupt(uint8_t chan);
+ void disableClearChanInterrupt(uint8_t chan);
+};
+
+} // namespace Mailbox
+
+#endif /* #ifndef MHU_V2_HPP */
diff --git a/drivers/mhu_v2/src/mhu_v2.cpp b/drivers/mhu_v2/src/mhu_v2.cpp
new file mode 100644
index 0000000..1144a0f
--- /dev/null
+++ b/drivers/mhu_v2/src/mhu_v2.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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 "ethosu_log.h"
+
+#include <mhu_v2.hpp>
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+
+namespace Mailbox {
+
+MHUv2::MHUv2(const uint32_t txBaseAddress, const uint32_t rxBaseAddress) :
+ txBaseAddr(reinterpret_cast<volatile uint32_t *>(txBaseAddress)),
+ rxBaseAddr(reinterpret_cast<volatile uint32_t *>(rxBaseAddress)) {
+
+ setCombinedRecvInterrupt(true);
+ enableAccessRequest(); // Set high throughout
+}
+
+void MHUv2::handleMessage() {
+ clearMessage();
+ notify();
+}
+
+MHUv2::~MHUv2() {
+ setCombinedRecvInterrupt(false);
+ disableAccessRequest();
+}
+
+bool MHUv2::verifyHardware() {
+ // Sanity check MHUv2.1 id's (tx/rx)
+ struct aidr_t *a;
+ uint32_t txAIDR = getTxAIDR();
+ uint32_t rxAIDR = getRxAIDR();
+
+ a = reinterpret_cast<struct aidr_t *>(&txAIDR);
+ if (a->ARCH_MAJOR_REV != 1 || a->ARCH_MINOR_REV != 1) {
+ return false;
+ }
+
+ a = reinterpret_cast<struct aidr_t *>(&rxAIDR);
+ if (a->ARCH_MAJOR_REV != 1 || a->ARCH_MINOR_REV != 1) {
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t MHUv2::getTxStatusForChan(uint8_t chan) {
+ assert(chan >= 0);
+ assert(chan < 124);
+ return txRead((chan * MHUv2_SND_CHAN_WINDOW_SIZE) + MHUv2_CH_ST);
+}
+
+uint32_t MHUv2::getRxStatusForChan(uint8_t chan) {
+ assert(chan >= 0);
+ assert(chan < 124);
+ return rxRead((chan * MHUv2_RCV_CHAN_WINDOW_SIZE) + MHUv2_CH_ST);
+}
+
+uint32_t MHUv2::getInterruptStatus() {
+ return txRead(MHUv2_SND_INT_ST_OFFS);
+}
+
+uint32_t MHUv2::getAccessReady() {
+ return txRead(MHUv2_SND_ACCESS_READY_OFFS);
+}
+
+uint32_t MHUv2::getAccessRequest() {
+ return txRead(MHUv2_SND_ACCESS_REQUEST_OFFS);
+}
+
+uint32_t MHUv2::getTxAIDR() {
+ return txRead(MHUv2_SND_AIDR_OFFS);
+}
+
+uint32_t MHUv2::getRxAIDR() {
+ return rxRead(MHUv2_RCV_AIDR_OFFS);
+}
+
+void MHUv2::enableAccessRequest() {
+ txWrite(MHUv2_SND_ACCESS_REQUEST_OFFS, 1);
+}
+
+void MHUv2::disableAccessRequest() {
+ txWrite(MHUv2_SND_ACCESS_REQUEST_OFFS, 0);
+}
+
+/*
+ * MHUv2.1
+ * sender: combined clear interrupt
+ */
+void MHUv2::setCombinedClearInterrupt(bool enable) {
+ uint32_t val = txRead(MHUv2_SND_INT_EN_OFFS);
+ if (enable) {
+ val |= (1 << 2);
+ } else {
+ val &= ~(1 << 2);
+ }
+ txWrite(MHUv2_SND_INT_EN_OFFS, val);
+}
+
+/*
+ * MHUv2.1
+ * receiver: combined recv interrupt
+ */
+void MHUv2::setCombinedRecvInterrupt(bool enable) {
+ uint32_t val = rxRead(MHUv2_RCV_INT_EN_OFFS);
+ if (enable) {
+ val |= (1 << 2);
+ } else {
+ val &= ~(1 << 2);
+ }
+ rxWrite(MHUv2_SND_INT_EN_OFFS, val);
+}
+
+// Enable/disable R2NR/NR2R interrupts
+void MHUv2::setReadyNotReadyInterrupts(bool enable) {
+ uint32_t val = txRead(MHUv2_SND_INT_EN_OFFS);
+ if (enable) {
+ val |= (1 << 0 | 1 << 1);
+ } else {
+ val &= ~(1 << 0 | 1 << 1);
+ }
+ txWrite(MHUv2_SND_INT_EN_OFFS, val);
+}
+
+void MHUv2::enableClearChanInterrupt(uint8_t chan) {
+ assert(chan >= 0);
+ assert(chan < 124);
+ txWrite((chan * MHUv2_SND_CHAN_WINDOW_SIZE) + MHUv2_CH_INT_EN, 1);
+}
+
+void MHUv2::disableClearChanInterrupt(uint8_t chan) {
+ assert(chan >= 0);
+ assert(chan < 124);
+ txWrite((chan * MHUv2_SND_CHAN_WINDOW_SIZE) + MHUv2_CH_INT_EN, 0);
+}
+
+/*
+ * Set channel status byte (with only minor error/state check(s))
+ * Doorbell only, chan 0
+ */
+bool MHUv2::sendMessage() {
+ // Check that the other end is ready to receive
+ if (!getAccessReady()) {
+ return false;
+ }
+ txWrite(MHUv2_CH_SET, 1);
+
+ return true;
+}
+
+void MHUv2::clearMessage() {
+ rxWrite(MHUv2_CH_CLR, 0xFFFFFFFF); // Doorbell uses only chan 0, but clear all 32bits to be safe
+}
+
+void MHUv2::txWrite(uint32_t offset, uint32_t value) {
+ write32(txBaseAddr, offset, value);
+}
+
+void MHUv2::rxWrite(uint32_t offset, uint32_t value) {
+ write32(rxBaseAddr, offset, value);
+}
+
+uint32_t MHUv2::txRead(uint32_t offset) {
+ return read32(txBaseAddr, offset);
+}
+
+uint32_t MHUv2::rxRead(uint32_t offset) {
+ return read32(rxBaseAddr, offset);
+}
+
+void MHUv2::printAIDR(bool tx, bool rx) {
+ struct aidr_t *a;
+ uint32_t aidr;
+
+ if (tx) {
+ aidr = getTxAIDR();
+ a = reinterpret_cast<struct aidr_t *>(&aidr);
+ LOG_INFO("TX MHUv2 reports: Major rev: %d, Minor rev: %d", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
+ }
+ if (rx) {
+ aidr = getRxAIDR();
+ a = reinterpret_cast<struct aidr_t *>(&aidr);
+ LOG_INFO("RX MHUv2 reports: Major rev: %d, Minor rev: %d", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
+ }
+}
+
+} // namespace Mailbox
diff --git a/drivers/mpu/CMakeLists.txt b/drivers/mpu/CMakeLists.txt
new file mode 100644
index 0000000..2b9797e
--- /dev/null
+++ b/drivers/mpu/CMakeLists.txt
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+add_library(mpu INTERFACE)
+
+target_sources(mpu INTERFACE
+ src/mpu.cpp)
+
+target_include_directories(mpu INTERFACE
+ include)
diff --git a/targets/corstone-300/mpu.hpp b/drivers/mpu/include/mpu.hpp
index dff73b6..dff73b6 100644
--- a/targets/corstone-300/mpu.hpp
+++ b/drivers/mpu/include/mpu.hpp
diff --git a/targets/corstone-300/mpu.cpp b/drivers/mpu/src/mpu.cpp
index 1d30ce0..338e3d1 100644
--- a/targets/corstone-300/mpu.cpp
+++ b/drivers/mpu/src/mpu.cpp
@@ -20,7 +20,7 @@
* Includes
****************************************************************************/
-#include "mpu.hpp"
+#include <mpu.hpp>
#include <cachel1_armv7.h>
#include <inttypes.h>
@@ -71,7 +71,7 @@ void loadAndEnableConfig(ARM_MPU_Region_t const *table, uint32_t cnt) {
ARM_MPU_Load(0, table, cnt);
// Enable MPU with default priv access to all other regions
- ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
+ ARM_MPU_Enable((1 << MPU_CTRL_PRIVDEFENA_Pos) & MPU_CTRL_PRIVDEFENA_Msk);
#endif
}
diff --git a/drivers/timing_adapter/CMakeLists.txt b/drivers/timing_adapter/CMakeLists.txt
new file mode 100644
index 0000000..f17eaeb
--- /dev/null
+++ b/drivers/timing_adapter/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+add_library(timing_adapter STATIC)
+target_include_directories(timing_adapter PUBLIC include)
+
+target_sources(timing_adapter PRIVATE src/timing_adapter.c)
+
diff --git a/drivers/timing_adapter/include/timing_adapter.h b/drivers/timing_adapter/include/timing_adapter.h
new file mode 100644
index 0000000..ef4f9b9
--- /dev/null
+++ b/drivers/timing_adapter/include/timing_adapter.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2019-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.
+ */
+
+#ifndef TIMING_ADAPTER_H_
+#define TIMING_ADAPTER_H_
+
+#include <stdint.h>
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/** TIMING ADAPTER
+ *
+ * The timing adapter is an AXI-to-AXI bridge for providing well-defined memory timing
+ * to allow performance evaluation of an AXI master. The bridge works by delaying the
+ * responses from the memory according to run-time configurable parameters that can be
+ * set in the timing adapter. Parameters include read and write response latencies,
+ * no. of outstanding transactions, and a model of interferring traffic.
+ */
+
+struct timing_adapter {
+ uintptr_t base_addr;
+};
+
+/** LIMITATIONS FOR FVP:
+ *
+ * - TA_MODE is hardcoded to 1 (one) at all times.
+ * - Only TA_PERFCTRL_AWTRANS and TA_PERFCTRL_ARTRANS support is
+ * implemented for the performance counter.
+ */
+
+struct timing_adapter_settings {
+ uint32_t maxr; // 6-bit field. Max no. of pending reads. 0=infinite
+ uint32_t maxw; // 6-bit field. Max no. of pending writes. 0=infinite
+ uint32_t maxrw; // 6-bit field. Max no. of pending reads+writes. 0=infinite
+ uint32_t rlatency; // 12-bit field. Minimum latency (clock cycles) from AVALID to RVALID.
+ uint32_t wlatency; // 12-bit field. Minimum latency (clock cycles) from WVALID&WLAST to BVALID.
+ uint32_t pulse_on; // No. of cycles addresses let through (0-65535).
+ uint32_t pulse_off; // No. of cycles addresses blocked (0-65535).
+ uint32_t bwcap; // 16-bit field. Max no. of 64-bit words transfered per pulse cycle 0=infinite
+ uint32_t perfctrl; // 6-bit field selecting an event for event counter 0=default
+ uint32_t perfcnt; // 32-bit event counter
+ uint32_t mode; // Bit 0: 1=enable dynamic clocking to avoid underrun
+ // Bit 1: 1=enable random AR reordering (0=default)
+ // Bit 2: 1=enable random R reordering (0=default)
+ // Bit 3: 1=enable random B reordering (0=default)
+ // Bit 11-4: Frequency scale 0=full speed, 255=(1/256) speed
+ uint32_t maxpending; // (Read-only) Max supported value in MAXR and MAXW registers
+ uint32_t histbin; // Controlls which histogram bin (0-15) that should be accessed by HISTCNT.
+ uint32_t histcnt; // 32-bit field. Read/write the selected histogram bin.
+};
+
+enum timing_adapter_perfctrl_settings {
+ TA_PERFCTRL_OFF = 0, // Disable performance counting
+ TA_PERFCTRL_CYCLES, // Count all cycles (root clock)
+ TA_PERFCTRL_UNDERRUN_R, // Unable to meet RLATENCY deadline
+ TA_PERFCTRL_UNDERRUN_B, // Unable to meet WLATENCY deadline
+ TA_PERFCTRL_OVERFLOW_AR, // Internal read address FIFO full
+ TA_PERFCTRL_OVERFLOW_AW, // Internal write address FIFO full
+ TA_PERFCTRL_OVERFLOW_R, // Internal read data FIFO full
+ TA_PERFCTRL_OVERFLOW_W, // Internal write data FIFO full
+ TA_PERFCTRL_OVERFLOW_B, // Internal write response FIFO full
+ TA_PERFCTRL_RREADY, // RREADY wait state
+ TA_PERFCTRL_BREADY, // BREADY wait state
+ TA_PERFCTRL_RTRANS, // Handshake on R channel
+ TA_PERFCTRL_WTRANS, // Handshake on W channel
+ TA_PERFCTRL_BTRANS, // Handshake on B channel
+ TA_PERFCTRL_ARTRANS, // Handshake on AR channel
+ TA_PERFCTRL_AWTRANS, // Handshake on AW channel
+ TA_PERFCTRL_ARQTIME, // Histogram of how much time spent with outstanding read transactions
+ TA_PERFCTRL_AWQTIME, // Histogram of how much time spent with outstanding write transactions
+ TA_PERFCTRL_MCLK_ON, // Count cycles when DUT clock is on
+ TA_PERFCTRL_MCLK_OFF, // Count cycles when DUT clock is off
+ TA_PERFCTRL_ARLEN0 = 32, // Handshake on AR channel with ARLEN=0
+ TA_PERFCTRL_AWLEN0 = 48 // Handshake on AW channel with AWLEN=0
+};
+
+int ta_init(struct timing_adapter *ta, uintptr_t base_addr);
+void ta_uninit(struct timing_adapter *ta);
+
+void ta_set_all(struct timing_adapter *ta, struct timing_adapter_settings *in);
+void ta_set_maxr(struct timing_adapter *ta, uint32_t val);
+void ta_set_maxw(struct timing_adapter *ta, uint32_t val);
+void ta_set_maxrw(struct timing_adapter *ta, uint32_t val);
+void ta_set_rlatency(struct timing_adapter *ta, uint32_t val);
+void ta_set_wlatency(struct timing_adapter *ta, uint32_t val);
+void ta_set_pulse_on(struct timing_adapter *ta, uint32_t val);
+void ta_set_pulse_off(struct timing_adapter *ta, uint32_t val);
+void ta_set_bwcap(struct timing_adapter *ta, uint32_t val);
+void ta_set_perfctrl(struct timing_adapter *ta, uint32_t val);
+void ta_set_perfcnt(struct timing_adapter *ta, uint32_t val);
+void ta_set_mode(struct timing_adapter *ta, uint32_t val);
+void ta_set_histbin(struct timing_adapter *ta, uint32_t val);
+void ta_set_histcnt(struct timing_adapter *ta, uint32_t val);
+
+void ta_get_all(struct timing_adapter *ta, struct timing_adapter_settings *out);
+uint32_t ta_get_maxr(struct timing_adapter *ta);
+uint32_t ta_get_maxw(struct timing_adapter *ta);
+uint32_t ta_get_maxrw(struct timing_adapter *ta);
+uint32_t ta_get_rlatency(struct timing_adapter *ta);
+uint32_t ta_get_wlatency(struct timing_adapter *ta);
+uint32_t ta_get_pulse_on(struct timing_adapter *ta);
+uint32_t ta_get_pulse_off(struct timing_adapter *ta);
+uint32_t ta_get_bwcap(struct timing_adapter *ta);
+uint32_t ta_get_perfctrl(struct timing_adapter *ta);
+uint32_t ta_get_perfcnt(struct timing_adapter *ta);
+uint32_t ta_get_mode(struct timing_adapter *ta);
+uint32_t ta_get_maxpending(struct timing_adapter *ta);
+uint32_t ta_get_histbin(struct timing_adapter *ta);
+uint32_t ta_get_histcnt(struct timing_adapter *ta);
+uint32_t ta_get_version(struct timing_adapter *ta);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/timing_adapter/src/timing_adapter.c b/drivers/timing_adapter/src/timing_adapter.c
new file mode 100644
index 0000000..65e4178
--- /dev/null
+++ b/drivers/timing_adapter/src/timing_adapter.c
@@ -0,0 +1,215 @@
+/*
+ * 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 <stdint.h>
+#include <timing_adapter.h>
+
+// Register offsets
+#define TA_MAXR 0x00
+#define TA_MAXW 0x04
+#define TA_MAXRW 0x08
+#define TA_RLATENCY 0x0C
+#define TA_WLATENCY 0x10
+#define TA_PULSE_ON 0x14
+#define TA_PULSE_OFF 0x18
+#define TA_BWCAP 0x1C
+#define TA_PERFCTRL 0x20
+#define TA_PERFCNT 0x24
+#define TA_MODE 0x28
+#define TA_MAXPENDING 0x2C
+#define TA_HISTBIN 0x30
+#define TA_HISTCNT 0x34
+#define TA_VERSION 0x38
+
+// Register masks
+#define TA_MAXR_MASK 0x0000003F
+#define TA_MAXW_MASK 0x0000003F
+#define TA_MAXRW_MASK 0x0000003F
+#define TA_RLATENCY_MASK 0x00000FFF
+#define TA_WLATENCY_MASK 0x00000FFF
+#define TA_PULSE_ON_MASK 0x0000FFFF
+#define TA_PULSE_OFF_MASK 0x0000FFFF
+#define TA_BWCAP_MASK 0x0000FFFF
+#define TA_PERFCTRL_MASK 0x0000003F
+#define TA_PERFCNT_MASK 0xFFFFFFFF
+#define TA_MODE_MASK 0x00000FFF
+#define TA_MAXPENDING_MASK 0xFFFFFFFF
+#define TA_HISTBIN_MASK 0x0000000F
+#define TA_HISTCNT_MASK 0xFFFFFFFF
+
+#define TA_VERSION_SUPPORTED 0x1117
+
+int ta_init(struct timing_adapter *ta, uintptr_t base_addr) {
+ ta->base_addr = base_addr;
+
+ if (ta_get_version(ta) != TA_VERSION_SUPPORTED) {
+ return -1;
+ }
+ return 0;
+}
+
+void ta_uninit(struct timing_adapter *ta) {
+ ta->base_addr = 0;
+}
+
+// -- Set API --------------------------------------
+void ta_set_all(struct timing_adapter *ta, struct timing_adapter_settings *in) {
+ ta_set_maxr(ta, in->maxr);
+ ta_set_maxw(ta, in->maxw);
+ ta_set_maxrw(ta, in->maxrw);
+ ta_set_rlatency(ta, in->rlatency);
+ ta_set_wlatency(ta, in->wlatency);
+ ta_set_pulse_on(ta, in->pulse_on);
+ ta_set_pulse_off(ta, in->pulse_off);
+ ta_set_bwcap(ta, in->bwcap);
+ ta_set_perfctrl(ta, in->perfctrl);
+ ta_set_perfcnt(ta, in->perfcnt);
+ ta_set_mode(ta, in->mode);
+ ta_set_histbin(ta, in->histbin);
+ ta_set_histcnt(ta, in->histcnt);
+}
+
+void ta_set_maxr(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_MAXR) = val & TA_MAXR_MASK;
+};
+
+void ta_set_maxw(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_MAXW) = val & TA_MAXW_MASK;
+};
+
+void ta_set_maxrw(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_MAXRW) = val & TA_MAXRW_MASK;
+};
+
+void ta_set_rlatency(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_RLATENCY) = val & TA_RLATENCY_MASK;
+};
+
+void ta_set_wlatency(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_WLATENCY) = val & TA_WLATENCY_MASK;
+};
+
+void ta_set_pulse_on(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_PULSE_ON) = val & TA_PULSE_ON_MASK;
+};
+
+void ta_set_pulse_off(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_PULSE_OFF) = val & TA_PULSE_OFF_MASK;
+};
+
+void ta_set_bwcap(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_BWCAP) = val & TA_BWCAP_MASK;
+};
+
+void ta_set_perfctrl(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_PERFCTRL) = val & TA_PERFCTRL_MASK;
+};
+
+void ta_set_perfcnt(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_PERFCNT) = val & TA_PERFCNT_MASK;
+};
+
+void ta_set_mode(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_MODE) = val & TA_MODE_MASK;
+};
+
+void ta_set_histbin(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_HISTBIN) = val & TA_HISTBIN_MASK;
+};
+
+void ta_set_histcnt(struct timing_adapter *ta, uint32_t val) {
+ *(volatile uint32_t *)(ta->base_addr + TA_HISTCNT) = val & TA_HISTCNT_MASK;
+};
+
+// -- Get API --------------------------------------
+void ta_get_all(struct timing_adapter *ta, struct timing_adapter_settings *out) {
+ out->maxr = ta_get_maxr(ta);
+ out->maxw = ta_get_maxw(ta);
+ out->maxrw = ta_get_maxrw(ta);
+ out->rlatency = ta_get_rlatency(ta);
+ out->wlatency = ta_get_wlatency(ta);
+ out->pulse_on = ta_get_pulse_on(ta);
+ out->pulse_off = ta_get_pulse_off(ta);
+ out->bwcap = ta_get_bwcap(ta);
+ out->perfctrl = ta_get_perfctrl(ta);
+ out->perfcnt = ta_get_perfcnt(ta);
+ out->mode = ta_get_mode(ta);
+ out->maxpending = ta_get_maxpending(ta);
+ out->histbin = ta_get_histbin(ta);
+ out->histcnt = ta_get_histcnt(ta);
+}
+
+uint32_t ta_get_maxr(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_MAXR) & TA_MAXR_MASK;
+};
+
+uint32_t ta_get_maxw(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_MAXW) & TA_MAXW_MASK;
+};
+
+uint32_t ta_get_maxrw(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_MAXRW) & TA_MAXRW_MASK;
+};
+
+uint32_t ta_get_rlatency(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_RLATENCY) & TA_RLATENCY_MASK;
+};
+
+uint32_t ta_get_wlatency(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_WLATENCY) & TA_WLATENCY_MASK;
+};
+
+uint32_t ta_get_pulse_on(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_PULSE_ON) & TA_PULSE_ON_MASK;
+};
+
+uint32_t ta_get_pulse_off(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_PULSE_OFF) & TA_PULSE_OFF_MASK;
+};
+
+uint32_t ta_get_bwcap(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_BWCAP) & TA_BWCAP_MASK;
+};
+
+uint32_t ta_get_perfctrl(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_PERFCTRL) & TA_PERFCTRL_MASK;
+};
+
+uint32_t ta_get_perfcnt(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_PERFCNT) & TA_PERFCNT_MASK;
+};
+
+uint32_t ta_get_mode(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_MODE) & TA_MODE_MASK;
+};
+
+uint32_t ta_get_maxpending(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_MAXPENDING) & TA_MAXPENDING_MASK;
+};
+
+uint32_t ta_get_histbin(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_HISTBIN) & TA_HISTBIN_MASK;
+};
+
+uint32_t ta_get_histcnt(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_HISTCNT) & TA_HISTCNT_MASK;
+};
+
+uint32_t ta_get_version(struct timing_adapter *ta) {
+ return *(volatile uint32_t *)(ta->base_addr + TA_VERSION);
+};
diff --git a/drivers/uart/CMakeLists.txt b/drivers/uart/CMakeLists.txt
new file mode 100644
index 0000000..e21de24
--- /dev/null
+++ b/drivers/uart/CMakeLists.txt
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2019-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.
+#
+
+add_library(ethosu_uart_common INTERFACE)
+
+target_include_directories(ethosu_uart_common INTERFACE
+ include
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+# UART configuration (Can be overriden from user project, default value is for target "Corestone-300")
+set(UART0_BASE "0x49303000" CACHE STRING "UART base address")
+set(UART0_BAUDRATE "115200" CACHE STRING "UART baudrate")
+set(SYSTEM_CORE_CLOCK "25000000" CACHE STRING "System core clock (Hz)")
+
+# Generate UART configuration file
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uart_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/uart_config.h")
+
+# Drivers
+add_library(ethosu_uart_cmsdk_apb STATIC src/uart_cmsdk_apb.c)
+target_link_libraries(ethosu_uart_cmsdk_apb PUBLIC ethosu_uart_common)
+
+add_library(ethosu_uart_pl011 STATIC src/uart_pl011.c)
+target_link_libraries(ethosu_uart_pl011 PUBLIC ethosu_uart_common)
+
+add_library(ethosu_uart_dummy STATIC src/uart_dummy.c)
+target_link_libraries(ethosu_uart_dummy PUBLIC ethosu_uart_common)
diff --git a/targets/corstone-300/uart.h b/drivers/uart/include/uart_stdout.h
index a430e9e..a489b3f 100644
--- a/targets/corstone-300/uart.h
+++ b/drivers/uart/include/uart_stdout.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -23,10 +23,10 @@
extern "C" {
#endif
-void uart_init(void);
-unsigned char uart_putc(unsigned char my_ch);
-unsigned char uart_getc(void);
-unsigned int uart_getline(char *lp, unsigned int len);
+void UartStdOutInit(void);
+unsigned char UartPutc(unsigned char my_ch);
+unsigned char UartGetc(void);
+unsigned int GetLine(char *lp, unsigned int len);
#if __cplusplus
}
diff --git a/targets/corstone-300/uart.c b/drivers/uart/src/uart_cmsdk_apb.c
index bd7dddf..2c644bb 100644
--- a/targets/corstone-300/uart.c
+++ b/drivers/uart/src/uart_cmsdk_apb.c
@@ -16,8 +16,10 @@
* limitations under the License.
*/
-#include "uart.h"
+/* Basic CMSDK APB UART driver */
+
#include "uart_config.h"
+#include "uart_stdout.h"
#include <stdint.h>
#include <stdio.h>
@@ -29,8 +31,6 @@
#define LF 0x0A
#define ESC 0x1B
-/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
-
#define __IO volatile
#define __I volatile const
#define __O volatile
@@ -50,8 +50,7 @@ typedef struct {
#define CMSDK_UART0 ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE)
#define CMSDK_UART0_BAUDRATE UART0_BAUDRATE
-void uart_init(void) {
- // SystemCoreClock / 9600
+void UartStdOutInit(void) {
CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE;
CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */
@@ -59,7 +58,7 @@ void uart_init(void) {
}
// Output a character
-unsigned char uart_putc(unsigned char my_ch) {
+unsigned char UartPutc(unsigned char my_ch) {
while ((CMSDK_UART0->STATE & 1))
; // Wait if Transmit Holding register is full
@@ -75,20 +74,12 @@ unsigned char uart_putc(unsigned char my_ch) {
}
// Get a character
-unsigned char uart_getc(void) {
+unsigned char UartGetc(void) {
unsigned char my_ch;
// unsigned int cnt;
while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty
- {
-#if 0
- cnt = MPS3_FPGAIO->CLK100HZ / 50;
- if (cnt & 0x8)
- MPS3_FPGAIO->LED = 0x01 << (cnt & 0x7);
- else
- MPS3_FPGAIO->LED = 0x80 >> (cnt & 0x7);
-#endif
- }
+ ;
my_ch = CMSDK_UART0->DATA;
@@ -100,12 +91,12 @@ unsigned char uart_getc(void) {
}
// Get line from terminal
-unsigned int uart_getline(char *lp, unsigned int len) {
+unsigned int GetLine(char *lp, unsigned int len) {
unsigned int cnt = 0;
char c;
do {
- c = uart_getc();
+ c = UartGetc();
switch (c) {
case CNTLQ: /* ignore Control S/Q */
case CNTLS:
@@ -115,11 +106,11 @@ unsigned int uart_getline(char *lp, unsigned int len) {
if (cnt == 0) {
break;
}
- cnt--; /* decrement count */
- lp--; /* and line pointer */
- uart_putc(0x08); /* echo backspace */
- uart_putc(' ');
- uart_putc(0x08);
+ cnt--; /* decrement count */
+ lp--; /* and line pointer */
+ UartPutc(0x08); /* echo backspace */
+ UartPutc(' ');
+ UartPutc(0x08);
fflush(stdout);
break;
case ESC:
@@ -131,9 +122,9 @@ unsigned int uart_getline(char *lp, unsigned int len) {
lp++; /* increment line pointer */
cnt++; /* and count */
c = LF;
- __attribute__((fallthrough)); /* intentional fallthrough */
+ /* fall through */
default:
- uart_putc(*lp = c); /* echo and store character */
+ UartPutc(*lp = c); /* echo and store character */
fflush(stdout);
lp++; /* increment line pointer */
cnt++; /* and count */
diff --git a/drivers/uart/src/uart_dummy.c b/drivers/uart/src/uart_dummy.c
new file mode 100644
index 0000000..66da44f
--- /dev/null
+++ b/drivers/uart/src/uart_dummy.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019-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 "uart_stdout.h"
+
+void UartStdOutInit(void) {}
+
+unsigned char UartPutc(unsigned char c) {
+ (void)c;
+ return 0;
+}
+
+unsigned char UartGetc(void) {
+ return 0;
+}
+
+unsigned int GetLine(char *lp, unsigned int len) {
+ (void)lp;
+ (void)len;
+ return 0;
+}
diff --git a/drivers/uart/src/uart_pl011.c b/drivers/uart/src/uart_pl011.c
new file mode 100644
index 0000000..d65269a
--- /dev/null
+++ b/drivers/uart/src/uart_pl011.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2019-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.
+ */
+
+/* Basic PL011 UART driver */
+
+#include "uart_config.h"
+#include "uart_stdout.h"
+#include <stdint.h>
+#include <stdio.h>
+
+#define CNTLQ 0x11
+#define CNTLS 0x13
+#define DEL 0x7F
+#define BACKSPACE 0x08
+#define CR 0x0D
+#define LF 0x0A
+#define ESC 0x1B
+
+/*****************************************************************************/
+/* UART Control Register Locations */
+/*****************************************************************************/
+#define UART0_DR *((volatile uint32_t *)UART0_BASE)
+#define UART0_RSR *((volatile uint32_t *)(UART0_BASE + 0x04))
+#define UART0_ECR *((volatile uint32_t *)(UART0_BASE + 0x04))
+#define UART0_LCRH *((volatile uint32_t *)(UART0_BASE + 0x2C))
+#define UART0_LCRM *((volatile uint32_t *)(UART0_BASE + 0x28))
+#define UART0_LCRL *((volatile uint32_t *)(UART0_BASE + 0x24))
+#define UART0_CR *((volatile uint32_t *)(UART0_BASE + 0x30))
+#define UART0_FR *((volatile uint32_t *)(UART0_BASE + 0x18))
+#define UART0_IIR *((volatile uint32_t *)(UART0_BASE + 0x1C))
+#define UART0_ICR *((volatile uint32_t *)(UART0_BASE + 0x44))
+
+/*****************************************************************************/
+/* Received Status Register - RSR */
+/*****************************************************************************/
+#define RSR_OVERRUN_ERROR 0x08
+#define RSR_BREAK_ERROR 0x04
+#define RSR_PARITY_ERROR 0x02
+#define RSR_FRAMING_ERROR 0x01
+
+/*****************************************************************************/
+/* Line Control High Byte Register - LCRH */
+/*****************************************************************************/
+#define LCRH_WORD_LENGTH_8 0x60
+#define LCRH_WORD_LENGTH_7 0x40
+#define LCRH_WORD_LENGTH_6 0x20
+#define LCRH_WORD_LENGTH_5 0x00
+#define LCRH_FIFO_ENABLED 0x10
+#define LCRH_2_STOP_BITS 0x08
+#define LCRH_EVEN_PARITY 0x04
+#define LCRH_PARITY_ENABLE 0x02
+#define LCRH_SEND_BREAK 0x01
+
+/*****************************************************************************/
+/* Line Control Medium Byte Register - LCRM */
+/* This register specifies the high byte of the Baud rate divisor */
+/*****************************************************************************/
+#define LCRM_BAUD_460800 0x00
+#define LCRM_BAUD_230400 0x00
+#define LCRM_BAUD_115200 0x00
+#define LCRM_BAUD_76800 0x00
+#define LCRM_BAUD_57600 0x00
+#define LCRM_BAUD_38400 0x00
+#define LCRM_BAUD_19200 0x00
+#define LCRM_BAUD_14400 0x00
+#define LCRM_BAUD_9600 0x00
+#define LCRM_BAUD_2400 0x01
+#define LCRM_BAUD_1200 0x02
+
+/*****************************************************************************/
+/* Line Control Low Byte Register - LCRL */
+/* This register specifies the low byte of the Baud rate divisor */
+/*****************************************************************************/
+#define LCRL_BAUD_460800 0x01
+#define LCRL_BAUD_230400 0x03
+#define LCRL_BAUD_115200 0x07
+#define LCRL_BAUD_76800 0x0B
+#define LCRL_BAUD_57600 0x0F
+#define LCRL_BAUD_38400 0xC
+#define LCRL_BAUD_19200 0x2F
+#define LCRL_BAUD_14400 0x3F
+#define LCRL_BAUD_9600 0x5F
+#define LCRL_BAUD_2400 0x7F
+#define LCRL_BAUD_1200 0xFF
+
+/*****************************************************************************/
+/* Control Register - CR */
+/*****************************************************************************/
+#define CR_LOOP_BACK_EN 0x80
+#define CR_TIMEOUT_INT_EN 0x40
+#define CR_TX_INT_ENABLE 0x100
+#define CR_RX_INT_ENABLE 0x200
+#define CR_MODSTAT_INT_EN 0x08
+#define CR_UART_ENABLE 0x01
+
+/*****************************************************************************/
+/* Flag Register - FR */
+/*****************************************************************************/
+#define FR_TX_FIFO_EMPTY 0x80
+#define FR_RX_FIFO_FULL 0x40
+#define FR_TX_FIFO_FULL 0x20
+#define FR_RX_FIFO_EMPTY 0x10
+#define FR_BUSY 0x08
+#define FR_CARRIER_DETECT 0x04
+#define FR_SET_READY 0x02
+#define FR_CLEAR_TO_SEND 0x01
+
+/*****************************************************************************/
+/* Interrupt Identification Register - IIR */
+/*****************************************************************************/
+#define IIR_RX_TIME_OUT 0x08
+#define IIR_TX 0x04
+#define IIR_RX 0x02
+#define IIR_MODEM 0x01
+
+void UartStdOutInit(void) {
+ // Disable the serial port while setting the baud rate and word length
+ UART0_CR = 0;
+
+ // Clear the receive status register
+ UART0_ECR = 0;
+
+ // Set the correct baud rate and word length
+ UART0_LCRL = LCRL_BAUD_115200;
+ UART0_LCRM = LCRM_BAUD_115200;
+ UART0_LCRH = LCRH_WORD_LENGTH_8;
+
+ // Explicitly disable FIFO's for char mode
+ UART0_LCRH &= ~LCRH_FIFO_ENABLED;
+
+ // Enable UART0 (and RX/TX) without interrupts
+ UART0_CR = CR_UART_ENABLE | CR_TX_INT_ENABLE | CR_RX_INT_ENABLE;
+}
+
+unsigned char UartPutc(unsigned char ch) {
+ if (ch == '\n') {
+ (void)UartPutc('\r');
+ }
+ while (UART0_FR & FR_TX_FIFO_FULL)
+ ;
+ UART0_DR = ch;
+
+ return ch;
+}
+
+unsigned char UartGetc(void) {
+ unsigned char c;
+ while (UART0_FR & FR_RX_FIFO_EMPTY)
+ ;
+ c = UART0_DR;
+ if (c == '\r') {
+ c = '\n';
+ }
+
+ return c;
+}
+
+// Get line from terminal
+unsigned int GetLine(char *lp, unsigned int len) {
+ unsigned int cnt = 0;
+ char c;
+
+ do {
+ c = UartGetc();
+ switch (c) {
+ case CNTLQ: /* ignore Control S/Q */
+ case CNTLS:
+ break;
+ case BACKSPACE:
+ case DEL:
+ if (cnt == 0) {
+ break;
+ }
+ cnt--; /* decrement count */
+ lp--; /* and line pointer */
+ UartPutc(0x08); /* echo backspace */
+ UartPutc(' ');
+ UartPutc(0x08);
+ fflush(stdout);
+ break;
+ case ESC:
+ case 0:
+ *lp = 0; /* ESC - stop editing line */
+ return 0;
+ case CR: /* CR - done, stop editing line */
+ *lp = c;
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ c = LF;
+ UartPutc(*lp = c); /* echo and store character */
+ fflush(stdout);
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ break;
+ default:
+ UartPutc(*lp = c); /* echo and store character */
+ fflush(stdout);
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ break;
+ }
+ } while (cnt < len - 2 && c != LF); /* check limit and CR */
+ *lp = 0; /* mark end of string */
+ return 1;
+}
diff --git a/targets/corstone-300/uart_config.h b/drivers/uart/uart_config.h.in
index 3df76ab..c016c3f 100644
--- a/targets/corstone-300/uart_config.h
+++ b/drivers/uart/uart_config.h.in
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -18,6 +18,6 @@
#pragma once
-#define UART0_BASE 0x49303000
-#define UART0_BAUDRATE 115200
-#define SYSTEM_CORE_CLOCK 25000000
+#define UART0_BASE (@UART0_BASE@)
+#define UART0_BAUDRATE (@UART0_BAUDRATE@)
+#define SYSTEM_CORE_CLOCK (@SYSTEM_CORE_CLOCK@)
diff --git a/targets/common/CMakeLists.txt b/targets/common/CMakeLists.txt
index 64e1334..d3b3f46 100644
--- a/targets/common/CMakeLists.txt
+++ b/targets/common/CMakeLists.txt
@@ -27,6 +27,8 @@ set(TFLU_BUILD_TYPE "release_with_logs" CACHE STRING "Tensorflow Lite Micro buil
add_subdirectory(${ETHOSU_CORE_SOFTWARE_PATH} core_software)
+add_subdirectory(../../drivers drivers)
+
###############################################################################
# Target
#
diff --git a/targets/corstone-300/CMakeLists.txt b/targets/corstone-300/CMakeLists.txt
index d2e3322..5dc3804 100644
--- a/targets/corstone-300/CMakeLists.txt
+++ b/targets/corstone-300/CMakeLists.txt
@@ -121,12 +121,14 @@ ethosu_target_link_options(ethosu_target_link INTERFACE
# Add drivers
target_sources(ethosu_target_startup INTERFACE
retarget.c
- uart.c
- target.cpp
- mpu.cpp)
+ target.cpp)
target_link_libraries(ethosu_target_startup INTERFACE
- $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver;timing_adapter>)
+ $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver>
+ mpu
+ timing_adapter
+ ethosu_mhu_dummy
+ ethosu_uart_cmsdk_apb)
if (TARGET ethosu_core_driver)
target_compile_definitions(ethosu_core_driver PUBLIC
diff --git a/targets/corstone-300/retarget.c b/targets/corstone-300/retarget.c
index 4bde44d..2549e42 100644
--- a/targets/corstone-300/retarget.c
+++ b/targets/corstone-300/retarget.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <time.h>
-#include "uart.h"
+#include "uart_stdout.h"
// armclang retargeting
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
@@ -206,7 +206,7 @@ void RETARGET(_exit)(int return_code) {
return_code);
while (*p != '\0') {
- uart_putc(*p++);
+ UartPutc(*p++);
}
while (1) {}
@@ -259,12 +259,12 @@ int rename(const char *oldn, const char *newn) {
int fputc(int ch, FILE *f) {
(void)(f);
- return uart_putc(ch);
+ return UartPutc(ch);
}
int fgetc(FILE *f) {
(void)f;
- return uart_putc(uart_getc());
+ return UartPutc(UartGetc());
}
#ifndef ferror
diff --git a/targets/corstone-300/target.cpp b/targets/corstone-300/target.cpp
index 88f98be..87ba0c4 100644
--- a/targets/corstone-300/target.cpp
+++ b/targets/corstone-300/target.cpp
@@ -29,7 +29,7 @@
#include "mpu.hpp"
#include <timing_adapter.h>
-#include "uart.h"
+#include "uart_stdout.h"
#include <inttypes.h>
#include <stdio.h>
@@ -281,7 +281,7 @@ namespace EthosU {
void targetSetup() {
// Initialize UART driver
- uart_init();
+ UartStdOutInit();
// Initialize timing adapter(s)
for (int i = 0; i < ETHOSU_NPU_COUNT; i++) {