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

📄 emul_chirp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* OpenFirmware doesn't define this error */    error("chirp: invalid ihandle passed to read method");  }  else {    /* do the reads */    int actual = 0;    while (actual < args.len) {      int remaining = args.len - actual;      int to_read = (remaining <= sizeof(buf) ? remaining : sizeof(buf));      int nr_read = device_instance_read(ihandle, buf, to_read);      if (nr_read < 0) {	actual = nr_read; /* the error */	break;      }      else if (nr_read == 0) {	break;      }      emul_write_buffer(buf,			args.addr + actual,			nr_read,			processor, cia);      actual += nr_read;    }    if (actual >= 0) {      args.actual = actual;      if (actual < sizeof(buf))	buf[actual] = '\0';      else	buf[sizeof(buf) - 1] = '\0';    }    else {      switch (actual) {      case sim_io_eof:	args.actual = 0;	break;      case sim_io_not_ready:	ASSERT(sim_io_not_ready == -2);	args.actual = sim_io_not_ready;	break;      default:	error("Bad error value %ld", (long)actual);	break;      }    }  }  /* return the result */  TRACE(trace_os_emul, ("read - out - actual=%ld `%s'\n",			(long)args.actual,			((args.actual > 0 && args.actual < sizeof(buf)) ? buf : "")			));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_write(os_emul_data *data,		 cpu *processor,		 unsigned_word cia){  struct write_args {    /*in*/    unsigned_cell ihandle;    unsigned_cell addr;    unsigned_cell len;    /*out*/    unsigned_cell actual;  } args;  char buf[1024];  device_instance *ihandle;  int actual;  /* get the args */  if (chirp_read_t2h_args(&args, sizeof(args), 3, 1, data, processor, cia))    return -1;  actual = args.len;  if (actual >= sizeof(buf))    actual = sizeof(buf) - 1;  emul_read_buffer(buf,		   args.addr,		   actual,		   processor, cia);  buf[actual] = '\0';  ihandle = external_to_device_instance(data->root, args.ihandle);  TRACE(trace_os_emul, ("write - in - ihandle=0x%lx(0x%lx`%s') `%s' (%ld)\n",			(unsigned long)args.ihandle,			(unsigned long)ihandle,			ihandle_name(ihandle),			buf, (long)actual));  if (ihandle == NULL) {    /* OpenFirmware doesn't define this error */    error("chirp: invalid ihandle passed to write method");  }  else {    /* write it out */    actual = device_instance_write(ihandle, buf, actual);    if (actual < 0)      args.actual = 0;    else      args.actual = actual;  }  /* return the result */  TRACE(trace_os_emul, ("write - out - actual=%ld\n",			(long)args.actual));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_seek(os_emul_data *data,		cpu *processor,		unsigned_word cia){  struct seek_args {    /*in*/    unsigned_cell ihandle;    unsigned_cell pos_hi;    unsigned_cell pos_lo;    /*out*/    unsigned_cell status;  } args;  int status;  device_instance *ihandle;  /* get the args */  if (chirp_read_t2h_args(&args, sizeof(args), 3, 1, data, processor, cia))    return -1;  ihandle = external_to_device_instance(data->root, args.ihandle);  TRACE(trace_os_emul, ("seek - in - ihandle=0x%lx(0x%lx`%s') pos.hi=0x%lx pos.lo=0x%lx\n",			(unsigned long)args.ihandle,			(unsigned long)ihandle,			ihandle_name(ihandle),			args.pos_hi, args.pos_lo));  if (ihandle == NULL) {    /* OpenFirmware doesn't define this error */    error("chirp: invalid ihandle passed to seek method");  }  else {    /* seek it out */    status = device_instance_seek(ihandle, args.pos_hi, args.pos_lo);    args.status = status;  }  /* return the result */  TRACE(trace_os_emul, ("seek - out - status=%ld\n",			(long)args.status));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}/* memory */static intchirp_emul_claim(os_emul_data *data,		 cpu *processor,		 unsigned_word cia){  /* NOTE: the client interface claim routine is *very* different to     the "claim" method described in IEEE-1275 appendix A.  The latter     uses real addresses while this uses virtual (effective)     addresses. */  struct claim_args {    /* in */    unsigned_cell virt;    unsigned_cell size;    unsigned_cell align;    /* out */    unsigned_cell baseaddr;  } args;  /* read the args */  if (chirp_read_t2h_args(&args, sizeof(args),			  3 /*n_args*/, 1 /*n_returns*/,			  data, processor, cia))    return -1;  TRACE(trace_os_emul, ("claim - in - virt=0x%lx size=%ld align=%d\n",			(unsigned long)args.virt,			(long int)args.size,			(int)args.align));  /* use the memory device to allocate (real) memory at the requested     address */  {    device_instance *memory = tree_find_ihandle_property(data->root, "/chosen/memory");    unsigned_cell mem_in[3];    unsigned_cell mem_out[1];    mem_in[0] = args.align; /*top-of-stack*/    mem_in[1] = args.size;    mem_in[2] = args.virt;    if (device_instance_call_method(memory, "claim",				    3, mem_in, 1, mem_out) < 0)      error("chirp: claim failed to allocate memory virt=0x%lx size=%ld align=%d",	    (unsigned long)args.virt,	    (long int)args.size,	    (int)args.align);    args.baseaddr = mem_out[0];  }  /* if using virtual addresses, create a 1-1 map of this address space */  if (!data->real_mode) {    error("chirp: claim method does not support virtual mode");  }  /* return the base address */  TRACE(trace_os_emul, ("claim - out - baseaddr=0x%lx\n",			(unsigned long)args.baseaddr));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static intchirp_emul_release(os_emul_data *data,		   cpu *processor,		   unsigned_word cia){  /* NOTE: the client interface release routine is *very* different to     the "claim" method described in IEEE-1275 appendix A.  The latter     uses real addresses while this uses virtual (effective)     addresses. */  struct claim_args {    /* in */    unsigned_cell virt;    unsigned_cell size;    /* out */  } args;  /* read the args */  if (chirp_read_t2h_args(&args, sizeof(args),			  2 /*n_args*/, 0 /*n_returns*/,			  data, processor, cia))    return -1;  TRACE(trace_os_emul, ("release - in - virt=0x%lx size=%ld\n",			(unsigned long)args.virt,			(long int)args.size));  /* use the memory device to release (real) memory at the requested     address */  {    device_instance *memory = tree_find_ihandle_property(data->root, "/chosen/memory");    unsigned_cell mem_in[2];    mem_in[0] = args.size;    mem_in[1] = args.virt;    if (device_instance_call_method(memory, "release",				    2, mem_in, 0, NULL) < 0)      error("chirp: claim failed to release memory virt=0x%lx size=%ld",	    (unsigned long)args.virt,	    (long int)args.size);  }  /* if using virtual addresses, remove the 1-1 map of this address space */  if (!data->real_mode) {    error("chirp: release method does not support virtual mode");  }  /* return the base address */  TRACE(trace_os_emul, ("release - out\n"));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}/* Control transfer */static intchirp_emul_boot(os_emul_data *data,		cpu *processor,		unsigned_word cia){  /* unlike OpenFirmware this one can take an argument */  struct boot_args {    /*in*/    unsigned_cell bootspec;    /*out*/  } args;  char bootspec[1024];  /* read in the arguments */  if (chirp_read_t2h_args(&args, sizeof(args), -1, 0, data, processor, cia))    cpu_halt(processor, cia, was_exited, -1);  if (args.bootspec != 0)    emul_read_string(bootspec, args.bootspec, sizeof(bootspec),		     processor, cia);  else    strcpy(bootspec, "(null)");  TRACE(trace_os_emul, ("boot - in bootspec=`%s'\n", bootspec));  /* just report this and exit */  printf_filtered("chrp: boot %s called, exiting.\n", bootspec);  cpu_halt(processor, cia, was_exited, 0);  return 0;}static intchirp_emul_enter(os_emul_data *data,		 cpu *processor,		 unsigned_word cia){  error("chirp: enter method not implemented\n");  return 0;}static intchirp_emul_exit(os_emul_data *data,		cpu *processor,		unsigned_word cia){  /* unlike OpenBoot this one can take an argument */  struct exit_args {    /*in*/    signed_cell status;    /*out*/  } args;  if (chirp_read_t2h_args(&args, sizeof(args), -1, 0, data, processor, cia))    cpu_halt(processor, cia, was_exited, -1);  cpu_halt(processor, cia, was_exited, args.status);  return 0;}static intchirp_emul_chain(os_emul_data *data,		 cpu *processor,		 unsigned_word cia){  error("chirp: chain method not implemented\n");  return 0;}/* user interface */static intchirp_emul_interpret(os_emul_data *data,		     cpu *processor,		     unsigned_word cia){  error("chirp: interpret method not implemented\n");  return 0;}static intchirp_emul_set_callback(os_emul_data *data,			cpu *processor,			unsigned_word cia){  error("chirp: set_callback method not implemented\n");  return 0;}static intchirp_emul_set_symbol_lookup(os_emul_data *data,			     cpu *processor,			     unsigned_word cia){  error("chirp: set_symbol_lookup method not implemented\n");  return 0;}/* Time */static intchirp_emul_milliseconds(os_emul_data *data,			cpu *processor,			unsigned_word cia){  struct test_args {    /*in*/    /*out*/    unsigned_cell ms;  } args;  unsigned64 time;  /* read in the arguments */  if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia))    return -1;  /* make up a number */  time = event_queue_time(psim_event_queue(cpu_system(processor))) / 1000000;  args.ms = time;  /* write the arguments back out */  TRACE(trace_os_emul, ("milliseconds - out - ms=%ld\n",			(unsigned long)args.ms));  chirp_write_h2t_args(&args,		       sizeof(args),		       data,		       processor, cia);  return 0;}static chirp_services services[] = {  /* client interface */  { "test", chirp_emul_test },  /* device tree */  { "peer", chirp_emul_peer },  { "child", chirp_emul_child },  { "parent", chirp_emul_parent },  { "instance-to-package", chirp_emul_instance_to_package },  { "getproplen", chirp_emul_getproplen },  { "getprop", chirp_emul_getprop },  { "nextprop", chirp_emul_nextprop },  /* { "setprop", chirp_emul_setprop }, */  { "canon", chirp_emul_canon },  { "finddevice", chirp_emul_finddevice },  { "instance-to-path", chirp_emul_instance_to_path },  { "package-to-path", chirp_emul_package_to_path },  { "call-method", chirp_emul_call_method },  /* device I/O */  { "open", chirp_emul_open },  { "close", chirp_emul_close },  { "read", chirp_emul_read },  { "write", chirp_emul_write },  { "seek", chirp_emul_seek },  { "write", chirp_emul_write },  /* memory */  { "claim", chirp_emul_claim },  { "release", chirp_emul_release },  /* control transfer */  { "boot", chirp_emul_boot },  { "enter", chirp_emul_enter },  { "exit", chirp_emul_exit },  { "chain", chirp_emul_chain },  /* user interface */  { "interpret", chirp_emul_interpret },  { "set_callback", chirp_emul_set_callback },  { "set_symbol_lookup", chirp_emul_set_symbol_lookup },  /* time */  { "milliseconds", chirp_emul_milliseconds },  { 0, /* sentinal */ },};/* main handlers *//* Any starting address greater than this is assumed to be an Chirp   rather than VEA */#ifndef CHIRP_START_ADDRESS#define CHIRP_START_ADDRESS 0x80000000#endif#ifndef CHIRP_LOAD_BASE#define CHIRP_LOAD_BASE -1#endiftypedef struct _chirp_note_desc {  signed32 real_mode;  signed32 real_base;  signed32 real_size;  signed32 virt_base;  signed32 virt_size;  signed32 load_base;} chirp_note_desc;typedef enum {  note_missing,  note_found,  note_correct,} note_found_status;typedef struct _chirp_note {  chirp_note_desc desc;  note_found_status found;} chirp_note;typedef struct _chirp_note_head {  unsigned32 namesz;  unsigned32 descsz;  unsigned32 type;} chirp_note_head;static voidmap_over_chirp_note(bfd *image,		    asection *sect,		    PTR obj){  chirp_note *note = (chirp_note*)obj;  if (strcmp(sect->name, ".note") == 0) {    chirp_note_head head;    char name[16];    /* check the head */    if (!bfd_get_section_contents(image, sect,				  &head, 0, sizeof(head)))      return;    head.namesz = bfd_get_32(image, (void*)&head.namesz);    head.descsz = bfd_get_32(image, (void*)&head.descsz);    head.type = bfd_get_32(image, (void*)&head.type);    if (head.type != 0x1275)      return;    /* check the name field */    if (head.namesz > sizeof(name)) {      error("chirp: note name too long (%d > %d)\n", (int)head.namesz, sizeof(name));    }    if (!bfd_get_section_contents(image, sect,				  name, sizeof(head), head.namesz)) {      error("chirp: note name unreadable\n");    }    if (strcmp(name, "PowerPC") != 0) {      printf_filtered("chirp: note name (%s) not `PowerPC'\n", name);    }

⌨️ 快捷键说明

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