/* * qemu user main * * Copyright (c) 2003 Fabrice Bellard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include "qemu.h" #define DEBUG_LOGFILE "/tmp/qemu.log" #ifdef __APPLE__ #include # define environ (*_NSGetEnviron()) #endif static const char *interp_prefix = CONFIG_QEMU_PREFIX; #if defined(__i386__) && !defined(CONFIG_STATIC) /* Force usage of an ELF interpreter even if it is an ELF shared object ! */ const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; #endif /* for recent libc, we add these dummy symbols which are not declared when generating a linked object (bug in ld ?) */ #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC) long __preinit_array_start[0]; long __preinit_array_end[0]; long __init_array_start[0]; long __init_array_end[0]; long __fini_array_start[0]; long __fini_array_end[0]; #endif /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example by remapping the process stack directly at the right place */ unsigned long x86_stack_size = 512 * 1024; void gemu_log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } /* timers for rdtsc */ #if defined(__i386__) int64_t cpu_get_real_ticks(void) { int64_t val; asm volatile ("rdtsc" : "=A" (val)); return val; } #elif defined(__x86_64__) int64_t cpu_get_real_ticks(void) { uint32_t low,high; int64_t val; asm volatile("rdtsc" : "=a" (low), "=d" (high)); val = high; val <<= 32; val |= low; return val; } #else static uint64_t emu_time; int64_t cpu_get_real_ticks(void) { return emu_time++; } #endif #ifdef TARGET_I386 /***********************************************************/ /* CPUX86 core interface */ uint64_t cpu_get_tsc(CPUX86State *env) { return cpu_get_real_ticks(); } void cpu_loop() { } #endif void usage(void) { printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n" "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n" "Linux CPU emulator (compiled for %s emulation)\n" "\n" "-h print this help\n" "-L path set the elf interpreter prefix (default=%s)\n" "-s size set the stack size in bytes (default=%ld)\n" "\n" "debug options:\n" #ifdef USE_CODE_COPY "-no-code-copy disable code copy acceleration\n" #endif "-l options activate log (logfile=%s)\n" "-p xen port number\n", "-d xen domain id\n", TARGET_ARCH, interp_prefix, x86_stack_size, DEBUG_LOGFILE); _exit(1); } /* XXX: currently only used for async signals (see signal.c) */ CPUState *global_env; /* used only if single thread */ CPUState *cpu_single_env = NULL; /* used to free thread contexts */ TaskState *first_task_state; int main(int argc, char **argv) { const char *filename; struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; TaskState ts1, *ts = &ts1; CPUState *env; int optind; const char *r; if (argc <= 1) usage(); /* init debug */ cpu_set_log_filename(DEBUG_LOGFILE); cpu_set_log(0); optind = 1; for(;;) { if (optind >= argc) break; r = argv[optind]; if (r[0] != '-') break; optind++; r++; if (!strcmp(r, "-")) { break; } else if (!strcmp(r, "l")) { int mask; CPULogItem *item; if (optind >= argc) break; r = argv[optind++]; mask = cpu_str_to_log_mask(r); if (!mask) { printf("Log items (comma separated):\n"); for(item = cpu_log_items; item->mask != 0; item++) { printf("%-10s %s\n", item->name, item->help); } exit(1); } cpu_set_log(mask); } else if (!strcmp(r, "s")) { r = argv[optind++]; x86_stack_size = strtol(r, (char **)&r, 0); if (x86_stack_size <= 0) usage(); if (*r == 'M') x86_stack_size *= 1024 * 1024; else if (*r == 'k' || *r == 'K') x86_stack_size *= 1024; } else if (!strcmp(r, "L")) { interp_prefix = argv[optind++]; } else if (!strcmp(r, "p")) { qemu_host_page_size = atoi(argv[optind++]); if (qemu_host_page_size == 0 || (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { fprintf(stderr, "page size must be a power of two\n"); exit(1); } } else #ifdef USE_CODE_COPY if (!strcmp(r, "no-code-copy")) { code_copy_enabled = 0; } else #endif { usage(); } } if (optind >= argc) usage(); filename = argv[optind]; /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); /* Zero out image_info */ memset(info, 0, sizeof(struct image_info)); /* Scan interp_prefix dir for replacement files. */ init_paths(interp_prefix); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(); global_env = env; /* build Task State */ memset(ts, 0, sizeof(TaskState)); env->opaque = ts; ts->used = 1; env->user_mode_only = 1; cpu_loop(env); /* never exits */ return 0; } 8'>108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
/*
   Concepts and parts of this file have been contributed by Uladzimir Pylinsky
   aka barthess.
 */

