| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- /** @file */
- // xos_syslog.h - XOS Event logging module.
- // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be included
- // in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- // NOTE: Do not include this file directly in your application. Including
- // xos.h will automatically include this file.
- #ifndef __XOS_SYSLOG_H__
- #define __XOS_SYSLOG_H__
- #include "xos_types.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- //-----------------------------------------------------------------------------
- // The XOS system log is an array of fixed size entries. The size of the log
- // is determined by the application, and memory for the log must be provided
- // at init time. Every time the log function is called, an entry is made in
- // the log and the next pointer advanced. When the log is full, it will wrap
- // around and start overwriting the oldest entries.
- // Logging can be done from C/C++ code as well as assembly code, and at any
- // interrupt level, even from high level interrupt handlers.
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // Defines.
- //-----------------------------------------------------------------------------
- #define XOS_SYSLOG_ENABLED 0x0001
- ///----------------------------------------------------------------------------
- ///
- /// Use this macro to compute how much memory to allocate for the syslog.
- ///
- ///----------------------------------------------------------------------------
- #define XOS_SYSLOG_SIZE(num_entries) \
- ( sizeof(XosSysLog) + ((num_entries - 1) * sizeof(XosSysLogEntry)) )
- ///----------------------------------------------------------------------------
- ///
- /// System log entry structure.
- ///
- ///----------------------------------------------------------------------------
- typedef struct XosSysLogEntry {
- uint32_t timestamp; ///< Timestamp in clock cycles
- uint32_t param1; ///< User defined value
- uint32_t param2; ///< User defined value
- struct XosSysLogEntry * next; ///< Link to next entry
- } XosSysLogEntry;
- ///----------------------------------------------------------------------------
- ///
- /// System log structure.
- ///
- ///----------------------------------------------------------------------------
- typedef struct XosSysLog {
- uint16_t flags; ///< Flags
- uint16_t size; ///< Number of entries
- XosSysLogEntry * next; ///< Next write position
- XosSysLogEntry entries[1]; ///< First entry
- } XosSysLog;
- //-----------------------------------------------------------------------------
- // Pointer to syslog area.
- //-----------------------------------------------------------------------------
- extern XosSysLog * xos_syslog;
- //----------------------------------------------------------------------------
- ///
- /// Initialize the syslog. Initializing the log also enables it. The system
- /// log always wraps around when full and overwrites the oldest entries.
- ///
- /// \param log_mem Pointer to allocated memory for the log.
- ///
- /// \param num_entries The number of entries that the log can contain.
- ///
- /// \return Returns nothing.
- ///
- //----------------------------------------------------------------------------
- static inline void
- xos_syslog_init(void * log_mem, uint16_t num_entries)
- {
- uint16_t i;
- xos_syslog = (XosSysLog *) log_mem;
- xos_syslog->size = num_entries;
- xos_syslog->next = xos_syslog->entries;
- for (i = 0; i < num_entries - 1; i++) {
- xos_syslog->entries[i].next = &(xos_syslog->entries[i+1]);
- xos_syslog->entries[i].timestamp = 0;
- }
- xos_syslog->entries[i].next = xos_syslog->entries;
- xos_syslog->entries[i].timestamp = 0;
- xos_syslog->flags = XOS_SYSLOG_ENABLED;
- }
- ///----------------------------------------------------------------------------
- ///
- /// Reset the syslog. All entries made up to now are abandoned and the write
- /// pointer is set to the first entry location.
- ///
- /// No parameters.
- ///
- /// \return Returns nothing.
- ///
- ///----------------------------------------------------------------------------
- static inline void
- xos_syslog_clear()
- {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- xos_syslog_init(xos_syslog, xos_syslog->size);
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- }
- ///----------------------------------------------------------------------------
- ///
- /// Enable logging to the syslog. This function needs to be called only if
- /// logging had been previously disabled via xos_syslog_disable(), since
- /// initializing the syslog automatically enables it.
- ///
- /// No parameters.
- ///
- /// \return Returns nothing.
- ///
- ///----------------------------------------------------------------------------
- static inline void
- xos_syslog_enable()
- {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- xos_syslog->flags |= XOS_SYSLOG_ENABLED;
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- }
- ///----------------------------------------------------------------------------
- ///
- /// Disable logging to the syslog. It is sometimes useful to disable logging
- /// while the log is being examined or dumped.
- ///
- /// No parameters.
- ///
- /// \return Returns nothing.
- ///
- ///----------------------------------------------------------------------------
- static inline void
- xos_syslog_disable()
- {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- xos_syslog->flags &= ~XOS_SYSLOG_ENABLED;
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- }
- ///----------------------------------------------------------------------------
- ///
- /// Write an entry into the syslog. This function does disable all interrupts
- /// since logging can be done from interrupt handlers as well. It will write
- /// into the log only if the log exists and is enabled.
- ///
- /// \param param1 User defined value.
- ///
- /// \param param2 User defined value.
- ///
- /// \return Returns nothing.
- ///
- ///----------------------------------------------------------------------------
- static inline void
- xos_syslog_write(uint32_t param1, uint32_t param2)
- {
- if (xos_syslog != XOS_NULL) {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- if ((xos_syslog->flags & XOS_SYSLOG_ENABLED) != 0) {
- XosSysLogEntry * next = xos_syslog->next;
- next->timestamp = xos_get_ccount();
- next->param1 = param1;
- next->param2 = param2;
- xos_syslog->next = next->next;
- }
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- }
- }
- ///----------------------------------------------------------------------------
- ///
- /// Read the first (oldest) entry in the syslog. Will return an error if the
- /// log has not been created or is empty. Storage to copy the entry must be
- /// provided by the caller.
- ///
- /// \param entry Pointer to storage where the entry data will be
- /// copied. This pointer must be passed to
- /// xos_syslog_get_next().
- ///
- /// \return Returns XOS_OK on success, else error code.
- ///
- ///----------------------------------------------------------------------------
- static inline int32_t
- xos_syslog_get_first(XosSysLogEntry * entry)
- {
- if (xos_syslog == XOS_NULL) {
- return XOS_ERR_NOT_FOUND;
- }
- if (entry != XOS_NULL) {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- XosSysLogEntry * next = xos_syslog->next;
- // 'next' should be pointing to the next entry to be overwritten, if we
- // have wrapped. This means it is the oldest entry. However if this entry
- // has a zero timestamp then we have not wrapped, in which case we must
- // look at the first entry in the list.
- if (next->timestamp == 0) {
- next = xos_syslog->entries;
- }
- *entry = *next;
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- return entry->timestamp ? XOS_OK : XOS_ERR_NOT_FOUND;
- }
- return XOS_ERR_INVALID_PARAMETER;
- }
- ///----------------------------------------------------------------------------
- ///
- /// Get the next sequential entry from the syslog. This function must be called
- /// only after xos_syslog_get_first() has been called.
- ///
- /// \param entry Pointer to storage where entry data will be copied.
- /// Must be the same pointer that was passed in the call
- /// to xos_syslog_get_first(), as it is used to keep track
- /// of the current position.
- ///
- /// \return Returns XOS_OK on success, else error code.
- ///
- ///----------------------------------------------------------------------------
- static inline int32_t
- xos_syslog_get_next(XosSysLogEntry * entry)
- {
- if (entry != XOS_NULL) {
- #if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
- #endif
- XosSysLogEntry * next = entry->next;
- int32_t ret = XOS_OK;
- // Make sure we're not pointing past the last entry.
- if ((next != XOS_NULL) && (next != xos_syslog->next) && (next->timestamp != 0)) {
- *entry = *next;
- }
- else {
- ret = XOS_ERR_NOT_FOUND;
- }
- #if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
- #endif
- return ret;
- }
- return XOS_ERR_INVALID_PARAMETER;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif // __XOS_SYSLOG_H__
|