summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/compression/xz/COPYING (renamed from cpukit/libmisc/xz/COPYING)0
-rw-r--r--cpukit/compression/xz/README (renamed from cpukit/libmisc/xz/README)0
-rw-r--r--cpukit/compression/xz/xz_config.h (renamed from cpukit/libmisc/xz/xz_config.h)0
-rw-r--r--cpukit/compression/xz/xz_crc32.c (renamed from cpukit/libmisc/xz/xz_crc32.c)0
-rw-r--r--cpukit/compression/xz/xz_crc64.c (renamed from cpukit/libmisc/xz/xz_crc64.c)0
-rw-r--r--cpukit/compression/xz/xz_dec_lzma2.c (renamed from cpukit/libmisc/xz/xz_dec_lzma2.c)0
-rw-r--r--cpukit/compression/xz/xz_dec_stream.c (renamed from cpukit/libmisc/xz/xz_dec_stream.c)0
-rw-r--r--cpukit/compression/xz/xz_lzma2.h (renamed from cpukit/libmisc/xz/xz_lzma2.h)0
-rw-r--r--cpukit/compression/xz/xz_private.h (renamed from cpukit/libmisc/xz/xz_private.h)0
-rw-r--r--cpukit/compression/xz/xz_stream.h (renamed from cpukit/libmisc/xz/xz_stream.h)0
-rw-r--r--cpukit/libmisc/cpuuse/cpuinforeport.c2
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagedata.c7
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagereport.c5
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagereset.c5
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagetop.c5
-rw-r--r--cpukit/libmisc/cpuuse/cpuuseimpl.h26
-rw-r--r--cpukit/libmisc/devnull/devzero.c2
-rw-r--r--cpukit/libmisc/regulator/regulator.c680
-rw-r--r--cpukit/libmisc/rtems-fdt/rtems-fdt-shell.c350
-rw-r--r--cpukit/libmisc/rtems-fdt/rtems-fdt.c257
-rw-r--r--cpukit/libmisc/serdbg/README134
-rw-r--r--cpukit/libmisc/serdbg/serdbg.c105
-rw-r--r--cpukit/libmisc/serdbg/serdbgio.c264
-rw-r--r--cpukit/libmisc/serdbg/termios_printk.c245
-rw-r--r--cpukit/libmisc/shell/login_check.c2
-rw-r--r--cpukit/libmisc/shell/login_prompt.c2
-rw-r--r--cpukit/libmisc/shell/main_blkstats.c2
-rw-r--r--cpukit/libmisc/shell/main_chmod.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdchmod.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdchown.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdls.c2
-rw-r--r--cpukit/libmisc/shell/main_cpuinfo.c2
-rw-r--r--cpukit/libmisc/shell/main_drvmgr.c25
-rw-r--r--cpukit/libmisc/shell/main_edit.c38
-rw-r--r--cpukit/libmisc/shell/main_flashdev.c584
-rw-r--r--cpukit/libmisc/shell/main_help.c94
-rw-r--r--cpukit/libmisc/shell/main_i2cdetect.c2
-rw-r--r--cpukit/libmisc/shell/main_i2cget.c2
-rw-r--r--cpukit/libmisc/shell/main_i2cset.c2
-rw-r--r--cpukit/libmisc/shell/main_lsof.c2
-rw-r--r--cpukit/libmisc/shell/main_mmove.c2
-rw-r--r--cpukit/libmisc/shell/main_pci.c27
-rw-r--r--cpukit/libmisc/shell/main_profreport.c2
-rw-r--r--cpukit/libmisc/shell/main_rtc.c2
-rw-r--r--cpukit/libmisc/shell/main_spi.c2
-rw-r--r--cpukit/libmisc/shell/shell-wait-for-input.c2
-rw-r--r--cpukit/libmisc/shell/shell.c183
-rw-r--r--cpukit/libmisc/stackchk/check.c158
-rw-r--r--cpukit/libmisc/untar/untar_tgz.c2
-rw-r--r--cpukit/libmisc/uuid/gen_uuid.c11
50 files changed, 2199 insertions, 1044 deletions
diff --git a/cpukit/libmisc/xz/COPYING b/cpukit/compression/xz/COPYING
index fc4fbf798d..fc4fbf798d 100644
--- a/cpukit/libmisc/xz/COPYING
+++ b/cpukit/compression/xz/COPYING
diff --git a/cpukit/libmisc/xz/README b/cpukit/compression/xz/README
index 1d5b9d85b2..1d5b9d85b2 100644
--- a/cpukit/libmisc/xz/README
+++ b/cpukit/compression/xz/README
diff --git a/cpukit/libmisc/xz/xz_config.h b/cpukit/compression/xz/xz_config.h
index eb9dac1a4b..eb9dac1a4b 100644
--- a/cpukit/libmisc/xz/xz_config.h
+++ b/cpukit/compression/xz/xz_config.h
diff --git a/cpukit/libmisc/xz/xz_crc32.c b/cpukit/compression/xz/xz_crc32.c
index 34532d14fd..34532d14fd 100644
--- a/cpukit/libmisc/xz/xz_crc32.c
+++ b/cpukit/compression/xz/xz_crc32.c
diff --git a/cpukit/libmisc/xz/xz_crc64.c b/cpukit/compression/xz/xz_crc64.c
index ca1caee899..ca1caee899 100644
--- a/cpukit/libmisc/xz/xz_crc64.c
+++ b/cpukit/compression/xz/xz_crc64.c
diff --git a/cpukit/libmisc/xz/xz_dec_lzma2.c b/cpukit/compression/xz/xz_dec_lzma2.c
index 6de808c5b3..6de808c5b3 100644
--- a/cpukit/libmisc/xz/xz_dec_lzma2.c
+++ b/cpukit/compression/xz/xz_dec_lzma2.c
diff --git a/cpukit/libmisc/xz/xz_dec_stream.c b/cpukit/compression/xz/xz_dec_stream.c
index d6525506a1..d6525506a1 100644
--- a/cpukit/libmisc/xz/xz_dec_stream.c
+++ b/cpukit/compression/xz/xz_dec_stream.c
diff --git a/cpukit/libmisc/xz/xz_lzma2.h b/cpukit/compression/xz/xz_lzma2.h
index 071d67bee9..071d67bee9 100644
--- a/cpukit/libmisc/xz/xz_lzma2.h
+++ b/cpukit/compression/xz/xz_lzma2.h
diff --git a/cpukit/libmisc/xz/xz_private.h b/cpukit/compression/xz/xz_private.h
index 482b90f363..482b90f363 100644
--- a/cpukit/libmisc/xz/xz_private.h
+++ b/cpukit/compression/xz/xz_private.h
diff --git a/cpukit/libmisc/xz/xz_stream.h b/cpukit/compression/xz/xz_stream.h
index 66cb5a7055..66cb5a7055 100644
--- a/cpukit/libmisc/xz/xz_stream.h
+++ b/cpukit/compression/xz/xz_stream.h
diff --git a/cpukit/libmisc/cpuuse/cpuinforeport.c b/cpukit/libmisc/cpuuse/cpuinforeport.c
index dcbc7f1747..ac9ad10169 100644
--- a/cpukit/libmisc/cpuuse/cpuinforeport.c
+++ b/cpukit/libmisc/cpuuse/cpuinforeport.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/cpuuse/cpuusagedata.c b/cpukit/libmisc/cpuuse/cpuusagedata.c
index 350ade309b..fa39a6d754 100644
--- a/cpukit/libmisc/cpuuse/cpuusagedata.c
+++ b/cpukit/libmisc/cpuuse/cpuusagedata.c
@@ -3,11 +3,10 @@
/**
* @file
*
- * @ingroup libmisc_cpuuse CPU Usage
+ * @ingroup RTEMSImplCPUUsageReporting
*
- * @brief CPU Usage Data
- *
- * CPU Usage Reporter - Shared Data
+ * @brief This source file contains the definition of
+ * ::CPU_usage_Uptime_at_last_reset.
*/
/*
diff --git a/cpukit/libmisc/cpuuse/cpuusagereport.c b/cpukit/libmisc/cpuuse/cpuusagereport.c
index bc7c897db5..bdeee375e3 100644
--- a/cpukit/libmisc/cpuuse/cpuusagereport.c
+++ b/cpukit/libmisc/cpuuse/cpuusagereport.c
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup libmisc_cpuuse CPU Usage
+ * @ingroup RTEMSImplCPUUsageReporting
*
- * @brief CPU Usage Report
+ * @brief This source file contains the definition of
+ * rtems_cpu_usage_report() and rtems_cpu_usage_report_with_plugin().
*/
/*
diff --git a/cpukit/libmisc/cpuuse/cpuusagereset.c b/cpukit/libmisc/cpuuse/cpuusagereset.c
index bdfba7c944..e56ab3cded 100644
--- a/cpukit/libmisc/cpuuse/cpuusagereset.c
+++ b/cpukit/libmisc/cpuuse/cpuusagereset.c
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup libmisc_cpuuse CPU Usage
+ * @ingroup RTEMSImplCPUUsageReporting
*
- * @brief CPU Usage Reset
+ * @brief This source file contains the definition of
+ * rtems_cpu_usage_reset().
*/
/*
diff --git a/cpukit/libmisc/cpuuse/cpuusagetop.c b/cpukit/libmisc/cpuuse/cpuusagetop.c
index 045a38ae55..eed89ad211 100644
--- a/cpukit/libmisc/cpuuse/cpuusagetop.c
+++ b/cpukit/libmisc/cpuuse/cpuusagetop.c
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup libmisc_cpuuse CPU Usage
+ * @ingroup RTEMSImplCPUUsageReporting
*
- * @brief CPU Usage Top
+ * @brief This source file contains the definition of
+ * rtems_cpu_usage_top() and rtems_cpu_usage_top_with_plugin().
*/
/*
diff --git a/cpukit/libmisc/cpuuse/cpuuseimpl.h b/cpukit/libmisc/cpuuse/cpuuseimpl.h
index 1162d1e892..8c6c407b4b 100644
--- a/cpukit/libmisc/cpuuse/cpuuseimpl.h
+++ b/cpukit/libmisc/cpuuse/cpuuseimpl.h
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplCPUUsageReporting
+ *
+ * @brief This header file provides interfaces of the
+ * @ref RTEMSImplCPUUsageReporting implementation.
+ */
+
/*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
@@ -35,8 +44,25 @@
extern "C" {
#endif
+/**
+ * @defgroup RTEMSImplCPUUsageReporting CPU Usage Reporting
+ *
+ * @ingroup RTEMSImpl
+ *
+ * @brief This group contains the implementation of
+ * @ref RTEMSAPICPUUsageReporting.
+ *
+ * @{
+ */
+
+/**
+ * @brief This object provides the uptime timestamp at the last CPU usage
+ * reset.
+ */
extern Timestamp_Control CPU_usage_Uptime_at_last_reset;
+/** @} */
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/libmisc/devnull/devzero.c b/cpukit/libmisc/devnull/devzero.c
index 7cfd05d4be..5be370b991 100644
--- a/cpukit/libmisc/devnull/devzero.c
+++ b/cpukit/libmisc/devnull/devzero.c
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2011 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/regulator/regulator.c b/cpukit/libmisc/regulator/regulator.c
new file mode 100644
index 0000000000..97a48be4f5
--- /dev/null
+++ b/cpukit/libmisc/regulator/regulator.c
@@ -0,0 +1,680 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @brief Regulator Library Implementation
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/regulator.h>
+#include <string.h>
+
+#include <rtems/regulatorimpl.h>
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * This method is the body for the task which delivers the output for
+ * this regulator instance at the configured rate.
+ *
+ * @param[in] arg points to the regulator instance this thread
+ * is associated with
+ *
+ * @note The argument passed in cannot be NULL if the
+ * rtems_regulator_create worked.
+ */
+static rtems_task _Regulator_Output_task_body(
+ rtems_task_argument arg
+)
+{
+ _Regulator_Control *the_regulator = (_Regulator_Control *)arg;
+ rtems_status_code sc;
+ size_t to_dequeue;
+ _Regulator_Message_t regulator_message;
+ size_t regulator_message_size;
+ bool release_it;
+
+ the_regulator->delivery_thread_is_running = true;
+
+ /**
+ * This thread uses a rate monotonic period object instance. A rate
+ * monotonic period object must be created by the thread using it.
+ * It can be deleted by any thread which simplifies clean up.
+ *
+ * The rate_monotonic_create() call can fail if the application
+ * is incorrectly configured. This thread has no way to report the
+ * failure. If it continues with an invalid id, then the thread will
+ * not block on the period and spin continuously consuming CPU. The only
+ * alternatives are to invoke rtems_fatal_error_occurred() or silently
+ * exit the thread.
+ */
+ sc = rtems_rate_monotonic_create(
+ rtems_build_name('P', 'E', 'R', 'D'),
+ &the_regulator->delivery_thread_period_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ goto exit_delivery_thread;
+ }
+
+ /**
+ * Loop on the rate_monotonic_period() based on the specified period.
+ */
+ while (1) {
+ sc = rtems_rate_monotonic_period(
+ the_regulator->delivery_thread_period_id,
+ the_regulator->Attributes.delivery_thread_period
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ /**
+ * If the delivery thread has been requested to exit, then
+ * quit processing messages, break out of this loop, and exit
+ * this thread.
+ */
+ if (the_regulator->delivery_thread_request_exit) {
+ break;
+ }
+
+ /**
+ * Loop for the configured number of messages to deliver per period.
+ * If we reach the point, there are no more messages, block for the
+ * rest of this period. If there are messages, deliver them.
+ */
+ for (to_dequeue = 0;
+ to_dequeue < the_regulator->Attributes.maximum_to_dequeue_per_period;
+ to_dequeue++) {
+ regulator_message_size = sizeof(_Regulator_Message_t);
+ sc = rtems_message_queue_receive(
+ the_regulator->queue_id,
+ &regulator_message,
+ &regulator_message_size,
+ RTEMS_NO_WAIT,
+ 0
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ if (sc != RTEMS_SUCCESSFUL) {
+ break;
+ }
+
+ release_it = the_regulator->Attributes.deliverer(
+ the_regulator->Attributes.deliverer_context,
+ regulator_message.buffer,
+ regulator_message.length
+ );
+
+ the_regulator->Statistics.delivered++;
+
+ /**
+ * The message was successfully delivered. If the delivery function
+ * wants the buffer returned, do it now. The delivery to the Destination
+ * may involve handing the buffer off to something like DMA
+ * and need to wait for it to complete before releasing the buffer.
+ *
+ * Note that this is the underlying RTEMS service
+ * used by @a rtems_regulator_obtain_buffer() and @a
+ * rtems_regulator_release_buffer().
+ */
+ if (release_it == true) {
+ the_regulator->Statistics.released++;
+ sc = rtems_partition_return_buffer(
+ the_regulator->messages_partition_id,
+ regulator_message.buffer
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ }
+ }
+ }
+
+ /**
+ * This thread was requested to exit. Do so.
+ */
+exit_delivery_thread:
+ the_regulator->delivery_thread_is_running = false;
+ the_regulator->delivery_thread_has_exited = true;
+
+ (void) rtems_rate_monotonic_delete(the_regulator->delivery_thread_period_id);
+
+ rtems_task_exit();
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * This method frees the resources associated with a regulator instance.
+ * The resources are freed in the opposite of the order in which they are
+ * allocated. This is used on error cases in @a rtems_regulator_create() and in
+ * @a rtems_regulator_delete().
+ *
+ * @param[in] the_regulator is the instance to operate upon
+ * @param[in] ticks is the length of time to wait for the delivery thread
+ * to exit
+ *
+ * @return This method returns true is successful and false on timeout.
+ */
+static bool _Regulator_Free_helper(
+ _Regulator_Control *the_regulator,
+ rtems_interval ticks
+)
+{
+ rtems_status_code sc;
+
+
+ /*
+ * If the output thread has not started running, then we can just delete it.
+ */
+
+ if (ticks == 0 || the_regulator->delivery_thread_is_running == false) {
+ sc = rtems_task_delete(the_regulator->delivery_thread_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ } else {
+ rtems_interval remaining = ticks;
+
+ the_regulator->delivery_thread_request_exit = true;
+
+ while (1) {
+ if (the_regulator->delivery_thread_has_exited) {
+ break;
+ }
+
+ if (remaining == 0) {
+ return false;
+ }
+
+ (void) rtems_task_wake_after(1);
+ remaining--;
+ }
+ }
+
+ /*
+ * The output thread deletes the rate monotonic period that it created.
+ */
+
+ /*
+ * The regulator's message_queue_storage is implicitly freed by this call.
+ */
+ sc = rtems_message_queue_delete(the_regulator->queue_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ sc = rtems_partition_delete(the_regulator->messages_partition_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ if (the_regulator->message_memory) {
+ free(the_regulator->message_memory);
+ }
+
+ the_regulator->initialized = 0;
+ free(the_regulator);
+ return true;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_create(
+ rtems_regulator_attributes *attributes,
+ rtems_regulator_instance **regulator
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code sc;
+ size_t alloc_size;
+
+ /**
+ * Perform basic validation of parameters
+ */
+ if (attributes == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (regulator == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ /**
+ * Verify attributes are OK. Some are checked by calls to object create
+ * methods. Specifically the following are not checked:
+ *
+ * - delivery_thread_priority by rtems_task_create()
+ * - delivery_thread_stack_size can be any value
+ */
+ if (attributes->deliverer == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (attributes->maximum_messages == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ if (attributes->maximum_message_size == 0) {
+ return RTEMS_INVALID_SIZE;
+ }
+
+ if (attributes->maximum_to_dequeue_per_period == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ if (attributes->delivery_thread_period == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /**
+ * Allocate memory for regulator instance
+ */
+ the_regulator = (_Regulator_Control *) calloc(sizeof(_Regulator_Control), 1);
+ if (the_regulator == NULL) {
+ return RTEMS_NO_MEMORY;
+ }
+
+ /**
+ * We do NOT want the delivery_thread_id field to be initialized to 0. If the
+ * @a rtems_task_create() fails, then the field will not be overwritten.
+ * This results in an attempt to rtems_task_delete(0) during clean
+ * up. The thread ID of 0 is self which results in the calling thread
+ * accidentally deleting itself.
+ */
+ the_regulator->delivery_thread_id = (rtems_id) -1;
+
+ /**
+ * Copy the attributes to an internal area for later use
+ */
+ the_regulator->Attributes = *attributes;
+
+ /**
+ * Allocate memory for the messages. There is no need to zero out the
+ * message memory because the user should fill that in.
+ */
+ alloc_size = attributes->maximum_message_size * attributes->maximum_messages;
+ the_regulator->message_memory = calloc(alloc_size, 1);
+ if (the_regulator->message_memory == NULL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return RTEMS_NO_MEMORY;
+ }
+
+ /**
+ * Associate message memory with a partition so allocations are atomic
+ */
+ sc = rtems_partition_create(
+ rtems_build_name('P', 'O', 'O', 'L'),
+ the_regulator->message_memory,
+ alloc_size,
+ attributes->maximum_message_size,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &the_regulator->messages_partition_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * Create the message queue between the sender and output thread
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER(sizeof(_Regulator_Message_t)) regulator_message_t;
+
+ size_t storage_size = sizeof(regulator_message_t) * attributes->maximum_messages;
+
+ the_regulator->message_queue_storage = malloc(storage_size);
+ if (the_regulator->message_queue_storage == NULL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return RTEMS_NO_MEMORY;
+ }
+
+ rtems_message_queue_config mq_config = {
+ .name = rtems_build_name('S', 'N', 'D', 'Q'),
+ .maximum_pending_messages = attributes->maximum_messages,
+ .maximum_message_size = sizeof(_Regulator_Message_t),
+ .storage_area = the_regulator->message_queue_storage,
+ .storage_size = storage_size,
+ .storage_free = free,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+ sc = rtems_message_queue_construct(
+ &mq_config,
+ &the_regulator->queue_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * @note A rate monotonic period object must be created by the thread
+ * using it. Thus that specific create operation is not included
+ * in this method. All other resources are allocated here.
+ */
+
+ /**
+ * Create the output thread Using the priority and stack size attributes
+ * specified by the user.
+ */
+ sc = rtems_task_create(
+ rtems_build_name('R', 'E', 'G', 'U'),
+ attributes->delivery_thread_priority,
+ attributes->delivery_thread_stack_size,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &the_regulator->delivery_thread_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * Start the output thread.
+ *
+ * @note There should be no way this call can fail. The task id is valid,
+ * the regulator output thread entry point is valid, and the argument
+ * is valid.
+ */
+ the_regulator->delivery_thread_is_running = true;
+ the_regulator->delivery_thread_request_exit = false;
+ the_regulator->delivery_thread_has_exited = false;
+
+ sc = rtems_task_start(
+ the_regulator->delivery_thread_id,
+ _Regulator_Output_task_body,
+ (rtems_task_argument) the_regulator
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ /**
+ * The regulator is successfully initialized. Set the initialized field
+ * to reflect this and return the instance pointer.
+ */
+ the_regulator->initialized = REGULATOR_INITIALIZED;
+
+ *regulator = (void *)the_regulator;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/**
+ * @brief Validate the regulator instance provided by the user
+ *
+ * Validate the regulator instance provided by the user
+ *
+ * @param[in] regulator is the instance provided by the user
+ * @param[inout] status will contain the RTEMS status for this check
+ *
+ * @return This method returns a @a _Regulator_Control instance pointer
+ * which is NULL if invalid or points to the internal regulator
+ * control structure if valid.
+ */
+static inline _Regulator_Control *_Regulator_Get(
+ rtems_regulator_instance *regulator,
+ rtems_status_code *status
+)
+{
+ _Regulator_Control *the_regulator = (_Regulator_Control *) regulator;
+
+ if (the_regulator == NULL) {
+ *status = RTEMS_INVALID_ADDRESS;
+ return NULL;
+ }
+
+ if (the_regulator->initialized != REGULATOR_INITIALIZED) {
+ *status = RTEMS_INCORRECT_STATE;
+ return NULL;
+ }
+
+ status = RTEMS_SUCCESSFUL;
+ return the_regulator;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_delete(
+ rtems_regulator_instance *regulator,
+ rtems_interval ticks
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * There can be no buffers outstanding
+ */
+ _Regulator_Statistics *stats = &the_regulator->Statistics;
+
+ if (stats->obtained != stats->released ) {
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ /**
+ * Free the resources associated with this regulator instance.
+ */
+ bool bc;
+ bc = _Regulator_Free_helper(the_regulator, ticks);
+ if (bc == false) {
+ return RTEMS_TIMEOUT;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * Allocate a buffer for the caller using the internal partition.
+ */
+rtems_status_code rtems_regulator_obtain_buffer(
+ rtems_regulator_instance *regulator,
+ void **buffer
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Allocate a buffer for the user application from the buffer pool managed
+ * by an Classic API partition.
+ */
+ status = rtems_partition_get_buffer(
+ the_regulator->messages_partition_id,
+ buffer
+ );
+
+ if (status == RTEMS_SUCCESSFUL) {
+ the_regulator->Statistics.obtained++;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * Allocate a buffer for the caller using the internal partition.
+ */
+rtems_status_code rtems_regulator_release_buffer(
+ rtems_regulator_instance *regulator,
+ void *buffer
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Deallocate the buffer to the buffer pool managed by a Classic
+ * API partition.
+ */
+ status = rtems_partition_return_buffer(
+ the_regulator->messages_partition_id,
+ buffer
+ );
+
+ if (status == RTEMS_SUCCESSFUL) {
+ the_regulator->Statistics.released++;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_send(
+ rtems_regulator_instance *regulator,
+ void *message,
+ size_t length
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+ _Regulator_Message_t regulator_message;
+
+ the_regulator = (_Regulator_Control *) regulator;
+
+ /**
+ * Validate the arguments and ensure the regulator was successfully
+ * initialized.
+ */
+ if (message == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (length == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Place the message pointer and length into a temporary structure. This
+ * lets the implementation internally send the message by reference and
+ * have a zero-copy implementation.
+ */
+ regulator_message.buffer = message;
+ regulator_message.length = length;
+
+ /**
+ * Send the application message to the output thread for delivery using
+ * a Classic API message queue.
+ */
+ status = rtems_message_queue_send(
+ the_regulator->queue_id,
+ &regulator_message,
+ sizeof(_Regulator_Message_t)
+ );
+ if (status != RTEMS_SUCCESSFUL) {
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_get_statistics(
+ rtems_regulator_instance *regulator,
+ rtems_regulator_statistics *statistics
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Validate the arguments and ensure the regulator was successfully
+ * initialized.
+ */
+ if (statistics == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Zero out the statistics structure in case the get period statistics
+ * fails below.
+ */
+ memset(statistics, 0, sizeof(rtems_regulator_statistics));
+
+ /**
+ * Fill in the caller's statistics structure from information
+ * maintained by the regulator instance about buffers processed.
+ */
+ statistics->obtained = the_regulator->Statistics.obtained;
+ statistics->released = the_regulator->Statistics.released;
+ statistics->delivered = the_regulator->Statistics.delivered;
+
+ /**
+ * Attempt to retrieve the delivery thread's period's statistics.
+ *
+ * NOTE; If the Delivery Thread has not run yet, the period will not
+ * exist yet. We should not fail for this reason but it is why
+ * we zeroed out the entire structure above.
+ */
+ (void) rtems_rate_monotonic_get_statistics(
+ the_regulator->delivery_thread_period_id,
+ &statistics->period_statistics
+ );
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libmisc/rtems-fdt/rtems-fdt-shell.c b/cpukit/libmisc/rtems-fdt/rtems-fdt-shell.c
index 76f5cd7dbb..0bf6c84208 100644
--- a/cpukit/libmisc/rtems-fdt/rtems-fdt-shell.c
+++ b/cpukit/libmisc/rtems-fdt/rtems-fdt-shell.c
@@ -127,32 +127,6 @@ rtems_fdt_get_value32 (const char* path,
size_t size,
uint32_t* value)
{
- const void* prop;
- int node;
- int length;
-
- node = rtems_fdt_path_offset(&cmd_fdt_handle, path);
- if (node < 0)
- {
- rtems_fdt_check_error (node, "path lookup", path);
- return false;
- }
-
- prop = rtems_fdt_getprop(&cmd_fdt_handle, node, property, &length);
- if (length < 0)
- {
- rtems_fdt_check_error (length, "get property", path);
- return false;
- }
-
- if (length != sizeof (uint32_t))
- {
- printf ("error: property is not sizeof(uint32_t): %s\n", path);
- return false;
- }
-
- *value = rtems_fdt_get_uint32 (prop);
-
return true;
}
@@ -185,7 +159,10 @@ rtems_fdt_shell_ls (int argc, char *argv[])
bool debug = false;
int arg = 1;
size_t path_len = 0;
+ int total_entries = 0;
int num_entries = 0;
+ int max_name_len = 0;
+ int name_offset = 0;
int i = 0;
while (arg < argc)
@@ -220,10 +197,15 @@ rtems_fdt_shell_ls (int argc, char *argv[])
++arg;
}
- if (!path)
+ if (path == NULL)
{
path = "";
}
+ else
+ {
+ if (path[0] != '/')
+ name_offset = 1;
+ }
/* Eliminate trailing slashes. */
path_len = strlen (path);
@@ -231,45 +213,99 @@ rtems_fdt_shell_ls (int argc, char *argv[])
if (path_len > 0 && path[path_len - 1] == '/')
path_len--;
- /* Loop through the entries, looking for matches. */
- num_entries = rtems_fdt_num_entries(&cmd_fdt_handle);
- printf("Total: %d\n", num_entries);
- for (i = 0; i < num_entries; i++)
+ /* Loop through the entries to get the mac name len. */
+ total_entries = rtems_fdt_num_entries(&cmd_fdt_handle);
+
+ for (i = 0; i < total_entries; i++)
{
/* Add it to the result set. */
const char *name = rtems_fdt_entry_name(&cmd_fdt_handle, i);
size_t name_len = strlen(name);
- if ((name_len > path_len) &&
- ((strncmp (path, name, path_len) == 0) && (name[path_len] == '/')) &&
- (recursive || (index(&name[path_len+1], '/') == 0)))
+ if ((name_len >= path_len + name_offset) &&
+ ((strncmp (path, name + name_offset, path_len) == 0) &&
+ ((name[path_len + name_offset] == '/' ||
+ name[path_len + name_offset] == '\0'))) &&
+ (recursive || name_len == path_len + name_offset ||
+ (strchr(&name[path_len + name_offset + 1], '/') == NULL)))
{
+ ++num_entries;
if (long_path)
{
- printf ("%s", name);
+ if (name_len > max_name_len)
+ {
+ max_name_len = name_len;
+ }
}
else if (name_len != path_len)
{
- printf ("%s", &name[path_len + 1]);
+ if (name_len - path_len > max_name_len)
+ {
+ max_name_len = name_len - path_len;
+ }
}
+ }
+ }
- if (debug)
+ printf("Total: %d of %d\n", num_entries, total_entries);
+
+ for (i = 0; i < total_entries; i++)
+ {
+ /* Add it to the result set. */
+ const char *name = rtems_fdt_entry_name(&cmd_fdt_handle, i);
+ size_t name_len = strlen(name);
+
+ if ((name_len >= path_len + name_offset) &&
+ ((strncmp (path, name + name_offset, path_len) == 0) &&
+ ((name[path_len + name_offset] == '/' ||
+ name[path_len + name_offset] == '\0'))) &&
+ (recursive || name_len == path_len + name_offset ||
+ (strchr(&name[path_len + name_offset + 1], '/') == NULL)))
+ {
+ const char* print_name = ".";
+
+ if (long_path)
{
- /* Get properties if we're in debug mode. */
- int proplen = 0;
- int offset = rtems_fdt_entry_offset(&cmd_fdt_handle, i);
- const void *prop = rtems_fdt_getprop(&cmd_fdt_handle, offset, "reg", &proplen);
- const void *prop2 = rtems_fdt_getprop(&cmd_fdt_handle, offset, "mask", &proplen);
+ print_name = name + name_offset;
+ }
+ else if (name_len != path_len + name_offset)
+ {
+ print_name = &name[path_len + name_offset + 1];
+ }
- if (prop)
- {
- printf(" addr 0x%08" PRIx32, *(uint32_t *)prop);
- }
+ printf ("%-*s", max_name_len, print_name);
- proplen = 0;
- if (prop2)
+ if (debug)
+ {
+ /* Get properties if we're in debug mode. */
+ int printed = 0;
+ const int noffset = rtems_fdt_entry_offset(&cmd_fdt_handle, i);
+ int poffset = rtems_fdt_first_prop_offset(&cmd_fdt_handle, noffset);
+ int address_cells =
+ rtems_fdt_getprop_address_cells(&cmd_fdt_handle, noffset);
+ int size_cells = rtems_fdt_getprop_size_cells(&cmd_fdt_handle, noffset);
+ printf("cells(a:%d s:%d) ", address_cells, size_cells);
+ while (poffset >= 0)
{
- printf(" mask 0x%08" PRIx32, *(uint32_t *)prop2);
+ int plen = 0;
+ const char* pname = NULL;
+ const uint8_t *pvalue =
+ rtems_fdt_getprop_by_offset(&cmd_fdt_handle, poffset, &pname, &plen);
+ if (pvalue != NULL)
+ {
+ int b;
+ if (printed > 0)
+ printf(",");
+ ++printed;
+ printf(" %s %i:", pname, plen);
+ for (b = 0; b < plen; ++b)
+ {
+ if (b > 0 && (b % 4) == 0)
+ printf(" ");
+ printf("%02" PRIx8, *pvalue++);
+ }
+ }
+ poffset = rtems_fdt_next_prop_offset(&cmd_fdt_handle, poffset);
}
}
@@ -283,9 +319,11 @@ rtems_fdt_shell_ls (int argc, char *argv[])
static int
rtems_fdt_shell_wr (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
- uint32_t value;
+ rtems_fdt_address_map addr_map;
+ uint64_t offset = 0;
+ uint32_t value;
+ int fmt;
+ int r;
if ((argc < 3) || (argc > 4))
return rtems_fdt_wrong_number_of_args ();
@@ -296,18 +334,30 @@ rtems_fdt_shell_wr (int argc, char *argv[])
}
else
{
- offset = strtoul (argv[2], 0, 0);
+ offset = strtoull (argv[2], 0, 0);
value = strtoul (argv[3], 0, 0);
}
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
return 1;
+ }
- address += offset;
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
+ return 1;
+ }
+
+ addr_map.address += offset;
+
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
- printf ("0x%08" PRIx32 " <= 0x%08" PRIx32 "\n", address, value);
+ printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 "\n", fmt, addr_map.address, value);
- rtems_fdt_write (address, value);
+ rtems_fdt_write (addr_map.address, value);
return 0;
}
@@ -315,8 +365,10 @@ rtems_fdt_shell_wr (int argc, char *argv[])
static int
rtems_fdt_shell_rd (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
+ rtems_fdt_address_map addr_map;
+ uint32_t offset = 0;
+ int fmt;
+ int r;
if ((argc < 1) || (argc > 3))
return rtems_fdt_wrong_number_of_args ();
@@ -324,12 +376,25 @@ rtems_fdt_shell_rd (int argc, char *argv[])
if (argc == 3)
offset = strtoul (argv[2], 0, 0);
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
return 1;
+ }
- address += offset;
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
+ return 1;
+ }
+
+ addr_map.address += offset;
- printf ("0x%08" PRIx32 " => 0x%08" PRIx32 "\n", address, rtems_fdt_read (address));
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
+
+ printf ("0x%0*" PRIx64 " => 0x%08" PRIx32 "\n",
+ fmt, addr_map.address, rtems_fdt_read (addr_map.address));
return 0;
}
@@ -337,11 +402,13 @@ rtems_fdt_shell_rd (int argc, char *argv[])
static int
rtems_fdt_shell_set (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
- uint32_t value;
- int mask_arg;
- uint32_t mask;
+ rtems_fdt_address_map addr_map;
+ uint32_t offset = 0;
+ uint32_t value;
+ int mask_arg;
+ uint32_t mask;
+ int fmt;
+ int r;
if ((argc < 3) || (argc > 4))
return rtems_fdt_wrong_number_of_args ();
@@ -354,24 +421,38 @@ rtems_fdt_shell_set (int argc, char *argv[])
mask_arg = 3;
}
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
+ return 1;
+ }
+
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
return 1;
+ }
+
+ addr_map.address += offset;
+
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
if (isdigit ((unsigned char) argv[mask_arg][0]))
mask = strtoul (argv[mask_arg], 0, 0);
else
{
+ mask = 0;
if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
return 1;
}
- address += offset;
- value = rtems_fdt_read (address);
+ value = rtems_fdt_read (addr_map.address);
- printf ("0x%08" PRIx32 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 " | 0x%08" PRIx32 "\n",
- address, value | mask, value, mask);
+ printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 " | 0x%08" PRIx32 "\n",
+ fmt, addr_map.address, value | mask, value, mask);
- rtems_fdt_write (address, value | mask);
+ rtems_fdt_write (addr_map.address, value | mask);
return 0;
}
@@ -379,11 +460,13 @@ rtems_fdt_shell_set (int argc, char *argv[])
static int
rtems_fdt_shell_cl (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
- uint32_t value;
- int mask_arg;
- uint32_t mask;
+ rtems_fdt_address_map addr_map;
+ uint32_t offset = 0;
+ uint32_t value;
+ int mask_arg;
+ uint32_t mask;
+ int fmt;
+ int r;
if ((argc < 3) || (argc > 4))
return rtems_fdt_wrong_number_of_args ();
@@ -396,25 +479,39 @@ rtems_fdt_shell_cl (int argc, char *argv[])
mask_arg = 3;
}
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
+ return 1;
+ }
+
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
return 1;
+ }
+
+ addr_map.address += offset;
+
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
if (isdigit ((unsigned char) argv[mask_arg][0]))
mask = strtoul (argv[mask_arg], 0, 0);
else
{
+ mask = 0;
if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
return 1;
}
- address += offset;
- value = rtems_fdt_read (address);
+ value = rtems_fdt_read (addr_map.address);
- printf ("0x%08" PRIx32 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 \
+ printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 \
" & ~0x%08" PRIx32 " (0x%08" PRIx32 ")\n",
- address, value & ~mask, value, mask, ~mask);
+ fmt, addr_map.address, value & ~mask, value, mask, ~mask);
- rtems_fdt_write (address, value & ~mask);
+ rtems_fdt_write (addr_map.address, value & ~mask);
return 0;
}
@@ -422,12 +519,14 @@ rtems_fdt_shell_cl (int argc, char *argv[])
static int
rtems_fdt_shell_up (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
- uint32_t set;
- uint32_t value;
- int mask_arg;
- uint32_t mask;
+ rtems_fdt_address_map addr_map;
+ uint32_t offset = 0;
+ uint32_t set;
+ uint32_t value;
+ int mask_arg;
+ uint32_t mask;
+ int fmt;
+ int r;
if ((argc < 4) || (argc > 5))
return rtems_fdt_wrong_number_of_args ();
@@ -442,25 +541,39 @@ rtems_fdt_shell_up (int argc, char *argv[])
set = strtoul (argv[mask_arg + 1], 0, 0);
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
return 1;
+ }
+
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
+ return 1;
+ }
+
+ addr_map.address += offset;
+
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
if (isdigit ((unsigned char) argv[mask_arg][0]))
mask = strtoul (argv[mask_arg], 0, 0);
else
{
+ mask = 0;
if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
return 1;
}
- address += offset;
- value = rtems_fdt_read (address);
+ value = rtems_fdt_read (addr_map.address);
- printf ("0x%08" PRIx32 " <= 0x%08" PRIx32 " = (0x%08" PRIx32 \
+ printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = (0x%08" PRIx32 \
" & ~0x%08" PRIx32 " (0x%08" PRIx32 ")) | 0x%08" PRIx32 "\n",
- address, (value & ~mask) | set, value, mask, ~mask, set);
+ fmt, addr_map.address, (value & ~mask) | set, value, mask, ~mask, set);
- rtems_fdt_write (address, (value & ~mask) | set);
+ rtems_fdt_write (addr_map.address, (value & ~mask) | set);
return 0;
}
@@ -468,13 +581,15 @@ rtems_fdt_shell_up (int argc, char *argv[])
static int
rtems_fdt_shell_tst (int argc, char *argv[])
{
- uint32_t address;
- uint32_t offset = 0;
- uint32_t test;
- uint32_t value = 0;
- int mask_arg;
- uint32_t mask;
- time_t start;
+ rtems_fdt_address_map addr_map;
+ uint32_t offset = 0;
+ uint32_t test;
+ uint32_t value = 0;
+ int mask_arg;
+ uint32_t mask;
+ time_t start;
+ int fmt;
+ int r;
if ((argc < 4) || (argc > 5))
return rtems_fdt_wrong_number_of_args ();
@@ -489,37 +604,50 @@ rtems_fdt_shell_tst (int argc, char *argv[])
test = strtoul (argv[mask_arg + 1], 0, 0);
- if (!rtems_fdt_get_value32 (argv[1], "reg", sizeof (uint32_t), &address))
+ r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
+ if (r < 0)
+ {
+ printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
return 1;
+ }
+
+ if (offset >= addr_map.size)
+ {
+ printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
+ return 1;
+ }
+
+ addr_map.address += offset;
+
+ fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
if (isdigit ((unsigned char) argv[mask_arg][0]))
mask = strtoul (argv[mask_arg], 0, 0);
else
{
- if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
+ mask = 0;
+ if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
return 1;
}
- address += offset;
-
start = time (NULL);
- printf ("0x%08" PRIx32 " => (value & 0x%08" PRIx32 ") == 0x%08" PRIx32 \
+ printf ("0x%0*" PRIx64 " => (value & 0x%08" PRIx32 ") == 0x%08" PRIx32 \
" for %ld seconds\n",
- address, mask, test, rtems_fdt_test_timeout);
+ fmt, addr_map.address, mask, test, rtems_fdt_test_timeout);
while ((time (NULL) - start) < rtems_fdt_test_timeout)
{
int i;
for (i = 0; i < 10000; ++i)
{
- value = rtems_fdt_read (address);
+ value = rtems_fdt_read (addr_map.address);
if ((value & mask) == test)
return 0;
}
}
- printf ("0x%08" PRIx32 " => 0x%08" PRIx32 ": timeout\n", address, value);
+ printf ("0x%0*" PRIx64 " => 0x%08" PRIx32 ": timeout\n", fmt, addr_map.address, value);
return 1;
}
diff --git a/cpukit/libmisc/rtems-fdt/rtems-fdt.c b/cpukit/libmisc/rtems-fdt/rtems-fdt.c
index 7dd2bc1047..9f8d7bfb24 100644
--- a/cpukit/libmisc/rtems-fdt/rtems-fdt.c
+++ b/cpukit/libmisc/rtems-fdt/rtems-fdt.c
@@ -25,9 +25,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <errno.h>
#include <fcntl.h>
-#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -35,6 +33,7 @@
#include <libfdt.h>
#include <zlib.h>
+#include <rtems/malloc.h>
#include <rtems/rtems-fdt.h>
#include <rtems/thread.h>
@@ -175,14 +174,14 @@ rtems_fdt_init_index (rtems_fdt_handle* fdt, rtems_fdt_blob* blob)
/*
* Create the index.
*/
- entries = calloc(num_entries, sizeof(rtems_fdt_index_entry));
+ entries = rtems_calloc(num_entries, sizeof(rtems_fdt_index_entry));
if (!entries)
{
return -RTEMS_FDT_ERR_NO_MEMORY;
}
- names = calloc(1, total_name_memory);
- if (!entries)
+ names = rtems_calloc(1, total_name_memory);
+ if (!names)
{
free(entries);
return -RTEMS_FDT_ERR_NO_MEMORY;
@@ -505,7 +504,7 @@ rtems_fdt_load (const char* filename, rtems_fdt_handle* handle)
{
size_t offset;
- cdata = malloc(sb.st_size);
+ cdata = rtems_malloc(sb.st_size);
if (!cdata)
{
close (bf);
@@ -546,7 +545,7 @@ rtems_fdt_load (const char* filename, rtems_fdt_handle* handle)
name_len = strlen (filename) + 1;
- blob = malloc(sizeof (rtems_fdt_blob) + name_len + bsize);
+ blob = rtems_malloc(sizeof (rtems_fdt_blob) + name_len + bsize);
if (!blob)
{
free(cdata);
@@ -649,7 +648,7 @@ rtems_fdt_register (const void* dtb, rtems_fdt_handle* handle)
return fe;
}
- blob = malloc(sizeof (rtems_fdt_blob));
+ blob = rtems_malloc(sizeof (rtems_fdt_blob));
if (!blob)
{
return -RTEMS_FDT_ERR_NO_MEMORY;
@@ -700,14 +699,14 @@ rtems_fdt_unload (rtems_fdt_handle* handle)
rtems_chain_extract_unprotected (&handle->blob->node);
+ rtems_fdt_release_index(&handle->blob->index);
+
free (handle->blob);
handle->blob = NULL;
rtems_fdt_unlock (fdt);
- rtems_fdt_release_index(&handle->blob->index);
-
return 0;
}
@@ -782,6 +781,27 @@ rtems_fdt_get_name (rtems_fdt_handle* handle, int nodeoffset, int* length)
return name;
}
+int
+rtems_fdt_first_prop_offset(rtems_fdt_handle* handle, int nodeoffset)
+{
+ return fdt_first_property_offset(handle->blob->blob, nodeoffset);
+}
+
+int
+rtems_fdt_next_prop_offset(rtems_fdt_handle* handle, int propoffset)
+{
+ return fdt_next_property_offset(handle->blob->blob, propoffset);
+}
+
+const void*
+rtems_fdt_getprop_by_offset(rtems_fdt_handle* handle,
+ int propoffset,
+ const char** name,
+ int* length)
+{
+ return fdt_getprop_by_offset(handle->blob->blob, propoffset, name, length);
+}
+
const void*
rtems_fdt_getprop_namelen (rtems_fdt_handle* handle,
int nodeoffset,
@@ -941,7 +961,8 @@ rtems_fdt_strerror (int errval)
"no memory",
"file not found",
"DTB read fail",
- "blob has references"
+ "blob has references",
+ "bad length"
};
if (errval > -RTEMS_FDT_ERR_RTEMS_MIN)
return fdt_strerror (errval);
@@ -977,7 +998,7 @@ rtems_fdt_prop_value(const char* const path,
if (length > (int) *size)
{
rtems_fdt_release_handle (&fdt);
- return RTEMS_FDT_ERR_BADPATH;
+ return -RTEMS_FDT_ERR_BADPATH;
}
*size = length;
@@ -987,11 +1008,29 @@ rtems_fdt_prop_value(const char* const path,
return 0;
}
+bool
+rtems_fdt_get_parent_prop_value(rtems_fdt_handle* handle,
+ int nodeoffset,
+ const char* name,
+ uint32_t* value)
+{
+ const void* prop;
+ int plen = 0;
+ int node = rtems_fdt_parent_offset(handle, nodeoffset);
+ if (node < 0)
+ return false;
+ prop = rtems_fdt_getprop(handle, node, name, &plen);
+ if (plen < 0)
+ return false;
+ *value = rtems_fdt_get_uint32(prop);
+ return true;
+}
+
int
rtems_fdt_prop_map(const char* const path,
const char* const propname,
const char* const names[],
- uint32_t* values,
+ uintptr_t* values,
size_t count)
{
rtems_fdt_handle fdt;
@@ -1006,10 +1045,9 @@ rtems_fdt_prop_map(const char* const path,
for (item = 0; item < count; item++)
{
- const void* prop;
- const uint8_t* p;
- int length;
- int subnode;
+ const void* prop;
+ int length;
+ int subnode;
subnode = rtems_fdt_subnode_offset (&fdt, node, names[item]);
if (subnode < 0)
@@ -1025,40 +1063,85 @@ rtems_fdt_prop_map(const char* const path,
return length;
}
- if (length != sizeof (uint32_t))
+ if (length > sizeof (uintptr_t))
{
rtems_fdt_release_handle (&fdt);
- return RTEMS_FDT_ERR_BADPATH;
+ return -RTEMS_FDT_ERR_BADPATH;
}
- p = prop;
-
- values[item] = ((((uint32_t) p[0]) << 24) |
- (((uint32_t) p[1]) << 16) |
- (((uint32_t) p[2]) << 8) |
- (uint32_t) p[3]);
+ values[item] = rtems_fdt_get_offset_len_uintptr(prop, 0, length);
}
return 0;
}
+uintptr_t
+rtems_fdt_get_offset_len_uintptr (const void* prop, int offset, int len)
+{
+ const uint8_t* p = prop;
+ uintptr_t value = 0;
+ int b;
+ if (len <= sizeof(uintptr_t)) {
+ for (b = 0; b < len; ++b) {
+ value = (value << 8) | (uintptr_t) p[offset++];
+ }
+ }
+ return value;
+}
+
+
uint32_t
-rtems_fdt_get_uint32 (const void* prop)
+rtems_fdt_get_offset_uint32 (const void* prop, int offset)
{
const uint8_t* p = prop;
uint32_t value;
- value = ((((uint32_t) p[0]) << 24) |
- (((uint32_t) p[1]) << 16) |
- (((uint32_t) p[2]) << 8) |
- (uint32_t) p[3]);
+ offset *= sizeof(uint32_t);
+ value = ((((uint32_t) p[offset + 0]) << 24) |
+ (((uint32_t) p[offset + 1]) << 16) |
+ (((uint32_t) p[offset + 2]) << 8) |
+ (uint32_t) p[offset + 3]);
return value;
}
+uint32_t
+rtems_fdt_get_uint32 (const void* prop)
+{
+ return rtems_fdt_get_offset_uint32(prop, 0);
+}
+
+uint64_t
+rtems_fdt_get_offset_uint64 (const void* prop, int offset)
+{
+ uint64_t value = rtems_fdt_get_offset_uint32(prop, offset);
+ value = (value << 16) << 16;
+ return value | rtems_fdt_get_offset_uint32(prop, offset + 1);
+}
+
+uint64_t
+rtems_fdt_get_uint64 (const void* prop)
+{
+ return rtems_fdt_get_offset_uint64(prop, 0);
+}
+
+uintptr_t
+rtems_fdt_get_uintptr (const void* prop)
+{
+ return rtems_fdt_get_offset_uintptr(prop, 0);
+}
+
+uintptr_t
+rtems_fdt_get_offset_uintptr (const void* prop, int offset)
+{
+ if (sizeof(intptr_t) == sizeof(uint32_t))
+ return rtems_fdt_get_offset_uint32(prop, offset);
+ return rtems_fdt_get_offset_uint64(prop, offset);
+}
+
int
rtems_fdt_get_value (const char* path,
const char* property,
size_t size,
- uint32_t* value)
+ uintptr_t* value)
{
rtems_fdt_handle fdt;
const void* prop;
@@ -1081,8 +1164,8 @@ rtems_fdt_get_value (const char* path,
return length;
}
- if (length == sizeof (uint32_t))
- *value = rtems_fdt_get_uint32 (prop);
+ if (length == sizeof (uintptr_t))
+ *value = rtems_fdt_get_uintptr (prop);
else
*value = 0;
@@ -1119,3 +1202,111 @@ rtems_fdt_entry_offset(rtems_fdt_handle* handle, int id)
{
return handle->blob->index.entries[id].offset;
}
+
+int
+rtems_fdt_getprop_address_cells(rtems_fdt_handle* handle, int nodeoffset)
+{
+ uint32_t value = 0;
+ if (!rtems_fdt_get_parent_prop_value(handle, nodeoffset, "#address-cells", &value))
+ return -1;
+ return value;
+}
+
+int
+rtems_fdt_getprop_size_cells(rtems_fdt_handle* handle, int nodeoffset)
+{
+ uint32_t value = 0;
+ if (!rtems_fdt_get_parent_prop_value(handle, nodeoffset, "#size-cells", &value))
+ return -1;
+ return value;
+}
+
+int rtems_fdt_getprop_address_map(rtems_fdt_handle* handle,
+ const char* path,
+ const char* name,
+ rtems_fdt_address_map* addr_map)
+{
+ const void* prop;
+ int plen = 0;
+ int poff = 0;
+ int len;
+
+ memset(addr_map, 0, sizeof(*addr_map));
+
+ addr_map->node = rtems_fdt_path_offset(handle, path);
+ if (addr_map->node < 0)
+ return -RTEMS_FDT_ERR_NOTFOUND;
+
+ addr_map->address_cells = rtems_fdt_getprop_address_cells(handle, addr_map->node);
+ addr_map->size_cells = rtems_fdt_getprop_size_cells(handle, addr_map->node);
+
+ prop = rtems_fdt_getprop(handle, addr_map->node, name, &plen);
+ if (plen < 0)
+ return -RTEMS_FDT_ERR_NOTFOUND;
+
+ if (addr_map->address_cells == 0)
+ return -RTEMS_FDT_ERR_BADOFFSET;
+
+ if (addr_map->address_cells < 0)
+ {
+ if (addr_map->size_cells > 0)
+ return -RTEMS_FDT_ERR_BADOFFSET;
+ addr_map->address_cells = 1;
+ }
+
+ if (addr_map->size_cells < 0)
+ {
+ addr_map->size = sizeof(uint32_t);
+ addr_map->size_cells = 0;
+ }
+
+ len = (addr_map->address_cells + addr_map->size_cells) * sizeof(uint32_t);
+
+ if (len != plen)
+ return -RTEMS_FDT_ERR_BADLENGTH;
+
+ switch (addr_map->address_cells)
+ {
+ case 1:
+ if (plen < sizeof(uint32_t))
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ addr_map->address = rtems_fdt_get_offset_uint32(prop, poff);
+ poff += 1;
+ plen -= sizeof(uint32_t);
+ break;
+ case 2:
+ if (plen < sizeof(uint64_t))
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ addr_map->address = rtems_fdt_get_offset_uint64(prop, poff);
+ poff += 2;
+ plen -= sizeof(uint64_t);
+ break;
+ default:
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ }
+
+ switch (addr_map->size_cells)
+ {
+ case 0:
+ addr_map->size = sizeof(uint32_t);
+ break;
+ case 1:
+ if (plen < sizeof(uint32_t))
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ addr_map->size = rtems_fdt_get_offset_uint32(prop, poff);
+ poff += 1;
+ plen -= sizeof(uint32_t);
+ break;
+ case 2:
+ if (plen < sizeof(uint64_t))
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ addr_map->size = rtems_fdt_get_offset_uint64(prop, poff);
+ poff += 2;
+ plen -= sizeof(uint64_t);
+ break;
+ default:
+ return -RTEMS_FDT_ERR_BADLENGTH;
+ }
+
+ return 0;
+}
diff --git a/cpukit/libmisc/serdbg/README b/cpukit/libmisc/serdbg/README
deleted file mode 100644
index 64623ebd89..0000000000
--- a/cpukit/libmisc/serdbg/README
+++ /dev/null
@@ -1,134 +0,0 @@
-This directory contains three useful packages related to the termios I/O
-system:
-
-PACKAGE SERDBGIO
-================
-"serdbgio" provides the "serial gdb" standard I/O functions "getDebugChar"
-and "putDebugChar" for any device driver supporting polled termios mode.
-
-The initialization function "serdbg_open" opens the v.24 port intended
-for the serial debug connection, and sets the desired baud rate. The
-"getDebugChar" and "putDebugChar" functions then interact with the
-corresponding driver using the calls intended for polled termios
-operation.
-
-Specification for the debug device, baud rate and other parameters is
-done in a global structure of type "serdbg_conf_t". A configuration
-mechanism quite similar to the overall RTEMS configuration is available.
-
-PACKAGE SERDBG
-==============
-"serdbg" provides a means to optionally initialize and/or start a
-serial gdb session as soon as possible, this means as soon as all
-drivers have been initialized. The serial debug I/O functions can
-either be integrated as special routines of the BSP drivers, or using
-the package "serdbgio"
-
-PACKAGE TERMIOS_PRINTK
-======================
-"termios_printk" provides a standard output function suitable to use
-with "printk". It uses the same technique as serdbgio, hooking the
-interface between a polled device driver and the termios system.
-
-
-REQUIREMENTS
-============
-
-- These two packages can be used with any polled termios device
-driver.
-- For standard initialization, they need a modified "bsppost.c"
-to perform the initialization calls.
-
-USAGE
-=====
-
-For using these packages add the following to your "init" module or
-your "system.h" file (Note: most macro settings fall back to a
-default, if not set.):
-
-/*
- * CONFIGURE_USE_SERDBG
- * set this macro, if you want to connect gdb over a serial line
- * when set, the debug stub will be connected after driver
- * initialization in "bsppost.c"
- */
-#define CONFIGURE_USE_SERDBG
-
-
-/*
- * CONFIGURE_SERDBG_SKIP_INIT_BKPT
- * set this macro, if you do not want the gdb interface to wait for a
- * debugger connection directly after initialization
- * If you set this macro, the gdb stub will only hook various
- * exception vectors when called from "bsppost.c".
- */
-/* #define CONFIGURE_SERDBG_SKIP_INIT_BKPT */
-
-/*
- * CONFIGURE_SERDBG_USE_POLLED_TERMIOS
- * set this macro, if you want "serdbgio" to provide the I/O
- * functions for the serial gdb connection
- */
-#define CONFIGURE_SERDBG_USE_POLLED_TERMIOS
-
-/*
- * CONFIGURE_SERDBG_DEVNAME
- * use this macro to specify the serial device to use
- * for "serdbgio".
- * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
- */
-#define CONFIGURE_SERDBG_DEVNAME "/dev/tty03"
-
-/*
- * CONFIGURE_SERDBG_BAUDRATE
- * use this macro to specify the baud rate to use
- * for "serdbgio".
- * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
- */
-#define CONFIGURE_SERDBG_BAUDRATE 57600
-
-/*
- * CONFIGURE_SERDBG_CALLOUT
- * use this macro to specify a routine that will called during I/O polling
- * Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
- * This function of type "void pollfnc(void)" can be used for e.g.
- * tickling a watchdog
- */
-/* #define CONFIGURE_SERDBG_CALLOUT tickle_my_watchdog_fnc */
-
-#include <serdbgcnf.h>
-
-/*
- * CONFIGURE_USE_TERMIOS_PRINTK
- * set this macro, if you want printk output to be sent to a serial
- * driver using the polled termios interface
- * when set, the printk output function will be connected after driver
- * initialization in "bsppost.c"
- */
-#define CONFIGURE_USE_TERMIOS_PRINTK
-
-/*
- * CONFIGURE_TERMIOS_PRINTK_DEVNAME
- * use this macro to specify the serial device to use
- * for printk output.
- * Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
- */
-#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
-
-/*
- * CONFIGURE_TERMIOS_PRINTK_BAUDRATE
- * use this macro to specify the baudrate to use
- * for printk output.
- * Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
- */
-#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
-
-/*
- * CONFIGURE_TERMIOS_PRINTK_CALLOUT
- * use this macro to specify a routine that will called during I/O polling
- * This function of type "void pollfnc(void)" can be used for e.g.
- * tickling a watchdog
- */
-/* #define CONFIGURE_TERMIOS_PRINTK_CALLOUT tickle_my_watchdog_fnc */
-
-#include <termios_printk_cnf.h>
diff --git a/cpukit/libmisc/serdbg/serdbg.c b/cpukit/libmisc/serdbg/serdbg.c
deleted file mode 100644
index c49e78762a..0000000000
--- a/cpukit/libmisc/serdbg/serdbg.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * RTEMS remote gdb over serial line
- *
- * This file contains intialization and utility functions to add
- * a gdb remote debug stub to an RTEMS system.
- */
-
-/*
- * Copyright (c) 2002 IMD Ingenieurbuero fuer Microcomputertechnik
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <rtems/serdbg.h>
-
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-int serdbg_init_dbg
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| initialize remote gdb session over serial line |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- void
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- static bool is_initialized = false;
-
- rtems_status_code rc = RTEMS_SUCCESSFUL;
-
- if (is_initialized) {
- return RTEMS_SUCCESSFUL;
- }
- is_initialized = true;
- /*
- * try to open serial device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if ((serdbg_conf.open_io != NULL) &&
- (0 > serdbg_conf.open_io(serdbg_conf.devname,serdbg_conf.baudrate))) {
- fprintf(stderr,
- "remote_gdb_init: cannot open device %s "
- "for gdb connection:%s\n",serdbg_conf.devname,strerror(errno));
- rc = RTEMS_IO_ERROR;
- }
- }
- /*
- * initialize gdb stub
- */
- if (rc == RTEMS_SUCCESSFUL) {
- set_debug_traps();
- }
- /*
- * now activate gdb stub
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- !serdbg_conf.skip_init_bkpt) {
- breakpoint();
- }
-
- /*
- * return to original function
- * this may be already unter gdb control
- */
- return rc;
-}
diff --git a/cpukit/libmisc/serdbg/serdbgio.c b/cpukit/libmisc/serdbg/serdbgio.c
deleted file mode 100644
index 07c77a0b03..0000000000
--- a/cpukit/libmisc/serdbg/serdbgio.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * TERMIOS serial gdb interface support
- * the functions in this file allow the standard gdb stubs like
- * "m68k-stub.c" to access any serial interfaces that work with
- * RTEMS termios in polled mode
- */
-
-/*
- * Copyright (c) 2002 IMD Ingenieurbuero fuer Microcomputertechnik
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <rtems/libio_.h>
-#include <errno.h>
-#include <unistd.h> /* close */
-#include <stdio.h>
-#include <fcntl.h>
-#include <termios.h>
-
-#include <rtems/termiostypes.h>
-#include <rtems/serdbg.h>
-
-
-/*
- * internal variables
- */
-int serdbg_fd = -1;
-struct rtems_termios_tty *serdbg_tty;
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-int serdbg_open
-
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| try to open given serial debug port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- const char *dev_name, /* name of device to open */
- uint32_t baudrate /* baud rate to use */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| 0 on success, -1 and errno otherwise |
-\*=========================================================================*/
-{
- bool err_occurred = false;
- rtems_libio_t *iop = NULL;
- struct termios act_termios;
- tcflag_t baudcode = B0;
-
-#define FD_STORE_CNT 3
- int fd_store[FD_STORE_CNT];
- int fd_store_used = 0;
-
- /*
- * translate baudrate into baud code
- */
- switch(baudrate) {
- case 50: baudcode = B50; break;
- case 75: baudcode = B75; break;
- case 110: baudcode = B110; break;
- case 134: baudcode = B134; break;
- case 150: baudcode = B150; break;
- case 200: baudcode = B200; break;
- case 300: baudcode = B300; break;
- case 600: baudcode = B600; break;
- case 1200: baudcode = B1200; break;
- case 1800: baudcode = B1800; break;
- case 2400: baudcode = B2400; break;
- case 4800: baudcode = B4800; break;
- case 9600: baudcode = B9600; break;
- case 19200: baudcode = B19200; break;
- case 38400: baudcode = B38400; break;
- case 57600: baudcode = B57600; break;
- case 115200: baudcode = B115200; break;
- case 230400: baudcode = B230400; break;
- case 460800: baudcode = B460800; break;
- default : err_occurred = true; errno = EINVAL; break;
- }
-
- /*
- * open device for serdbg operation
- * skip any fds that are between 0..2, because they are
- * reserved for stdin/out/err
- */
- if (!err_occurred &&
- (dev_name != NULL) &&
- (dev_name[0] != '\0')) {
- do {
- serdbg_fd = open(dev_name,O_RDWR);
- if (serdbg_fd < 0) {
- err_occurred = true;
- }
- else {
- if (serdbg_fd < 3) {
- if (fd_store_used >= FD_STORE_CNT) {
- err_occurred = true;
- }
- else {
- fd_store[fd_store_used++] = serdbg_fd;
- }
- }
- }
- } while (!err_occurred &&
- (serdbg_fd < 3));
- }
- /*
- * close any fds, that have been placed in fd_store
- * so fd 0..2 are reusable again
- */
- while (--fd_store_used >= 0) {
- close(fd_store[fd_store_used]);
- }
-
- /*
- * capture tty structure
- */
- if (!err_occurred) {
- iop = rtems_libio_iop(serdbg_fd);
- serdbg_tty = iop->data1;
- }
- /*
- * set device baudrate
- * (and transp mode, this is not really needed)
- * ...
- */
- /*
- * ... get fd settings
- */
- if (!err_occurred &&
- (0 != tcgetattr(serdbg_fd,&act_termios))) {
- err_occurred = true;
- }
- if (!err_occurred) {
- act_termios.c_iflag
- &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- act_termios.c_oflag
- &= ~OPOST;
-
- act_termios.c_lflag
- &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
-
- cfsetospeed(&act_termios,baudcode);
- cfsetispeed(&act_termios,baudcode);
-
- if (0 != tcsetattr(serdbg_fd,TCSANOW,&act_termios)) {
- err_occurred = true;
- }
- }
- return (err_occurred
- ? -1
- : 0);
-}
-
-void putDebugChar(char c) __attribute__ ((__weak__));
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-void putDebugChar
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| send one character to serial port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- char c /* character to print */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none> |
-\*=========================================================================*/
-{
- /*
- * call serdbg polling callout, if available
- */
- if (serdbg_conf.callout != NULL) {
- serdbg_conf.callout();
- }
- /*
- * check, whether debug serial port is available
- */
- if ((serdbg_tty != NULL) &&
- (serdbg_tty->device.write != NULL)) {
- /*
- * send character to debug serial port
- */
- serdbg_tty->device.write(serdbg_tty->minor,&c,1);
- }
-}
-
-int getDebugChar(void) __attribute__ ((__weak__));
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-int getDebugChar
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| wait for one character from serial port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- void /* none */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| received character |
-\*=========================================================================*/
-{
- int c = -1;
- /*
- * check, whether debug serial port is available
- */
- if ((serdbg_tty != NULL) &&
- (serdbg_tty->device.pollRead != NULL)) {
- do {
- /*
- * call serdbg polling callout, if available
- */
- if (serdbg_conf.callout != NULL) {
- serdbg_conf.callout();
- }
- /*
- * get character from debug serial port
- */
- c = serdbg_tty->device.pollRead(serdbg_tty->minor);
- } while (c < 0);
- }
- return c;
-}
diff --git a/cpukit/libmisc/serdbg/termios_printk.c b/cpukit/libmisc/serdbg/termios_printk.c
deleted file mode 100644
index 2b5a7f8e69..0000000000
--- a/cpukit/libmisc/serdbg/termios_printk.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * TERMIOS printk support
- * this module performs low-level printk output using
- * a polled termios driver
- */
-
-/*
- * Copyright (c) 2002 IMD Ingenieurbuero fuer Microcomputertechnik
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <rtems/libio_.h>
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <termios.h>
-
-#include <rtems/termiostypes.h>
-#include <rtems/bspIo.h>
-#include <rtems/termios_printk.h>
-
-/*
- * internal variables
- */
-int termios_printk_fd = -1;
-struct rtems_termios_tty *termios_printk_tty;
-
-static void _termios_printk_null_char(
- char c RTEMS_UNUSED)
-{
- return;
-}
-
-BSP_output_char_function_type BSP_output_char = _termios_printk_null_char;
-BSP_polling_getchar_function_type BSP_poll_char;
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-void termios_printk_outputchar
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| send one character to serial port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- char c /* character to print */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none> |
-\*=========================================================================*/
-{
- /*
- * check, whether printk serial port is available
- */
-
- if ((termios_printk_tty != NULL) &&
- (termios_printk_tty->device.write != NULL)) {
- /*
- * call termios_printk polling callout, if available
- */
- if (termios_printk_conf.callout != NULL) {
- termios_printk_conf.callout();
- }
- /*
- * send character to debug serial port
- */
- termios_printk_tty->device.write(termios_printk_tty->minor,&c,1);
- }
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-int termios_printk_inputchar
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| wait for one character from serial port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- void /* none */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| received character |
-\*=========================================================================*/
-{
- int c = -1;
- /*
- * check, whether debug serial port is available
- */
- if ((termios_printk_tty != NULL) &&
- (termios_printk_tty->device.pollRead != NULL)) {
- do {
- /*
- * call termios_printk polling callout, if available
- */
- if (termios_printk_conf.callout != NULL) {
- termios_printk_conf.callout();
- }
- /*
- * get character from debug serial port
- */
- c = termios_printk_tty->device.pollRead(termios_printk_tty->minor);
- } while (c < 0);
- }
- return c;
-}
-
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-int termios_printk_open
-
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| try to open given serial debug port |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- const char *dev_name, /* name of device to open */
- uint32_t baudrate /* baud rate to use */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| 0 on success, -1 and errno otherwise |
-\*=========================================================================*/
-{
- bool err_occurred = false;
- rtems_libio_t *iop = NULL;
- struct termios act_termios;
- tcflag_t baudcode = B0;
-
- if (termios_printk_fd >= 0) {
- /*
- * already initialized
- */
- return 0;
- }
- /*
- * translate baudrate into baud code
- */
- switch(baudrate) {
- case 50: baudcode = B50; break;
- case 75: baudcode = B75; break;
- case 110: baudcode = B110; break;
- case 134: baudcode = B134; break;
- case 150: baudcode = B150; break;
- case 200: baudcode = B200; break;
- case 300: baudcode = B300; break;
- case 600: baudcode = B600; break;
- case 1200: baudcode = B1200; break;
- case 1800: baudcode = B1800; break;
- case 2400: baudcode = B2400; break;
- case 4800: baudcode = B4800; break;
- case 9600: baudcode = B9600; break;
- case 19200: baudcode = B19200; break;
- case 38400: baudcode = B38400; break;
- case 57600: baudcode = B57600; break;
- case 115200: baudcode = B115200; break;
- case 230400: baudcode = B230400; break;
- case 460800: baudcode = B460800; break;
- default : err_occurred = true; errno = EINVAL; break;
- }
- /*
- * open device for serdbg operation
- */
- if (!err_occurred &&
- (dev_name != NULL) &&
- (dev_name[0] != '\0')) {
- termios_printk_fd = open(dev_name,O_RDWR);
- if (termios_printk_fd < 0) {
- err_occurred = true;
- }
- }
- /*
- * capture tty structure
- */
- if (!err_occurred) {
- iop = rtems_libio_iop(termios_printk_fd);
- termios_printk_tty = iop->data1;
- }
- /*
- * set device baudrate
- * (and transp mode, this is not really needed)
- * ...
- */
- /*
- * ... get fd settings
- */
- if (!err_occurred &&
- (0 != tcgetattr(termios_printk_fd,&act_termios))) {
- err_occurred = true;
- }
- if (!err_occurred) {
-
- cfsetospeed(&act_termios,baudcode);
- cfsetispeed(&act_termios,baudcode);
-
- if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) {
- err_occurred = true;
- }
- }
- if (!err_occurred) {
- BSP_output_char = termios_printk_outputchar;
- BSP_poll_char = termios_printk_inputchar;
- }
- return (err_occurred
- ? -1
- : 0);
-}
diff --git a/cpukit/libmisc/shell/login_check.c b/cpukit/libmisc/shell/login_check.c
index 5ba2332070..d9bce28a7d 100644
--- a/cpukit/libmisc/shell/login_check.c
+++ b/cpukit/libmisc/shell/login_check.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2009-2014 embedded brains GmbH and others.
+ * Copyright (C) 2009, 2014 embedded brains GmbH & Co. KG
*
* Based on work from Chris Johns and Fernando Ruiz.
*
diff --git a/cpukit/libmisc/shell/login_prompt.c b/cpukit/libmisc/shell/login_prompt.c
index 6eda753607..149966be63 100644
--- a/cpukit/libmisc/shell/login_prompt.c
+++ b/cpukit/libmisc/shell/login_prompt.c
@@ -48,7 +48,7 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*
- * Copyright (c) 2009 embedded brains GmbH and others.
+ * Copyright (c) 2009 embedded brains GmbH & Co. KG
*
* Based on work from Chris Johns, Fernando Ruiz and Till Straumann.
*
diff --git a/cpukit/libmisc/shell/main_blkstats.c b/cpukit/libmisc/shell/main_blkstats.c
index 294dd1b7d9..3acc652d87 100644
--- a/cpukit/libmisc/shell/main_blkstats.c
+++ b/cpukit/libmisc/shell/main_blkstats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2012 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_chmod.c b/cpukit/libmisc/shell/main_chmod.c
index 1f646d92d4..9a42cbd940 100644
--- a/cpukit/libmisc/shell/main_chmod.c
+++ b/cpukit/libmisc/shell/main_chmod.c
@@ -56,7 +56,7 @@ static int rtems_shell_main_chmod(
* Now change the files modes
*/
for (n=2 ; n < argc ; n++) {
- sc = chmod(argv[n++], mode);
+ sc = chmod(argv[n], mode);
_Assert_Unused_variable_unequal(sc, -1);
}
diff --git a/cpukit/libmisc/shell/main_cmdchmod.c b/cpukit/libmisc/shell/main_cmdchmod.c
index dee4d899a8..b6ec03bd5d 100644
--- a/cpukit/libmisc/shell/main_cmdchmod.c
+++ b/cpukit/libmisc/shell/main_cmdchmod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cmdchown.c b/cpukit/libmisc/shell/main_cmdchown.c
index 6ceab0f5b1..ba44d70ebb 100644
--- a/cpukit/libmisc/shell/main_cmdchown.c
+++ b/cpukit/libmisc/shell/main_cmdchown.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cmdls.c b/cpukit/libmisc/shell/main_cmdls.c
index ab11c83892..529e070e8b 100644
--- a/cpukit/libmisc/shell/main_cmdls.c
+++ b/cpukit/libmisc/shell/main_cmdls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cpuinfo.c b/cpukit/libmisc/shell/main_cpuinfo.c
index 846f5efd4a..70179dcee8 100644
--- a/cpukit/libmisc/shell/main_cpuinfo.c
+++ b/cpukit/libmisc/shell/main_cpuinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_drvmgr.c b/cpukit/libmisc/shell/main_drvmgr.c
index bdf8d1c9ae..6090dde6b1 100644
--- a/cpukit/libmisc/shell/main_drvmgr.c
+++ b/cpukit/libmisc/shell/main_drvmgr.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* DRVMGR Command Implementation
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
diff --git a/cpukit/libmisc/shell/main_edit.c b/cpukit/libmisc/shell/main_edit.c
index 4cc742719a..8317452b7b 100644
--- a/cpukit/libmisc/shell/main_edit.c
+++ b/cpukit/libmisc/shell/main_edit.c
@@ -412,6 +412,9 @@ static void move_gap(struct editor *ed, int pos, int minsize) {
if (gapsize + MINEXTEND > minsize) minsize = gapsize + MINEXTEND;
newsize = (ed->end - ed->start) - gapsize + minsize;
start = (unsigned char *) malloc(newsize); // TODO check for out of memory
+ if (start == NULL) {
+ return;
+ }
gap = start + pos;
rest = gap + minsize;
end = start + newsize;
@@ -755,8 +758,23 @@ static void get_console_size(struct env *env) {
env->cols = ws.ws_col;
env->lines = ws.ws_row - 1;
#elif defined(__rtems__)
- env->cols = 80;
+ char* e;
env->lines = 25;
+ env->cols = 80;
+ e = getenv("LINES");
+ if (e != NULL) {
+ int lines = strtol(e, 0, 10);
+ if (lines > 0) {
+ env->lines = lines - 1;
+ }
+ }
+ e = getenv("COLUMNS");
+ if (e != NULL) {
+ int cols = strtol(e, 0, 10);
+ if (cols > 0) {
+ env->cols = cols;
+ }
+ }
#else
struct term *term = gettib()->proc->term;
env->cols = term->cols;
@@ -1695,7 +1713,6 @@ static void copy_selection(struct editor *ed) {
ed->env->clipboard = (unsigned char *) realloc(ed->env->clipboard, ed->env->clipsize);
if (!ed->env->clipboard) return;
copy(ed, ed->env->clipboard, selstart, ed->env->clipsize);
- select_toggle(ed);
}
static void cut_selection(struct editor *ed) {
@@ -1794,14 +1811,14 @@ static void save_editor(struct editor *ed) {
ed->refresh = 1;
}
-static void close_editor(struct editor *ed) {
+static struct editor* close_editor(struct editor *ed) {
struct env *env = ed->env;
if (ed->dirty) {
display_message(ed, "Close %s without saving changes (y/n)? ", ed->filename);
if (!ask()) {
ed->refresh = 1;
- return;
+ return ed;
}
}
@@ -1813,6 +1830,7 @@ static void close_editor(struct editor *ed) {
new_file(ed, "");
}
ed->refresh = 1;
+ return ed;
}
static void pipe_command(struct editor *ed) {
@@ -2113,7 +2131,7 @@ static void edit(struct editor *ed) {
case ctrl('e'): select_toggle(ed); break;
case ctrl('a'): select_all(ed); break;
- case ctrl('c'): copy_selection(ed); break;
+ case ctrl('c'): copy_selection(ed);select_toggle(ed); break;
case ctrl('f'): find_text(ed, 0); break;
case ctrl('l'): goto_line(ed); break;
case ctrl('g'): find_text(ed, 1); break;
@@ -2136,15 +2154,7 @@ static void edit(struct editor *ed) {
case ctrl('s'): save_editor(ed); break;
case ctrl('p'): pipe_command(ed); break;
#endif
-#if defined(__rtems__)
- /*
- * Coverity spotted this as using ed after free() so changing
- * the order of the statements.
- */
- case ctrl('w'): ed = ed->env->current; close_editor(ed); break;
-#else
- case ctrl('w'): close_editor(ed); ed = ed->env->current; break;
-#endif
+ case ctrl('w'): ed = close_editor(ed); break;
}
}
}
diff --git a/cpukit/libmisc/shell/main_flashdev.c b/cpukit/libmisc/shell/main_flashdev.c
new file mode 100644
index 0000000000..ca2454b33c
--- /dev/null
+++ b/cpukit/libmisc/shell/main_flashdev.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2023 Aaron Nyholm
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <errno.h>
+#include <rtems/shell.h>
+
+#include <dev/flash/flashdev.h>
+
+static int flashdev_shell_read(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_write(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_erase(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_type(char *dev_path);
+static int flashdev_shell_jedecid(char *dev_path);
+static int flashdev_shell_page_off(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_page_idx(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_pg_count(char *dev_path);
+static int flashdev_shell_wb_size(char *dev_path);
+
+static int flashdev_shell_ioctl_value(
+ char *dev_path,
+ int ioctl_call,
+ void *ret
+);
+
+static int flashdev_shell_page(
+ char *dev_path,
+ int argc,
+ char *argv[],
+ int ioctl_call
+);
+
+static const char rtems_flashdev_shell_usage [] =
+ "simple flash read / write / erase\n"
+ "\n"
+ "flashdev <FLASH_DEV_PATH> [OPTION]\n"
+ " -r <address> <bytes> Read at address for bytes\n"
+ " -w <address> <file> Write file to address\n"
+ " -e <address> <bytes> Erase at address for bytes\n"
+ " -t Print the flash type\n"
+ " -d Print the JEDEC ID of flash device\n"
+ " -o <address> Print the page information of page at address\n"
+ " -i <index> Print the page information of page at index\n"
+ " -p Print the number of pages\n"
+ " -b Print the write block size\n"
+ " -h Print this help\n";
+
+
+static int rtems_flashdev_shell_main( int argc, char *argv[] ) {
+
+ char *dev_path = NULL;
+ int i;
+
+ for (i = 1; i < argc; ++i) {
+ if (argv[i][0] == '-') {
+ /*
+ * Check that a path to flashdev has been provided before running
+ * command.
+ */
+ if (dev_path == NULL) {
+ printf("Please input FLASH_DEV_PATH before instruction\n");
+ return 1;
+ }
+ /* Run command */
+ switch (argv[i][1]) {
+ case ('r'):
+ /* Read */
+ return flashdev_shell_read(dev_path, argc, &argv[i]);
+ case ('w'):
+ /* Write */
+ return flashdev_shell_write(dev_path, argc, &argv[i]);
+ case ('e'):
+ /* Erase */
+ return flashdev_shell_erase(dev_path, argc, &argv[i]);
+ case ('t'):
+ /* Flash Type */
+ return flashdev_shell_type(dev_path);
+ case ('d'):
+ /* JEDEC Id */
+ return flashdev_shell_jedecid(dev_path);
+ case ('o'):
+ /* Page info by offset */
+ return flashdev_shell_page_off(dev_path, argc, &argv[i]);
+ case ('i'):
+ /* Page info by index */
+ return flashdev_shell_page_idx(dev_path, argc, &argv[i]);
+ case ('p'):
+ /* Page count */
+ return flashdev_shell_pg_count(dev_path);
+ case ('b'):
+ /* Write block size */
+ return flashdev_shell_wb_size(dev_path);
+ case ('h'):
+ default:
+ /* Help */
+ printf(rtems_flashdev_shell_usage);
+ break;
+ }
+ } else if (dev_path == NULL) {
+ dev_path = argv[i];
+ } else {
+ printf("Invalid argument: %s\n", argv[i]);
+ return 1;
+ }
+ }
+
+ if (argc == 1) {
+ printf(rtems_flashdev_shell_usage);
+ }
+
+ return 0;
+}
+
+int flashdev_shell_read(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ uint32_t bytes;
+ int fd;
+ int status;
+ void *buffer;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ bytes = (uint32_t) strtoul(argv[2], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ /* Move to address */
+ status = lseek(fd, address, SEEK_SET);
+ if (status == -1) {
+ printf("Reading failed\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Create a buffer to read into */
+ buffer = calloc((bytes + bytes%4), 1);
+ if (buffer == NULL) {
+ printf("Failed to allocate read buffer\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Read into buffer */
+ status = read(fd, buffer, bytes);
+ if (status == -1) {
+ printf("Reading failed\n");
+ free(buffer);
+ close(fd);
+ return -1;
+ }
+
+ /* Print buffer out in 32bit blocks */
+ printf("Reading %s at 0x%08x for %d bytes\n", dev_path, address, bytes);
+ for (int i = 0; i < (bytes/4); i++) {
+ printf("%08x ", ((uint32_t*)buffer)[i]);
+ if ((i+1)%4 == 0) {
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ /* Clean up */
+ free(buffer);
+ close(fd);
+ return 0;
+}
+
+int flashdev_shell_write(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ int flash;
+ int file;
+ int status;
+ int read_len;
+ off_t length;
+ void *buffer;
+ uint32_t offset;
+ char *file_path;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ file_path = argv[2];
+
+ /* Open flash device and move to write offset */
+ flash = open(dev_path, O_WRONLY);
+ if (flash == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+ status = lseek(flash, address, SEEK_SET);
+ if (status == -1) {
+ printf("Reading failed\n");
+ close(flash);
+ return -1;
+ }
+
+ /* Open file and get file length */
+ file = open(file_path, O_RDONLY);
+ if (file == -1) {
+ printf("Couldn't open %s\n", file_path);
+ close(flash);
+ return -1;
+ }
+
+ length = lseek(file, 0, SEEK_END);
+ if (length == -1) {
+ close(flash);
+ close(file);
+ printf("Couldn't find length of file\n");
+ return -1;
+ }
+
+ if (lseek(file, 0, SEEK_SET) == -1) {
+ close(flash);
+ close(file);
+ printf("Couldn't find length of file\n");
+ return -1;
+ }
+
+ /* Create buffer */
+ buffer = calloc(1, 0x1000);
+
+ /* Write file to flash device in 0x1000 byte chunks */
+ offset = 0;
+ while (offset != length) {
+
+ read_len = length - offset;
+ if (read_len > 0x1000) {
+ read_len = 0x1000;
+ }
+
+ status = read(file, buffer, read_len);
+ if (status == -1) {
+ free(buffer);
+ close(flash);
+ close(file);
+ printf("Can't read %s\n", file_path);
+ return -1;
+ }
+
+ status = write(flash, buffer, read_len);
+ if (status == -1) {
+ free(buffer);
+ close(flash);
+ close(file);
+ printf("Can't write %s\n", dev_path);
+ return -1;
+ }
+
+ offset = offset + read_len;
+ }
+
+ /* Clean up */
+ close(flash);
+ close(file);
+ free(buffer);
+ return 0;
+}
+
+int flashdev_shell_erase(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ uint32_t bytes;
+ int fd;
+ int status;
+ rtems_flashdev_region args;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ bytes = (uint32_t) strtoul(argv[2], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDWR);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ printf("Erasing at %08x for %x bytes\n", address, bytes);
+
+ /* Erase flash */
+ args.offset = address;
+ args.size = bytes;
+
+ status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &args);
+ if (status == -1) {
+ printf("Erase failed\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Clean up */
+ close(fd);
+
+ return 0;
+}
+
+int flashdev_shell_type( char *dev_path )
+{
+ int type;
+ int status;
+
+ /* Get type */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_TYPE,
+ &type
+ );
+
+ if (status) {
+ printf("Failed to get flash type\n");
+ return status;
+ }
+
+ /* Print type */
+ switch(type) {
+ case RTEMS_FLASHDEV_NOR:
+ printf("NOR flash\n");
+ break;
+ case RTEMS_FLASHDEV_NAND:
+ printf("NAND flash\n");
+ break;
+ default:
+ printf("Unknown type\n");
+ }
+
+ return 0;
+}
+
+int flashdev_shell_jedecid( char *dev_path ) {
+ uint32_t ret;
+ int status;
+
+ /* Get JEDEC Id */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_JEDEC_ID,
+ &ret
+ );
+
+ /* Print JEDEC Id */
+ if (status) {
+ printf("Failed to get JEDEC Id\n");
+ return status;
+ } else {
+ printf("JEDEC Id: 0x%x\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_page_off(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ return flashdev_shell_page(
+ dev_path,
+ argc,
+ argv,
+ RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_OFFSET
+ );
+}
+
+static int flashdev_shell_page_idx(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ return flashdev_shell_page(
+ dev_path,
+ argc,
+ argv,
+ RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_INDEX
+ );
+}
+
+static int flashdev_shell_pg_count( char *dev_path )
+{
+ uint32_t ret;
+ int status;
+
+ /* Get Page Count */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_PAGE_COUNT,
+ &ret
+ );
+
+ /* Print Page Count */
+ if (status) {
+ printf("Failed to get page count\n");
+ return status;
+ } else {
+ printf("Page count: 0x%x\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_wb_size( char *dev_path )
+{
+ size_t ret;
+ int status;
+
+ /* Get Write Block Size */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_WRITE_BLOCK_SIZE,
+ &ret
+ );
+
+ /* Print Write Block Size */
+ if (status) {
+ printf("Failed to get write block size\n");
+ return status;
+ } else {
+ printf("Write block size: 0x%zx\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_ioctl_value(
+ char *dev_path,
+ int ioctl_call,
+ void *ret
+)
+{
+ int fd;
+ int status;
+
+ fd = open(dev_path, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ status = ioctl(fd, ioctl_call, ret);
+ if (status == -1) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+static int flashdev_shell_page(
+ char *dev_path,
+ int argc,
+ char *argv[],
+ int ioctl_call
+)
+{
+ rtems_flashdev_ioctl_page_info pg_info;
+ int fd;
+ int status;
+
+ /* Check arguments */
+ if (argc < 4) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ pg_info.location = (off_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDWR);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ status = ioctl(fd, ioctl_call, &pg_info);
+ if (status == -1) {
+ printf("Failed to get page info\n");
+ close(fd);
+ return -1;
+ }
+
+ printf(
+ "Page offset: 0x%jx\nPage length: 0x%zx\n",
+ pg_info.page_info.offset,
+ pg_info.page_info.size
+ );
+
+ /* Clean up */
+ close(fd);
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_FLASHDEV_Command = {
+ .name = "flashdev",
+ .usage = rtems_flashdev_shell_usage,
+ .topic = "misc",
+ .command = rtems_flashdev_shell_main,
+};
diff --git a/cpukit/libmisc/shell/main_help.c b/cpukit/libmisc/shell/main_help.c
index 564bc30a9c..e6d939d08f 100644
--- a/cpukit/libmisc/shell/main_help.c
+++ b/cpukit/libmisc/shell/main_help.c
@@ -22,23 +22,34 @@
#include "internal.h"
#include <string.h>
+static int rtems_shell_help_pause(int line, int lines) {
+ if (lines && line >= lines - 1) {
+ printf("\rPress any key to continue...");
+ (void) getchar();
+ printf("\r%*c\r", 29, ' ');
+ line = 0;
+ }
+ return line;
+}
+
/*
* show the help for one command.
*/
static int rtems_shell_help_cmd(
- const rtems_shell_cmd_t *shell_cmd
+ const rtems_shell_cmd_t *shell_cmd, int indent, int line,
+ int cols, int lines
)
{
const char * pc;
- int col,line;
+ int col;
if (!rtems_shell_can_see_cmd(shell_cmd)) {
return 0;
}
- printf("%-12.12s - ",shell_cmd->name);
- col = 14;
- line = 1;
+ printf("%-*s - ", indent, shell_cmd->name);
+ indent += 3;
+ col = indent;
if (shell_cmd->alias) {
printf("is an <alias> for command '%s'",shell_cmd->alias->name);
} else if (shell_cmd->usage) {
@@ -48,8 +59,10 @@ static int rtems_shell_help_cmd(
case '\r':
break;
case '\n':
- putchar('\n');
- col = 0;
+ if (*(pc + 1) != '\0') {
+ putchar('\n');
+ col = 0;
+ }
break;
default:
putchar(*pc);
@@ -57,19 +70,21 @@ static int rtems_shell_help_cmd(
break;
}
pc++;
- if (col>78) { /* What daring... 78?*/
+ if (col > (cols - 3)) {
if (*pc) {
putchar('\n');
col = 0;
}
}
- if (!col && *pc) {
- printf(" ");
- col = 12;line++;
+ if (col == 0 && *pc) {
+ line = rtems_shell_help_pause(line + 1, lines);
+ printf("%*c", indent, ' ');
+ col = indent;
}
}
}
puts("");
+ line = rtems_shell_help_pause(line + 1, lines);
return line;
}
@@ -83,15 +98,27 @@ static int rtems_shell_help(
char * argv[]
)
{
- int col,line,lines,arg;
- char* lines_env;
+ int col,line,cols,lines,arg,indent;
+ char *lines_env, *cols_env;
rtems_shell_topic_t *topic;
+ rtems_shell_cmd_t *shell_cmd;
+ lines = 16;
+ cols = 80;
lines_env = getenv("SHELL_LINES");
- if (lines_env)
+ if (lines_env) {
lines = strtol(lines_env, 0, 0);
- else
- lines = 16;
+ } else {
+ lines_env = getenv("LINES");
+ if (lines_env) {
+ lines = strtol(lines_env, 0, 0);
+ }
+ }
+
+ cols_env = getenv("COLUMNS");
+ if (cols_env) {
+ cols = strtol(cols_env, 0, 0);
+ }
if (argc<2) {
printf("help: The topics are\n");
@@ -101,7 +128,7 @@ static int rtems_shell_help(
if (!col){
col = printf(" %s",topic->topic);
} else {
- if ((col+strlen(topic->topic)+2)>78){
+ if ((col+strlen(topic->topic)+2)>(cols - 2)){
printf("\n");
col = printf(" %s",topic->topic);
} else {
@@ -113,18 +140,19 @@ static int rtems_shell_help(
printf("\n");
return 1;
}
+ indent = 0;
+ shell_cmd = rtems_shell_first_cmd;
+ while (shell_cmd) {
+ size_t len = strlen(shell_cmd->name);
+ if (len > indent) {
+ indent = len;
+ }
+ shell_cmd = shell_cmd->next;
+ }
line = 0;
for (arg = 1;arg<argc;arg++) {
const char *cur = argv[arg];
- rtems_shell_cmd_t *shell_cmd;
-
- if (lines && (line > lines)) {
- printf("Press any key to continue...");
- (void) getchar(); /* we only want to know a character was pressed */
- printf("\n");
- line = 0;
- }
- topic = rtems_shell_lookup_topic(cur);
+ topic = rtems_shell_lookup_topic(cur);
if (topic == NULL) {
if ((shell_cmd = rtems_shell_lookup_cmd(cur)) == NULL) {
if (strcmp(cur, "all") != 0) {
@@ -132,11 +160,11 @@ static int rtems_shell_help(
"help: topic or cmd '%s' not found. Try <help> alone for a list\n",
cur
);
- line++;
+ line = rtems_shell_help_pause(line + 1, lines);
continue;
}
} else {
- line+= rtems_shell_help_cmd(shell_cmd);
+ line = rtems_shell_help_cmd(shell_cmd, indent, line, cols, lines);
continue;
}
}
@@ -144,18 +172,12 @@ static int rtems_shell_help(
line++;
shell_cmd = rtems_shell_first_cmd;
while (shell_cmd) {
- if (topic == NULL || !strcmp(topic->topic,shell_cmd->topic))
- line+= rtems_shell_help_cmd(shell_cmd);
- if (lines && (line > lines)) {
- printf("Press any key to continue...");
- (void) getchar();
- printf("\n");
- line = 0;
+ if (topic == NULL || !strcmp(topic->topic,shell_cmd->topic)) {
+ line = rtems_shell_help_cmd(shell_cmd, indent, line, cols, lines);
}
shell_cmd = shell_cmd->next;
}
}
- puts("");
return 0;
}
diff --git a/cpukit/libmisc/shell/main_i2cdetect.c b/cpukit/libmisc/shell/main_i2cdetect.c
index e953b4eaef..1a863434b7 100644
--- a/cpukit/libmisc/shell/main_i2cdetect.c
+++ b/cpukit/libmisc/shell/main_i2cdetect.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_i2cget.c b/cpukit/libmisc/shell/main_i2cget.c
index ffa551308b..5726c6ea14 100644
--- a/cpukit/libmisc/shell/main_i2cget.c
+++ b/cpukit/libmisc/shell/main_i2cget.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_i2cset.c b/cpukit/libmisc/shell/main_i2cset.c
index d9025b3b28..cdc42a57f9 100644
--- a/cpukit/libmisc/shell/main_i2cset.c
+++ b/cpukit/libmisc/shell/main_i2cset.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_lsof.c b/cpukit/libmisc/shell/main_lsof.c
index efe886e6de..2cc35f96fe 100644
--- a/cpukit/libmisc/shell/main_lsof.c
+++ b/cpukit/libmisc/shell/main_lsof.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2012, 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_mmove.c b/cpukit/libmisc/shell/main_mmove.c
index 38731b10a2..0029882d62 100644
--- a/cpukit/libmisc/shell/main_mmove.c
+++ b/cpukit/libmisc/shell/main_mmove.c
@@ -62,7 +62,7 @@ static int rtems_shell_main_mmove(
/*
* Now copy the memory.
*/
- memcpy(dst, src, length);
+ memmove(dst, src, length);
return 0;
}
diff --git a/cpukit/libmisc/shell/main_pci.c b/cpukit/libmisc/shell/main_pci.c
index 08fdae78ae..4902ed07b9 100644
--- a/cpukit/libmisc/shell/main_pci.c
+++ b/cpukit/libmisc/shell/main_pci.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* LIBPCI Command Implementation
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
@@ -356,7 +375,7 @@ static int shell_pci_infodev(
printf(" PCIID: 0x%04x\n", dev->busdevfun);
bus = dev->bus;
if (!bus) {
- printf(" AT BUS: 0x%x via Host Bridge\n", bus->num);
+ printf(" AT BUS: via Host Bridge\n");
} else {
printf(" AT BUS: 0x%x via Bridge at [%x:%x:%x]\n", bus->num,
PCI_DEV_EXPAND(bus->dev.busdevfun));
diff --git a/cpukit/libmisc/shell/main_profreport.c b/cpukit/libmisc/shell/main_profreport.c
index a3c64a5e5d..ab14cc1e49 100644
--- a/cpukit/libmisc/shell/main_profreport.c
+++ b/cpukit/libmisc/shell/main_profreport.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2015 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_rtc.c b/cpukit/libmisc/shell/main_rtc.c
index 21ca8bb9d1..940c7c9b52 100644
--- a/cpukit/libmisc/shell/main_rtc.c
+++ b/cpukit/libmisc/shell/main_rtc.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2009 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_spi.c b/cpukit/libmisc/shell/main_spi.c
index 487a22fc6c..9c47ba0054 100644
--- a/cpukit/libmisc/shell/main_spi.c
+++ b/cpukit/libmisc/shell/main_spi.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/shell-wait-for-input.c b/cpukit/libmisc/shell/shell-wait-for-input.c
index db1387baf3..60d6ea4225 100644
--- a/cpukit/libmisc/shell/shell-wait-for-input.c
+++ b/cpukit/libmisc/shell/shell-wait-for-input.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2011 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index 64f90be121..9cefc80255 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -1,6 +1,6 @@
/**
* @file
- *
+ *
* @brief Instantatiate a new terminal shell.
*/
@@ -805,6 +805,183 @@ void rtems_shell_print_env(
}
#endif
+/*
+ * Wait for the string to return or timeout.
+ */
+static bool rtems_shell_term_wait_for(const int fd, const char* str, const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ while (msec-- > 0 && str[i] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ if (ch[0] != str[i++]) {
+ return false;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Buffer a string up to the end string
+ */
+static int rtems_shell_term_buffer_until(const int fd,
+ char* buf,
+ const int size,
+ const char* end,
+ const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ int e = 0;
+ memset(&buf[0], 0, size);
+ while (msec-- > 0 && i < size && end[e] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ buf[i++] = ch[0];
+ if (ch[0] == end[e]) {
+ e++;
+ } else {
+ e = 0;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0 || end[e] != '\0') {
+ return -1;
+ }
+ i -= e;
+ if (i < size) {
+ buf[i] = '\0';
+ }
+ return i;
+}
+
+/*
+ * Determine if the terminal has the row and column values
+ * swapped
+ *
+ * https://github.com/tmux/tmux/issues/3457
+ *
+ * Tmux has a bug where the lines and cols are swapped. There is a lag
+ * in the time it takes to get the fix into code so see if tmux is
+ * running and which version and work around the bug.
+ *
+ * The terminal device needs to have VMIN=0, and VTIME=0
+ */
+static bool rtems_shell_term_row_column_swapped(const int fd, const int timeout) {
+ char buf[64];
+ memset(&buf[0], 0, sizeof(buf));
+ /*
+ * CSI > Ps q
+ * Ps = 0 => DCS > | text ST
+ */
+ fputs("\033[>0q", stdout);
+ fflush(stdout);
+ if (rtems_shell_term_wait_for(fd, "\033P>|", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "\033\\", timeout);
+ if (len > 0) {
+ if (memcmp(buf, "tmux ", 5) == 0) {
+ static const char* bad_versions[] = {
+ "3.2", "3.2a", "3.3", "3.3a"
+ };
+ size_t i;
+ for (i = 0; i < RTEMS_ARRAY_SIZE(bad_versions); ++i) {
+ if (strcmp(bad_versions[i], buf + 5) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ * Direct method to get the size of an XTERM window.
+ *
+ * If you do not use an XTERM the env variables are not define.
+ */
+static void rtems_shell_winsize( void )
+{
+ const int fd = fileno(stdin);
+ struct winsize ws;
+ const int timeout = 150;
+ char buf[64];
+ bool ok = false;
+ int lines = 0;
+ int cols = 0;
+ int r;
+ r = ioctl(fd, TIOCGWINSZ, &ws);
+ if (r == 0) {
+ ok = true;
+ lines = ws.ws_row;
+ cols = ws.ws_col;
+ } else if (isatty(fd)) {
+ struct termios cterm;
+ if (tcgetattr(fd, &cterm) >= 0) {
+ struct termios term = cterm;
+ term.c_cc[VMIN] = 0;
+ term.c_cc[VTIME] = 0;
+ if (tcsetattr (fd, TCSADRAIN, &term) >= 0) {
+ memset(&buf[0], 0, sizeof(buf));
+ /*
+ * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous
+ *
+ * CSI 1 8 t
+ */
+ fputs("\033[18t", stdout);
+ fflush(stdout);
+ if (rtems_shell_term_wait_for(fd, "\033[8;", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), ";", timeout);
+ if (len > 0) {
+ int i;
+ lines = 0;
+ i = 0;
+ while (i < len) {
+ lines *= 10;
+ lines += buf[i++] - '0';
+ }
+ len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "t", timeout);
+ if (len > 0) {
+ cols = 0;
+ i = 0;
+ while (i < len) {
+ cols *= 10;
+ cols += buf[i++] - '0';
+ }
+ ok = true;
+ }
+ }
+ }
+ }
+ if (rtems_shell_term_row_column_swapped(fd, timeout)) {
+ int tmp = lines;
+ lines = cols;
+ cols = tmp;
+ }
+ tcsetattr (fd, TCSADRAIN, &cterm);
+ }
+ }
+ if (ok) {
+ snprintf(buf, sizeof(buf) - 1, "%d", lines);
+ setenv("LINES", buf, 1);
+ snprintf(buf, sizeof(buf) - 1, "%d", cols);
+ setenv("COLUMNS", buf, 1);
+ }
+}
+
static rtems_task rtems_shell_task(rtems_task_argument task_argument)
{
rtems_shell_env_t *shell_env = (rtems_shell_env_t*) task_argument;
@@ -984,7 +1161,9 @@ static bool shell_main_loop(
memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE);
if (!rtems_shell_make_args(cmd_argv, &argc, argv,
RTEMS_SHELL_MAXIMUM_ARGUMENTS)) {
- int exit_code = rtems_shell_execute_cmd(argv[0], argc, argv);
+ int exit_code;
+ rtems_shell_winsize();
+ exit_code = rtems_shell_execute_cmd(argv[0], argc, argv);
if (shell_env->exit_code != NULL)
*shell_env->exit_code = exit_code;
if (exit_code != 0 && shell_env->exit_on_error)
diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c
index 48342ce957..53b96f462c 100644
--- a/cpukit/libmisc/stackchk/check.c
+++ b/cpukit/libmisc/stackchk/check.c
@@ -413,134 +413,166 @@ static inline void *Stack_check_Find_high_water_mark(
return (void *) base;
#endif
- return (void *)0;
+ return NULL;
}
-static bool Stack_check_Dump_stack_usage(
- const Stack_Control *stack,
- const void *current,
- const char *name,
- uint32_t id,
- const rtems_printer *printer
+static void Stack_check_Visit_stack(
+ const Stack_Control *stack,
+ const void *current,
+ const char *name,
+ rtems_id id,
+ rtems_stack_checker_visitor visit,
+ void *arg
)
{
- uint32_t size;
- uint32_t used;
- void *low;
- void *high_water_mark;
+ rtems_stack_checker_info info;
/* This is likely to occur if the stack checker is not actually enabled */
if ( stack->area == NULL ) {
- return false;
+ return;
}
- low = Stack_check_Usable_stack_start(stack);
- size = Stack_check_Usable_stack_size(stack);
+ info.id = id;
+ info.name = name;
+ info.current = current;
+ info.begin = Stack_check_Usable_stack_start( stack );
+ info.size = Stack_check_Usable_stack_size( stack );
- high_water_mark = Stack_check_Find_high_water_mark(low, size);
+ if ( Stack_check_Initialized ) {
+ void *high_water_mark;
- if ( high_water_mark )
- used = Stack_check_Calculate_used( low, size, high_water_mark );
- else
- used = 0;
+ high_water_mark =
+ Stack_check_Find_high_water_mark( info.begin, info.size );
- rtems_printf(
- printer,
- "0x%08" PRIx32 " %-21s 0x%08" PRIxPTR " 0x%08" PRIxPTR " 0x%08" PRIxPTR " %6" PRId32 " ",
- id,
- name,
- (uintptr_t) stack->area,
- (uintptr_t) stack->area + (uintptr_t) stack->size - 1,
- (uintptr_t) current,
- size
- );
-
- if (Stack_check_Initialized) {
- rtems_printf( printer, "%6" PRId32 "\n", used );
+ if ( high_water_mark != NULL ) {
+ info.used =
+ Stack_check_Calculate_used( info.begin, info.size, high_water_mark );
+ } else {
+ info.used = 0;
+ }
} else {
- rtems_printf( printer, "N/A\n" );
+ info.used = UINTPTR_MAX;
}
- return false;
+ ( *visit )( &info, arg );
}
-static bool Stack_check_Dump_threads_usage(
+typedef struct {
+ rtems_stack_checker_visitor visit;
+ void *arg;
+} Stack_check_Visitor;
+
+static bool Stack_check_Visit_thread(
Thread_Control *the_thread,
void *arg
)
{
+ Stack_check_Visitor *visitor;
char name[ 22 ];
- const rtems_printer *printer;
uintptr_t sp = _CPU_Context_Get_SP( &the_thread->Registers );
- printer = arg;
+ visitor = arg;
_Thread_Get_name( the_thread, name, sizeof( name ) );
- Stack_check_Dump_stack_usage(
+ Stack_check_Visit_stack(
&the_thread->Start.Initial_stack,
(void *) sp,
name,
the_thread->Object.id,
- printer
+ visitor->visit,
+ visitor->arg
);
return false;
}
-static void Stack_check_Dump_interrupt_stack_usage(
- const Stack_Control *stack,
- uint32_t id,
- const rtems_printer *printer
+static void Stack_check_Visit_interrupt_stack(
+ const Stack_Control *stack,
+ uint32_t id,
+ rtems_stack_checker_visitor visit,
+ void *arg
)
{
- Stack_check_Dump_stack_usage(
+ Stack_check_Visit_stack(
stack,
NULL,
"Interrupt Stack",
id,
- printer
+ visit,
+ arg
);
}
-/*
- * rtems_stack_checker_report_usage
- */
+static void Stack_check_Print_info(
+ const rtems_stack_checker_info *info,
+ void *arg
+)
+{
+ const rtems_printer *printer;
+
+ printer = arg;
+
+ rtems_printf(
+ printer,
+ "0x%08" PRIx32 " %-21s 0x%08" PRIxPTR " 0x%08" PRIxPTR " 0x%08" PRIxPTR " %6" PRIuPTR " ",
+ info->id,
+ info->name,
+ (uintptr_t) info->begin,
+ (uintptr_t) info->begin + info->size - 1,
+ (uintptr_t) info->current,
+ info->size
+ );
+
+ if ( info->used != UINTPTR_MAX ) {
+ rtems_printf( printer, "%6" PRIuPTR "\n", info->used );
+ } else {
+ rtems_printf( printer, "N/A\n" );
+ }
+}
void rtems_stack_checker_report_usage_with_plugin(
const rtems_printer* printer
)
{
- uint32_t cpu_max;
- uint32_t cpu_index;
-
rtems_printf(
printer,
" STACK USAGE BY THREAD\n"
"ID NAME LOW HIGH CURRENT AVAIL USED\n"
);
- /* iterate over all threads and dump the usage */
- rtems_task_iterate(
- Stack_check_Dump_threads_usage,
+ rtems_stack_checker_iterate(
+ Stack_check_Print_info,
RTEMS_DECONST( rtems_printer *, printer )
);
+}
+
+void rtems_stack_checker_report_usage( void )
+{
+ rtems_printer printer;
+ rtems_print_printer_printk(&printer);
+ rtems_stack_checker_report_usage_with_plugin( &printer );
+}
+
+void rtems_stack_checker_iterate( rtems_stack_checker_visitor visit, void *arg )
+{
+ Stack_check_Visitor visitor;
+ uint32_t cpu_max;
+ uint32_t cpu_index;
+
+ visitor.visit = visit;
+ visitor.arg = arg;
+ rtems_task_iterate( Stack_check_Visit_thread, &visitor );
cpu_max = rtems_scheduler_get_processor_maximum();
for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
- Stack_check_Dump_interrupt_stack_usage(
+ Stack_check_Visit_interrupt_stack(
&Stack_check_Interrupt_stack[ cpu_index ],
cpu_index,
- printer
+ visit,
+ arg
);
}
}
-void rtems_stack_checker_report_usage( void )
-{
- rtems_printer printer;
- rtems_print_printer_printk(&printer);
- rtems_stack_checker_report_usage_with_plugin( &printer );
-}
-
static void Stack_check_Prepare_interrupt_stacks( void )
{
Stack_Control stack;
diff --git a/cpukit/libmisc/untar/untar_tgz.c b/cpukit/libmisc/untar/untar_tgz.c
index 5298b871dc..d2612fd566 100644
--- a/cpukit/libmisc/untar/untar_tgz.c
+++ b/cpukit/libmisc/untar/untar_tgz.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/uuid/gen_uuid.c b/cpukit/libmisc/uuid/gen_uuid.c
index 71b8a569bb..5601c887c9 100644
--- a/cpukit/libmisc/uuid/gen_uuid.c
+++ b/cpukit/libmisc/uuid/gen_uuid.c
@@ -171,7 +171,12 @@ static int get_random_fd(void)
fcntl(fd, F_SETFD, i | FD_CLOEXEC);
}
#endif
+#ifdef __rtems__
+ srand((((time_t)getpid()) << ((sizeof(pid_t)*CHAR_BIT)>>1)) ^ getuid()
+ ^ tv.tv_sec ^ tv.tv_usec);
+#else
srand((getpid() << ((sizeof(pid_t)*CHAR_BIT)>>1)) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+#endif
#ifdef DO_JRAND_MIX
jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
@@ -343,11 +348,17 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
state_fd = open("/var/lib/libuuid/clock.txt",
O_RDWR|O_CREAT, 0660);
(void) umask(save_umask);
+#ifdef __rtems__
+ if (state_fd >= 0) {
+#endif
state_f = fdopen(state_fd, "r+");
if (!state_f) {
close(state_fd);
state_fd = -1;
}
+#ifdef __rtems__
+ }
+#endif
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;