/**
 * @file    hal_i2c.h
 * @brief   I2C Driver macros and structures.
 *
 * @addtogroup I2C
 * @{
 */

#ifndef HAL_I2C_H
#define HAL_I2C_H

#if (HAL_USE_I2C == TRUE) || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver constants.                                                         */
/*===========================================================================*/

/* TODO: To be reviewed, too STM32-centric.*/
/**
 * @name    I2C bus error conditions
 * @{
 */
#define I2C_NO_ERROR               0x00    /**< @brief No error.            */
#define I2C_BUS_ERROR              0x01    /**< @brief Bus Error.           */
#define I2C_ARBITRATION_LOST       0x02    /**< @brief Arbitration Lost.    */
#define I2C_ACK_FAILURE            0x04    /**< @brief Acknowledge Failure. */
#define I2C_OVERRUN                0x08    /**< @brief Overrun/Underrun.    */
#define I2C_PEC_ERROR              0x10    /**< @brief PEC Error in
                                                reception.                  */
#define I2C_TIMEOUT                0x20    /**< @brief Hardware timeout.    */
#define I2C_SMB_ALERT              0x40    /**< @brief SMBus Alert.         */
/** @} */

/*===========================================================================*/
/* Driver pre-compile time settings.                                         */
/*===========================================================================*/

/**
 * @brief   Enables the mutual exclusion APIs on the I2C bus.
 */
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION    TRUE
#endif

/*===========================================================================*/
/* Derived constants and error checks.                                       */
/*===========================================================================*/

/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/**
 * @brief   Driver state machine possible states.
 */
typedef enum {
  I2C_UNINIT = 0,                           /**< Not initialized.           */
  I2C_STOP = 1,                             /**< Stopped.                   */
  I2C_READY = 2,                            /**< Ready.                     */
  I2C_ACTIVE_TX = 3,                        /**< Transmitting.              */
  I2C_ACTIVE_RX = 4,                        /**< Receiving.                 */
  I2C_LOCKED = 5                            /**> Bus or driver locked.      */
} i2cstate_t;

#include "hal_i2c_lld.h"

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/**
 * @brief   Wakes up the waiting thread notifying no errors.
 *
 * @param[in] i2cp      pointer to the @p I2CDriver object
 *
 * @notapi
 */
#define _i2c_wakeup_isr(i2cp) do {                                          \
  osalSysLockFromISR();                                                     \
  osalThreadResumeI(&(i2cp)->thread, MSG_OK);                               \
  osalSysUnlockFromISR();                                                   \
} while(0)

/**
 * @brief   Wakes up the waiting thread notifying errors.
 *
 * @param[in] i2cp      pointer to the @p I2CDriver object
 *
 * @notapi
 */
#define _i2c_wakeup_error_isr(i2cp) do {                                    \
  osalSysLockFromISR();                                                     \
  osalThreadResumeI(&(i2cp)->thread, MSG_RESET);                            \
  osalSysUnlockFromISR();                                                   \
} while(0)

/**
 * @brief   Wrap i2cMasterTransmitTimeout function with TIME_INFINITE timeout.
 * @api
 */
#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes)       \
  (i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes,     \
                            TIME_INFINITE))

/**
 * @brief   Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout.
 * @api
 */
#define i2cMasterReceive(i2cp, addr, rxbuf, rxbytes)                        \
  (i2cMasterReceiveTimeout(i2cp, addr, rxbuf, rxbytes, TIME_INFINITE))

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#ifdef __cplusplus
extern "C" {
#endif
  void i2cInit(void);
  void i2cObjectInit(I2CDriver *i2cp);
  void i2cStart(I2CDriver *i2cp, const I2CConfig *config);
  void i2cStop(I2CDriver *i2cp);
  i2cflags_t i2cGetErrors(I2CDriver *i2cp);
  msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp,
                                 i2caddr_t addr,
                                 const uint8_t *txbuf, size_t txbytes,
                                 uint8_t *rxbuf, size_t rxbytes,
                                 sysinterval_t timeout);
  msg_t i2cMasterReceiveTimeout(I2CDriver *i2cp,
                                i2caddr_t addr,
                                uint8_t *rxbuf, size_t rxbytes,
                                sysinterval_t timeout);
#if I2C_USE_MUTUAL_EXCLUSION == TRUE
  void i2cAcquireBus(I2CDriver *i2cp);
  void i2cReleaseBus(I2CDriver *i2cp);
#endif

#ifdef __cplusplus
}
#endif

#endif /* HAL_USE_I2C == TRUE */

#endif /* HAL_I2C_H */

/** @} */