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

📄 emul_chirp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  This file is part of the program psim.    Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney    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 _EMUL_CHIRP_C_#define _EMUL_CHIRP_C_/* Note: this module is called via a table.  There is no benefit in   making it inline */#include "emul_generic.h"#include "emul_chirp.h"#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifndef STATIC_INLINE_EMUL_CHIRP#define STATIC_INLINE_EMUL_CHIRP STATIC_INLINE#endif/* EMULATION   OpenFirmware - IEEE Standard for Boot (Initialization   Configuration) Firmware.   DESCRIPTION   BUGS      This code assumes that the memory node has #address-cells and   #size-cells set to one.  For future implementations, this may not   be the case.   *//* Descriptor of the open boot services being emulated */typedef int (chirp_handler)     (os_emul_data *data,      cpu *processor,      unsigned_word cia);typedef struct _chirp_services {  const char *name;  chirp_handler *handler;} chirp_services;/* The OpenBoot emulation is, at any time either waiting for a client   request or waiting on a client callback */typedef enum {  serving,  emulating,  faulting,} chirp_emul_state;struct _os_emul_data {  chirp_emul_state state;  unsigned_word return_address;  unsigned_word arguments;  unsigned_word n_args;  unsigned_word n_returns;  chirp_services *service;  device *root;  chirp_services *services;  /* configuration */  unsigned_word memory_size;  unsigned_word real_base;  unsigned_word real_size;  unsigned_word virt_base;  unsigned_word virt_size;  int real_mode;  int little_endian;  int floating_point_available;  int interrupt_prefix;  unsigned_word load_base;  /* hash table */  unsigned_word nr_page_table_entry_groups;  unsigned_word htab_offset;  unsigned_word htab_ra;  unsigned_word htab_va;  unsigned_word sizeof_htab;  /* virtual address of htab */  unsigned_word stack_offset;  unsigned_word stack_ra;  unsigned_word stack_va;  unsigned_word sizeof_stack;  /* addresses of emulation instructions virtual/real */  unsigned_word code_offset;  unsigned_word code_va;  unsigned_word code_ra;  unsigned_word sizeof_code;  unsigned_word code_client_va;  unsigned_word code_client_ra;  unsigned_word code_callback_va;  unsigned_word code_callback_ra;  unsigned_word code_loop_va;  unsigned_word code_loop_ra;};/* returns the name of the corresponding Ihandle */static const char *ihandle_name(device_instance *ihandle){  if (ihandle == NULL)    return "";  else    return device_name(device_instance_device(ihandle));}/* Read/write the argument list making certain that all values are   converted to/from host byte order.   In the below only n_args+n_returns is read/written */static intchirp_read_t2h_args(void *args,		    int sizeof_args,		    int n_args,		    int n_returns,		    os_emul_data *data,		    cpu *processor,		    unsigned_word cia){  unsigned_cell *words;  int i;  /* check against the number of arguments specified by the client     program */  if ((n_args >= 0 && data->n_args != n_args)      || (n_returns >= 0 && data->n_returns != n_returns)) {    TRACE(trace_os_emul, ("%s - invalid nr of args - n_args=%ld, n_returns=%ld\n",			  data->service->name,			  (long)data->n_args,			  (long)data->n_returns));    return -1;  }  /* check that there is enough space */  if (sizeof(unsigned_cell) * (data->n_args + data->n_returns) > sizeof_args)    return -1;  /* bring in the data */  memset(args, 0, sizeof_args);  emul_read_buffer(args, data->arguments + 3 * sizeof(unsigned_cell),		   sizeof(unsigned_cell) * (data->n_args + data->n_returns),		   processor, cia);  /* convert all words to host format */  words = args;  for (i = 0; i < (sizeof_args / sizeof(unsigned_cell)); i++)    words[i] = T2H_cell(words[i]);  return 0;}static voidchirp_write_h2t_args(void *args,		     int sizeof_args,		     os_emul_data *data,		     cpu *processor,		     unsigned_word cia){  int i;  unsigned_cell *words;  /* convert to target everything */  words = args;  for (i = 0; i < (sizeof_args / sizeof(unsigned_cell)); i++)    words[i] = H2T_cell(words[i]);  /* bring in the data */  emul_write_buffer(args, data->arguments + 3 * sizeof(unsigned_cell),		    sizeof(unsigned_cell) * (data->n_args + data->n_returns),		    processor, cia);}/* OpenBoot emulation functions *//* client interface */static intchirp_emul_test(os_emul_data *data,		cpu *processor,		unsigned_word cia){  struct test_args {    /*in*/    unsigned_cell name; /*string*/    /*out*/    unsigned_cell missing;  } args;  char name[32];  chirp_services *service = NULL;  /* read in the arguments */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  emul_read_string(name, args.name, sizeof(name),		   processor, cia);  TRACE(trace_os_emul, ("test - in - name=`%s'\n", name));  /* see if we know about the service */  service = data->services;  while (service->name != NULL && strcmp(service->name, name) != 0) {    service++;  }  if (service->name == NULL)    args.missing = -1;  else    args.missing = 0;  /* write the arguments back out */  TRACE(trace_os_emul, ("test - out - missing=%ld\n",			(long)args.missing));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}/* Device tree */static intchirp_emul_peer(os_emul_data *data,		cpu *processor,		unsigned_word cia){  struct peer_args {    /*in*/    unsigned_cell phandle;    /*out*/    unsigned_cell sibling_phandle;  } args;  device *phandle;  device *sibling_phandle = NULL;  /* read in the arguments */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  phandle = external_to_device(data->root, args.phandle);  TRACE(trace_os_emul, ("peer - in - phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.phandle,			(unsigned long)phandle,			(phandle == NULL ? "" : device_name(phandle))));  /* find the peer */  if (args.phandle == 0) {    sibling_phandle = data->root;    args.sibling_phandle = device_to_external(sibling_phandle);  }  else if (phandle == NULL) {    sibling_phandle = NULL;    args.sibling_phandle = -1;  }  else {    sibling_phandle = device_sibling(phandle);    if (sibling_phandle == NULL)      args.sibling_phandle = 0;    else      args.sibling_phandle = device_to_external(sibling_phandle);  }  /* write the arguments back out */  TRACE(trace_os_emul, ("peer - out - sibling_phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.sibling_phandle,			(unsigned long)sibling_phandle,			(sibling_phandle == NULL ? "" : device_name(sibling_phandle))));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_child(os_emul_data *data,		 cpu *processor,		 unsigned_word cia){  struct child_args {    /*in*/    unsigned_cell phandle;    /*out*/    unsigned_cell child_phandle;  } args;  device *phandle;  device *child_phandle;  /* read the arguments in */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  phandle = external_to_device(data->root, args.phandle);  TRACE(trace_os_emul, ("child - in - phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.phandle,			(unsigned long)phandle,			(phandle == NULL ? "" : device_name(phandle))));  /* find a child */  if (args.phandle == 0      || phandle == NULL) {    child_phandle = NULL;    args.child_phandle = -1;  }  else {    child_phandle = device_child(phandle);    if (child_phandle == NULL)      args.child_phandle = 0;    else      args.child_phandle = device_to_external(child_phandle);  }  /* write the result out */  TRACE(trace_os_emul, ("child - out - child_phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.child_phandle,			(unsigned long)child_phandle,			(child_phandle == NULL ? "" : device_name(child_phandle))));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_parent(os_emul_data *data,		  cpu *processor,		  unsigned_word cia){  struct parent_args {    /*in*/    unsigned_cell phandle;    /*out*/    unsigned_cell parent_phandle;  } args;  device *phandle;  device *parent_phandle;  /* read the args in */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  phandle = external_to_device(data->root, args.phandle);  TRACE(trace_os_emul, ("parent - in - phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.phandle,			(unsigned long)phandle,			(phandle == NULL ? "" : device_name(phandle))));  /* find a parent */  if (args.phandle == 0      || phandle == NULL) {    parent_phandle = NULL;    args.parent_phandle = -1;  }  else {    parent_phandle = device_parent(phandle);    if (parent_phandle == NULL)      args.parent_phandle = 0;    else      args.parent_phandle = device_to_external(parent_phandle);  }  /* return the result */  TRACE(trace_os_emul, ("parent - out - parent_phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.parent_phandle,			(unsigned long)parent_phandle,			(parent_phandle == NULL ? "" : device_name(parent_phandle))));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_instance_to_package(os_emul_data *data,			       cpu *processor,			       unsigned_word cia){  struct instance_to_package_args {    /*in*/    unsigned_cell ihandle;    /*out*/    unsigned_cell phandle;  } args;  device_instance *ihandle;  device *phandle = NULL;  /* read the args in */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  ihandle = external_to_device_instance(data->root, args.ihandle);  TRACE(trace_os_emul, ("instance-to-package - in - ihandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.ihandle,			(unsigned long)ihandle,			ihandle_name(ihandle)));  /* find the corresponding phandle */  if (ihandle == NULL) {    phandle = NULL;    args.phandle = -1;  }  else {    phandle = device_instance_device(ihandle);    args.phandle = device_to_external(phandle);  }  /* return the result */  TRACE(trace_os_emul, ("instance-to-package - out - phandle=0x%lx(0x%lx`%s')\n",			(unsigned long)args.phandle,			(unsigned long)phandle,			(phandle == NULL ? "" : device_name(phandle))));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_getproplen(os_emul_data *data,		      cpu *processor,		      unsigned_word cia){  struct getproplen_args {    /*in*/    unsigned_cell phandle;    unsigned_cell name;    /*out*/    unsigned_cell proplen;  } args;  char name[32];  device *phandle;  /* read the args in */  if (chirp_read_t2h_args(&args, sizeof(args), 2, 1, data, processor, cia))    return -1;  phandle = external_to_device(data->root, args.phandle);  emul_read_string(name,		   args.name,		   sizeof(name),		   processor, cia);  TRACE(trace_os_emul, ("getproplen - in - phandle=0x%lx(0x%lx`%s') name=`%s'\n",			(unsigned long)args.phandle,			(unsigned long)phandle,			(phandle == NULL ? "" : device_name(phandle)),			name));  /* find our prop and get its length */  if (args.phandle == 0      || phandle == NULL) {    args.proplen = -1;  }  else {    const device_property *prop = device_find_property(phandle, name);    if (prop == (device_property*)0) {      args.proplen = -1;    }    else {      args.proplen = prop->sizeof_array;    }  }  /* return the result */  TRACE(trace_os_emul, ("getproplen - out - proplen=%ld\n",			(unsigned long)args.proplen));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_getprop(os_emul_data *data,		   cpu *processor,		   unsigned_word cia){  struct getprop_args {    /*in*/    unsigned_cell phandle;    unsigned_cell name;    unsigned_cell buf;    unsigned_cell buflen;    /*out*/    unsigned_cell size;  } args;  char name[32];  device *phandle;  /* read in the args, the return is optional */  if (chirp_read_t2h_args(&args, sizeof(args), 4, -1, data, processor, cia))    return -1;  phandle = external_to_device(data->root, args.phandle);  emul_read_string(name,		   args.name,

⌨️ 快捷键说明

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