⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dv-m68hc11sio.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  dv-m68hc11sio.c -- Simulation of the 68HC11 serial device.    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.    Written by Stephane Carrez (stcarrez@worldnet.fr)    (From a driver model Contributed by Cygnus Solutions.)    This file is part of the program GDB, the GNU debugger.        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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        */#include "sim-main.h"#include "hw-main.h"#include "dv-sockser.h"#include "sim-assert.h"/* DEVICE        m68hc11sio - m68hc11 serial I/O      DESCRIPTION        Implements the m68hc11 serial I/O controller described in the m68hc11        user guide. The serial I/O controller is directly connected to the CPU        interrupt. The simulator implements:            - baud rate emulation            - 8-bits transfers       PROPERTIES   backend {tcp | stdio}        Use dv-sockser TCP-port backend or stdio for backend.  Default: stdio.      PORTS   reset (input)        Reset port. This port is only used to simulate a reset of the serial        I/O controller. It should be connected to the RESET output of the cpu.   *//* port ID's */enum{  RESET_PORT};static const struct hw_port_descriptor m68hc11sio_ports[] = {  { "reset", RESET_PORT, 0, input_port, },  { NULL, },};/* Serial Controller information.  */struct m68hc11sio {  enum {sio_tcp, sio_stdio} backend; /* backend */  /* Number of cpu cycles to send a bit on the wire.  */  unsigned long baud_cycle;  /* Length in bits of characters sent, this includes the     start/stop and parity bits.  Together with baud_cycle, this     is used to find the number of cpu cycles to send/receive a data.  */  unsigned int  data_length;  /* Information about next character to be transmited.  */  unsigned char tx_has_char;  unsigned char tx_char;  unsigned char rx_char;  unsigned char rx_clear_scsr;    /* Periodic I/O polling.  */  struct hw_event* tx_poll_event;  struct hw_event* rx_poll_event;};/* Finish off the partially created hw device.  Attach our local   callbacks.  Wire up our port names etc.  */static hw_io_read_buffer_method m68hc11sio_io_read_buffer;static hw_io_write_buffer_method m68hc11sio_io_write_buffer;static hw_port_event_method m68hc11sio_port_event;static hw_ioctl_method m68hc11sio_ioctl;#define M6811_SCI_FIRST_REG (M6811_BAUD)#define M6811_SCI_LAST_REG  (M6811_SCDR)static voidattach_m68hc11sio_regs (struct hw *me,                        struct m68hc11sio *controller){  hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,                     M6811_SCI_FIRST_REG,                     M6811_SCI_LAST_REG - M6811_SCI_FIRST_REG + 1,		     me);  if (hw_find_property(me, "backend") != NULL)    {      const char *value = hw_find_string_property(me, "backend");      if(! strcmp(value, "tcp"))	controller->backend = sio_tcp;      else if(! strcmp(value, "stdio"))	controller->backend = sio_stdio;      else	hw_abort (me, "illegal value for backend parameter `%s':"                  "use tcp or stdio", value);    }}static voidm68hc11sio_finish (struct hw *me){  struct m68hc11sio *controller;  controller = HW_ZALLOC (me, struct m68hc11sio);  set_hw_data (me, controller);  set_hw_io_read_buffer (me, m68hc11sio_io_read_buffer);  set_hw_io_write_buffer (me, m68hc11sio_io_write_buffer);  set_hw_ports (me, m68hc11sio_ports);  set_hw_port_event (me, m68hc11sio_port_event);#ifdef set_hw_ioctl  set_hw_ioctl (me, m68hc11sio_ioctl);#else  me->to_ioctl = m68hc11sio_ioctl;#endif  /* Preset defaults.  */  controller->backend = sio_stdio;  /* Attach ourself to our parent bus.  */  attach_m68hc11sio_regs (me, controller);  /* Initialize to reset state.  */  controller->tx_poll_event = NULL;  controller->rx_poll_event = NULL;  controller->tx_char       = 0;  controller->tx_has_char   = 0;  controller->rx_clear_scsr = 0;  controller->rx_char       = 0;}/* An event arrives on an interrupt port.  */static voidm68hc11sio_port_event (struct hw *me,                       int my_port,                       struct hw *source,                       int source_port,                       int level){  SIM_DESC sd;  struct m68hc11sio *controller;  sim_cpu *cpu;  unsigned8 val;    controller = hw_data (me);  sd         = hw_system (me);  cpu        = STATE_CPU (sd, 0);    switch (my_port)    {    case RESET_PORT:      {	HW_TRACE ((me, "SCI reset"));        /* Reset the state of SCI registers.  */        val = 0;        m68hc11sio_io_write_buffer (me, &val, io_map,                                    (unsigned_word) M6811_BAUD, 1);        m68hc11sio_io_write_buffer (me, &val, io_map,                                    (unsigned_word) M6811_SCCR1, 1);        m68hc11sio_io_write_buffer (me, &val, io_map,                                    (unsigned_word) M6811_SCCR2, 1);                cpu->ios[M6811_SCSR]    = M6811_TC | M6811_TDRE;        controller->rx_char     = 0;        controller->tx_char     = 0;        controller->tx_has_char = 0;        controller->rx_clear_scsr = 0;        if (controller->rx_poll_event)          {            hw_event_queue_deschedule (me, controller->rx_poll_event);            controller->rx_poll_event = 0;          }        if (controller->tx_poll_event)          {            hw_event_queue_deschedule (me, controller->tx_poll_event);            controller->tx_poll_event = 0;          }        /* In bootstrap mode, initialize the SCI to 1200 bauds to           simulate some initial setup by the internal rom.  */        if (((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA)) == M6811_SMOD)          {            unsigned char val = 0x33;                        m68hc11sio_io_write_buffer (me, &val, io_map,                                        (unsigned_word) M6811_BAUD, 1);            val = 0x12;            m68hc11sio_io_write_buffer (me, &val, io_map,                                        (unsigned_word) M6811_SCCR2, 1);          }        break;      }    default:      hw_abort (me, "Event on unknown port %d", my_port);      break;    }}voidm68hc11sio_rx_poll (struct hw *me, void *data){  SIM_DESC sd;  struct m68hc11sio *controller;  sim_cpu *cpu;  char cc;  int cnt;  int check_interrupt = 0;    controller = hw_data (me);  sd         = hw_system (me);  cpu        = STATE_CPU (sd, 0);  switch (controller->backend)    {    case sio_tcp:      cnt = dv_sockser_read (sd);      if (cnt != -1)        {          cc = (char) cnt;          cnt = 1;        }      break;    case sio_stdio:      cnt = sim_io_poll_read (sd, 0 /* stdin */, &cc, 1);      break;    default:      cnt = 0;      break;    }  if (cnt == 1)    {      /* Raise the overrun flag if the previous character was not read.  */      if (cpu->ios[M6811_SCSR] & M6811_RDRF)        cpu->ios[M6811_SCSR] |= M6811_OR;      cpu->ios[M6811_SCSR]     |= M6811_RDRF;      controller->rx_char       = cc;      controller->rx_clear_scsr = 0;      check_interrupt = 1;    }  else    {      /* handle idle line detect here.  */      ;    }  if (controller->rx_poll_event)    {      hw_event_queue_deschedule (me, controller->rx_poll_event);      controller->rx_poll_event = 0;    }  if (cpu->ios[M6811_SCCR2] & M6811_RE)    {      unsigned long clock_cycle;      /* Compute CPU clock cycles to wait for the next character.  */      clock_cycle = controller->data_length * controller->baud_cycle;      controller->rx_poll_event = hw_event_queue_schedule (me, clock_cycle,                                                           m68hc11sio_rx_poll,                                                           NULL);    }  if (check_interrupt)      interrupts_update_pending (&cpu->cpu_interrupts);}voidm68hc11sio_tx_poll (struct hw *me, void *data){  SIM_DESC sd;  struct m68hc11sio *controller;  sim_cpu *cpu;    controller = hw_data (me);  sd         = hw_system (me);  cpu        = STATE_CPU (sd, 0);  cpu->ios[M6811_SCSR] |= M6811_TDRE;  cpu->ios[M6811_SCSR] |= M6811_TC;    /* Transmitter is enabled and we have something to send.  */  if ((cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -