From e9cdc6374dc730dc61d2a8a81beabe563ad7fe88 Mon Sep 17 00:00:00 2001 From: Yulia Garbovich Date: Tue, 23 Nov 2021 20:00:04 +0200 Subject: 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 --- drivers/CMakeLists.txt | 49 ++++++ drivers/mailbox/CMakeLists.txt | 21 +++ drivers/mailbox/include/mailbox.hpp | 100 +++++++++++ drivers/mailbox/src/mailbox.cpp | 65 +++++++ drivers/mhu_dummy/CMakeLists.txt | 23 +++ drivers/mhu_dummy/include/mhu_dummy.hpp | 36 ++++ drivers/mhu_dummy/src/mhu_dummy.cpp | 33 ++++ drivers/mhu_juno/CMakeLists.txt | 23 +++ drivers/mhu_juno/include/mhu_juno.hpp | 66 +++++++ drivers/mhu_juno/src/mhu_juno.cpp | 76 ++++++++ drivers/mhu_v2/CMakeLists.txt | 23 +++ drivers/mhu_v2/include/mhu_v2.hpp | 169 ++++++++++++++++++ drivers/mhu_v2/src/mhu_v2.cpp | 209 ++++++++++++++++++++++ drivers/mpu/CMakeLists.txt | 25 +++ drivers/mpu/include/mpu.hpp | 42 +++++ drivers/mpu/src/mpu.cpp | 79 +++++++++ drivers/timing_adapter/CMakeLists.txt | 23 +++ drivers/timing_adapter/include/timing_adapter.h | 133 ++++++++++++++ drivers/timing_adapter/src/timing_adapter.c | 215 +++++++++++++++++++++++ drivers/uart/CMakeLists.txt | 41 +++++ drivers/uart/include/uart_stdout.h | 35 ++++ drivers/uart/src/uart_cmsdk_apb.c | 136 +++++++++++++++ drivers/uart/src/uart_dummy.c | 36 ++++ drivers/uart/src/uart_pl011.c | 220 ++++++++++++++++++++++++ drivers/uart/uart_config.h.in | 23 +++ targets/common/CMakeLists.txt | 2 + targets/corstone-300/CMakeLists.txt | 10 +- targets/corstone-300/mpu.cpp | 79 --------- targets/corstone-300/mpu.hpp | 42 ----- targets/corstone-300/retarget.c | 8 +- targets/corstone-300/target.cpp | 4 +- targets/corstone-300/uart.c | 145 ---------------- targets/corstone-300/uart.h | 35 ---- targets/corstone-300/uart_config.h | 23 --- 34 files changed, 1915 insertions(+), 334 deletions(-) create mode 100644 drivers/CMakeLists.txt create mode 100644 drivers/mailbox/CMakeLists.txt create mode 100644 drivers/mailbox/include/mailbox.hpp create mode 100644 drivers/mailbox/src/mailbox.cpp create mode 100644 drivers/mhu_dummy/CMakeLists.txt create mode 100644 drivers/mhu_dummy/include/mhu_dummy.hpp create mode 100644 drivers/mhu_dummy/src/mhu_dummy.cpp create mode 100644 drivers/mhu_juno/CMakeLists.txt create mode 100644 drivers/mhu_juno/include/mhu_juno.hpp create mode 100644 drivers/mhu_juno/src/mhu_juno.cpp create mode 100644 drivers/mhu_v2/CMakeLists.txt create mode 100644 drivers/mhu_v2/include/mhu_v2.hpp create mode 100644 drivers/mhu_v2/src/mhu_v2.cpp create mode 100644 drivers/mpu/CMakeLists.txt create mode 100644 drivers/mpu/include/mpu.hpp create mode 100644 drivers/mpu/src/mpu.cpp create mode 100644 drivers/timing_adapter/CMakeLists.txt create mode 100644 drivers/timing_adapter/include/timing_adapter.h create mode 100644 drivers/timing_adapter/src/timing_adapter.c create mode 100644 drivers/uart/CMakeLists.txt create mode 100644 drivers/uart/include/uart_stdout.h create mode 100644 drivers/uart/src/uart_cmsdk_apb.c create mode 100644 drivers/uart/src/uart_dummy.c create mode 100644 drivers/uart/src/uart_pl011.c create mode 100644 drivers/uart/uart_config.h.in delete mode 100644 targets/corstone-300/mpu.cpp delete mode 100644 targets/corstone-300/mpu.hpp delete mode 100644 targets/corstone-300/uart.c delete mode 100644 targets/corstone-300/uart.h delete mode 100644 targets/corstone-300/uart_config.h 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 +#include +#include + +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 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 + +#include +#include + +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 + +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 + +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 + +#include +#include + +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 + +#include +#include +#include +#include +#include + +namespace Mailbox { + +MHUJuno::MHUJuno(const uint32_t baseAddress) { + baseAddr = reinterpret_cast(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 + +#include +#include +#include +#include + +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 + +#include +#include +#include +#include +#include + +namespace Mailbox { + +MHUv2::MHUv2(const uint32_t txBaseAddress, const uint32_t rxBaseAddress) : + txBaseAddr(reinterpret_cast(txBaseAddress)), + rxBaseAddr(reinterpret_cast(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(&txAIDR); + if (a->ARCH_MAJOR_REV != 1 || a->ARCH_MINOR_REV != 1) { + return false; + } + + a = reinterpret_cast(&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(&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(&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/drivers/mpu/include/mpu.hpp b/drivers/mpu/include/mpu.hpp new file mode 100644 index 0000000..dff73b6 --- /dev/null +++ b/drivers/mpu/include/mpu.hpp @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/**************************************************************************** + * Includes + ****************************************************************************/ + +#include + +/**************************************************************************** + * Types and functions + ****************************************************************************/ + +namespace EthosU { +namespace Mpu { + +enum { WTRA_index, WBWARA_index }; + +/** + * Dump the MPU tables. + */ +void dump(); + +void loadAndEnableConfig(ARM_MPU_Region_t const *table, uint32_t cnt); + +}; // namespace Mpu +}; // namespace EthosU diff --git a/drivers/mpu/src/mpu.cpp b/drivers/mpu/src/mpu.cpp new file mode 100644 index 0000000..338e3d1 --- /dev/null +++ b/drivers/mpu/src/mpu.cpp @@ -0,0 +1,79 @@ +/* + * 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. + */ + +/**************************************************************************** + * Includes + ****************************************************************************/ + +#include + +#include +#include +#include + +using namespace std; + +/**************************************************************************** + * Functions + ****************************************************************************/ + +namespace EthosU { +namespace Mpu { + +void dump() { +#ifdef ARM_MPU_ARMV8_H + uint32_t mpuRegions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; + + printf("MPU available with %" PRIu32 " regions.\n", mpuRegions); + + printf(" PRIVDEFENA : %lx\n", (MPU->CTRL & MPU_CTRL_PRIVDEFENA_Msk) >> MPU_CTRL_PRIVDEFENA_Pos); + printf(" HFNMIENA : %lx\n", (MPU->CTRL & MPU_CTRL_HFNMIENA_Msk) >> MPU_CTRL_HFNMIENA_Pos); + printf(" ENABLE : %lx\n", (MPU->CTRL & MPU_CTRL_ENABLE_Msk) >> MPU_CTRL_ENABLE_Pos); + + for (size_t region = 0; region < mpuRegions; region++) { + MPU->RNR = region; + printf("-- Region %2d - RBAR:%08" PRIx32 " RLAR:%08" PRIx32 "\n", region, MPU->RBAR, MPU->RLAR); + } +#endif +} + +static void initializeAttributes() { +#ifdef ARM_MPU_ARMV8_H + /* Initialize attributes corresponding to the enums defined in mpu.hpp */ + const uint8_t WTRA = + ARM_MPU_ATTR_MEMORY_(1, 0, 1, 0); // Non-transient, Write-Through, Read-allocate, Not Write-allocate + const uint8_t WBWARA = ARM_MPU_ATTR_MEMORY_(1, 1, 1, 1); // Non-transient, Write-Back, Read-allocate, Write-allocate + + ARM_MPU_SetMemAttr(WTRA_index, ARM_MPU_ATTR(WTRA, WTRA)); + ARM_MPU_SetMemAttr(WBWARA_index, ARM_MPU_ATTR(WBWARA, WBWARA)); +#endif +} + +void loadAndEnableConfig(ARM_MPU_Region_t const *table, uint32_t cnt) { +#ifdef ARM_MPU_ARMV8_H + initializeAttributes(); + + ARM_MPU_Load(0, table, cnt); + + // Enable MPU with default priv access to all other regions + ARM_MPU_Enable((1 << MPU_CTRL_PRIVDEFENA_Pos) & MPU_CTRL_PRIVDEFENA_Msk); +#endif +} + +}; // namespace Mpu +}; // namespace EthosU 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 + +#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 +#include + +// 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/drivers/uart/include/uart_stdout.h b/drivers/uart/include/uart_stdout.h new file mode 100644 index 0000000..a489b3f --- /dev/null +++ b/drivers/uart/include/uart_stdout.h @@ -0,0 +1,35 @@ +/* + * 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 _UART_STDOUT_H_ +#define _UART_STDOUT_H_ + +#if __cplusplus +extern "C" { +#endif + +void UartStdOutInit(void); +unsigned char UartPutc(unsigned char my_ch); +unsigned char UartGetc(void); +unsigned int GetLine(char *lp, unsigned int len); + +#if __cplusplus +} +#endif + +#endif diff --git a/drivers/uart/src/uart_cmsdk_apb.c b/drivers/uart/src/uart_cmsdk_apb.c new file mode 100644 index 0000000..2c644bb --- /dev/null +++ b/drivers/uart/src/uart_cmsdk_apb.c @@ -0,0 +1,136 @@ +/* + * 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 CMSDK APB UART driver */ + +#include "uart_config.h" +#include "uart_stdout.h" +#include +#include + +#define CNTLQ 0x11 +#define CNTLS 0x13 +#define DEL 0x7F +#define BACKSPACE 0x08 +#define CR 0x0D +#define LF 0x0A +#define ESC 0x1B + +#define __IO volatile +#define __I volatile const +#define __O volatile + +typedef struct { + __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */ + __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */ + __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */ + union { + __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ + __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ + }; + __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */ +} CMSDK_UART_TypeDef; + +#define CMSDK_UART0_BASE UART0_BASE +#define CMSDK_UART0 ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE) +#define CMSDK_UART0_BAUDRATE UART0_BAUDRATE + +void UartStdOutInit(void) { + CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE; + + CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */ + (1ul << 1)); /* RX enable */ +} + +// Output a character +unsigned char UartPutc(unsigned char my_ch) { + while ((CMSDK_UART0->STATE & 1)) + ; // Wait if Transmit Holding register is full + + if (my_ch == '\n') { + CMSDK_UART0->DATA = '\r'; + while ((CMSDK_UART0->STATE & 1)) + ; // Wait if Transmit Holding register is full + } + + CMSDK_UART0->DATA = my_ch; // write to transmit holding register + + return (my_ch); +} + +// Get a character +unsigned char UartGetc(void) { + unsigned char my_ch; + // unsigned int cnt; + + while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty + ; + + my_ch = CMSDK_UART0->DATA; + + // Convert CR to LF + if (my_ch == '\r') + my_ch = '\n'; + + return (my_ch); +} + +// 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; + /* fall through */ + 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/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 +#include + +#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/drivers/uart/uart_config.h.in b/drivers/uart/uart_config.h.in new file mode 100644 index 0000000..c016c3f --- /dev/null +++ b/drivers/uart/uart_config.h.in @@ -0,0 +1,23 @@ +/* + * 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. + */ + +#pragma once + +#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 - $<$:ethosu_core_driver;timing_adapter>) + $<$: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/mpu.cpp b/targets/corstone-300/mpu.cpp deleted file mode 100644 index 1d30ce0..0000000 --- a/targets/corstone-300/mpu.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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. - */ - -/**************************************************************************** - * Includes - ****************************************************************************/ - -#include "mpu.hpp" - -#include -#include -#include - -using namespace std; - -/**************************************************************************** - * Functions - ****************************************************************************/ - -namespace EthosU { -namespace Mpu { - -void dump() { -#ifdef ARM_MPU_ARMV8_H - uint32_t mpuRegions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; - - printf("MPU available with %" PRIu32 " regions.\n", mpuRegions); - - printf(" PRIVDEFENA : %lx\n", (MPU->CTRL & MPU_CTRL_PRIVDEFENA_Msk) >> MPU_CTRL_PRIVDEFENA_Pos); - printf(" HFNMIENA : %lx\n", (MPU->CTRL & MPU_CTRL_HFNMIENA_Msk) >> MPU_CTRL_HFNMIENA_Pos); - printf(" ENABLE : %lx\n", (MPU->CTRL & MPU_CTRL_ENABLE_Msk) >> MPU_CTRL_ENABLE_Pos); - - for (size_t region = 0; region < mpuRegions; region++) { - MPU->RNR = region; - printf("-- Region %2d - RBAR:%08" PRIx32 " RLAR:%08" PRIx32 "\n", region, MPU->RBAR, MPU->RLAR); - } -#endif -} - -static void initializeAttributes() { -#ifdef ARM_MPU_ARMV8_H - /* Initialize attributes corresponding to the enums defined in mpu.hpp */ - const uint8_t WTRA = - ARM_MPU_ATTR_MEMORY_(1, 0, 1, 0); // Non-transient, Write-Through, Read-allocate, Not Write-allocate - const uint8_t WBWARA = ARM_MPU_ATTR_MEMORY_(1, 1, 1, 1); // Non-transient, Write-Back, Read-allocate, Write-allocate - - ARM_MPU_SetMemAttr(WTRA_index, ARM_MPU_ATTR(WTRA, WTRA)); - ARM_MPU_SetMemAttr(WBWARA_index, ARM_MPU_ATTR(WBWARA, WBWARA)); -#endif -} - -void loadAndEnableConfig(ARM_MPU_Region_t const *table, uint32_t cnt) { -#ifdef ARM_MPU_ARMV8_H - initializeAttributes(); - - ARM_MPU_Load(0, table, cnt); - - // Enable MPU with default priv access to all other regions - ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); -#endif -} - -}; // namespace Mpu -}; // namespace EthosU diff --git a/targets/corstone-300/mpu.hpp b/targets/corstone-300/mpu.hpp deleted file mode 100644 index dff73b6..0000000 --- a/targets/corstone-300/mpu.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -/**************************************************************************** - * Includes - ****************************************************************************/ - -#include - -/**************************************************************************** - * Types and functions - ****************************************************************************/ - -namespace EthosU { -namespace Mpu { - -enum { WTRA_index, WBWARA_index }; - -/** - * Dump the MPU tables. - */ -void dump(); - -void loadAndEnableConfig(ARM_MPU_Region_t const *table, uint32_t cnt); - -}; // namespace Mpu -}; // namespace EthosU 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 #include -#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 -#include "uart.h" +#include "uart_stdout.h" #include #include @@ -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++) { diff --git a/targets/corstone-300/uart.c b/targets/corstone-300/uart.c deleted file mode 100644 index bd7dddf..0000000 --- a/targets/corstone-300/uart.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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.h" -#include "uart_config.h" -#include -#include - -#define CNTLQ 0x11 -#define CNTLS 0x13 -#define DEL 0x7F -#define BACKSPACE 0x08 -#define CR 0x0D -#define LF 0x0A -#define ESC 0x1B - -/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ - -#define __IO volatile -#define __I volatile const -#define __O volatile - -typedef struct { - __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */ - __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */ - __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */ - union { - __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ - __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ - }; - __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */ -} CMSDK_UART_TypeDef; - -#define CMSDK_UART0_BASE UART0_BASE -#define CMSDK_UART0 ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE) -#define CMSDK_UART0_BAUDRATE UART0_BAUDRATE - -void uart_init(void) { - // SystemCoreClock / 9600 - CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE; - - CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */ - (1ul << 1)); /* RX enable */ -} - -// Output a character -unsigned char uart_putc(unsigned char my_ch) { - while ((CMSDK_UART0->STATE & 1)) - ; // Wait if Transmit Holding register is full - - if (my_ch == '\n') { - CMSDK_UART0->DATA = '\r'; - while ((CMSDK_UART0->STATE & 1)) - ; // Wait if Transmit Holding register is full - } - - CMSDK_UART0->DATA = my_ch; // write to transmit holding register - - return (my_ch); -} - -// Get a character -unsigned char uart_getc(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; - - // Convert CR to LF - if (my_ch == '\r') - my_ch = '\n'; - - return (my_ch); -} - -// Get line from terminal -unsigned int uart_getline(char *lp, unsigned int len) { - unsigned int cnt = 0; - char c; - - do { - c = uart_getc(); - 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 */ - uart_putc(0x08); /* echo backspace */ - uart_putc(' '); - uart_putc(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; - __attribute__((fallthrough)); /* intentional fallthrough */ - default: - uart_putc(*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.h b/targets/corstone-300/uart.h deleted file mode 100644 index a430e9e..0000000 --- a/targets/corstone-300/uart.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019-2020 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 _UART_STDOUT_H_ -#define _UART_STDOUT_H_ - -#if __cplusplus -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); - -#if __cplusplus -} -#endif - -#endif diff --git a/targets/corstone-300/uart_config.h b/targets/corstone-300/uart_config.h deleted file mode 100644 index 3df76ab..0000000 --- a/targets/corstone-300/uart_config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2019-2020 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. - */ - -#pragma once - -#define UART0_BASE 0x49303000 -#define UART0_BAUDRATE 115200 -#define SYSTEM_CORE_CLOCK 25000000 -- cgit v1.2.1