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

📄 device.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  This file is part of the program psim.    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>    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.     */#ifndef _DEVICE_C_#define _DEVICE_C_#include <stdio.h>#include "device_table.h"#include "cap.h"#include "events.h"#include "psim.h"#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif#include <ctype.h>STATIC_INLINE_DEVICE (void) clean_device_properties(device *);/* property entries */typedef struct _device_property_entry device_property_entry;struct _device_property_entry {  device_property_entry *next;  device_property *value;  const void *init_array;  unsigned sizeof_init_array;};/* Interrupt edges */typedef struct _device_interrupt_edge device_interrupt_edge;struct _device_interrupt_edge {  int my_port;  device *dest;  int dest_port;  device_interrupt_edge *next;  object_disposition disposition;};STATIC_INLINE_DEVICE\(void)attach_device_interrupt_edge(device_interrupt_edge **list,			     int my_port,			     device *dest,			     int dest_port,			     object_disposition disposition){  device_interrupt_edge *new_edge = ZALLOC(device_interrupt_edge);  new_edge->my_port = my_port;  new_edge->dest = dest;  new_edge->dest_port = dest_port;  new_edge->next = *list;  new_edge->disposition = disposition;  *list = new_edge;}STATIC_INLINE_DEVICE\(void)detach_device_interrupt_edge(device *me,			     device_interrupt_edge **list,			     int my_port,			     device *dest,			     int dest_port){  while (*list != NULL) {    device_interrupt_edge *old_edge = *list;    if (old_edge->dest == dest	&& old_edge->dest_port == dest_port	&& old_edge->my_port == my_port) {      if (old_edge->disposition == permenant_object)	device_error(me, "attempt to delete permenant interrupt");      *list = old_edge->next;      zfree(old_edge);      return;    }  }  device_error(me, "attempt to delete unattached interrupt");}STATIC_INLINE_DEVICE\(void)clean_device_interrupt_edges(device_interrupt_edge **list){  while (*list != NULL) {    device_interrupt_edge *old_edge = *list;    switch (old_edge->disposition) {    case permenant_object:      list = &old_edge->next;      break;    case tempoary_object:      *list = old_edge->next;      zfree(old_edge);      break;    }  }}/* A device */struct _device {  /* my name is ... */  const char *name;  device_unit unit_address;  const char *path;  int nr_address_cells;  int nr_size_cells;  /* device tree */  device *parent;  device *children;  device *sibling;  /* its template methods */  void *data; /* device specific data */  const device_callbacks *callback;  /* device properties */  device_property_entry *properties;  /* interrupts */  device_interrupt_edge *interrupt_destinations;  /* any open instances of this device */  device_instance *instances;  /* the internal/external mappings and other global requirements */  cap *ihandles;  cap *phandles;  psim *system;  /* debugging */  int trace;};/* an instance of a device */struct _device_instance {  void *data;  char *args;  char *path;  const device_instance_callbacks *callback;  /* the root instance */  device *owner;  device_instance *next;  /* interposed instance */  device_instance *parent;  device_instance *child;};/* creation */STATIC_INLINE_DEVICE\(const char *)device_full_name(device *leaf,                 char *buf,                 unsigned sizeof_buf){  /* get a buffer */  char full_name[1024];  if (buf == (char*)0) {    buf = full_name;    sizeof_buf = sizeof(full_name);  }  /* construct a name */  if (leaf->parent == NULL) {    if (sizeof_buf < 1)      error("device_full_name: buffer overflow");    *buf = '\0';  }  else {    char unit[1024];    device_full_name(leaf->parent, buf, sizeof_buf);    if (leaf->parent != NULL        && device_encode_unit(leaf->parent,                              &leaf->unit_address,                              unit+1,                              sizeof(unit)-1) > 0)      unit[0] = '@';    else      unit[0] = '\0';    if (strlen(buf) + strlen("/") + strlen(leaf->name) + strlen(unit)        >= sizeof_buf)      error("device_full_name: buffer overflow");    strcat(buf, "/");    strcat(buf, leaf->name);    strcat (buf, unit);  }    /* return it usefully */  if (buf == full_name)    buf = (char *) strdup(full_name);  return buf;}STATIC_INLINE_DEVICE\(device *)device_create_from(const char *name,		   const device_unit *unit_address,		   void *data,		   const device_callbacks *callbacks,		   device *parent){  device *new_device = ZALLOC(device);  /* insert it into the device tree */  new_device->parent = parent;  new_device->children = NULL;  if (parent != NULL) {    device **sibling = &parent->children;    while ((*sibling) != NULL)      sibling = &(*sibling)->sibling;    *sibling = new_device;  }  /* give it a name */  new_device->name = (char *) strdup(name);  new_device->unit_address = *unit_address;  new_device->path = device_full_name(new_device, NULL, 0);  /* its template */  new_device->data = data;  new_device->callback = callbacks;  /* its properties - already null */  /* interrupts - already null */  /* mappings - if needed */  if (parent == NULL) {    new_device->ihandles = cap_create(name);    new_device->phandles = cap_create(name);  }  else {    new_device->ihandles = device_root(parent)->ihandles;    new_device->phandles = device_root(parent)->phandles;  }  cap_add(new_device->phandles, new_device);  return new_device;}INLINE_DEVICE\(device *)device_create(device *parent,	      const char *base,	      const char *name,	      const char *unit_address,	      const char *args){  const device_descriptor *const *table;  for (table = device_table; *table != NULL; table++) {    const device_descriptor *descr;    for (descr = *table; descr->name != NULL; descr++) {      if (strcmp(base, descr->name) == 0) {	device_unit address = { 0 };	void *data = NULL;	if (parent != NULL)	  if (device_decode_unit(parent, unit_address, &address) < 0)	    device_error(parent, "invalid address %s for device %s",			 unit_address, name);	if (descr->creator != NULL)	  data = descr->creator(name, &address, args);	return device_create_from(name, &address, data,				  descr->callbacks, parent);      }    }  }  device_error(parent, "attempt to attach unknown device %s", name);  return NULL;}INLINE_DEVICE\(void)device_usage(int verbose){  const device_descriptor *const *table;  if (verbose == 1) {    int pos = 0;    for (table = device_table; *table != NULL; table++) {      const device_descriptor *descr;      for (descr = *table; descr->name != NULL; descr++) {	pos += strlen(descr->name) + 2;	if (pos > 75) {	  pos = strlen(descr->name) + 2;	  printf_filtered("\n");	}	printf_filtered("  %s", descr->name);      }      printf_filtered("\n");    }  }  if (verbose > 1) {    for (table = device_table; *table != NULL; table++) {      const device_descriptor *descr;      for (descr = *table; descr->name != NULL; descr++) {	printf_filtered("  %s:\n", descr->name);	/* interrupt ports */	if (descr->callbacks->interrupt.ports != NULL) {	  const device_interrupt_port_descriptor *ports =	    descr->callbacks->interrupt.ports;	  printf_filtered("    interrupt ports:");	  while (ports->name != NULL) {	    printf_filtered(" %s", ports->name);	    ports++;	  }	  printf_filtered("\n");	}	/* general info */	if (descr->callbacks->usage != NULL)	  descr->callbacks->usage(verbose);      }    }  }} /* Device node: */INLINE_DEVICE\(device *)device_parent(device *me){  return me->parent;}INLINE_DEVICE\(device *)device_root(device *me){  ASSERT(me != NULL);  while (me->parent != NULL)    me = me->parent;  return me;}INLINE_DEVICE\(device *)device_sibling(device *me){  return me->sibling;}INLINE_DEVICE\(device *)device_child(device *me){  return me->children;}INLINE_DEVICE\(const char *)device_name(device *me){  return me->name;}INLINE_DEVICE\(const char *)device_path(device *me){  return me->path;}INLINE_DEVICE\(void *)device_data(device *me){  return me->data;}INLINE_DEVICE\(psim *)device_system(device *me){  return me->system;}INLINE_DEVICE\(const device_unit *)device_unit_address(device *me){  return &me->unit_address;}INLINE_DEVICE\(int)device_address_to_attach_address(device *me,				 const device_unit *address,				 int *attach_space,				 unsigned_word *attach_address,				 device *client){  if (me->callback->convert.address_to_attach_address == NULL)    device_error(me, "no convert.address_to_attach_address method");  return me->callback->convert.address_to_attach_address(me, address, attach_space, attach_address, client);}INLINE_DEVICE\(int)device_size_to_attach_size(device *me,			   const device_unit *size,			   unsigned *nr_bytes,			   device *client){  if (me->callback->convert.size_to_attach_size == NULL)    device_error(me, "no convert.size_to_attach_size method");  return me->callback->convert.size_to_attach_size(me, size, nr_bytes, client);}INLINE_DEVICE\(int)device_decode_unit(device *bus,		   const char *unit,		   device_unit *address){  if (bus->callback->convert.decode_unit == NULL)    device_error(bus, "no convert.decode_unit method");  return bus->callback->convert.decode_unit(bus, unit, address);}INLINE_DEVICE\(int)device_encode_unit(device *bus,		   const device_unit *unit_address,		   char *buf,		   int sizeof_buf){  if (bus->callback->convert.encode_unit == NULL)    device_error(bus, "no convert.encode_unit method");  return bus->callback->convert.encode_unit(bus, unit_address, buf, sizeof_buf);}INLINE_DEVICE\(unsigned)device_nr_address_cells(device *me){  if (me->nr_address_cells == 0) {    if (device_find_property(me, "#address-cells") != NULL)      me->nr_address_cells = device_find_integer_property(me, "#address-cells");    else      me->nr_address_cells = 2;  }  return me->nr_address_cells;}INLINE_DEVICE\(unsigned)device_nr_size_cells(device *me){  if (me->nr_size_cells == 0) {    if (device_find_property(me, "#size-cells") != NULL)      me->nr_size_cells = device_find_integer_property(me, "#size-cells");    else      me->nr_size_cells = 1;

⌨️ 快捷键说明

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